Ответ 1
Для этого вы можете использовать ExternalProject
модуль. Он предназначен для создания внешних зависимостей - даже тех, которые не используют CMake. Здесь полезная статья о ее использовании.
Итак, скажите, что у вас есть подкаталог "common-rust", а его Cargo.toml содержит:
[package]
name = "rust_example"
version = "0.1.0"
[lib]
name = "rust_example"
crate-type = ["staticlib"]
и он предоставляет функцию add
через свой lib.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 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_32
, userenv
и advapi32
связаны. Очевидно, это не будет кросс-платформенным, но вы можете справиться с этим достаточно легко (например, установите переменную в список зависимостей, соответствующих каждой платформе внутри блока 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;
}
Здесь ссылка на рабочий проект .