# Thoughts on improving the cross-compiling documentation

**URL:** <https://igraph.discourse.group/t/thoughts-on-improving-the-cross-compiling-documentation/859>\
**Category:** Installation\
**Tags:** C\
**Created:** [13 September 2021 00:35 UTC](https://igraph.discourse.group/t/thoughts-on-improving-the-cross-compiling-documentation/859 "2021-09-13T00:35:32Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Aaron](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/aaron/32/570_2.png) [@Aaron](https://igraph.discourse.group/u/Aaron)\
**Post date:** [13 September 2021 00:35 UTC](https://igraph.discourse.group/t/thoughts-on-improving-the-cross-compiling-documentation/859/1 "2021-09-13T00:35:32Z")

</div>

I’ve successfully compiled igraph’s C core to Webassembly for one of my projects, which enables the creation of some cool web applications that use igraph in the browser. This was mostly - and surprisingly - painless; the only sticking point was that Section 4.3 was a little vague about the exact workflow for generating and using a different `arith.h`. At the very least, it would have been helpful to see the exact CMake command to define a custom `arith.h` path - I needed some trial and error to eventually get:

```r
set(F2C_EXTERNAL_ARITH_HEADER "path/to/custom/arith.h" CACHE FILEPATH "" FORCE)

```

Listing a few case studies on how exactly to generate a cross-compiled `arith.h` would also have been nice. For example, [this](https://github.com/jkanche/scran.js/blob/master/wasm/extern/igraph/CMakeLists.txt) is the CMake file used to generate my Wasm-compatible `arith.h`.

---

<div class="post-metadata">

**Author:** ![tamas](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/tamas/32/1261_2.png) [@tamas](https://igraph.discourse.group/u/tamas)\
**Post date:** [14 September 2021 10:43 UTC](https://igraph.discourse.group/t/thoughts-on-improving-the-cross-compiling-documentation/859/2 "2021-09-14T10:43:34Z")

</div>

Thanks for the feedback; we will improve the documentation a bit in the section that you mentioned. However, before doing that, I’d like to understand why you are setting things the way you do it.

In theory, the preferred way for cross-compiling igraph and setting the path to the `arith.h` header should be done in the invocation to CMake (that is, if you are building igraph on its own and not as part of another project):

```bash
$ mkdir build
$ cd build
$ cmake .. -DF2C_EXTERNAL_ARITH_HEADER=path/to/custom/arith.h
$ cmake --build .

```

An alternative way is to use the CMake GUI (if you have it installed):

```bash
$ mkdir build
$ cd build
$ ccmake .
# set things on the GUI, optionally making advanced variables
# visible by pressing 't'
$ cmake --build .

```

Now, I would have assumed that if igraph is built as part of another project, one can simply use `set(F2C_EXTERNAL_ARITH_HEADER "path/to/custom/arith.h")` in the parent CMakeLists.txt file, without the `CACHE FILEPATH "" FORCE` part. Can you explain why these arguments are necessary?

Also, there are multiple ways to include igraph as an external project into another if simply linking to igraph is not enough (as it is in your case). My approach was typically to vendor igraph’s source in the project tree, and then call something like `add_subdirectory(vendor/igraph)` in `CMakeLists.txt`. It could be the case that since you are using `FetchContent`, things work differently and that’s why the extra arguments to `set()` are necessary, but I’d like to understand this before documenting it. There is also the [ExternalProject](https://cmake.org/cmake/help/v3.20/module/ExternalProject.html) module in CMake, which apparently allows passing extra arguments to CMake in the configuration step of the sub-project, so this could be yet another place where `F2C_EXTERNAL_ARITH_HEADER` is injected.

Long story short, I’m primarily interested in whether the `set()` command you outlined above could be simplified by omitting the `CACHE FILEPATH "" FORCE` part or they are absolutely necessary in your use-case.

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [14 September 2021 14:29 UTC](https://igraph.discourse.group/t/thoughts-on-improving-the-cross-compiling-documentation/859/3 "2021-09-14T14:29:28Z")

</div>

I am not at all familiar with compiling for WebAssembly. Is (static) linking really not possible with this system? Do you really need to compile igraph and your project at the same time? Is it not possible to first compile igraph into a static library, then link to it from your project?

---

<div class="post-metadata">

**Author:** ![Aaron](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/aaron/32/570_2.png) [@Aaron](https://igraph.discourse.group/u/Aaron)\
**Post date:** [16 September 2021 05:56 UTC](https://igraph.discourse.group/t/thoughts-on-improving-the-cross-compiling-documentation/859/4 "2021-09-16T05:56:47Z")

</div>

Thanks both - responses below. I’ll preface this by saying that I’m definitely a CMake novice, so there may well be a smarter way of doing things than the approach I ended up with.

> [@tamas](#):
>
> Long story short, I’m primarily interested in whether the `set()` command you outlined above could be simplified by omitting the `CACHE FILEPATH "" FORCE` part or they are absolutely necessary in your use-case.

Indeed, that’s what I tried first. But apparently, CMake’s local variables (defined by `SET()` without `CACHE`) are not the same as CMake’s cache variables (defined by `SET()` with `CACHE`). So setting the former doesn’t actually get alter the variable used by `igraph/vendor/f2c/CMakeLists.txt`.

Further reading of various CMake docs indicates that the cache variables are very much designed with command line arguments in mind, and indeed, `-DF2C_EXTERNAL_ARITH_HEADER=path/to/custom/arith.h` works fine. However, sometimes it’s nice to just throw it into the `CMakeLists.txt` so that it’s included in every build, no matter what. As such, I followed the advice [here](https://cliutils.gitlab.io/modern-cmake/chapters/basics/variables.html) (see comments about the “make-shift global variable”) to forcibly set it, always, to the desired path.

For those who are interested, I made a little example to demonstrate:

```auto
cmake_minimum_required(VERSION 3.14)

project(test
    VERSION 1.0.0
    DESCRIPTION "Testing"
    LANGUAGES CXX)

set(F2C_EXTERNAL_ARITH_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/arith.h")

include(FetchContent)

FetchContent_Declare(
    igraph
    URL https://github.com/igraph/igraph/releases/download/0.9.4/igraph-0.9.4.tar.gz
    URL_HASH MD5=ea8d7791579cfbc590060570e0597f6b
)

FetchContent_MakeAvailable(igraph)

```

When cross-compiled with Emscripten’s CMake configuration, this gives a warning about an unset `F2C_etc.`, which is only eliminated when adding those extra flags to `SET()`.

(An extra consideration is that I use the same `CMakeLists.txt` to _generate_ the `arith.h` in the first place, by adding some instructions to cross-compile and execute the `arithchk.c` thing. In this case, it’s natural to set the `F2C_etc.` variable inside the `CMakeLists.txt` because CMake already knows the location of the newly generated `arith.h`. Setting it on the command line makes it a bit more awkward because I need to manually ensure that the path I generated inside the `CMakeLists.txt` is the same as that used on the command line.)

To be honest, I think the real issue here is that CMake’s way of setting cache variables inside `CMakeLists.txt` is way more complicated than setting it on the command line. Maybe this is by design, I don’t know, but it isn’t really an issue with **igraph** itself. Nonetheless, it would have been helpful if the **igraph** C installation docs provided a link to some instructions on setting these cache variables inside the `CMakeLists.txt`, given that the same documentation already shows how to set some of these variables in command-line `cmake` invocations.

> [@szhorvat](#):
>
> Is (static) linking really not possible with this system? Do you really need to compile igraph and your project at the same time? Is it not possible to first compile igraph into a static library, then link to it from your project?

Static linking is possible, but not for object files generated for the host architecture. I basically need to build `libgraph.a` as a Wasm “static library”, and then I link my project (also compiled to Wasm) to that. Which makes sense to me; the Wasm binary won’t have the full numerical capabilities of any given host architecture, given that the same binary needs to run on everyone’s browser.

So, I could certainly compile **igraph** somewhere else and re-use the resulting `libgraph.a` static library in all my igraph-related Wasm projects. But that initial compilation would still need to use a separate toolchain and a different `arith.h` that is appropriate to the Wasm target.

---

<div class="post-metadata">

**Author:** ![Vsevolod](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/vsevolod/32/788_2.png) [@Vsevolod](https://igraph.discourse.group/u/Vsevolod)\
**Post date:** [21 June 2022 08:09 UTC](https://igraph.discourse.group/t/thoughts-on-improving-the-cross-compiling-documentation/859/5 "2022-06-21T08:09:53Z")

</div>

Good day, Aaron!  
I seek for graph library in js, but not found one with good theoretical methods. Now, with wasm, it will be good way to use existing non-js libs. So can you help with igraph-wasm module?  
If you have compiled igraph, can you share the wasm module?  
p.s. Can you say more about your project?  
p.p.s. I want to use it for a small graph analisys: [Attitudes in Sankey Diagram / moskvo / Observable](https://observablehq.com/@moskvo/attitudes-in-sankey-diagram)
