我已经用现有的Cmac++project构建了一个Qt.我想开始添加 rust 代码,我可以从主C++代码库里面调用.

构建项目的正确方式是什么?

目前的项目 struct :

./CMakeLists.txt
./subproject-foo/CMakeLists.txt
./subproject-foo/src/...
./subproject-bar/CmakeLists.txt
./subproject-bar/src/...
./common/CMakeLists.txt
./common/src/...

我想添加一个类似 struct 的common-rust/...目录.

我该如何将其纳入项目中?

推荐答案

你可以用ExternalProject module来做这个.它的设计允许构建外部依赖关系——即使是不使用CMake的依赖关系.下面是关于使用它的useful article.

假设你有你的"common rust"子目录和它的Cargo .toml包含:

[package]
name = "rust_example"
version = "0.1.0"

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

它通过其库公开了一个函数add.rs:

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

然后是你的顶级CMakeLists.txt可以是这样的:

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上try 过,因此ws2_32userenvadvapi32是链接的.这显然不是跨平台的,但您可以很容易地处理它(例如,将一个变量设置为if..else块中适合每个平台的依赖项列表,并将其附加到target_link_libraries调用中).

还请注意,这取决于路径中是否有可用的Cargo .

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

#include <cstdint>
#include <iostream>

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

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

这里有一个链接到一个正在工作的example project.

Rust相关问答推荐

在‘await’点上使用‘std::同步::Mutex’是否总是会导致僵局?

Rust kill std::processs::child

为什么要在WASM库中查看Rust函数需要`#[no_mangle]`?

这种获取-释放关系是如何运作的?

如何格式化传入Rust中mysql crate的Pool::new的字符串

除了调用`waker.wake()`之外,我如何才能确保future 将再次被轮询?

为什么AsyncRead在Box上的实现有一个Unpin特征绑定?

返回优化后的标题:返回异步块的闭包的类型擦除

OpenGL 如何同时渲染无纹理的四边形和有纹理的四边形

为什么这段 Rust 代码会在没有递归或循环的情况下导致堆栈溢出?

是否可以通过可变引用推进可变切片?

在 Rust 中使用 `SecTrustSettingsSetTrustSettings` 绑定导致 `errSecInternalComponent`

rust tokio::spawn 在 mutexguard 之后等待

为什么数组不像向量那样在 for 块之后移动?

`移动||异步移动{...}`,如何知道哪个移动正在移动哪个?

Rust 中 `Option` 的内存开销不是常量

将 `&T` 转换为新类型 `&N`

在空表达式语句中移动的值

如何制作具有关联类型的特征的类型擦除版本?

在传输不可复制的值时实现就地枚举修改