Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clang: fix target triple for MinGW #5980

Merged
merged 1 commit into from
Dec 16, 2024
Merged

Conversation

Doekin
Copy link
Contributor

@Doekin Doekin commented Dec 16, 2024

fixes #5973

@waruqi waruqi added this to the v2.9.7 milestone Dec 16, 2024
@waruqi waruqi merged commit a2ee23e into xmake-io:dev Dec 16, 2024
19 checks passed
@ifarbod
Copy link
Contributor

ifarbod commented Dec 18, 2024

@Doekin I thought the correct target triple is x86_64-w64-mingw32 ? Why is it windows-gnu here

I use LLVM MinGW and these are what I build with --target= x86_64-w64-mingw32, i686-w64-mingw32, armv7-w64-mingw32, aarch64-w64-mingw32

@Doekin
Copy link
Contributor Author

Doekin commented Dec 19, 2024

Hi, @ifarbod,

Thank you for raising this point!

The reason I opted for x86_64-w64-windows-gnu is that Clang internally normalizes x86_64-w64-mingw32 to x86_64-w64-windows-gnu. For example:

$ clang -v --target=x86_64-w64-mingw32 src\hello.c  
clang version 19.1.5 (https://github.com/llvm/llvm-project.git ab4b5a2db582958af1ee308a790cfdb42bd24720)  
Target: x86_64-w64-windows-gnu  
Thread model: posix  
InstalledDir: D:/Applications/Scoop/apps/mingw-mstorsjo-llvm-ucrt/19.1.5-20241203/bin  
(Omitted)  

This also aligns with Clang's naming conventions, such as x86_64-windows-msvc and x86_64-linux-gnu.

I’d love to hear your thoughts and see if there’s any perspective or use case I might have missed.

@ifarbod
Copy link
Contributor

ifarbod commented Dec 19, 2024

@Doekin This makes sense to me, but maybe we should future-proof this in case Clang decides to change it later, I've never seen anyone specify x86_64-w64-windows-gnu as the target directly when building with MinGW, I do appreciate your take - let's keep it like this until an issue arises.

Also another thing to note here:

elseif toolchain:is_arch("i386", "x86", "i686") then
        target = "i686"
        march = "-m32"

-m32 doesn't always mean x86, if you're on an ARM64 macOS system, it means armv7!

> clang -m32 --version
Apple clang version 15.0.0 (clang-1500.3.9.[4](https://github.com/ifarbod/macos-action-test/actions/runs/12099541383/job/33737211547#step:5:5))
Target: arm-apple-darwin23.6.0
Thread model: posix
InstalledDir: /Applications/Xcode_1[5](https://github.com/ifarbod/macos-action-test/actions/runs/12099541383/job/33737211547#step:5:6).4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Offtopic: Regarding Clang, and compiling for Windows, have you tried to compile on Windows host+target (x86_64-pc-windows-msvc), with regular Clang, and the MSVC linker (link.exe)? It is possible in reality (Chrome is built like this) but Xmake lacks support for it.

@star-hengxing
Copy link
Contributor

Offtopic: Regarding Clang, and compiling for Windows, have you tried to compile on Windows host+target (x86_64-pc-windows-msvc), with regular Clang, and the MSVC linker (link.exe)? It is possible in reality (Chrome is built like this) but Xmake lacks support for it.

clang toolchains support it. #5848 (comment)

@Doekin
Copy link
Contributor Author

Doekin commented Dec 19, 2024

-m32 doesn't always mean x86, if you're on an ARM64 macOS system, it means armv7!

I didn’t know that—appreciate you sharing it!

I tried compiling with --target=x86_64-pc-windows-msvc. It seems that Clang uses link.exe. Here are a couple of examples:

Clang: Source → Binary

$ clang -v -m64 --target=x86_64-pc-windows-msvc .\src\hello.c
clang version 19.1.5 (https://github.com/llvm/llvm-project.git ab4b5a2db582958af1ee308a790cfdb42bd24720)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: D:/Applications/Scoop/apps/mingw-mstorsjo-llvm-ucrt/19.1.5-20241203/bin
 "D:/Applications/Scoop/apps/mingw-mstorsjo-llvm-ucrt/19.1.5-20241203/bin/clang-19.exe" -cc1 -triple x86_64-pc-windows-msvc19.42.34435 -emit-obj -mincremental-linker-compatible -dumpdir a- -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name hello.c -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -fdebug-compilation-dir=D:/projects/cpp-playground -v -fcoverage-compilation-dir=D:/projects/cpp-playground -resource-dir D:/Applications/Scoop/apps/mingw-mstorsjo-llvm-ucrt/19.1.5-20241203/lib/clang/19 -internal-isystem D:/Applications/Scoop/apps/mingw-mstorsjo-llvm-ucrt/19.1.5-20241203/lib/clang/19/include -internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Tools\\MSVC\\14.42.34433\\include" -internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Auxiliary\\VS\\include" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.26100.0\\ucrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\um" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\shared" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\winrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\cppwinrt" -internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Tools\\MSVC\\14.42.34433\\include" -internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Auxiliary\\VS\\include" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.26100.0\\ucrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\um" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\shared" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\winrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\cppwinrt" -ferror-limit 19 -fmessage-length=120 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.42.34435 -fskip-odr-check-in-gmf -fdelayed-template-parsing -fcolor-diagnostics -faddrsig -o C:/Users/leemu/AppData/Local/Temp/hello-28881d.o -x c ".\\src\\hello.c"
clang -cc1 version 19.1.5 based upon LLVM 19.1.5 default target x86_64-w64-mingw32
ignoring duplicate directory "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.42.34433\include"
ignoring duplicate directory "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\VS\include"
ignoring duplicate directory "C:\Program Files (x86)\Windows Kits\10\include\10.0.26100.0\ucrt"
ignoring duplicate directory "C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\um"
ignoring duplicate directory "C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\shared"
ignoring duplicate directory "C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\winrt"
ignoring duplicate directory "C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\cppwinrt"
#include "..." search starts here:
#include <...> search starts here:
 D:/Applications/Scoop/apps/mingw-mstorsjo-llvm-ucrt/19.1.5-20241203/lib/clang/19/include
 C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.42.34433\include
 C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\VS\include
 C:\Program Files (x86)\Windows Kits\10\include\10.0.26100.0\ucrt
 C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\um
 C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\shared
 C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\winrt
 C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\cppwinrt
End of search list.
 "C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Tools\\MSVC\\14.42.34433\\bin/Hostx64/x64/link.exe" -out:a.exe -defaultlib:libcmt -defaultlib:oldnames -libpath:D:/Applications/Scoop/apps/mingw-mstorsjo-llvm-ucrt/19.1.5-20241203/lib/clang/19/lib/windows -nologo C:/Users/leemu/AppData/Local/Temp/hello-28881d.o

Clang: Source → Object, link.exe : Object → Binary

$ clang -v -m64 -c -nodefaultlibs -nostdinc -nostdlib -I "C:\Program Files (x86)\Windows Kits\10\include\10.0.26100.0\ucrt" -I "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.42.34433\include" --target=x86_64-pc-windows-msvc src\hello.c
clang version 19.1.5 (https://github.com/llvm/llvm-project.git ab4b5a2db582958af1ee308a790cfdb42bd24720)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: D:/Applications/Scoop/apps/mingw-mstorsjo-llvm-ucrt/19.1.5-20241203/bin
 (in-process)
 "D:/Applications/Scoop/apps/mingw-mstorsjo-llvm-ucrt/19.1.5-20241203/bin/clang-19.exe" -cc1 -triple x86_64-pc-windows-msvc19.42.34435 -emit-obj -mincremental-linker-compatible -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name hello.c -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -fdebug-compilation-dir=D:/projects/cpp-playground -v -fcoverage-compilation-dir=D:/projects/cpp-playground -nostdsysteminc -nobuiltininc -resource-dir D:/Applications/Scoop/apps/mingw-mstorsjo-llvm-ucrt/19.1.5-20241203/lib/clang/19 -I "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.26100.0\\ucrt" -I "C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Tools\\MSVC\\14.42.34433\\include" -ferror-limit 19 -fmessage-length=120 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.42.34435 -fskip-odr-check-in-gmf -fdelayed-template-parsing -fcolor-diagnostics -faddrsig -o hello.o -x c "src\\hello.c"
clang -cc1 version 19.1.5 based upon LLVM 19.1.5 default target x86_64-w64-mingw32
#include "..." search starts here:
#include <...> search starts here:
 C:\Program Files (x86)\Windows Kits\10\include\10.0.26100.0\ucrt
 C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.42.34433\include
End of search list.
$ link -nologo -out:hello.exe libcmt.lib .\hello.o

@star-hengxing
Copy link
Contributor

star-hengxing commented Dec 19, 2024

clang always uses msvc link on windows plat unless -fuse-ld=lld-link is used

set_toolchains("clang")
add_cxflags("-v")
add_ldflags("-v")
-- add_ldflags("-fuse-ld=lld-link")

target("test")
    set_kind("binary")
    add_files("src/main.cpp")
[ 50%]: cache compiling.release src\main.cpp
clang -c -Qunused-arguments -m64 --target=x86_64-pc-windows-msvc -fexceptions -fcxx-exceptions -v -o build\.objs\test\windows\x64\release\src\main.cpp.obj src\main.cpp
clang version 19.1.4
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Users\star\scoop\apps\llvm\19.1.4\bin
 (in-process)
 "C:\\Users\\star\\scoop\\apps\\llvm\\19.1.4\\bin\\clang.exe" -cc1 -triple x86_64-pc-windows-msvc19.42.34435 -E -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic "-fdebug-compilation-dir=A:\\project\\xmake\\test" -v "-fcoverage-compilation-dir=A:\\project\\xmake\\test" -resource-dir "C:\\Users\\star\\scoop\\apps\\llvm\\19.1.4\\lib\\clang\\19" -dependency-file "C:\\Users\\star\\AppData\\Local\\Temp\\.xmake\\241220\\_7DDA23B0A2F248008DD91ECF943CB360" -MT "build\\.objs\\test\\windows\\x64\\release\\src\\__cpp_main.cpp.cpp" -internal-isystem "C:\\Users\\star\\scoop\\apps\\llvm\\19.1.4\\lib\\clang\\19\\include" -internal-isystem "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.42.34433\\include" -internal-isystem "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.42.34433\\atlmfc\\include" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\ucrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\shared" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\um" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\winrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\cppwinrt" -fdeprecated-macro -ferror-limit 19 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.42.34435 -std=c++14 -fskip-odr-check-in-gmf -fdelayed-template-parsing -fcxx-exceptions -fexceptions -fcolor-diagnostics -fansi-escape-codes -faddrsig -o "build\\.objs\\test\\windows\\x64\\release\\src\\__cpp_main.cpp.cpp" -x c++ "src\\main.cpp"
clang -cc1 version 19.1.4 based upon LLVM 19.1.4 default target x86_64-pc-windows-msvc
#include "..." search starts here:
#include <...> search starts here:
 C:\Users\star\scoop\apps\llvm\19.1.4\lib\clang\19\include
 C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.42.34433\include
 C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.42.34433\atlmfc\include
 C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt
 C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\shared
 C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um
 C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\winrt
[ 75%]: linking.release test.exe
clang++ -o build\windows\x64\release\test.exe build\.objs\test\windows\x64\release\src\main.cpp.obj -m64 --target=x86_64-pc-windows-msvc -v
clang version 19.1.4
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Users\star\scoop\apps\llvm\19.1.4\bin
 "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.42.34433\\bin\\Hostx64\\x64\\link.exe" "-out:build\\windows\\x64\\release\\test.exe" -defaultlib:libcmt -defaultlib:oldnames "-libpath:C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.42.34433\\lib\\x64" "-libpath:C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.42.34433\\atlmfc\\lib\\x64" "-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.22621.0\\ucrt\\x64" "-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.22621.0\\um\\x64" "-libpath:C:\\Users\\star\\scoop\\apps\\llvm\\19.1.4\\lib\\clang\\19\\lib\\windows" -nologo "build\\.objs\\test\\windows\\x64\\release\\src\\main.cpp.obj"
[100%]: build ok, spent 0.578s
clang++ -o build\windows\x64\release\test.exe build\.objs\test\windows\x64\release\src\main.cpp.obj -m64 --target=x86_64-windows-msvc -fuse-ld=lld-link -v
clang version 19.1.4
Target: x86_64-unknown-windows-msvc
Thread model: posix
InstalledDir: C:\Users\star\scoop\apps\llvm\19.1.4\bin
 "C:\\Users\\star\\scoop\\apps\\llvm\\19.1.4\\bin\\lld-link" "-out:build\\windows\\x64\\release\\test.exe" -defaultlib:libcmt -defaultlib:oldnames "-libpath:C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.42.34433\\lib\\x64" "-libpath:C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.42.34433\\atlmfc\\lib\\x64" "-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.22621.0\\ucrt\\x64" "-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.22621.0\\um\\x64" "-libpath:C:\\Users\\star\\scoop\\apps\\llvm\\19.1.4\\lib\\clang\\19\\lib\\windows" -nologo "build\\.objs\\test\\windows\\x64\\release\\src\\main.cpp.obj"

@ifarbod
Copy link
Contributor

ifarbod commented Dec 19, 2024

@Doekin Did you invoke link.exe manually or was it done by Xmake?

Also, I noticed something, do you think that -pc is unnecessary (for x64 and x86 I mean)?

image

@star-hengxing Are you sure? It's using clang wrapper to link (in your results), not MSVC link.exe

[ 75%]: linking.release test.exe
clang++ -o build\windows\x64\release\test.exe build\.objs\test\windows\x64\release\src\main.cpp.obj -m64 --target=x86_64-pc-windows-msvc -v

@ifarbod
Copy link
Contributor

ifarbod commented Dec 19, 2024

Let me show an example, this is a basic Windows app that is going to be compiled with multiple toolchains:

main.cpp:

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    MessageBoxW(nullptr, L"Successful!", L"Message", MB_OK);
    return 0;
}

xmake.lua:

set_project("Windows Demo")
set_xmakever("2.9.7")

set_languages("c17", "cxx20")

add_rules("mode.debug", "mode.releasedbg", "mode.release")
add_rules("plugin.vsxmake.autoupdate")
add_rules("plugin.compile_commands.autoupdate")

set_allowedplats("windows", "mingw")

target("demo-app", function()
    set_group("demo")

    set_kind("binary")
    add_files("src/*.cpp")

    if is_plat("windows", "mingw") then
        add_rules("win.sdk.application")
    end
end)

Compiling with MSVC (default)

cl.exe and link.exe from VS 2022. Works fine with no issues, this is what most people use Xmake with.

xmake f -c -p windows -a x86 -m debug && xmake -rvD

> cl.exe "-std:c++20" "-nologo"
...
[ 75%]: linking.debug demo-app.exe
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Preview\\VC\\Tools\\MSVC\\14.43.34604\\bin\\HostX64\\x86\\link.exe" -nologo -dynamicbase -nxcompat -machine:x86 -debug -pdb:build\windows\x86\debug\demo-app.pdb kernel32.lib user32.lib gdi32.lib winspool.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib comdlg32.lib setupapi.lib shlwapi.lib strsafe.lib -subsystem:windows -out:build\windows\x86\debug\demo-app.exe build\.objs\demo-app\windows\x86\debug\src\main.cpp.obj
checking for cl.exe ... C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.43.34604\bin\HostX64\x86\cl.exe
checking for the c compiler (cc) ... cl.exe
...
[100%]: build ok, spent 1.281s

LLVM MinGW

Also works - and very popular, Xmake supports this configuration very well.

xmake f -c -p mingw -a i386 -m debug && xmake -rvD

...
[ 75%]: linking.debug demo-app.exe
C:\Dev\Tools\llvm-mingw-20241203-msvcrt-x86_64\bin\i686-w64-mingw32-g++ -o build\mingw\i386\debug\demo-app.exe build\.objs\demo-app\mingw\i386\debug\src\main.cpp.obj -m32 -lkernel32 -luser32 -lgdi32 -lwinspool -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lcomctl32 -lcomdlg32 -lsetupapi -lshlwapi -mwindows
...
[100%]: build ok, spent 1.734s

Clang (and Windows SDK from Microsoft)

clang compiler, clang linker, this is the default toolchain given by Xmake, works very well but doesn't support a lot of linker flags

xmake f -c -p windows -a x86 -m debug --toolchain=clang && xmake -rvD

checking for clang ... ok
checking for the c++ compiler (cxx) ... clang
checking for flags (-fvisibility-inlines-hidden) ... ok
> clang "-fvisibility-inlines-hidden" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
checking for flags (-O0) ... ok
> clang "-O0" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
checking for flags (-std=c++20) ... ok
> clang "-std=c++20" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
[ 50%]: cache compiling.debug src\main.cpp
clang -c -Qunused-arguments -m32 --target=i686-windows-msvc -g -O0 -std=c++20 -fexceptions -fcxx-exceptions -finput-charset=UTF-8 -fexec-charset=UTF-8 -o build\.objs\demo-app\windows\x86\debug\src\main.cpp.obj src\main.cpp
checking for flags (-MMD -MF) ... ok
> clang "-MMD" "-MF" "C:\Users\iFarbod\AppData\Local\Temp\.xmake\241219\_FB1AAF43BC9542708068D4B5405846A0" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
checking for flags (-fdiagnostics-color=always) ... ok
> clang "-fdiagnostics-color=always" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
checking for flags (-fansi-escape-codes) ... ok
> clang "-fansi-escape-codes" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
checking for flags (-Wno-gnu-line-marker -Werror) ... ok
> clang "-Wno-gnu-line-marker" "-Werror" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
[ 75%]: linking.debug demo-app.exe
clang++ -o build\windows\x86\debug\demo-app.exe build\.objs\demo-app\windows\x86\debug\src\main.cpp.obj -m32 --target=i686-windows-msvc -g -lkernel32 -luser32 -lgdi32 -lwinspool -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lcomctl32 -lcomdlg32 -lsetupapi -lshlwapi -lstrsafe
LINK : build\windows\x86\debug\demo-app.exe not found or not built by the last incremental link; performing full link
checking for clang ... ok
checking for the c compiler (cc) ... clang

...

create ok!
compile_commands.json updated!
[100%]: build ok, spent 3.0s

@star-hengxing As you can see, this isn't using link.exe directly, looks like a wrapper to me (which is not what I want)

Now, clang-cl:

xmake f -c -p windows -a x86 -m debug --toolchain=clang-cl && xmake -rvD

checking for Microsoft Visual Studio (x86) version ... 2022
checking for LLVM Clang C/C++ Compiler (x86) version ... 19.1.5
checking for clang-cl.exe ... C:\Program Files\LLVM\bin\clang-cl.exe
checking for the c++ compiler (cxx) ... clang-cl.exe
checking for C:\Program Files\LLVM\bin\clang-cl.exe ... ok
checking for flags (-FS -Fd) ... ok
> clang-cl.exe "-FS" "-FdC:\Users\iFarbod\AppData\Local\Temp\.xmake\241219\_20DDBB3D1C4F4C0084FAD4ABFE862750.pdb" "-m32"
checking for flags (-Od) ... ok
> clang-cl.exe "-Od" "-m32"
checking for flags (-std:c++20) ... ok
> clang-cl.exe "-std:c++20" "-m32"
[ 50%]: cache compiling.debug src\main.cpp
"C:\\Program Files\\LLVM\\bin\\clang-cl.exe" -c -m32 -Zi -FS -Fdbuild\windows\x86\debug\compile.demo-app.pdb -Od -std:c++20 /EHsc /utf-8 -Fobuild\.objs\demo-app\windows\x86\debug\src\main.cpp.obj src\main.cpp
checking for flags (-fcolor-diagnostics) ... ok
> clang-cl.exe "-fcolor-diagnostics" "-m32"
checking for flags (-fansi-escape-codes) ... ok
> clang-cl.exe "-fansi-escape-codes" "-m32"
[ 75%]: linking.debug demo-app.exe
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Preview\\VC\\Tools\\MSVC\\14.43.34604\\bin\\HostX64\\x86\\link.exe" -nologo -dynamicbase -nxcompat -machine:x86 -debug -pdb:build\windows\x86\debug\demo-app.pdb kernel32.lib user32.lib gdi32.lib winspool.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib comdlg32.lib setupapi.lib shlwapi.lib strsafe.lib -subsystem:windows -out:build\windows\x86\debug\demo-app.exe build\.objs\demo-app\windows\x86\debug\src\main.cpp.obj
checking for clang-cl.exe ... C:\Program Files\LLVM\bin\clang-cl.exe
checking for the c compiler (cc) ... clang-cl.exe

...

create ok!
compile_commands.json updated!
[100%]: build ok, spent 2.89s

This does use link.exe directly, which is what I want - but I want to use clang, not clang-cl. (just like Chromium does)

@waruqi told me to use this but Xmake fails to pass the correct flags to link.exe in this combination

xmake f -c -p windows -a x86 -m debug --toolchain=clang --ld=link && xmake -rvD

checking for clang ... ok
checking for the c++ compiler (cxx) ... clang
checking for flags (-fvisibility-inlines-hidden) ... ok
> clang "-fvisibility-inlines-hidden" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
checking for flags (-O0) ... ok
> clang "-O0" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
checking for flags (-std=c++20) ... ok
> clang "-std=c++20" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
[ 50%]: cache compiling.debug src\main.cpp
clang -c -Qunused-arguments -m32 --target=i686-windows-msvc -g -O0 -std=c++20 -fexceptions -fcxx-exceptions -finput-charset=UTF-8 -fexec-charset=UTF-8 -o build\.objs\demo-app\windows\x86\debug\src\main.cpp.obj src\main.cpp
checking for flags (-MMD -MF) ... ok
> clang "-MMD" "-MF" "C:\Users\iFarbod\AppData\Local\Temp\.xmake\241219\_D5F18BC232D144408D39B1F4571A4670" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
checking for flags (-fdiagnostics-color=always) ... ok
> clang "-fdiagnostics-color=always" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
checking for flags (-fansi-escape-codes) ... ok
> clang "-fansi-escape-codes" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
checking for flags (-Wno-gnu-line-marker -Werror) ... ok
> clang "-Wno-gnu-line-marker" "-Werror" "-Qunused-arguments" "-m32" "--target=i686-windows-msvc"
[ 75%]: linking.debug demo-app.exe
link -nologo -dynamicbase -nxcompat -m32 --target=i686-windows-msvc -machine:x86 -debug -pdb:build\windows\x86\debug\demo-app.pdb kernel32.lib user32.lib gdi32.lib winspool.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib comdlg32.lib setupapi.lib shlwapi.lib strsafe.lib -subsystem:windows -out:build\windows\x86\debug\demo-app.exe build\.objs\demo-app\windows\x86\debug\src\main.cpp.obj
create ok!
compile_commands.json updated!
error: @programdir\core\main.lua:329: @programdir\actions\build\main.lua:148: @programdir\modules\async\runjobs.lua:325: @programdir\actions\build\kinds\binary.lua:53: @programdir\modules\core\tools\link.lua:175:
stack traceback:
    [C]: in function 'error'
    [@programdir\core\base\os.lua:1004]:
    [@programdir\modules\core\tools\link.lua:175]: in function 'catch'
    [@programdir\core\sandbox\modules\try.lua:123]: in function 'try'
    [@programdir\modules\core\tools\link.lua:151]:
    [C]: in function 'xpcall'
    [@programdir\core\base\utils.lua:244]:
    [@programdir\core\tool\linker.lua:232]: in function 'link'
    [@programdir\actions\build\kinds\binary.lua:53]: in function 'callback'
    [@programdir\modules\core\project\depend.lua:217]: in function 'on_changed'
    [@programdir\actions\build\kinds\binary.lua:41]: in function '_do_link_target'
    [@programdir\actions\build\kinds\binary.lua:83]:
    [@programdir\actions\build\kinds\binary.lua:110]: in function '_link_target'
    [@programdir\actions\build\kinds\binary.lua:138]: in function 'jobfunc'
    [@programdir\modules\async\runjobs.lua:241]:
    [C]: in function 'xpcall'
    [@programdir\core\base\utils.lua:244]: in function 'trycall'
    [@programdir\core\sandbox\modules\try.lua:117]: in function 'try'
    [@programdir\modules\async\runjobs.lua:224]: in function 'cotask'
    [@programdir\core\base\scheduler.lua:406]:

stack traceback:
        [C]: in function 'error'
        @programdir\core\base\os.lua:1004: in function 'os.raiselevel'
        (...tail calls...)
        @programdir\core\main.lua:329: in upvalue 'cotask'
        @programdir\core\base\scheduler.lua:406: in function <@programdir\core\base\scheduler.lua:399>

And since Xmake doesn't show link.exe's output, I'll provide it here myself:

link -nologo -dynamicbase -nxcompat -m32 --target=i686-windows-msvc -machine:x86 -debug -pdb:build\windows\x86\debug\demo-app.pdb kernel32.lib user32.lib gdi32.lib winspool.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib comdlg32.lib setupapi.lib shlwapi.lib strsafe.lib -subsystem:windows -out:build\windows\x86\debug\demo-app.exe build\.objs\demo-app\windows\x86\debug\src\main.cpp.obj
LINK : warning LNK4044: unrecognized option '/m32'; ignored
LINK : warning LNK4044: unrecognized option '/-target=i686-windows-msvc'; ignored
LINK : build\windows\x86\debug\demo-app.exe not found or not built by the last incremental link; performing full link
main.cpp.obj : error LNK2019: unresolved external symbol __imp__MessageBoxW@16 referenced in function _WinMain@16
LINK : error LNK2001: unresolved external symbol _WinMainCRTStartup
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\kernel32.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\user32.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\gdi32.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\winspool.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\advapi32.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\shell32.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\ole32.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\oleaut32.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\uuid.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\odbc32.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\odbccp32.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\comctl32.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\comdlg32.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\setupapi.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\shlwapi.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64\strsafe.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
build\windows\x86\debug\demo-app.exe : fatal error LNK1120: 2 unresolved externals

@star-hengxing The ideal behavior is that Xmake invokes link.exe just like it does for clang-cl as shown above (and not add -m32 --target=i686-windows-msvc for link.exe which it doesn't recognize)

@Doekin
Copy link
Contributor Author

Doekin commented Dec 20, 2024

@Doekin Did you invoke link.exe manually or was it done by Xmake?

Yes, I ran clang -c and link separately to verify whether object files compiled by Clang can be linked with the MSVC linker.

Also, I noticed something, do you think that -pc is unnecessary (for x64 and x86 I mean)?

-pc might be unnecessary in this context.

@star-hengxing Are you sure? It's using the Clang wrapper to link (in your results), not MSVC link.exe

[ 75%]: linking.release test.exe  
clang++ -o build\windows\x64\release\test.exe build\.objs\test\windows\x64\release\src\main.cpp.obj -m64 --target=x86_64-pc-windows-msvc -v  

From what I’ve seen, Clang internally invokes link.exe. Here's an example:

$ clang -v -m64 --target=x86_64-pc-windows-msvc .\hello.o
clang version 19.1.5 (https://github.com/llvm/llvm-project.git ab4b5a2db582958af1ee308a790cfdb42bd24720)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: D:/Applications/Scoop/apps/mingw-mstorsjo-llvm-ucrt/19.1.5-20241203/bin
 "C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Tools\\MSVC\\14.42.34433\\bin/Hostx64/x64/link.exe" -out:a.exe -defaultlib:libcmt -defaultlib:oldnames -libpath:D:/Applications/Scoop/apps/mingw-mstorsjo-llvm-ucrt/19.1.5-20241203/lib/clang/19/lib/windows -nologo ".\\hello.o"

This demonstrates that link.exe is being used when targeting x86_64-pc-windows-msvc.

@ifarbod
Copy link
Contributor

ifarbod commented Dec 20, 2024

@Doekin Yeah from what I've seen, Clang has a wrapper for link.exe, I thought it's impossible to pass arguments to it, until I discovered -Wl

e.g.

add_ldflags("-Wl,-manifest:embed", {force = true})

I just want to see Xmake in a state that it supports all kind of possible combinations for compiling Windows programs (mingw, msvc, clang, bare clang, etc.) - for example, you can't cross compile for armv7 or arm64 with clang-cl on Xmake (it is possible in reality though)

Also I remembered that Visual Studio on ARM, and Clang on Windows 11 ARM64 both exist and I'm not sure if Xmake supports compiling on these (CoPilot+ PC) - most of the attention is on macOS ARM64 so Linux and Windows arm support is usually forgotten by most projects.

@Doekin
Copy link
Contributor Author

Doekin commented Dec 20, 2024

That’s impressive. We might need more testing to ensure all these combinations are fully supported.

@star-hengxing
Copy link
Contributor

@Doekin Yeah from what I've seen, Clang has a wrapper for link.exe, I thought it's impossible to pass arguments to it, until I discovered -Wl

this project only supports mingw & windows (clang + msvc stl) platform, you can use it as a reference.
https://github.com/lhmouse/mcfgthread/blob/d76d0cc9ee74b034fecbe9d0de4cd969571825c9/meson.build#L185-L193

That’s impressive. We might need more testing to ensure all these combinations are fully supported.

We can open a new issue for discussion.

@ifarbod
Copy link
Contributor

ifarbod commented Dec 20, 2024

I'd like to also help out if possible, let's open new issues and/or discussions.

My current issues:

  • clang toolchain doesn't support link.exe directly (xmake uses clang wrapper) - but support for this should be trivial as clang-cl can invoke it correctly - also you can easily find real world examples that do this
  • Support for HostARM64 cl.exe and other tools
  • Better support for ARM64 macOS and Linux cross-compiling for Windows (x86, x64, armv7, arm64) - this means that checking the host architecture so if we're on arm64 and intended to target armv7, make Xmake pass -m32
  • Fix clang-cl for armv7 and arm64
  • Have a rule/policy to only generate compile-commands with either clang-cl or clang (for Windows)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

目标平台为 MinGW 时,Clang 工具链参数 --target=x86_64-windows-gnu 不适用于 LLVM-MinGW
4 participants