【问题标题】:How can I build Rust code with a C++/Qt/CMake project?如何使用 C++/Qt/CMake 项目构建 Rust 代码?
【发布时间】:2015-09-18 16:14:02
【问题描述】:

我有一个使用 CMake 构建的现有 C++/Qt project。我想开始添加可以从主 C++ 代码库中调用的 Rust 代码。

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

当前项目结构:

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

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

我怎样才能把它整合到项目中?

【问题讨论】:

  • 你可以使用cargo吗?如果是这样,我建议只制定一些要求 Cargo 的规则。

标签: c++ qt cmake rust


【解决方案1】:

您可以为此使用ExternalProject module。它旨在允许构建外部依赖项——即使是不使用 CMake 的依赖项。这是一个useful article 使用它。

假设你有你的“common-rust”子目录,它的 Cargo.toml 包含:

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

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

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

#[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 上尝试过,因此链接了 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 的链接。

【讨论】:

  • 哇,多么全面的答案。非常感谢!
  • 是的 - 不用担心。这是一个有趣的问题,我想看看它是如何工作的 :)
  • 如果您在 Windows 以外的平台上构建,则需要将系统链接库 ws2_32 userenv advapi32 更改为其他内容。例如,在 macOS 上,您需要:m c System resolv.
【解决方案2】:

现在有一个项目可以用来构建:腐蚀https://github.com/corrosion-rs/corrosion

所以你的 CMakeLists.txt 就只有这个:

# See the Corrosion README to find more ways to get Corrosion
find_package(Corrosion REQUIRED)

corrosion_import_crate(MANIFEST_PATH ${CMAKE_SOURCE_DIR}/common-rust)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-26
    • 2017-04-10
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    相关资源
    最近更新 更多