如何通过CMake实现make命令自动构建Rust自定义目标,并支持统一的install与clean操作
如何通过CMake实现make命令自动构建Rust自定义目标,并支持统一的install与clean操作
我来帮你一步步解决这个问题,刚好我之前也做过类似的CMake整合Rust项目的工作,咱们分几个部分来调整你的配置:
一、让Rust目标自动随make构建
你当前的build-binary是自定义目标,默认make不会自动触发它,而且还存在CARGO_BUILD_FLAGS参数传递失败的问题,我们一起修复:
- 给
build-binary添加ALL关键字,让它成为默认构建集合的一部分,这样执行make时会自动构建Rust二进制; - 加上
COMMAND_EXPAND_LISTS参数,解决带空格的CARGO_BUILD_FLAGS变量无法正确展开为多个命令行参数的问题; - 让Rust目标依赖C库,确保C库构建完成后再编译Rust(避免Rust链接时找不到C++库的情况)。
修改后的add_custom_target部分代码如下:
# 先确保Rust目标依赖C++库(这里假设你的C++库目标名为proj-lib,对应add_subdirectory(proj-lib)里的目标) add_dependencies(build-binary proj-lib) add_custom_target( build-binary ALL COMMAND cargo build --package proj-bin ${CARGO_BUILD_FLAGS} COMMAND_EXPAND_LISTS WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Building Rust project with Cargo..." )
二、实现统一的make install
要让make install同时安装C++库和Rust二进制,我们需要给Rust的产物添加安装规则:
- 先根据构建模式确定Rust二进制的路径;
- 使用
install(PROGRAMS)将二进制安装到系统默认的二进制目录(或你指定的目录)。
在你的CMakeLists.txt末尾添加以下代码:
# 确定Rust二进制的构建路径 if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(RUST_BINARY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/target/debug/proj-bin") else() set(RUST_BINARY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/target/release/proj-bin") endif() # 安装Rust二进制到系统bin目录(默认是/usr/local/bin,可通过CMAKE_INSTALL_PREFIX修改) install( PROGRAMS ${RUST_BINARY_PATH} DESTINATION ${CMAKE_INSTALL_BINDIR} COMMENT "Installing Rust binary..." ) # 如果你还需要安装C++库的头文件等,确保proj-lib/CMakeLists.txt里已经有对应的install规则,比如: # install(TARGETS proj-lib LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) # install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/proj-lib)
三、实现统一的make clean
默认的make clean只会清理CMake管理的C++产物,我们需要让它同时清理Rust的target目录:
添加一个自定义的clean目标,并让CMake默认的clean目标依赖它:
add_custom_target( clean-binary COMMAND cargo clean WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Cleaning Rust project artifacts..." ) # 让默认clean目标依赖clean-binary,执行make clean时会同时清理两者 add_dependencies(clean clean-binary)
完整修改后的根目录CMakeLists.txt
把上面的调整整合后,你的根目录CMakeLists.txt应该是这样的:
cmake_minimum_required(VERSION 3.22) project(proj) set(CMAKE_BUILD_TYPE "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug") message(STATUS "Building in Debug mode") add_compile_definitions(DEBUG=1) else() message(STATUS "Building in Release mode") add_compile_definitions(NDEBUG=1) endif() set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) set(CMAKE_INSTALL_RPATH "${ORIGIN}") set(VERSION "1.1.1") # Shared vs Static (LIB_TYPE) option(BUILD_SHARED_LIBS "Build shared libraries" ON) # this builds C++ shared library add_subdirectory(proj-lib) # this builds a Rust binary if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(CARGO_BUILD_FLAGS "--no-default-features --features debug_mode") else() set(CARGO_BUILD_FLAGS "--release --no-default-features --features release_mode") endif() message("cargo build flags ${CARGO_BUILD_FLAGS}") # 让Rust目标依赖C++库,确保构建顺序 add_dependencies(build-binary proj-lib) add_custom_target( build-binary ALL COMMAND cargo build --package proj-bin ${CARGO_BUILD_FLAGS} COMMAND_EXPAND_LISTS WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Building Rust project with Cargo..." ) # 配置Rust二进制安装规则 if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(RUST_BINARY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/target/debug/proj-bin") else() set(RUST_BINARY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/target/release/proj-bin") endif() install( PROGRAMS ${RUST_BINARY_PATH} DESTINATION ${CMAKE_INSTALL_BINDIR} COMMENT "Installing Rust binary..." ) # 配置统一clean规则 add_custom_target( clean-binary COMMAND cargo clean WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Cleaning Rust project artifacts..." ) add_dependencies(clean clean-binary)
验证效果
现在你只需要执行常规的CMake构建流程:
mkdir build && cd build cmake .. make
make会自动先构建C库,再构建Rust二进制;执行make install会同时安装两者;执行make clean会同时清理C和Rust的构建产物。
备注:内容来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

