-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
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:
runtime/eng/native/configuretools.cmake
Line 80 in df6fdef
| 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:
runtime/eng/native/configuretools.cmake
Lines 85 to 93 in df6fdef
| 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:
runtime/eng/native/functions.cmake
Lines 256 to 268 in df6fdef
| 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.