Skip to content

Commit

Permalink
clang-win: use lld linker, fix embed-manifest-via=linker (#385)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kojoley authored May 21, 2024
1 parent 0c9c980 commit a7af57e
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 31 deletions.
2 changes: 1 addition & 1 deletion Jamroot.jam
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ exe b2
<toolset>clang-win:<find-static-library>advapi32
<toolset>clang-win:<find-static-library>user32
<target-os>windows,<toolset>gcc:<source>src/engine/res.rc
<target-os>windows,<toolset>clang:<source>src/engine/res.rc
<target-os>windows,<toolset>clang-linux:<source>src/engine/res.rc
<toolset>msvc:<embed-manifest-file>src/engine/b2.exe.manifest
<toolset>clang-win:<embed-manifest-file>src/engine/b2.exe.manifest
;
Expand Down
16 changes: 14 additions & 2 deletions src/tools/clang-win.jam
Original file line number Diff line number Diff line change
Expand Up @@ -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 ;
Expand All @@ -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=,)\:<embed-manifest-via>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=,)\:<embed-manifest-via>mt ;
}

toolset.flags clang-win.link LIBRARY_OPTION <toolset>clang-win : "" : unchecked ;

# Enable response file control
Expand Down
2 changes: 1 addition & 1 deletion src/tools/flags.jam
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ generators.register
generators.register
[ class.new flag-check-generator EXE : <toolset>msvc : "(LNK4044)" ] ;
generators.register
[ class.new flag-check-generator EXE : <toolset>clang : "(LNK4044)" ] ; # FIXME: <toolset>clang-win doesn't work but <toolset>clang does
[ class.new flag-check-generator EXE : <toolset>clang : "(LNK4044|ignoring unknown argument)" ] ;
generators.register
[ class.new flag-check-generator OBJ : <toolset>intel : "(#10006)" ] ;
generators.register
Expand Down
22 changes: 9 additions & 13 deletions src/tools/msvc.jam
Original file line number Diff line number Diff line change
Expand Up @@ -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)/<embed-manifest-via>mt : /MANIFEST ;
toolset.flags $(toolset).link LINKFLAGS $(conditions)/<embed-manifest-via>linker/<embed-manifest>off : /MANIFEST ;
toolset.flags $(toolset).link LINKFLAGS $(conditions)/<embed-manifest-via>linker/<embed-manifest>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=,)\:<embed-manifest-via>linker ;
}
else {
toolset.add-requirements $(conditionx:J=,)\:<embed-manifest-via>mt ;
}
}

toolset.pop-checking-for-flags-module ;
Expand Down Expand Up @@ -2012,6 +2004,10 @@ local rule register-toolset-really ( )
toolset.flags msvc LINKFLAGS <user-interface>native : "/subsystem:native" ;
toolset.flags msvc LINKFLAGS <user-interface>auto : "/subsystem:posix" ;

toolset.flags msvc.link LINKFLAGS <embed-manifest-via>mt : /MANIFEST ;
toolset.flags msvc.link LINKFLAGS <embed-manifest-via>linker/<embed-manifest>off : /MANIFEST ;
toolset.flags msvc.link LINKFLAGS <embed-manifest-via>linker/<embed-manifest>on : "/MANIFEST:EMBED" ;

toolset.flags msvc.link LINKFLAGS <linkflags> ;
toolset.flags msvc.link LINKPATH <library-path> ;

Expand Down
3 changes: 1 addition & 2 deletions test/path_specials.py
Original file line number Diff line number Diff line change
Expand Up @@ -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']:
Expand Down
24 changes: 12 additions & 12 deletions test/toolset-mock/src/linkx.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit a7af57e

Please sign in to comment.