Open bertulli opened 2 weeks ago
I would also like to add I am facing a similar issue I believe. I receive similar errors from my cxx_build when I allow corrosion to dictate the rust linker. If I set NO_LINKER_OVERRIDE then everything builds but at runtime there are undefined symbols.
corrosion provides the corrosion_add_cxxbridge()
helper function for generating the cxx bindings.
Any build.rs
files are basically a black box for corrosion, so it can't really help if you use the build.rs approach. You can make it work, but ensuring that the link line on both sides (C++ and rust) is correct can be difficult.
Thanks for your answer! There's something I don't understand then, I think.
First: if I got it right, the reason the CMake linker isn't working in my example is that I'm trying to link the Azure library to my Rust executable, but the function throwing an error isn't there: it is function cxxbridge1$IoTHub_Init
, which is generated by cxx and is found in libMWE.a
. So I would need to link the Azure SDK to that, but this is not what I expressed in my current CMake. My first question is: should it really matter? Given that libMWE.a
is a static library, can't I link it partially with the functions it finds, and then postpone all the "executable-level" linking just to the last invocation, where the executable is produced?
Second: how can I use Corrosion to do that? From what I understand from the docs, the function corrosion_add_cxxbridge
is used to export the bindings to C++, not from. In other words, I can use it to create a Rust library and link it into a C++ executable, not the other way around. Is this correct, or am I doing something wrong? I tried adding to my example
corrosion_add_cxxbridge(iothub_client_cxx
CRATE MWE
FILES main.rs)
target_link_libraries(iothub_client_cxx iothub_client)
but it didn't work, also because I then can't find the headers in the cxx-bridge include. Thanks!
In other words, I can use it to create a Rust library and link it into a C++ executable, not the other way around.
No, its supposed to work both ways. Here is a very simple example / test project which links a cpp library into a rust binary: https://github.com/corrosion-rs/corrosion/tree/master/test/cxxbridge/cxxbridge_cpp2rust
Hi, thanks for your work. I am trying to use Corrosion to build a binary crate using a C/C++ CMake built library (the Azure IoTHub C SDK). What I don't understand (or perhaps I missed in the docs) is how should I link the two, as I currently can't do that using plain CMake, and I don't know if the problem is from Corrosion, CMake, cxx or rustc.
In practice, I noticed that linking using only CMake (doesn't matter if I use
target_link_libraries
orcorrosion_link_libraries
) will correctly set up the relevant-L
and-l
flags on the rustc command invocation, but apparently the libraries are not correctly read(?). At compile time I get errors like:Note that the function I'm calling (and for which I set up the interface using cxx) is plain C
IoTHub_Init()
in the librarylibiothub_client.a
, built by CMake in directoryMWE/build/out/iothub_client
. I checked and it is present, and the symbol is exported when usingnm
. You can see it is present in the rustc invocation (or at least it seems to me), but I get the error. Whereas, if I include them by thebuild.rs
script, the linking works, so I was wondering if the problem was on Corrosion side. What am I doing wrong? Thanks!Context:
CMakeLists.txt
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(FetchContent)
FetchContent_Declare( Corrosion GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
GIT_TAG v0.5 # Optionally specify a commit hash, version tag or branch here
) FetchContent_MakeAvailable(Corrosion)
##################### Azure C SDK ############################
Set Azure IoT SDK C settings
set(use_mqtt ON CACHE BOOL "Set mqtt on" FORCE ) set(skip_samples ON CACHE BOOL "Set slip_samples on" FORCE ) set(BUILD_TESTING OFF CACHE BOOL "Set BUILD_TESTING off" FORCE )
additional provisioning settings
set(use_prov_client ON) set(hsm_type_x509 ON)
Add Azure IoT SDK C
add_subdirectory(./azure-iot-sdk-c out)
compileAsC99()
Conditionally use the SDK trusted certs in the samples
if(${use_sample_trusted_cert}) add_definitions(-DSET_TRUSTED_CERT_IN_SAMPLES) include_directories(${PROJECT_SOURCE_DIR}/certs) set(iothub_c_files ${iothub_c_files} ${PROJECT_SOURCE_DIR}/certs/certs.c) endif()
include_directories(.)
################## main ############################
Import targets defined in a package or workspace manifest
Cargo.toml
filecorrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES MWE)
target_include_directories(MWE INTERFACE ${UMOCK_C_INC_FOLDER}) target_include_directories(MWE INTERFACE ${MACRO_UTILS_INC_FOLDER}) target_include_directories(MWE INTERFACE ${IOTHUB_CLIENT_INC_FOLDER}) target_include_directories(MWE INTERFACE azure-iot-sdk-c/provisioning_client/inc) target_include_directories(MWE INTERFACE azure-iot-sdk-c/iothub_client/inc) target_include_directories(MWE INTERFACE ${SHARED_UTIL_INC_FOLDER}) target_include_directories(MWE INTERFACE ${CMAKE_CURRENT_LIST_DIR}/adapters) target_include_directories(MWE INTERFACE ${AZURE_SDK_PATH}/deps/umock-c/inc) target_include_directories(MWE INTERFACE ${AZURE_SDK_PATH}/c-utility/deps/azure-macro-utils-c/inc)
target_include_directories(MWE INTERFACE ${DEV_AUTH_MODULES_CLIENT_INC_FOLDER})
if (${use_http}) corrosion_link_libraries(MWE prov_http_transport) endif() if (${use_mqtt}) corrosion_link_libraries(MWE prov_mqtt_transport prov_mqtt_ws_transport iothub_client_mqtt_transport) endif()
corrosion_link_libraries(MWE iothub_client) corrosion_link_libraries(MWE prov_device_ll_client) corrosion_link_libraries(MWE prov_auth_client) corrosion_link_libraries(MWE aziotsharedutil) corrosion_link_libraries(MWE hsm_security_client)
azure-iot-sdk-c
Cargo.toml
[[bin]] name = "MWE"
[dependencies] cxx = "1.0" regex = "1.11.1"
[build-dependencies] cxx-build = "1.0"