【问题标题】:Linking Rust project to cmake project that links to other cmake projects将 Rust 项目链接到链接到其他 cmake 项目的 cmake 项目
【发布时间】:2021-03-23 06:40:58
【问题描述】:

我正在使用 cmake crate 编译一个依赖并编译其他 CMake 项目的 CMake 项目

这是我的build.rs

extern crate cmake;
use cmake::Config;

fn main() {
    let dst = Config::new("src/cpp")
        .define("COMPILE_TARGET", "DESKTOP_x86_64")
        .define("FLAVOR", "DESKTOP")
        .define("LIBOPENVPN3_NOT_BUILD_EXAMPLES", "TRUE")
        .build();

    println!("cargo:rustc-link-search=native={}", dst.display());
    println!("cargo:rustc-link-lib=static=libopenvpn3");
    println!("cargo:rustc-link-lib=dylib=stdc++");
}

这就是我的src/cpp/CMakeLists.txt 编译libopenvpn3 的方式

add_library(libopenvpn3 SHARED OpenVpnInstance.cpp)
target_link_libraries(libopenvpn3 crypto ssl lzo lz4 tins)

但是,当我使用 cargo build 构建时,我会从所有这些库中获得对对象的未定义引用:crypto ssl lzo lz4 tins

我也尝试过创建libopenvpn3STATIC,所以最终的libopenvpn3 将包含所有需要的库:crypto, ssl, lzo, lz4, tins,就像这样:add_library(libopenvpn3 STATIC OpenVpnInstance.cpp),但我仍然得到错误。我认为其他库(crypto, ssl, lzo, lz4, tins)只有在它们也是静态的情况下才会包含在libopenvpn3 中。还是不行?

无论如何,我认为我应该在build.rs 上重新链接这些库,如下所示:

println!("cargo:rustc-link-lib=dylib=openvpn");
println!("cargo:rustc-link-lib=dylib=crypto");
println!("cargo:rustc-link-lib=dylib=lzo");
println!("cargo:rustc-link-lib=dylib=lz4");
println!("cargo:rustc-link-lib=dylib=tins");

但我不知道它们在哪里,因为它们是从 CMakeLists.txt 生成的,而且我认为硬编码生成它们的路径不是一个好主意。

我应该在这里做什么?

更新:

错误示例:

  /home/dev/orwell/liborwell_rust/src/libopenvpn3/src/cpp/openvpn3/openvpn3/openvpn/openssl/util/pem.hpp:66: undefined reference to `BIO_new_mem_buf'
  /usr/bin/ld: /home/dev/orwell/liborwell_rust/src/libopenvpn3/src/cpp/openvpn3/openvpn3/openvpn/openssl/util/pem.hpp:73: undefined reference to `PEM_read_bio'
  /usr/bin/ld: /home/dev/orwell/liborwell_rust/src/libopenvpn3/src/cpp/openvpn3/openvpn3/openvpn/openssl/util/pem.hpp:91: undefined reference to `CRYPTO_free'
  /usr/bin/ld: /home/dev/orwell/liborwell_rust/src/libopenvpn3/src/cpp/openvpn3/openvpn3/openvpn/openssl/util/pem.hpp:92: undefined reference to `CRYPTO_free'
  /usr/bin/ld: /home/dev/orwell/liborwell_rust/src/libopenvpn3/src/cpp/openvpn3/openvpn3/openvpn/openssl/util/pem.hpp:93: undefined reference to `CRYPTO_free'
  /usr/bin/ld: /home/dev/orwell/liborwell_rust/src/libopenvpn3/src/cpp/openvpn3/openvpn3/openvpn/openssl/util/pem.hpp:95: undefined reference to `BIO_free'
  /usr/bin/ld: /home/dev/orwell/lab/hyper_vpn/target/debug/deps/liblibopenvpn3-7498dcb6c355a9d6.rlib(OpenVpnInstance.cpp.o): in function `SimplePacketCrafter::replaceSourceAddressIpv4(unsigned char*, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
  /home/dev/orwell/liborwell_rust/src/libopenvpn3/src/cpp/SimplePacketCrafter.h:117: undefined reference to `Tins::IP::IP(unsigned char const*, unsigned int)'
  /usr/bin/ld: /home/dev/orwell/liborwell_rust/src/libopenvpn3/src/cpp/SimplePacketCrafter.h:118: undefined reference to `Tins::IPv4Address::IPv4Address(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
  /usr/bin/ld: /home/dev/orwell/liborwell_rust/src/libopenvpn3/src/cpp/SimplePacketCrafter.h:118: undefined reference to `Tins::IP::src_addr(Tins::IPv4Address)'
  /usr/bin/ld: /home/dev/orwell/liborwell_rust/src/libopenvpn3/src/cpp/SimplePacketCrafter.h:119: undefined reference to `Tins::PDU::serialize()'
  /usr/bin/ld: /home/dev/orwell/lab/hyper_vpn/target/debug/deps/liblibopenvpn3-7498dcb6c355a9d6.rlib(OpenVpnInstance.cpp.o): in function `Tins::IP::~IP()':
  /home/dev/orwell/liborwell_rust/src/libopenvpn3/src/cpp/libtins/include/tins/ip.h:63: undefined reference to `vtable for Tins::IP'
  /usr/bin/ld: /home/dev/orwell/liborwell_rust/src/libopenvpn3/src/cpp/libtins/include/tins/ip.h:63: undefined reference to `Tins::PDU::~PDU()'

【问题讨论】:

  • “我从所有这些库中获得了对对象的未定义引用” - 请显示(添加到问题帖子中)完全正确这些错误。如果有很多错误,只显示第一个就足够了。
  • @Tsyvarev 刚刚更新,看看。比如Tins::IP::~IP(),这个是libopenvpn3编译链接的,在tins上,链接自target_link_libraries(libopenvpn3 crypto ssl lzo lz4 tins)
  • @Gatonito 我需要对此导入的支持。我有一个 .so,它依赖于其他 .so 文件,如加密、ssl。能否请您指导我将所有依赖项一起导入的步骤。

标签: c++ cmake rust rust-cargo


【解决方案1】:

在 CMakeLists.txt 上,我正在做:

install(TARGETS libopenvpn3 DESTINATION .)

但后来我做到了

install(TARGETS libopenvpn3 crypto ssl lzo lz4 tins DESTINATION .)

所以它会安装所有需要的库

那么,这个build.rs 有效:

extern crate cmake;
use cmake::Config;

fn main() {
    let dst = Config::new("src/cpp")
        .define("COMPILE_TARGET", "DESKTOP_x86_64")
        .define("FLAVOR", "DESKTOP")
        .define("LIBOPENVPN3_NOT_BUILD_EXAMPLES", "TRUE")
        .build();

    println!("cargo:rustc-link-search=native={}", dst.display());
    println!("cargo:rustc-link-lib=dylib=stdc++");
    println!("cargo:rustc-link-lib=static=libopenvpn3");
    println!("cargo:rustc-link-lib=static=crypto");
    println!("cargo:rustc-link-lib=static=lzo");
    println!("cargo:rustc-link-lib=static=lz4");
    println!("cargo:rustc-link-lib=static=tins");
    println!("cargo:rustc-link-lib=static=ssl");
}

但是,我不知道为什么我必须在 Rust 中再次链接它们。它们应该包含在 libopenvpn3 中,因为它们是静态的,不是吗?

【讨论】:

  • 请与我分享上述安装目标的 CmakeList.txt。在这一行之前我应该​​如何调用依赖库
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多