diff options
Diffstat (limited to 'content/2022-05-30-cmake-cargo-example.md')
-rw-r--r-- | content/2022-05-30-cmake-cargo-example.md | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/content/2022-05-30-cmake-cargo-example.md b/content/2022-05-30-cmake-cargo-example.md new file mode 100644 index 0000000..56810e6 --- /dev/null +++ b/content/2022-05-30-cmake-cargo-example.md @@ -0,0 +1,68 @@ ++++ +title = "Example: integrate cargo into cmake" + +[taxonomies] +tags = ["rust", "c++", "cmake"] ++++ + +This post outlines an example on how to integrate a library written in `rust` +into a cmake based `C/C++` project using the [ExternalProject][cmake-ext_prj] +module. +I created that post mainly as reference for myself but hopefully it is helpful +to someone else who stumbles across it :^) + +The rust library is compiled as static library and then linked into the +executable written in C. The top-level cmake file to build the executable just +includes the rust crate via [add_subdirectory][cmake-add_sub] and then adds a +link dependency. + +```cmake +{{ include(path="2022-05-30-cmake-cargo-example/CMakeLists.txt") }} +``` + +The more interesting bits are included in the rust crate. + +First we have to tell cargo to output a static library. This can be done with +the following configuration in the [Cargo.toml][cargo-toml] file. +```toml +[lib] +crate-type = ["staticlib"] +``` +> A header file with the C definitions is automatically generated using the +> [cbindgen][cbindgen] crate invoked from the [build.rs][build-rs] script. + +Finally we can write a `CMakeLists.txt` file which exposes a pseudo target +`libcalc` to cmake which consumers can depend on. The pseudo target depends on +the `ext_libcalc` ([ExternalProject][cmake-ext_prj]) target. + +The `BUILD_COMMAND` contains an generator expression to build the rust crate in +release mode in case `CMAKE_BUILD_TYPE=Release` is configured. + +Additionally, the properties of the `libcalc` pseudo target are setup to +automatically add the correct static library and add the include path +accordingly for consumers. + +With this setup, the rust crate is nicely build out of source. This is achieved +by the following two configurations: +- Pass `--target-dir` to cargo to specify the build directory. +- Setup `LIBCALC_BUILD_DIR` before invoking cargo to tell [build.rs][build-rs] + where to generate the C header. + +```cmake +{{ include(path="2022-05-30-cmake-cargo-example/libcalc/CMakeLists.txt") }} +``` + +The sources referenced in this post are available [here][post-src]. This +repository includes the following Makefile to build and run the calc +executable. +```make +{{ include(path="2022-05-30-cmake-cargo-example/Makefile") }} +``` + +[post-src]: https://git.memzero.de/johannst/blog/src/branch/main/content/2022-05-30-cmake-cargo-example +[cargo-toml]: https://git.memzero.de/johannst/blog/src/branch/main/content/2022-05-30-cmake-cargo-example/libcalc/Cargo.toml +[build-rs]: https://git.memzero.de/johannst/blog/src/branch/main/content/2022-05-30-cmake-cargo-example/libcalc/build.rs +[make]: https://git.memzero.de/johannst/blog/src/branch/main/content/2022-05-30-cmake-cargo-example/Makefile +[cbindgen]:https://lib.rs/crates/cbindgen +[cmake-add_sub]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html?highlight=add_subdirectory +[cmake-ext_prj]: https://cmake.org/cmake/help/latest/module/ExternalProject.html |