Commonly encountered (Non-Corrosion) Issues
Table of Contents
- Linking Debug C/C++ libraries into Rust fails on Windows MSVC targets
- Linking Rust static libraries into Debug C/C++ binaries fails on Windows MSVC targets
- Missing
soname
on Linux forcdylibs
- Missing
install_name
on MacOS forccdylibs
/ Hardcoded references to the build-directory
Linking Debug C/C++ libraries into Rust fails on Windows MSVC targets
rustc
always links against the non-debug Windows runtime on *-msvc
targets.
This is tracked in this issue
and could be fixed upstream.
A typical error message for this issue is:
Compiling rust_bin v0.1.0 (D:\a\corrosion\corrosion\test\cxxbridge\cxxbridge_cpp2rust\rust)
error: linking with `link.exe` failed: exit code: 1319
[ redacted ]
= note: cxxbridge-cpp.lib(lib.cpp.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in libcxx-bafec361a1a30317.rlib(cxx.o)
cxxbridge-cpp.lib(lib.cpp.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in libcxx-bafec361a1a30317.rlib(cxx.o)
cpp_lib.lib(cpplib.cpp.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in libcxx-bafec361a1a30317.rlib(cxx.o)
cpp_lib.lib(cpplib.cpp.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in libcxx-bafec361a1a30317.rlib(cxx.o)
msvcrt.lib(initializers.obj) : warning LNK4098: defaultlib 'msvcrtd.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
Solutions
One solution is to also use the non-debug version when building the C/C++ libraries.
You can set the MSVC_RUNTIME_LIBRARY target properties of your C/C++ libraries to the non-debug variants.
By default you will probably want to select the MultiThreadedDLL
variant, unless you specified
-Ctarget-feature=+crt-static
in your
RUSTFLAGS
.
Linking Rust static libraries into Debug C/C++ binaries fails on Windows MSVC targets
This issue is quite similar to the previous one, except that this time it's a Rust library being linked into a C/C++ target. If it's 100% only Rust code you likely won't even have any issues. However, if somewhere in the dependency graph C/C++ code is built and linked into your Rust library, you will likely encounter this issue. Please note, that using cxx counts as using C++ code and will lead to this issue.
The previous solution should also work for this case, but additionally you may also
have success by using
corrosion_set_env_vars(your_rust_lib "CFLAGS=-MDd" "CXXFLAGS=-MDd")
(or -MTd
for a statically linked
runtime).
For debug builds, this is likely to be the preferable solution. It assumes that downstream C/C++ code
is built by the cc
crate, which respects the CFLAGS
and CXXFLAGS
environment variables.
Missing soname
on Linux for cdylibs
Cargo doesn't support setting the soname
field for cdylib, which may cause issues.
You can set the soname manually by passing a linker-flag such as -Clink-arg=-Wl,-soname,libyour_crate.so
to the linker via corrosion_add_target_local_rustflags()
and additionally seting the IMPORTED_SONAME
property on the import CMake target:
set_target_properties(your_crate-shared PROPERTIES IMPORTED_SONAME libyour_crate.so)
Replace your_crate
with the name of your shared library as defined in the [lib]
section of your Cargo.toml
Manifest file.
Attention: The Linux section may not be entirely correct, maybe $ORIGIN
needs to be added to the linker arguments.
Feel free to open a pull-request with corrections.
Missing install_name
on MacOS for ccdylibs
/ Hardcoded references to the build-directory
The solution here is essentially the same as in the previous section.
corrosion_add_target_local_rustflags(your_crate -Clink-arg=-Wl,-install_name,@rpath/libyour_crate.dylib,-current_version,${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR},-compatibility_version,${PROJECT_VERSION_MAJOR}.0)
set_target_properties(your_crate-shared PROPERTIES IMPORTED_NO_SONAME 0)
set_target_properties(your_crate-shared PROPERTIES IMPORTED_SONAME libyour_crate.dylib)
When building binaries using this shared library, you should set the build rpath to the output directory of
your shared library, e.g. by setting set(CMAKE_BUILD_RPATH ${YOUR_CUSTOM_OUTPUT_DIRECTORY})
before adding
executables.
For a practical example, you may look at Slint PR 2455.