Связывание проекта Rust с проектом cmake, который ссылается на другие проекты cmake

Я использую ящик cmake для компиляции проекта 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.

Я также попытался сделать libopenvpn3 STATIC, чтобы окончательный 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()'

person Gatonito    schedule 04.03.2021    source источник
comment
Я получаю неопределенные ссылки на объекты из всех этих библиотек - Пожалуйста, покажите (добавьте в вопрос) эти ошибки точно. В случае большого количества ошибок достаточно показать только первые.   -  person Tsyvarev    schedule 04.03.2021
comment
@Tsyvarev только что обновился, посмотрите. Например, Tins::IP::~IP(), это скомпилировано и связано с libopenvpn3 и находится на tins, связано с target_link_libraries(libopenvpn3 crypto ssl lzo lz4 tins)   -  person Gatonito    schedule 05.03.2021


Ответы (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, поскольку они статичны, не так ли?

person Gatonito    schedule 05.03.2021