Skip to content

Commit

Permalink
msvc: handle flags that come from native-static-libs (#511)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
russelltg authored Apr 26, 2024
1 parent 6e9505c commit fce4fe5
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 7 deletions.
2 changes: 2 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@
- Set the `AR_<triple>` 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)

Expand Down
4 changes: 4 additions & 0 deletions cmake/Corrosion.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
29 changes: 22 additions & 7 deletions cmake/FindRust.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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}")
Expand Down Expand Up @@ -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})
Expand All @@ -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.
Expand All @@ -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}")
Expand Down Expand Up @@ -762,28 +770,35 @@ 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.
# In practice there aren't likely going to be any major differences, so we just do it once
# 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
Expand Down

0 comments on commit fce4fe5

Please sign in to comment.