找回密码
 立即注册
首页 业界区 业界 Rust/C/C++ 混合构建 - Cmake集成Cargo编译动态库 ...

Rust/C/C++ 混合构建 - Cmake集成Cargo编译动态库

祉遛吾 7 天前
Cmake是一个强大的多语言编译工具,其内置模块提供了强大的扩展能力。
Rust官方的构建工具是Cargo,其提供了依赖下载,上传和编译等多项功能,极大的便利了Rust项目的开发。
目前C++多数用Cmake构建,如果是Rust集成cmake构建c++动态库,可以用Cargo构建脚本集成cmake-rs构建。
如果要调用Cargo构建Rust编译的动态库,并且通过cmake作为构建工具统一调度,目前主流方案是使用Cmake内置的add_custom_target模块调用Cargo构建。
Playground

1、cargo new rust-lib —lib 创建rust 项目,并在Cargo.toml中指定类型为cdylib
  1. [package]
  2. name = "rust_lib"
  3. version = "0.1.0"
  4. edition = "2021"
  5. [dependencies]
  6. [lib]
  7. crate-type = ["cdylib"]
复制代码
2、在 src/lib.rs 创建greet_from_rust动态库函数
  1. #[no_mangle]
  2. pub extern "C" fn greet_from_rust() {
  3.     println!("Hello, greeting!")
  4. }
复制代码
3、创建call_rust.c,内容如下
  1. extern void greet_from_rust();
  2. int main(void) {
  3.     greet_from_rust();
  4.     return 0;
  5. }
复制代码
4、编写Cmake构建规则,创建CMakeLists.txt, 其内容如下
  1. cmake_minimum_required(VERSION 3.22)
  2. project(call_rust)
  3. set(ARGS --target-dir ${CMAKE_BINARY_DIR}/target)
  4. if (CMAKE_BUILD_TYPE STREQUAL "Release")
  5.     message(STATUS "[RUST] Detected release build")
  6.     set(build_profile "release")
  7.     set(ARGS ${ARGS} --release)
  8. else()
  9.     message(STATUS "[RUST] Using default debug build")
  10.     set(build_profile "debug")
  11. endif()
  12. add_custom_target(
  13.     cargo_build ALL
  14.     COMMAND
  15.         ${CMAKE_COMMAND} -E env
  16.         cargo build ${ARGS}
  17.     DEPENDS src/lib.rs
  18. )
  19. add_executable(call_rust call_rust.c)
  20. add_library(rust_lib SHARED IMPORTED)
  21. set_property(TARGET rust_lib PROPERTY IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/target/${build_profile}/librust_lib.so")
  22. target_link_libraries(call_rust PUBLIC rust_lib)总结
复制代码
add_custom_target调用Cargo将src/lib.rs 编译成动态库,为了方便将Cargo的构建目录指定在当前项目下。
add_library和set_property 将生成的动态库绑定到rust_lib 这个target上,最后将动态库rust_lib通过
target_link_libraries 链接到call_rust二进制target上
Cmake构建配置完成,我们可以通过
cmake  -DCMAKE_BUILD_TYPE:STRING=Release . 和cmake  -DCMAKE_BUILD_TYPE:STRING=Debug .
这两个命令切换构建选项,这也对应了Cargo构建的—release选项,然后通过
cmake —build . 构建当前项目, 输出
  1. $ cmake  -DCMAKE_BUILD_TYPE:STRING=Release . && cmake --build . && ./call_rust
  2. -- [RUST] Detected release build
  3. -- Configuring done
  4. -- Generating done
  5. -- Build files have been written to: /root/workspace/build-tool-examples/rust_lib
  6. Compiling rust_lib v0.1.0 (/root/workspace/build-tool-examples/rust_lib)
  7. Finished release profile [optimized] target(s) in 0.44s
  8. [  0%] Built target cargo_build
  9. Consolidate compiler generated dependencies of target call_rust
  10. [ 50%] Linking C executable call_rust
  11. [100%] Built target call_rust
  12. Hello, greeting!
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册