From 518b46400f45a525681cc9325c45e3a6a934f4c3 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Sat, 10 Oct 2026 03:21:36 +0100 Subject: Support self-contained Windows compiler toolchain This will need to be accompanied by the publication of my toolchains repo at some point which has scripts to set up fixed versions of MSVC and LLVM, with way less space wasted than the official distributions thereof. Also that'll become necessary for a period of time until I figure out why LLVM 22 and 23 are unable to link SST now; we are stuck on 20 for the foreseeable future which makes having a self-contained thing quite helpful. This change also includes a couple of other build script improvements too, most notably debug builds without having to edit the damn script every time. --- compile | 2 ++ compile.bat | 57 +++++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/compile b/compile index 39a2d99..ea00965 100755 --- a/compile +++ b/compile @@ -24,6 +24,8 @@ warnings="-Wall -pedantic -Wno-parentheses -Wno-missing-braces \ stdflags="-std=c2x -D_DEFAULT_SOURCE -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64" dbg=0 +if [ "$1" = "dbg" ]; then dbg=1; fi + if [ "$dbg" = 1 ]; then cflags="-O0 -g3 -masm=intel -fsanitize-trap=undefined -DSST_DBG" ldflags="-O0 -g3" diff --git a/compile.bat b/compile.bat index b015925..3eae3a8 100644 --- a/compile.bat +++ b/compile.bat @@ -8,21 +8,46 @@ if not exist .build\ ( ) if not exist .build\include\ md .build\include -if "%CC%"=="" set CC=clang --target=i686-pc-windows-msvc -if "%HOSTCC%"=="" set HOSTCC=clang - -set host64=0 +:: XXX: still need to publicly document all the toolchain stuff +if not defined SST_TOOLCHAINS_ROOT goto :notoolchain +set _clang="%SST_TOOLCHAINS_ROOT%\llvm\bin\clang" -Xmicrosoft-windows-sys-root "%SST_TOOLCHAINS_ROOT%\msvc" +set CC=%_clang% --target=i686-pc-windows-msvc +:: note: we just assume x64 host here because toolchains repo currently assumes +:: assumes that too. supporting 32-bit hosts with that would be complex and +:: almost certainly completely useless lol +set HOSTCC=%_clang% --target=x86_64-pc-windows-msvc +set host64=1 +:: the llvm distro I've got currently doesn't have an lld-link.exe but does have +:: an ld.lld.exe; this may change in the future I suppose so support both. +if exist "%SST_TOOLCHAINS_ROOT%\llvm\bin\lld-link.exe" ( + set LLDLINK="%SST_TOOLCHAINS_ROOT%\llvm\bin\lld-link" +) else ( + set LLDLINK="%SST_TOOLCHAINS_ROOT%\llvm\bin\ld.lld.exe" -flavor link +) +set LLVMRC="%SST_TOOLCHAINS_ROOT%\llvm\bin\llvm-rc.exe" +goto :toolchaindone + +:notoolchain +if not defined CC set CC=clang --target=i686-pc-windows-msvc +if not defined HOSTCC set HOSTCC=clang +:: XXX: kinda non-standard variables here, not sure what else would make sense? +if not defined LLDLINK set LLDLINK=lld-link +if not defined LLVMRC set LLVMRC=llvm-rc ( echo:#ifndef _WIN64 echo:#error echo:#endif ) | %HOSTCC% -E - >nul 2>nul && set host64=1 +:toolchaindone set warnings=-Wall -pedantic -Wno-parentheses -Wno-missing-braces ^ -Wno-gnu-zero-variadic-macro-arguments -Werror=implicit-function-declaration ^ -Werror=vla set dbg=0 +if "%~1"=="dbg" set dbg=1 +set onething=%~2 + :: XXX: -Og would be nice but apparently a bunch of stuff still gets inlined :: which can be somewhat annoying so -O0 it is. if "%dbg%"=="1" ( @@ -46,9 +71,14 @@ set dmodname= -DMODULE_NAME=%basename% if "%dmodname%"==" -DMODULE_NAME=con_" set dmodname= -DMODULE_NAME=con if "%dmodname%"==" -DMODULE_NAME=sst" set dmodname= set objs=%objs% .build/%basename%%ext%.o +:: extremely poor man's incremental build: manually specify one changed source +:: file by basename. the full source list is still put together so everything +:: gets relinked from existing objects. would obviously be good to have a real +:: build system, but this can be occasionally handy and took very low effort :) +if not "%onething%"=="" if not "src/%onething%.c"=="%1" exit /b 0 %CC% -c -mno-stack-arg-probe %cflags% %warnings% %stdflags% -include src/1.h ^ --I.build/include -D_DLL%dmodname% -o .build/%basename%%ext%.o %1 || goto :end -goto :eof +-I.build/include -D_DLL%dmodname% -o .build/%basename%%ext%.o %1 +exit /b %errorlevel% :main @@ -116,11 +146,12 @@ if "%dbg%"=="1" ( if "%dbg%"=="1" set src=%src% src/udis86.c if "%dbg%"=="0" set src=%src% src/wincrt.c +if defined onething goto :skiphost %CC% -fuse-ld=lld -shared -O0 -w -o .build/bcryptprimitives.dll -Wl,-def:src/stubs/bcryptprimitives.def src/stubs/bcryptprimitives.c set lbcryptprimitives_host=-lbcryptprimitives if %host64%==1 ( :: note: no mangling madness on x64, so we can just call the linker directly - lld-link -machine:x64 -def:src/stubs/bcryptprimitives.def -implib:.build/bcryptprimitives64.lib + %LLDLINK% -machine:x64 -def:src/stubs/bcryptprimitives.def -implib:.build/bcryptprimitives64.lib set lbcryptprimitives_host=-lbcryptprimitives64 ) %CC% -fuse-ld=lld -shared -O0 -w -o .build/tier0.dll src/stubs/tier0.c @@ -136,7 +167,9 @@ if %host64%==1 ( .build\mkgamedata.exe gamedata/engine.txt gamedata/gamelib.txt gamedata/inputsystem.txt ^ gamedata/matchmaking.txt gamedata/vgui2.txt gamedata/vguimatsurface.txt gamedata/vphysics.txt || goto :end .build\mkentprops.exe gamedata/entprops.txt || goto :end -llvm-rc /FO .build\dll.res src\dll.rc || goto :end +%LLVMRC% /FO .build\dll.res src\dll.rc || goto :end + +:skiphost for %%b in (%src%) do ( call :cc %%b || goto :end ) :: we need different library names for debugging because Microsoft... :: actually, it's different anyway because we don't use vcruntime for releases @@ -169,9 +202,13 @@ move /y .build\sst.dll sst.dll >nul 2>nul || ( :: in some eventual future invocation if exist .build\sst.old.dll del .build\sst.old.dll >nul 2>nul -%HOSTCC% -fuse-ld=lld -O2 -g %warnings% %stdflags% -include test/test.h -o .build/bitbuf.test.exe test/bitbuf.test.c || goto :end +:: can also skip recompiling the tests on partial recompiles, probably +:: (technically not always safe to do, but whatever, fine in practice) +if not defined onething ( + %HOSTCC% -fuse-ld=lld -O2 -g %warnings% %stdflags% -include test/test.h -o .build/bitbuf.test.exe test/bitbuf.test.c || goto :end + %HOSTCC% -fuse-ld=lld -O2 -g %warnings% %stdflags% -include test/test.h -o .build/x86.test.exe test/x86.test.c || goto :end +) .build\bitbuf.test.exe || goto :end -%HOSTCC% -fuse-ld=lld -O2 -g %warnings% %stdflags% -include test/test.h -o .build/x86.test.exe test/x86.test.c || goto :end .build\x86.test.exe || goto :end :end -- cgit v1.2.3-54-g00ecf