corrosion
corrosion copied to clipboard
Support installing libraries
Current Behavior
When attempting to use a Rust library my_lib
in a C++ application my_app
, using Corrosion, the linker reports an error during the linking phase.
Error Output:
[ 59%] Linking CXX executable my_app
ld: cannot find -lmy_lib-static
Relevant issue: https://github.com/corrosion-rs/corrosion/issues/261#issuecomment-1307223603
Expected Behavior
The my_app
application should successfully link with the my_lib
Rust library without the need for renaming the output static library file.
I was able to temporarily resolve this issue by renaming the output static library as follows:
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/libmy_lib.a
DESTINATION
${lib_dest}
RENAME
libmy_lib-static.a
)
Steps To Reproduce
Here is a snippet of the CMakeLists.txt file which reproduces the issue:
corrosion_import_crate(
MANIFEST_PATH ${CARGO_MANIFEST_DIR}/Cargo.toml
CRATES my_lib
)
target_link_libraries(my_app my_lib)
install(
TARGETS
my_lib
EXPORT
MyTargets
DESTINATION
${lib_dest}/
)
cmake -S. -Bbuild -DRust_CARGO_TARGET=mips-unknown-linux-gnu ...
Environment
- OS: Docker, debian:buster-slim
- CMake: 3.25.0
- CMake Generator: Unix Makefiles
- Cross Compilation Toolchain: mips-unknown-linux-gnu
CMake configure log with Debug log-level
No response
CMake Build step log
No response
To clarify: the install step is essential to reproduce this issue, correct?
Yes, the install step is essential to reproduce this issue. It seems that Corrosion is appending a -static suffix to the target name for static libraries, which is causing a mismatch during the linking phase because the library with the -static suffix is not being installed.
https://github.com/corrosion-rs/corrosion/blob/fc8dd409ba168c6a24572c72cf076154b913ebaa/cmake/Corrosion.cmake#L456C10-L456C10
if(has_staticlib)
add_library(${target_name}-static STATIC IMPORTED GLOBAL)
add_dependencies(${target_name}-static cargo-build_${target_name})
...
target_link_libraries(${target_name} INTERFACE ${target_name}-static)
Using an installed library is curenntly not supported, but it would make sense to add support.
I don't have much experience with install
, so it would immensely help if you could provide a minimal example of a project, that imports a Rust project, installs and then uses the installed static library to link. This would allow me to test out different solutions on that demo project.
It seems that Corrosion is appending a -static suffix
Corrosion creates an INTERFACE target that links to either the -static
or -shared
library . Changing this in any way would likely break lots of existing users code.
INTERFACE libraries basically cannot be installed as far as I can tell, but IMPORTED'ed libraries have some minor support. And in-fact with the existing code you can sort of kinda install to the degree cmake allows installing prebuilt binaries.
get_target_property(myrustlib_import_target myrustlib INTERFACE_LINK_LIBRARIES)
install(IMPORTED_RUNTIME_ARTIFACTS ${myrustlib_import_target}
LIBRARY DESTINATION ...
)
This is pretty limited and actually doesnt even support headers either, but is documented https://cmake.org/cmake/help/latest/command/install.html#imported-runtime-artifacts
Hilariously INTERFACE libraries supposedly do support installing public headers per https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/22 (See the 3.19 test cases and the newer FILE_SET features)
Hopefully these workarounds help someone else, but it does not look very good for being able to treat corrosion targets like real first-class cmake targets as it stands. Beyond simple installs both INTERFACE and IMPORTED targets have many other limitations you might experience in a large cmake build.
Thanks.
I was looking for a way to install a bin crate executable (converted from C to rust) and install(IMPORTED_RUNTIME_ARTIFACTS target_name)
was enough to replace the original install_executable(target_name)
.
Mentioning how to do this in the docs would be helpful. :wink: