From fce4fe54328ada11b823f9ae72346b4e97a27844 Mon Sep 17 00:00:00 2001 From: Russell Greene Date: Fri, 26 Apr 2024 13:23:40 -0500 Subject: [PATCH] msvc: handle flags that come from native-static-libs (#511) * msvc: handle flags that come from native-static-libs As of https://github.com/rust-lang/rust/pull/122268/files, rust emits /defaultlib:msvcrt in native-static-libs This ends up in INTERFACE_LINK_LIBRARIES, and then ninja thinks it's a file: ninja: error: '/defaultlib:msvcrt', needed by 'cpp-exe.exe', missing and no known rule to make it This check to see if libraries start with a slash, and then assuming that they are a flag, and putting those in INTERFACE_LINK_OPTIONS instead. --- RELEASES.md | 2 ++ cmake/Corrosion.cmake | 4 ++++ cmake/FindRust.cmake | 29 ++++++++++++++++++++++------- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index fe8783cc..0bb6956d 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -23,12 +23,14 @@ - Set the `AR_` variable for `cc-rs` (except for msvc targets) [#456] - `corrosion_experimental_cbindgen()` now forwards the Rust target-triple (e.g. `aarch64-unknown-linux-gnu`) to cbindgen via the `TARGET` environment variable. The `hostbuild` property is considered. [#507] +- Detect msvc linker flags coming from `--print=native-static-libs` and put them into `INTERFACE_LINK_OPTIONS` instead of `INTERFACE_LINK_LIBRARIES` [#511] [#459]: https://github.com/corrosion-rs/corrosion/pull/459 [#456]: https://github.com/corrosion-rs/corrosion/pull/456 [#455]: https://github.com/corrosion-rs/corrosion/pull/455 [#506]: https://github.com/corrosion-rs/corrosion/pull/506 [#507]: https://github.com/corrosion-rs/corrosion/pull/507 +[#511]: https://github.com/corrosion-rs/corrosion/pull/511 # v0.4.7 (2024-01-19) diff --git a/cmake/Corrosion.cmake b/cmake/Corrosion.cmake index fa58d7b8..00d3d47b 100644 --- a/cmake/Corrosion.cmake +++ b/cmake/Corrosion.cmake @@ -422,6 +422,10 @@ function(_corrosion_add_library_target) TARGET ${target_name}-static PROPERTY INTERFACE_LINK_LIBRARIES ${Rust_CARGO_TARGET_LINK_NATIVE_LIBS} ) + set_property( + TARGET ${target_name}-static + PROPERTY INTERFACE_LINK_OPTIONS ${Rust_CARGO_TARGET_LINK_OPTIONS} + ) if(is_macos) set_property(TARGET ${target_name}-static PROPERTY INTERFACE_LINK_DIRECTORIES "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib" diff --git a/cmake/FindRust.cmake b/cmake/FindRust.cmake index c6479c15..9079c469 100644 --- a/cmake/FindRust.cmake +++ b/cmake/FindRust.cmake @@ -133,7 +133,7 @@ function(_corrosion_parse_target_triple target_triple out_arch out_vendor out_os set("${out_env}" "${CMAKE_MATCH_6}" PARENT_SCOPE) endfunction() -function(_corrosion_determine_libs_new target_triple out_libs) +function(_corrosion_determine_libs_new target_triple out_libs out_flags) set(package_dir "${CMAKE_BINARY_DIR}/corrosion/required_libs") # Cleanup on reconfigure to get a cleans state (in case we change something in the future) file(REMOVE_RECURSE "${package_dir}") @@ -162,6 +162,7 @@ function(_corrosion_determine_libs_new target_triple out_libs) if(cargo_build_error_message MATCHES "native-static-libs: ([^\r\n]+)\r?\n") string(REPLACE " " ";" "libs_list" "${CMAKE_MATCH_1}") set(stripped_lib_list "") + set(flag_list "") set(was_last_framework OFF) foreach(lib ${libs_list}) @@ -175,10 +176,16 @@ function(_corrosion_determine_libs_new target_triple out_libs) set(was_last_framework OFF) continue() endif() - # Strip leading `-l` (unix) and potential .lib suffix (windows) - string(REGEX REPLACE "^-l" "" "stripped_lib" "${lib}") - string(REGEX REPLACE "\.lib$" "" "stripped_lib" "${stripped_lib}") - list(APPEND stripped_lib_list "${stripped_lib}") + + # Flags start with / for MSVC + if (lib MATCHES "^/" AND ${target_triple} MATCHES "msvc$") + list(APPEND flag_list "${lib}") + else() + # Strip leading `-l` (unix) and potential .lib suffix (windows) + string(REGEX REPLACE "^-l" "" "stripped_lib" "${lib}") + string(REGEX REPLACE "\.lib$" "" "stripped_lib" "${stripped_lib}") + list(APPEND stripped_lib_list "${stripped_lib}") + endif() endforeach() set(libs_list "${stripped_lib_list}") # Special case `msvcrt` to link with the debug version in Debug mode. @@ -190,6 +197,7 @@ function(_corrosion_determine_libs_new target_triple out_libs) endif() endif() set("${out_libs}" "${libs_list}" PARENT_SCOPE) + set("${out_flags}" "${flag_list}" PARENT_SCOPE) endfunction() if (NOT "${Rust_TOOLCHAIN}" STREQUAL "$CACHE{Rust_TOOLCHAIN}") @@ -762,10 +770,13 @@ set(Rust_CARGO_HOST_ENV "${rust_host_env}" CACHE INTERNAL "Host environment") if(NOT DEFINED CACHE{Rust_CARGO_TARGET_LINK_NATIVE_LIBS}) message(STATUS "Determining required link libraries for target ${Rust_CARGO_TARGET_CACHED}") unset(required_native_libs) - _corrosion_determine_libs_new("${Rust_CARGO_TARGET_CACHED}" required_native_libs) + _corrosion_determine_libs_new("${Rust_CARGO_TARGET_CACHED}" required_native_libs required_link_flags) if(DEFINED required_native_libs) message(STATUS "Required static libs for target ${Rust_CARGO_TARGET_CACHED}: ${required_native_libs}" ) endif() + if(DEFINED required_link_flags) + message(STATUS "Required link flags for target ${Rust_CARGO_TARGET_CACHED}: ${required_link_flags}" ) + endif() # In very recent corrosion versions it is possible to override the rust compiler version # per target, so to be totally correct we would need to determine the libraries for # every installed Rust version, that the user could choose from. @@ -773,17 +784,21 @@ if(NOT DEFINED CACHE{Rust_CARGO_TARGET_LINK_NATIVE_LIBS}) # for the target and once for the host target (if cross-compiling). set(Rust_CARGO_TARGET_LINK_NATIVE_LIBS "${required_native_libs}" CACHE INTERNAL "Required native libraries when linking Rust static libraries") + set(Rust_CARGO_TARGET_LINK_OPTIONS "${required_link_flags}" CACHE INTERNAL + "Required link flags when linking Rust static libraries") endif() if(Rust_CROSSCOMPILING AND NOT DEFINED CACHE{Rust_CARGO_HOST_TARGET_LINK_NATIVE_LIBS}) message(STATUS "Determining required link libraries for target ${Rust_CARGO_HOST_TARGET_CACHED}") unset(host_libs) - _corrosion_determine_libs_new("${Rust_CARGO_HOST_TARGET_CACHED}" host_libs) + _corrosion_determine_libs_new("${Rust_CARGO_HOST_TARGET_CACHED}" host_libs host_flags) if(DEFINED host_libs) message(STATUS "Required static libs for host target ${Rust_CARGO_HOST_TARGET_CACHED}: ${host_libs}" ) endif() set(Rust_CARGO_HOST_TARGET_LINK_NATIVE_LIBS "${host_libs}" CACHE INTERNAL "Required native libraries when linking Rust static libraries for the host target") + set(Rust_CARGO_HOST_TARGET_LINK_OPTIONS "${host_flags}" CACHE INTERNAL + "Required linker flags when linking Rust static libraries for the host target") endif() # Set the input variables as non-cache variables so that the variables are available after