如何使用C / Qt / CMake项目构建Rust代码?

How can I build Rust code with a C++/Qt/CMake project?

我有一个使用CMake构建的现有C / Qt项目。我想开始添加Rust代码,我可以从主C代码库内部调用该代码。

构造项目的正确方法是什么?

当前项目结构:

1
2
3
4
5
6
7
./CMakeLists.txt
./subproject-foo/CMakeLists.txt
./subproject-foo/src/...
./subproject-bar/CmakeLists.txt
./subproject-bar/src/...
./common/CMakeLists.txt
./common/src/...

我想添加一个具有类似结构的common-rust/...目录。

如何将其合并到项目中?


您可以为此使用ExternalProject模块。它旨在允许建立外部依赖关系-甚至不使用CMake的依赖关系。这是有关使用它的有用文章。

因此,假设您有" common-rust"子目录,并且其Cargo.toml包含:

1
2
3
4
5
6
7
[package]
name ="rust_example"
version ="0.1.0"

[lib]
name ="rust_example"
crate-type = ["staticlib"]

并通过其lib.rs公开函数add

1
2
3
4
#[no_mangle]
pub extern fn add(lhs: u32, rhs: u32) -> u32 {
    lhs + rhs
}

然后您的顶级CMakeLists.txt可能看起来像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
add_executable(Example cpp/main.cpp)

# Enable ExternalProject CMake module
include(ExternalProject)

# Set default ExternalProject root directory
set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/Rust)

# Add rust_example as a CMake target
ExternalProject_Add(
    rust_example
    DOWNLOAD_COMMAND""
    CONFIGURE_COMMAND""
    BUILD_COMMAND cargo build COMMAND cargo build --release
    BINARY_DIR"${CMAKE_SOURCE_DIR}/common-rust"
    INSTALL_COMMAND""
    LOG_BUILD ON)

# Create dependency of Example on rust_example
add_dependencies(Example rust_example)

# Specify Example's link libraries
target_link_libraries(Example
    debug"${CMAKE_SOURCE_DIR}/common-rust/target/debug/librust_example.a"
    optimized"${CMAKE_SOURCE_DIR}/common-rust/target/release/librust_example.a"
    ws2_32 userenv advapi32)

set_target_properties(Example PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON)

当将Rust目标构建为staticlib时,它将输出应链接的其他库。我只在Windows上尝试过此操作,因此将ws2_32userenvadvapi32链接在一起。这显然不是跨平台的,但是您可以足够轻松地处理它(例如,将变量设置为if..else块内适合每个平台的依赖项列表,并将其附加到target_link_libraries调用中)。 >

还请注意,这取决于路径中是否有货物。

您现在应该走了。文件" cpp / main.cpp"可能包含以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
#include <cstdint>
#include <iostream>

extern"C" {
  uint32_t add(uint32_t lhs, uint32_t rhs);
}

int main() {
  std::cout <<"1300 + 14 ==" << add(1300, 14) << '\
'
;
  return 0;
}

这是一个正在运行的示例项目的链接。