Skip to content

Conversation

@Maetveis
Copy link
Contributor

The Intel C++ Compiler (ICX) passes linker flags through the driver unlike MSVC and clang-cl, and therefore needs them to be prefixed with /Qoption,link (the equivalent of -Wl, for gcc on *nix).

Use LINKER: prefix wherever supported by cmake, when that's not possible fall-back to ${CMAKE_CXX_LINKER_WRAPPER_FLAG}. CMake replaces these with /Qoption,link for ICX and with the empty string for MSVC and clang-cl.

For target_link_libraries neither LINKER: (not supported prior to CMake 3.32) nor ${CMAKE_CXX_LINKER_WRAPPER_FLAG} (does not begin with - would be taken as a library name) works, use -Qoption,link directly within a conditional generator expression that we're linking with ICX.

For MSVC and clang-cl no functional change is intended.

Tested by compiling with ICX and setting
CMAKE_(EXE|SHARED|STATIC|MODULE)_LINKER_FLAGS_INIT to -Werror=unknown-argument.

RFC: https://discourse.llvm.org/t/rfc-cmake-linker-flags-need-wl-equivalent-for-intel-c-icx-on-windows/82446

The Intel C++ Compiler (ICX) passes linker flags through the driver unlike MSVC and clang-cl, and therefore needs them to be prefixed with `/Qoption,link` (the equivalent of `-Wl,` for gcc on *nix). Use `LINKER:` prefix wherever supported by cmake, when that's not possible fall-back to `${CMAKE_CXX_LINKER_WRAPPER_FLAG}`. CMake replaces these with `/Qoption,link` for ICX and with the empty string for MSVC and clang-cl. For `target_link_libraries` neither `LINKER:` (not supported prior to CMake 3.32) nor `${CMAKE_CXX_LINKER_WRAPPER_FLAG}` (does not begin with `-` would be taken as a library name) works, use `-Qoption,link` directly within a conditional generator expression that we're linking with ICX. For MSVC and clang-cl no functional change is intended. Tested by compiling with ICX and setting `CMAKE_(EXE|SHARED|STATIC|MODULE)_LINKER_FLAGS_INIT` to `-Werror=unknown-argument`. RFC: https://discourse.llvm.org/t/rfc-cmake-linker-flags-need-wl-equivalent-for-intel-c-icx-on-windows/82446
@llvmbot llvmbot added cmake Build system in general and CMake in particular llvm:support labels Oct 17, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 17, 2024

@llvm/pr-subscribers-llvm-support

Author: Mészáros Gergely (Maetveis)

Changes

The Intel C++ Compiler (ICX) passes linker flags through the driver unlike MSVC and clang-cl, and therefore needs them to be prefixed with /Qoption,link (the equivalent of -Wl, for gcc on *nix).

Use LINKER: prefix wherever supported by cmake, when that's not possible fall-back to ${CMAKE_CXX_LINKER_WRAPPER_FLAG}. CMake replaces these with /Qoption,link for ICX and with the empty string for MSVC and clang-cl.

For target_link_libraries neither LINKER: (not supported prior to CMake 3.32) nor ${CMAKE_CXX_LINKER_WRAPPER_FLAG} (does not begin with - would be taken as a library name) works, use -Qoption,link directly within a conditional generator expression that we're linking with ICX.

For MSVC and clang-cl no functional change is intended.

Tested by compiling with ICX and setting
CMAKE_(EXE|SHARED|STATIC|MODULE)_LINKER_FLAGS_INIT to -Werror=unknown-argument.

RFC: https://discourse.llvm.org/t/rfc-cmake-linker-flags-need-wl-equivalent-for-intel-c-icx-on-windows/82446


Full diff: https://github.com/llvm/llvm-project/pull/112680.diff

5 Files Affected:

  • (modified) llvm/cmake/modules/AddLLVM.cmake (+5-5)
  • (modified) llvm/cmake/modules/HandleLLVMOptions.cmake (+1-1)
  • (modified) llvm/cmake/platforms/WinMsvc.cmake (+4)
  • (modified) llvm/lib/Support/CMakeLists.txt (+12-4)
  • (modified) llvm/tools/llvm-shlib/CMakeLists.txt (+1-1)
diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index c62b5649facae1..9f5e4344b898a7 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -149,20 +149,20 @@ function(add_llvm_symbol_exports target_name export_file) set(export_file_linker_flag "${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}") if(MSVC) # cl.exe or clang-cl, i.e. MSVC style command line interface - set(export_file_linker_flag "/DEF:\"${export_file_linker_flag}\"") + set(export_file_linker_flag "LINKER:/DEF:${export_file_linker_flag}") elseif(CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") # clang in msvc mode, calling a link.exe/lld-link style linker - set(export_file_linker_flag "-Wl,/DEF:\"${export_file_linker_flag}\"") + set(export_file_linker_flag "-Wl,/DEF:${export_file_linker_flag}") elseif(MINGW) # ${export_file_linker_flag}, which is the plain file name, works as is # when passed to the compiler driver, which then passes it on to the # linker as an input file. - set(export_file_linker_flag "\"${export_file_linker_flag}\"") + set(export_file_linker_flag "${export_file_linker_flag}") else() message(FATAL_ERROR "Unsupported Windows toolchain") endif() - set_property(TARGET ${target_name} APPEND_STRING PROPERTY - LINK_FLAGS " ${export_file_linker_flag}") + set_property(TARGET ${target_name} APPEND PROPERTY + LINK_OPTIONS "${export_file_linker_flag}") endif() add_custom_target(${target_name}_exports DEPENDS ${native_export_file}) diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake index 990afafae0f94f..0112850928fae6 100644 --- a/llvm/cmake/modules/HandleLLVMOptions.cmake +++ b/llvm/cmake/modules/HandleLLVMOptions.cmake @@ -542,7 +542,7 @@ if(MSVC) # behavior was changed in CMake 2.8.11 (Issue 12437) to use the MSVC default # value (1 MB) which is not enough for us in tasks such as parsing recursive # C++ templates in Clang. - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:10000000") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_CXX_LINKER_WRAPPER_FLAG}/STACK:10000000") elseif(MINGW OR CYGWIN) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--stack,16777216") diff --git a/llvm/cmake/platforms/WinMsvc.cmake b/llvm/cmake/platforms/WinMsvc.cmake index 40d47f12c53ab7..00746c0826929d 100644 --- a/llvm/cmake/platforms/WinMsvc.cmake +++ b/llvm/cmake/platforms/WinMsvc.cmake @@ -324,6 +324,10 @@ if(case_sensitive_filesystem) -libpath:"${msvc_lib_symlinks_dir}") endif() +if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.25") + list(TRANSFORM LINK_FLAGS PREPEND "${CMAKE_CXX_LINKER_WRAPPER_FLAG}") +endif() + string(REPLACE ";" " " LINK_FLAGS "${LINK_FLAGS}") string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " ${LINK_FLAGS}") string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " ${LINK_FLAGS}") diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index 97188b0672f032..531bdeaca12614 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -74,6 +74,14 @@ elseif( CMAKE_HOST_UNIX ) endif() endif( WIN32 ) +set(WL "") +if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.25" + AND MSVC + AND NOT CMAKE_GENERATOR MATCHES "Visual Studio") + #IntelLLVM requires to pass linker flags with a wrapper + set(WL "$<$<OR:$<LINK_LANG_AND_ID:C,IntelLLVM>,$<LINK_LANG_AND_ID:CXX,IntelLLVM>,$<LINK_LANG_AND_ID:Fortran,IntelLLVM>>:-Qoption,link,>") +endif() + # Delay load shell32.dll if possible to speed up process startup. set (delayload_flags) if (MSVC) @@ -81,7 +89,7 @@ if (MSVC) # than invoking `link.exe` directly. In such a case, the flags should be # marked as `-Xlinker` to pass them directly to the linker. As a temporary # workaround simply elide the delay loading. - set (delayload_flags $<$<NOT:$<LINK_LANGUAGE:Swift>>:delayimp -delayload:shell32.dll -delayload:ole32.dll>) + set (delayload_flags $<$<NOT:$<LINK_LANGUAGE:Swift>>:delayimp ${WL}-delayload:shell32.dll ${WL}-delayload:ole32.dll>) endif() # Link Z3 if the user wants to build it. @@ -104,16 +112,16 @@ if(LLVM_INTEGRATED_CRT_ALLOC) if((LLVM_INTEGRATED_CRT_ALLOC MATCHES "rpmalloc$") OR LLVM_ENABLE_RPMALLOC) add_compile_definitions(ENABLE_OVERRIDE ENABLE_PRELOAD) set(ALLOCATOR_FILES "${LLVM_INTEGRATED_CRT_ALLOC}/rpmalloc/rpmalloc.c") - set(delayload_flags "${delayload_flags} -INCLUDE:malloc") + set(delayload_flags "${delayload_flags} ${WL}-INCLUDE:malloc") elseif(LLVM_INTEGRATED_CRT_ALLOC MATCHES "snmalloc$") set(ALLOCATOR_FILES "${LLVM_INTEGRATED_CRT_ALLOC}/src/snmalloc/override/new.cc") - set(system_libs ${system_libs} "mincore.lib" "-INCLUDE:malloc") + set(system_libs ${system_libs} "mincore.lib" "${WL}-INCLUDE:malloc") elseif(LLVM_INTEGRATED_CRT_ALLOC MATCHES "mimalloc$") set(MIMALLOC_LIB "${LLVM_INTEGRATED_CRT_ALLOC}/out/msvc-x64/Release/mimalloc-static.lib") if(NOT EXISTS "${MIMALLOC_LIB}") message(FATAL_ERROR "Cannot find the mimalloc static library. To build it, first apply the patch from https://github.com/microsoft/mimalloc/issues/268 then build the Release x64 target through ${LLVM_INTEGRATED_CRT_ALLOC}\\ide\\vs2019\\mimalloc.sln") endif() - set(system_libs ${system_libs} "${MIMALLOC_LIB}" "-INCLUDE:malloc") + set(system_libs ${system_libs} "${MIMALLOC_LIB}" "${WL}-INCLUDE:malloc") endif() endif() diff --git a/llvm/tools/llvm-shlib/CMakeLists.txt b/llvm/tools/llvm-shlib/CMakeLists.txt index 0436bd973b44b9..ede3c5034e045f 100644 --- a/llvm/tools/llvm-shlib/CMakeLists.txt +++ b/llvm/tools/llvm-shlib/CMakeLists.txt @@ -188,7 +188,7 @@ if(LLVM_BUILD_LLVM_C_DYLIB AND MSVC) if (LLVM_INTEGRATED_CRT_ALLOC AND MSVC) # Make sure we search LLVMSupport first, before the CRT libs - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -INCLUDE:malloc") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_CXX_LINKER_WRAPPER_FLAG}-INCLUDE:malloc") endif() endif() 
@Maetveis Maetveis merged commit 7ab6d39 into llvm:main Oct 23, 2024
7 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 23, 2024

