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

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

toml 复制代码
[package]
name = "rust_lib"
version = "0.1.0"
edition = "2021"

[dependencies]

[lib]
crate-type = ["cdylib"]

2、在 src/lib.rs 创建greet_from_rust动态库函数

rust 复制代码
#[no_mangle]
pub extern "C" fn greet_from_rust() {
    println!("Hello, greeting!")
}

3、创建call_rust.c,内容如下

c 复制代码
extern void greet_from_rust();

int main(void) {
    greet_from_rust();
    return 0;
}

4、编写Cmake构建规则,创建CMakeLists.txt, 其内容如下

复制代码
cmake_minimum_required(VERSION 3.22)
project(call_rust)

set(ARGS --target-dir ${CMAKE_BINARY_DIR}/target)

if (CMAKE_BUILD_TYPE STREQUAL "Release")
    message(STATUS "[RUST] Detected release build")
    set(build_profile "release")
    set(ARGS ${ARGS} --release)
else()
    message(STATUS "[RUST] Using default debug build")
    set(build_profile "debug")
endif()

add_custom_target(
    cargo_build ALL
    COMMAND 
        ${CMAKE_COMMAND} -E env 
        cargo build ${ARGS}
    DEPENDS src/lib.rs
)

add_executable(call_rust call_rust.c)
add_library(rust_lib SHARED IMPORTED)
set_property(TARGET rust_lib PROPERTY IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/target/${build_profile}/librust_lib.so")
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 . 构建当前项目, 输出

shell 复制代码
$ cmake  -DCMAKE_BUILD_TYPE:STRING=Release . && cmake --build . && ./call_rust
-- [RUST] Detected release build
-- Configuring done
-- Generating done
-- Build files have been written to: /root/workspace/build-tool-examples/rust_lib
Compiling rust_lib v0.1.0 (/root/workspace/build-tool-examples/rust_lib)
Finished release profile [optimized] target(s) in 0.44s
[  0%] Built target cargo_build
Consolidate compiler generated dependencies of target call_rust
[ 50%] Linking C executable call_rust
[100%] Built target call_rust
Hello, greeting!
相关推荐
wuminyu15 小时前
Kafka中sendfile与mmap实现机制解析
java·linux·c语言·jvm·c++
Blockbuater_drug16 小时前
FreeSASA: 开源 SASA 计算库,pip 一条命令替代 NACCESS
c语言·开源·sasa·freesasa·溶剂可及表面积·naccess·python api
Logic10117 小时前
C语言/数据结构位运算题解:异或XOR找出蛋糕订单中的“VIP独特口味“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
Logic10118 小时前
C语言/数据结构位运算题解:异或XOR找出飞行棋中的“独特颜色棋子“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
Logic10120 小时前
C语言/数据动态规划题解:翻转一次子数组后的最大子数组和——四状态DP(O(n)时间O(1)空间)
c语言·数据结构·动态规划·时间复杂度·算法题·状态机dp·最大子数组和
无小道20 小时前
C++——列表初始化
c++·列表初始化
blueSatchel20 小时前
c++action 编写(ros-humble)
c++·ros2
Logic1011 天前
C语言/数据结构字符串题解:找出DNA序列中未配对的独特序列——排序+遍历(O(nlogn))
c语言·数据结构·字符串·数组·排序·时间复杂度·算法题
老赵的博客1 天前
c++面试之从虚函数表到Rtti一次性讲清楚
c++·qt
Navigator_Z1 天前
LeetCode //C - 1248. Count Number of Nice Subarrays
c语言·算法·leetcode