Skip to content

Commit

Permalink
Fix linking Rust targets on Macos 11
Browse files Browse the repository at this point in the history
For Rust targets, Rust will invoke the linker and add (among others) the
 -lSystem flag. This works fine for the default linker, but if we use a
  custom linker (e.g. g++, or even /usr/bin/ld), then we must provide
  that path to the System library.

Adding -L<path> to RUSTFLAGS works fine for regular libraries, but fails
 for build-scripts (See rust-lang/cargo#4423 )
because there is no way to set RUSTFLAGS for build scripts when
cross-compiling. This is mostly an issue because we always specify the
target, even when building for host, but that is already sufficient for
the RUSTFLAGS to not apply to the build-script-build.

Target specific RUSTFLAGS (i.e CARGO_TARGET_<triple>_RUSTFLAGS also
don't seem to affect buildscripts.

Setting LIBRARY_PATH=<path> applies to normal targets and build-scripts
too, and seems to fix the issue.

My previous fix probably only fixed the case where a rust library gets
linked into a foreign library or executable.
  • Loading branch information
jschwe committed Apr 12, 2022
1 parent b8631d4 commit 9a1cb76
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions cmake/Corrosion.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,15 @@ function(_add_cargo_build)
set(cargo_target_option "$<IF:${if_not_host_build_condition},--target=${_CORROSION_RUST_CARGO_TARGET},--target=${_CORROSION_RUST_CARGO_HOST_TARGET}>")
set(target_artifact_dir "$<IF:${if_not_host_build_condition},${_CORROSION_RUST_CARGO_TARGET},${_CORROSION_RUST_CARGO_HOST_TARGET}>")

# Rust will add `-lSystem` as a flag for the linker on macOS. Adding the -L flag via RUSTFLAGS only fixes the
# problem partially - buildscripts still break, since they won't receive the RUSTFLAGS. This seems to only be a
# problem if we specify the linker ourselves (which we do, since this is necessary for e.g. linking C++ code).
# We can however set `LIBRARY_PATH`, which is propagated to the build-script-build properly.
if(NOT CMAKE_CROSSCOMPILING AND CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(cargo_library_path "LIBRARY_PATH=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib")
elseif(CMAKE_CROSSCOMPILING AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
set(cargo_library_path "$<IF:${if_not_host_build_condition},,LIBRARY_PATH=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib>")
endif()

if(cargo_profile_name)
set(cargo_profile "--profile=${cargo_profile_name}")
Expand Down Expand Up @@ -321,6 +330,7 @@ function(_add_cargo_build)
${rustflags_genex_test}
${cargo_target_linker}
${corrosion_cc_rs_flags}
${cargo_library_path}
CORROSION_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR}
CARGO_BUILD_RUSTC="${_CORROSION_RUSTC}"
"${_CORROSION_CARGO}"
Expand Down

0 comments on commit 9a1cb76

Please sign in to comment.