+++ 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="content/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="content/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="content/2022-05-30-cmake-cargo-example/Makefile") }} ``` [post-src]: https://git.memzero.de/blog/tree/content/2022-05-30-cmake-cargo-example?h=main [cargo-toml]: https://git.memzero.de/blog/tree/content/2022-05-30-cmake-cargo-example/libcalc/Cargo.toml?h=main [build-rs]: https://git.memzero.de/blog/tree/content/2022-05-30-cmake-cargo-example/libcalc/build.rs?h=main [make]: https://git.memzero.de/blog/tree//content/2022-05-30-cmake-cargo-example/Makefile?h=main [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