LLVM Buildbot has detected a new failure on builder llvm-clang-aarch64-darwin running on doug-worker-5 while building llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/190/builds/8125

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure) ******************** TEST 'Clang :: Analysis/live-stmts.cpp' FAILED ******************** Exit Code: 1 Command Output (stderr): -- RUN: at line 1: /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/clang -cc1 -internal-isystem /Users/buildbot/buildbot-root/aarch64-darwin/build/lib/clang/20/include -nostdsysteminc -analyze -analyzer-constraints=range -setup-static-analyzer -w -analyzer-checker=debug.DumpLiveExprs /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/test/Analysis/live-stmts.cpp 2>&1 | /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/FileCheck /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/test/Analysis/live-stmts.cpp + /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/clang -cc1 -internal-isystem /Users/buildbot/buildbot-root/aarch64-darwin/build/lib/clang/20/include -nostdsysteminc -analyze -analyzer-constraints=range -setup-static-analyzer -w -analyzer-checker=debug.DumpLiveExprs /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/test/Analysis/live-stmts.cpp + /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/FileCheck /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/test/Analysis/live-stmts.cpp �[1m/Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/test/Analysis/live-stmts.cpp:239:16: �[0m�[0;1;31merror: �[0m�[1mCHECK-EMPTY: is not on the line after the previous match �[0m// CHECK-EMPTY: �[0;1;32m ^ �[0m�[1m<stdin>:180:1: �[0m�[0;1;30mnote: �[0m�[1m'next' match was here �[0m �[0;1;32m^ �[0m�[1m<stdin>:177:1: �[0m�[0;1;30mnote: �[0m�[1mprevious match ended here �[0m �[0;1;32m^ �[0m�[1m<stdin>:178:1: �[0m�[0;1;30mnote: �[0m�[1mnon-matching line after previous match is here �[0mImplicitCastExpr 0x121933f78 '_Bool' <LValueToRValue> �[0;1;32m^ �[0m Input file: <stdin> Check file: /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/test/Analysis/live-stmts.cpp -dump-input=help explains the following input dump. Input was: <<<<<< �[1m�[0m�[0;1;30m 1: �[0m�[1m�[0;1;46m �[0m �[0;1;30m 2: �[0m�[1m�[0;1;46m�[0m[ B0 (live expressions at block exit) ]�[0;1;46m �[0m �[0;1;32mcheck:21 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ �[0m�[0;1;30m 3: �[0m�[1m�[0;1;46m�[0m �[0m �[0;1;32mempty:22 ^ �[0m�[0;1;30m 4: �[0m�[1m�[0;1;46m�[0m �[0m �[0;1;32mempty:23 ^ �[0m�[0;1;30m 5: �[0m�[1m�[0;1;46m�[0m[ B1 (live expressions at block exit) ]�[0;1;46m �[0m �[0;1;32mcheck:24 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ �[0m�[0;1;30m 6: �[0m�[1m�[0;1;46m�[0m �[0m �[0;1;32mempty:25 ^ �[0m�[0;1;30m 7: �[0m�[1m�[0;1;46m�[0m �[0m �[0;1;32mempty:26 ^ �[0m�[0;1;30m 8: �[0m�[1m�[0;1;46m�[0m[ B2 (live expressions at block exit) ]�[0;1;46m �[0m �[0;1;32mcheck:27 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ �[0m�[0;1;30m 9: �[0m�[1m�[0;1;46m�[0m �[0m �[0;1;32mempty:28 ^ �[0m�[0;1;30m 10: �[0m�[1m�[0;1;46m�[0mDeclRefExpr 0x1219312e0 'int' lvalue ParmVar 0x121915a00 'y' 'int'�[0;1;46m �[0m �[0;1;32mnext:29 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ �[0m�[0;1;30m 11: �[0m�[1m�[0;1;46m�[0m �[0m �[0;1;32mempty:30 ^ �[0m�[0;1;30m 12: �[0m�[1m�[0;1;46m�[0mDeclRefExpr 0x121931300 'int' lvalue ParmVar 0x121915a80 'z' 'int'�[0;1;46m �[0m ... 
@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 23, 2024

LLVM Buildbot has detected a new failure on builder lld-x86_64-win running on as-worker-93 while building llvm at step 7 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/146/builds/1442

Here is the relevant piece of the build log for the reference
Step 7 (test-build-unified-tree-check-all) failure: test (failure) ******************** TEST 'LLVM-Unit :: Support/./SupportTests.exe/36/87' FAILED ******************** Script(shard): -- GTEST_OUTPUT=json:C:\a\lld-x86_64-win\build\unittests\Support\.\SupportTests.exe-LLVM-Unit-12492-36-87.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=87 GTEST_SHARD_INDEX=36 C:\a\lld-x86_64-win\build\unittests\Support\.\SupportTests.exe -- Script: -- C:\a\lld-x86_64-win\build\unittests\Support\.\SupportTests.exe --gtest_filter=ProgramEnvTest.CreateProcessLongPath -- C:\a\lld-x86_64-win\llvm-project\llvm\unittests\Support\ProgramTest.cpp(160): error: Expected equality of these values: 0 RC Which is: -2 C:\a\lld-x86_64-win\llvm-project\llvm\unittests\Support\ProgramTest.cpp(163): error: fs::remove(Twine(LongPath)): did not return errc::success. error number: 13 error message: permission denied C:\a\lld-x86_64-win\llvm-project\llvm\unittests\Support\ProgramTest.cpp:160 Expected equality of these values: 0 RC Which is: -2 C:\a\lld-x86_64-win\llvm-project\llvm\unittests\Support\ProgramTest.cpp:163 fs::remove(Twine(LongPath)): did not return errc::success. error number: 13 error message: permission denied ******************** 
@frobtech frobtech mentioned this pull request Oct 25, 2024
NoumanAmir657 pushed a commit to NoumanAmir657/llvm-project that referenced this pull request Nov 4, 2024
The Intel C++ Compiler (ICX) passes linker flags through the driver unlike MSVC and clang-cl, and therefore needs them to be prefixed with `/Qoption,link` (the equivalent of `-Wl,` for gcc on *nix). Use `LINKER:` prefix wherever supported by cmake, when that's not possible fall-back to `${CMAKE_CXX_LINKER_WRAPPER_FLAG}`. CMake replaces these with `/Qoption,link` for ICX and with the empty string for MSVC and clang-cl. For `target_link_libraries` neither `LINKER:` (not supported prior to CMake 3.32) nor `${CMAKE_CXX_LINKER_WRAPPER_FLAG}` (does not begin with `-` would be taken as a library name) works, use `-Qoption,link` directly within a conditional generator expression that we're linking with ICX. For MSVC and clang-cl no functional change is intended. Tested by compiling with ICX and setting `CMAKE_(EXE|SHARED|STATIC|MODULE)_LINKER_FLAGS_INIT` to `-Werror=unknown-argument`. RFC: https://discourse.llvm.org/t/rfc-cmake-linker-flags-need-wl-equivalent-for-intel-c-icx-on-windows/82446
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cmake Build system in general and CMake in particular llvm:support

4 participants