Skip to content

Incorrect GNU linker detection when cross-compiling on non-GNU-linker host OS #94355

@directhex

Description

@directhex

Description

LLD, the LLVM linker, does not support s390x architecture. As a result, it is necessary to link using BFD or Gold, the GNU linkers. If you don't pass any -fuse-ld= flags to Clang, it assumes BFD. However, if you only have BFD for the target architecture (i.e. s390x-linux-gnu-ld without ld, then our linker detection fails:

separate_arguments(ldVersion UNIX_COMMAND "${CMAKE_C_COMPILER} ${CMAKE_SHARED_LINKER_FLAGS} -Wl,--version")

will error out with:

clang-16: error: unable to execute command: Executable "ld" doesn't exist!
clang-16: error: linker command failed with exit code 1 (use -v to see invocation)

Which, in our logic, causes the final else() block to apply, setting LD_OSX:

if("${ldVersionOutput}" MATCHES "LLD")
set(LD_LLVM 1)
elseif("${ldVersionOutput}" MATCHES "GNU ld" OR "${ldVersionOutput}" MATCHES "GNU gold" OR "${ldVersionOutput}" MATCHES "GNU linkers")
set(LD_GNU 1)
elseif("${ldVersionOutput}" MATCHES "Solaris Link")
set(LD_SOLARIS 1)
else(CLR_CMAKE_HOST_OSX OR CLR_CMAKE_HOST_MACCATALYST)
set(LD_OSX 1)
endif()

Later, this value is used to determine command line flags passed to the linker:

function(set_exports_linker_option exports_filename)
if(LD_GNU OR LD_SOLARIS OR LD_LLVM)
# Add linker exports file option
if(LD_SOLARIS)
set(EXPORTS_LINKER_OPTION -Wl,-M,${exports_filename} PARENT_SCOPE)
else()
set(EXPORTS_LINKER_OPTION -Wl,--version-script=${exports_filename} PARENT_SCOPE)
endif()
elseif(LD_OSX)
# Add linker exports file option
set(EXPORTS_LINKER_OPTION -Wl,-exported_symbols_list,${exports_filename} PARENT_SCOPE)
endif()
endfunction()

BFD does not support the OSX -exported_symbols_list, syntax, it needs to be passed with the --version-script= syntax from the earlier if block:

  /usr/local/bin/s390x-linux-gnu-ld:/home/directhex/Projects/runtime/artifacts/obj/linux-s390x.Release/fxr/standalone/hostfxr.exports: file format not recognized; treating as linker script
  /usr/local/bin/s390x-linux-gnu-ld:/home/directhex/Projects/runtime/artifacts/obj/linux-s390x.Release/fxr/standalone/hostfxr.exports:1: syntax error

This problem can be worked around by adding a valid --target=<triple> flag to the -Wl,--version call in configuretools.cmake (which adds the triple prefix to the forked ld command), but with the twisty nesting of imports, it's not clear to me yet how to get the triple into that file.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions