ARTICLE AD BOX
In my project, the Rust binary rust-bin needs to link to a C++ shared library sub-project cpp-lib, for which I'm using cmake rust crate as a build dependency. The entire project builds fine, but the C++ shared library is not getting installed to /usr/local/lib and also the library header files not getting installed to /usr/local/include, instead they are getting installed in the C++ sub-project cpp-lib path.
Project Hierarchy
. ├── CMakeLists.txt ├── Cargo.toml └── rust-bin ├── Cargo.toml ├── build.rs ├── cpp-lib │ ├── CMakeLists.txt │ ├── inc │ │ └── lib.hpp │ └── src │ └── lib.cpp └── src └── main.rsCMakeLists.txt
cmake_minimum_required(VERSION 3.22) project(cmake-demo) 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") string(REPLACE "." ";" ver_list ${VERSION}) list(GET ver_list 0 LIB_MAJOR) list(GET ver_list 1 LIB_MINOR) include(GNUInstallDirs) if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(CARGO_BUILD_FLAGS ) set(RUST_BUILD_TYPE "debug") else() set(CARGO_BUILD_FLAGS --release) set(RUST_BUILD_TYPE "release") endif() add_custom_target( build-bin ALL COMMAND cargo build --package rust-bin ${CARGO_BUILD_FLAGS} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Building Rust project with Cargo..." ) install( PROGRAMS "${PROJECT_SOURCE_DIR}/target/${RUST_BUILD_TYPE}/rust-bin" TYPE BIN ) set_target_properties( build-bin PROPERTIES ADDITIONAL_CLEAN_FILES "${PROJECT_SOURCE_DIR}/target" )Cargo.toml
[workspace] resolver = "3" members = ["rust-bin"] [workspace.package] version = "1.1.1" edition = "2024" publish = false [profile.optimized-release] inherits = "release" lto = true strip = true [profile.yocto-release] inherits = "release" lto = truerust-bin/Cargo.toml
[package] name = "rust-bin" version.workspace = true edition.workspace = true publish.workspace = true [dependencies] [build-dependencies] cmake = "0.1.57"rust-bin/build.rs
use std::env; use cmake::Config; fn main() { let manifest = env!("CARGO_MANIFEST_DIR"); let cpp_lib_path = format!("{manifest}/cpp-lib"); let out_dir = format!("{manifest}/cpp-lib"); let dst = Config::new(cpp_lib_path) .pic(true) .out_dir(out_dir.clone()) .build(); println!("{}", dst.display()); println!("cargo:rustc-link-search=native={out_dir}/lib"); println!("cargo::rustc-link-arg=-Wl,-rpath='$$ORIGIN/../lib'"); println!("cargo::rustc-link-lib=sup_lib"); }rust-bin/src/main.rs
fn main() { println!("Hello, world!"); }rust-bin/cpp-lib/CMakeLists.txt
cmake_minimum_required(VERSION 3.22) project(cmake-cpp-lib) 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") string(REPLACE "." ";" ver_list ${VERSION}) list(GET ver_list 0 LIB_MAJOR) list(GET ver_list 1 LIB_MINOR) # Shared vs Static (LIB_TYPE) option(BUILD_SHARED_LIBS "Build shared libraries" ON) include(GNUInstallDirs) set(TARGET_NAME sup_lib) set(TARGET_ALIAS_NAME sup-lib) set(SRC src/lib.cpp ) add_library(${TARGET_NAME} ${SRC}) add_library(${PROJECT_NAME}::${TARGET_ALIAS_NAME} ALIAS ${TARGET_NAME}) set_target_properties( ${TARGET_NAME} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_RPATH}" ) target_include_directories( ${TARGET_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> ) set_target_properties( ${TARGET_NAME} PROPERTIES OUTPUT_NAME ${TARGET_NAME} VERSION "${VERSION}" SOVERSION "${LIB_MAJOR}.${LIB_MINOR}" ) install( TARGETS ${TARGET_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install( DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/inc" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}-${TARGET_ALIAS_NAME}" FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp" )rust-bin/cpp-lib/src/lib.cpp
#include "lib.hpp" int add(int a, int b) { return a + b; }rust-bin/cpp-lib/inc/lib.hpp
int add(int a, int b);Build steps (from main project)
mkdir build cd build cmake .. make