From a7af57e291f6dcc873337a3f386d6bced7a81716 Mon Sep 17 00:00:00 2001 From: Nikita Kniazev Date: Tue, 21 May 2024 22:28:36 +0300 Subject: [PATCH] clang-win: use lld linker, fix embed-manifest-via=linker (#385) Fixes bfgroup/b2/issues/159 --- Jamroot.jam | 2 +- src/tools/clang-win.jam | 16 ++++++++++++++-- src/tools/flags.jam | 2 +- src/tools/msvc.jam | 22 +++++++++------------- test/path_specials.py | 3 +-- test/toolset-mock/src/linkx.py | 24 ++++++++++++------------ 6 files changed, 38 insertions(+), 31 deletions(-) diff --git a/Jamroot.jam b/Jamroot.jam index afe7421c71..73f5dbf079 100644 --- a/Jamroot.jam +++ b/Jamroot.jam @@ -153,7 +153,7 @@ exe b2 clang-win:advapi32 clang-win:user32 windows,gcc:src/engine/res.rc - windows,clang:src/engine/res.rc + windows,clang-linux:src/engine/res.rc msvc:src/engine/b2.exe.manifest clang-win:src/engine/b2.exe.manifest ; diff --git a/src/tools/clang-win.jam b/src/tools/clang-win.jam index 92fed5e463..639a343c26 100644 --- a/src/tools/clang-win.jam +++ b/src/tools/clang-win.jam @@ -209,9 +209,9 @@ rule init ( version ? : command * : options * ) } toolset.flags clang-win.compile .CC $(cond) : $(compiler) --target=$(clang-arch)-pc-windows-msvc ; - toolset.flags clang-win.link .LD $(cond) : $(compiler) --target=$(clang-arch)-pc-windows-msvc ; + toolset.flags clang-win.link .LD $(cond) : $(compiler) --target=$(clang-arch)-pc-windows-msvc -fuse-ld=lld ; toolset.flags clang-win.link LINKOPT $(cond) : /link ; - toolset.flags clang-win.link LINKFLAGS $(cond) : "/incremental:no" "/manifest" "/machine:$(linker-arch)" ; + toolset.flags clang-win.link LINKFLAGS $(cond) : "/incremental:no" "/machine:$(linker-arch)" ; if $(arch) = x86 { toolset.flags clang-win.compile .ASM $(cond) : $(assembler) -nologo -c -Zp4 -Cp -Cx ; @@ -230,6 +230,18 @@ rule init ( version ? : command * : options * ) } } + local conditions = [ feature.split $(condition) ] ; + if ! [ version.version-less [ SPLIT_BY_CHARACTERS $(version) : . ] : 15 ] { + toolset.add-defaults $(conditions:J=,)\:linker ; + } + else { + # Clang seems to not care about adding WinSDK to PATH. + # Both MSVC link and LLVM lld-link (until v15) will fail to embed manifest. + # LINK : fatal error LNK1158: cannot run 'rc.exe' + # lld-link: error: unable to find mt.exe in PATH: no such file or directory + toolset.add-requirements $(conditions:J=,)\:mt ; + } + toolset.flags clang-win.link LIBRARY_OPTION clang-win : "" : unchecked ; # Enable response file control diff --git a/src/tools/flags.jam b/src/tools/flags.jam index 8bf6431c9f..72cc1ab728 100644 --- a/src/tools/flags.jam +++ b/src/tools/flags.jam @@ -116,7 +116,7 @@ generators.register generators.register [ class.new flag-check-generator EXE : msvc : "(LNK4044)" ] ; generators.register - [ class.new flag-check-generator EXE : clang : "(LNK4044)" ] ; # FIXME: clang-win doesn't work but clang does + [ class.new flag-check-generator EXE : clang : "(LNK4044|ignoring unknown argument)" ] ; generators.register [ class.new flag-check-generator OBJ : intel : "(#10006)" ] ; generators.register diff --git a/src/tools/msvc.jam b/src/tools/msvc.jam index 54a6ced323..0dc654fd8f 100644 --- a/src/tools/msvc.jam +++ b/src/tools/msvc.jam @@ -602,21 +602,13 @@ rule configure-version-specific ( toolset : version : conditions ) toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-arm) : "/MACHINE:ARM" ; toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-arm64) : "/MACHINE:ARM64" ; - if [ version.version-less [ SPLIT_BY_CHARACTERS [ MATCH "^([0123456789.]+)" : $(version) ] : . ] : 11 ] - { - # Make sure that manifest will be generated even if there is no - # dependencies to put there. - toolset.flags $(toolset).link LINKFLAGS $(conditions) : /MANIFEST ; - } - else - { - toolset.flags $(toolset).link LINKFLAGS $(conditions)/mt : /MANIFEST ; - toolset.flags $(toolset).link LINKFLAGS $(conditions)/linker/off : /MANIFEST ; - toolset.flags $(toolset).link LINKFLAGS $(conditions)/linker/on : "/MANIFEST:EMBED" ; - - local conditionx = [ feature.split $(conditions) ] ; + local conditionx = [ feature.split $(conditions) ] ; + if ! [ version.version-less [ SPLIT_BY_CHARACTERS [ MATCH "^([0123456789.]+)" : $(version) ] : . ] : 11 ] { toolset.add-defaults $(conditionx:J=,)\:linker ; } + else { + toolset.add-requirements $(conditionx:J=,)\:mt ; + } } toolset.pop-checking-for-flags-module ; @@ -2012,6 +2004,10 @@ local rule register-toolset-really ( ) toolset.flags msvc LINKFLAGS native : "/subsystem:native" ; toolset.flags msvc LINKFLAGS auto : "/subsystem:posix" ; + toolset.flags msvc.link LINKFLAGS mt : /MANIFEST ; + toolset.flags msvc.link LINKFLAGS linker/off : /MANIFEST ; + toolset.flags msvc.link LINKFLAGS linker/on : "/MANIFEST:EMBED" ; + toolset.flags msvc.link LINKFLAGS ; toolset.flags msvc.link LINKPATH ; diff --git a/test/path_specials.py b/test/path_specials.py index 80252083c0..e47ee42de4 100644 --- a/test/path_specials.py +++ b/test/path_specials.py @@ -24,8 +24,7 @@ def test_dir(dir_name): if os.name == 'nt' and len(tmpdir) > 256: tmp = {} # cl.exe and link.exe still does not support long paths - # clang-cl does support long path, but it uses link.exe by default - if t.toolset.startswith('msvc') or t.toolset.startswith('clang-win'): + if t.toolset.startswith('msvc'): do_compile_test = False # on windows gcc doesn't support long path, ld doesn't support neither unicode nor long path if os.environ.get('MSYSTEM') in ['UCRT64', 'MINGW64', 'MINGW32'] and t.toolset in ['gcc', 'clang']: diff --git a/test/toolset-mock/src/linkx.py b/test/toolset-mock/src/linkx.py index 2c7cd518fb..b28a7138ae 100644 --- a/test/toolset-mock/src/linkx.py +++ b/test/toolset-mock/src/linkx.py @@ -7,27 +7,27 @@ from MockProgram import * if allow_properties("variant=debug", "link=shared", "threading=multi", "runtime-link=shared", "windows-api=desktop"): - command('link', '/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\threading-multi\lib.obj'), '/DEBUG', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\threading-multi\l1.dll')), '/DLL', arg('/IMPLIB:', output_file(r'bin\msvc-14.3\debug\threading-multi\l1.implib'))) - command('link', '/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\threading-multi\main.obj'), input_file(r'bin\msvc-14.3\debug\threading-multi\l1.implib'), '/DEBUG', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\threading-multi\test.exe'))) + command('link', unordered('/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\threading-multi\lib.obj'), '/DEBUG', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\threading-multi\l1.dll')), '/DLL', arg('/IMPLIB:', output_file(r'bin\msvc-14.3\debug\threading-multi\l1.implib')))) + command('link', unordered('/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\threading-multi\main.obj'), input_file(r'bin\msvc-14.3\debug\threading-multi\l1.implib'), '/DEBUG', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\threading-multi\test.exe')))) if allow_properties("variant=release", "link=shared", "threading=multi", "runtime-link=shared", "windows-api=desktop"): - command('link', '/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\release\threading-multi\lib.obj'), '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\release\threading-multi\l1.dll')), '/DLL', arg('/IMPLIB:', output_file(r'bin\msvc-14.3\release\threading-multi\l1.implib'))) - command('link', '/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\release\threading-multi\main.obj'), input_file(r'bin\msvc-14.3\release\threading-multi\l1.implib'), '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\release\threading-multi\test.exe'))) + command('link', unordered('/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\release\threading-multi\lib.obj'), '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\release\threading-multi\l1.dll')), '/DLL', arg('/IMPLIB:', output_file(r'bin\msvc-14.3\release\threading-multi\l1.implib')))) + command('link', unordered('/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\release\threading-multi\main.obj'), input_file(r'bin\msvc-14.3\release\threading-multi\l1.implib'), '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\release\threading-multi\test.exe')))) if allow_properties("variant=debug", "link=static", "threading=multi", "runtime-link=shared", "windows-api=desktop"): - command('link', '/lib', '/NOLOGO', arg('/out:', output_file(r'bin\msvc-14.3\debug\link-static\threading-multi\l1.lib')), input_file(r'bin\msvc-14.3\debug\link-static\threading-multi\lib.obj')) - command('link', '/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\link-static\threading-multi\main.obj'), input_file(r'bin\msvc-14.3\debug\link-static\threading-multi\l1.lib'), '/DEBUG', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\link-static\threading-multi\test.exe'))) + command('link', unordered('/lib', '/NOLOGO', arg('/out:', output_file(r'bin\msvc-14.3\debug\link-static\threading-multi\l1.lib')), input_file(r'bin\msvc-14.3\debug\link-static\threading-multi\lib.obj'))) + command('link', unordered('/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\link-static\threading-multi\main.obj'), input_file(r'bin\msvc-14.3\debug\link-static\threading-multi\l1.lib'), '/DEBUG', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\link-static\threading-multi\test.exe')))) if allow_properties("variant=debug", "link=static", "threading=single", "runtime-link=static", "windows-api=desktop"): - command('link', '/lib', '/NOLOGO', arg('/out:', output_file(r'bin\msvc-14.3\debug\link-static\runtime-link-static\l1.lib')), input_file(r'bin\msvc-14.3\debug\link-static\runtime-link-static\lib.obj')) - command('link', '/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\link-static\runtime-link-static\main.obj'), input_file(r'bin\msvc-14.3\debug\link-static\runtime-link-static\l1.lib'), '/DEBUG', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\link-static\runtime-link-static\test.exe'))) + command('link', unordered('/lib', '/NOLOGO', arg('/out:', output_file(r'bin\msvc-14.3\debug\link-static\runtime-link-static\l1.lib')), input_file(r'bin\msvc-14.3\debug\link-static\runtime-link-static\lib.obj'))) + command('link', unordered('/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\link-static\runtime-link-static\main.obj'), input_file(r'bin\msvc-14.3\debug\link-static\runtime-link-static\l1.lib'), '/DEBUG', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\link-static\runtime-link-static\test.exe')))) if allow_properties("variant=debug", "link=shared", "threading=multi", "runtime-link=shared", "windows-api=store"): - command('link', '/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-store\lib.obj'), '/DEBUG', '/APPCONTAINER', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-store\l1.dll')), '/DLL', arg('/IMPLIB:', output_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-store\l1.implib'))) - command('link', '/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-store\main.obj'), input_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-store\l1.implib'), '/DEBUG', '/APPCONTAINER', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-store\test.exe'))) + command('link', unordered('/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-store\lib.obj'), '/DEBUG', '/APPCONTAINER', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-store\l1.dll')), '/DLL', arg('/IMPLIB:', output_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-store\l1.implib')))) + command('link', unordered('/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-store\main.obj'), input_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-store\l1.implib'), '/DEBUG', '/APPCONTAINER', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-store\test.exe')))) if allow_properties("variant=debug", "link=shared", "threading=multi", "runtime-link=shared", "windows-api=phone"): - command('link', '/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-phone\lib.obj'), '/DEBUG', '/APPCONTAINER', '/NODEFAULTLIB:kernel32.lib', '/NODEFAULTLIB:ole32.lib', 'WindowsPhoneCore.lib', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-phone\l1.dll')), '/DLL', arg('/IMPLIB:', output_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-phone\l1.implib'))) - command('link', '/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-phone\main.obj'), input_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-phone\l1.implib'), '/DEBUG', '/APPCONTAINER', '/NODEFAULTLIB:kernel32.lib', '/NODEFAULTLIB:ole32.lib', 'WindowsPhoneCore.lib', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-phone\test.exe'))) + command('link', unordered('/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-phone\lib.obj'), '/DEBUG', '/APPCONTAINER', '/NODEFAULTLIB:kernel32.lib', '/NODEFAULTLIB:ole32.lib', 'WindowsPhoneCore.lib', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-phone\l1.dll')), '/DLL', arg('/IMPLIB:', output_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-phone\l1.implib')))) + command('link', unordered('/NOLOGO', '/INCREMENTAL:NO', input_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-phone\main.obj'), input_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-phone\l1.implib'), '/DEBUG', '/APPCONTAINER', '/NODEFAULTLIB:kernel32.lib', '/NODEFAULTLIB:ole32.lib', 'WindowsPhoneCore.lib', '/MACHINE:X64', '/MANIFEST:EMBED', '/subsystem:console', arg('/out:', output_file(r'bin\msvc-14.3\debug\threading-multi\windows-api-phone\test.exe')))) main()