Xây dựng hỗn hợp Rust/C/C++ - Tích hợp Cargo với CMake để biên dịch thư viện động

CMake là một công cụ biên dịch đa ngữ mạnh mẽ, với các module tích hợp sẵn cung cấp khả năng mở rộng đáng kể.

Công cụ xây dựng chính thức của Rust là Cargo, cung cấp nhiều tính năng như tải xuống, tải lên và biên dịch các gói phụ thuộc, giúp quá trình phát triển dự án Rust trở nên thuận tiện hơn.

Hiện nay, hầu hết các dự án C++ sử dụng CMake để quản lý việc xây dựng. Khi cần tích hợp Rust vào hệ thống CMake để xây dựng thư viện động C++, có thể sử dụng kịch bản xây dựng Cargo với crate cmakes-rs.

Để gọi Cargo xây dựng thư viện động từ Rust và sử dụng CMake làm công cụ điều phối thống nhất, phương pháp phổ biến hiện nay là sử dụng module add_custom_target của CMake để gọi quá trình xây dựng Cargo.

Ví dụ thực tế

  1. Tạo dự án Rust mới bằng lệnh cargo new rust-shared --lib và chỉ định loại thư viện là cdylib trong Cargo.toml
[package]
name = "rust_shared"
version = "0.2.0"
edition = "2021"

[dependencies]

[lib]
crate-type = ["cdylib"]
  1. Tạo hàm trong thư viện động tại src/lib.rs
#[no_mangle]
pub extern "C" fn say_hello_from_rust() {
    println!("Xin chào từ thế giới Rust!")
}
  1. Tạo file main.c để gọi hàm từ thư viện Rust
extern void say_hello_from_rust();

int main(void) {
    say_hello_from_rust();
    return 0;
}
    Viết quy tắc xây dựng CMake trong CMakeLists.txt
cmake_minimum_required(VERSION 3.22)
project(rust_c_integration)

set(CARGO_ARGS --target-dir ${CMAKE_BINARY_DIR}/rust_target)

if (CMAKE_BUILD_TYPE STREQUAL "Release")
    message(STATUS "[RUST] Phát hiện bản build Release")
    set(build_mode "release")
    set(CARGO_ARGS ${CARGO_ARGS} --release)
else()
    message(STATUS "[RUST] Sử dụng build debug mặc định")
    set(build_mode "debug")
endif()

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

add_executable(main_program main.c)
add_library(rust_shared SHARED IMPORTED)
set_property(TARGET rust_shared PROPERTY IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/rust_target/${build_mode}/librust_shared.so")
target_link_libraries(main_program PUBLIC rust_shared)

Module add_custom_target gọi Cargo để biên dịch src/lib.rs thành thư viện động. Để thuận tiện, thư mục xây dựng của Cargo được đặt trong dự án hiện tại.

add_libraryset_property liên kết thư viện động đã tạo với target rust_shared. Cuối cùng, thư viện rust_shared được liên kết với target nhị phân main_program thông qua target_link_libraries.

Cấu hình xây dựng CMake đã hoàn tất. Chúng ta có thể sử dụng các lệnh sau để chuyển đổi tùy chọn xây dựng:

cmake -DCMAKE_BUILD_TYPE:STRING=Release .
cmake -DCMAKE_BUILD_TYPE:STRING=Debug .

Các lệnh này tương ứng với tùy chọn --release của Cargo. Sau đó, sử dụng:

cmake --build .

để xây dựng dự án hiện tại. Kết quả đầu ra:

$ cmake -DCMAKE_BUILD_TYPE:STRING=Release . && cmake --build . && ./main_program
-- [RUST] Phát hiện bản build Release
-- Configuring done
-- Generating done
-- Build files have been written to: /duong/dan/d/toi/danh muc/xay-dung
Compiling rust_shared v0.2.0 (/duong/dan/d/toi/danh muc/xay-dung)
Finished release profile [optimized] target(s) in 0.52s
[  0%] Built target rust_build
Consolidate compiler generated dependencies of target main_program
[ 50%] Linking C executable main_program
[100%] Built target main_program
Xin chào từ thế giới Rust!

Thẻ: cmake Rust cargo thư viện động tích hợp-build

Đăng vào ngày 30 tháng 6 lúc 13:40