如何在cmake+corrosion-rs构建的C++项目中正确链接自有C库与Rust子项目?
如何在cmake+corrosion-rs构建的C++项目中正确链接自有C库与Rust子项目?
嘿,我来帮你搞定这个链接问题~先对齐下你的场景:你有个C++主项目,里面嵌了个Rust目录,用来给主项目的C API做封装,整个项目靠cmake --build build构建,Rust子项目由corrosion-rs负责编译。对吧?那咱们一步步来解决链接的核心问题:
第一步:把你的自有C库变成CMake可识别的目标
首先得让CMake明确知道你的C库是什么——别直接用原始的库文件路径,用CMake的add_library把它声明成一个正式目标,这样后续依赖传递才不会乱。比如你的C库源码在src/c_api下,头文件在include/c_api,那CMake代码可以这么写:
# 声明C库目标,这里用STATIC,要是动态库就改SHARED add_library(my_c_lib STATIC src/c_api/file1.c src/c_api/file2.c ) # 把C库的头文件目录暴露出去,这样依赖它的目标(包括Rust)能找到头文件 target_include_directories(my_c_lib PUBLIC ${PROJECT_SOURCE_DIR}/include/c_api )
第二步:用corrosion-rs关联Rust子项目和C库
接下来要让corrosion知道Rust子项目需要依赖这个C库。先确保你已经在CMake里引入了corrosion,然后导入Rust子项目的Cargo.toml,再把C库目标链接到Rust crate上:
# 先找到corrosion(你应该已经在CMake里配置过这个了) find_package(Corrosion REQUIRED) # 导入rust目录下的Cargo项目,假设你的crate名字是my_rust_api corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml) # 把C库链接到Rust crate上,PRIVATE表示只有Rust编译时需要这个依赖 target_link_libraries(my_rust_api PRIVATE my_c_lib)
另外,Rust代码这边要注意:调用C API的地方必须用extern "C"块声明函数,比如:
extern "C" { fn my_c_function(arg: i32) -> i32; }
如果你的C API头文件里有大量声明,也可以用bindgen自动生成Rust绑定,但如果是简单的API,手动写也没问题。
第三步:把Rust子项目链接到主C++目标
最后一步,让你的C++主程序能调用Rust封装的API。假设你的主程序是个可执行文件my_cpp_app,那把Rust crate链接上去就行:
add_executable(my_cpp_app src/main.cpp ) # 链接Rust crate和C库(如果主程序本身也直接用C库的话) target_link_libraries(my_cpp_app PRIVATE my_rust_api my_c_lib )
几个避坑提醒
- C API的调用约定必须是C风格:你的C头文件里一定要用
extern "C"包裹函数声明,不然C++编译时会做名字修饰,Rust找不到对应的符号:
#ifdef __cplusplus extern "C" { #endif int my_c_function(int arg); #ifdef __cplusplus } #endif
- 检查函数签名匹配:Rust里的
extern "C"声明必须和C库的函数签名完全一致,包括参数类型、返回值类型,不然链接时会报符号找不到。 - 静态/动态库的一致性:如果你的C库是动态库,要确保Rust和C++编译时都能找到对应的动态库文件;如果是静态库,CMake会自动处理库文件的路径,不用额外操心。
备注:内容来源于stack exchange,提问作者Taloonys
相关产品推荐
相关产品推荐

