aboutsummaryrefslogtreecommitdiffhomepage
path: root/content/2022-05-30-cmake-cargo-example.md
diff options
context:
space:
mode:
authorJohannes Stoelp <johannes.stoelp@gmail.com>2022-05-30 20:44:53 +0200
committerJohannes Stoelp <johannes.stoelp@gmail.com>2022-05-30 20:44:53 +0200
commita93e90cf3c50344a2582acb0e60187dbef90ee28 (patch)
tree2fd049370f4bf5df5792258d3471f582d1bf7449 /content/2022-05-30-cmake-cargo-example.md
parent3389d0a128d874d930e22f256b2646dd86b3b402 (diff)
downloadblog-a93e90cf3c50344a2582acb0e60187dbef90ee28.tar.gz
blog-a93e90cf3c50344a2582acb0e60187dbef90ee28.zip
cmake: add example how to integrate cargo
Diffstat (limited to 'content/2022-05-30-cmake-cargo-example.md')
-rw-r--r--content/2022-05-30-cmake-cargo-example.md68
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