Skip to content

Commit 308b8f6

Browse files
authored
Merge pull request #140 from kcbanner/msvc_build
Windows (MSVC) bootstrapping script
2 parents cfed40a + 7999896 commit 308b8f6

File tree

3 files changed

+285
-1
lines changed

3 files changed

+285
-1
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ For other versions, check the git tags of this repository.
2020
* all: Deleted unused files.
2121
* LLVM: Support .lib extension for static zstd.
2222
* LLVM: Copied CMake modules from out of tree.
23+
* LLVM: Portable handling of .def linker flag
2324
* Clang: Disable building of libclang-cpp.so.
2425
* LLD: Added additional include directory to Zig's libunwind.
2526
* zlib: Delete the ability to build a shared library.
@@ -59,6 +60,20 @@ significantly affect how long it takes to build:
5960

6061
When it succeeds, output can be found in `out/zig-<triple>-<cpu>/`.
6162

63+
## Windows Build Instructions
64+
65+
Bootstrapping on Windows with MSVC is also possible via `build.bat`, which
66+
takes the same arguments as `build` above.
67+
68+
This script requires that the "C++ CMake tools for Windows" component be
69+
installed via the Visual Studio installer.
70+
71+
The script must be run within the `Developer Command Prompt for VS 2019` shell:
72+
73+
```
74+
build.bat <arch>-<os>-<abi> <mcpu>
75+
```
76+
6277
### Supported Triples
6378

6479
If you try a "not tested" one and find a problem please file an issue,

build.bat

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
@echo off
2+
3+
SETLOCAL EnableDelayedExpansion
4+
if NOT DEFINED VSCMD_VER (
5+
echo error: this script must be run within the visual studio developer command prompt
6+
exit /b 1
7+
)
8+
9+
where ninja >nul 2>nul
10+
if %ERRORLEVEL% neq 0 (
11+
echo error: this script requires ninja to be installed, as the Visual Studio cmake generator doesn't support alternate compilers
12+
exit /b %ERRORLEVEL%
13+
)
14+
15+
if "%1" == "" (set "TARGET=x86_64-windows-gnu") ELSE (set TARGET=%~1)
16+
if "%2" == "" (set "MCPU=native") ELSE (set MCPU=%~2)
17+
18+
set TARGET_ABI=
19+
set TARGET_OS_CMAKE=
20+
FOR /F "tokens=2,3 delims=-" %%i IN ("%TARGET%") DO (
21+
IF "%%i"=="macos" set "TARGET_OS_CMAKE=Darwin"
22+
IF "%%i"=="freebsd" set "TARGET_OS_CMAKE=FreeBSD"
23+
IF "%%i"=="windows" set "TARGET_OS_CMAKE=Windows"
24+
IF "%%i"=="linux" set "TARGET_OS_CMAKE=Linux"
25+
set TARGET_ABI=%%j
26+
)
27+
28+
set OUTDIR=out-win
29+
set ROOTDIR=%~dp0
30+
set "ROOTDIR_CMAKE=%ROOTDIR:\=/%"
31+
set ZIG_VERSION=0.11.0-dev.995+7350f0d9b
32+
33+
set JOBS_ARG=
34+
35+
pushd %ROOTDIR%
36+
37+
rem Build zlib for the host
38+
mkdir "%ROOTDIR%%OUTDIR%\build-zlib-host"
39+
cd "%ROOTDIR%%OUTDIR%\build-zlib-host"
40+
cmake "%ROOTDIR%/zlib" ^
41+
-G "Ninja" ^
42+
-DCMAKE_INSTALL_PREFIX="%ROOTDIR%/%OUTDIR%/host" ^
43+
-DCMAKE_PREFIX_PATH="%ROOTDIR%/%OUTDIR%/host" ^
44+
-DCMAKE_BUILD_TYPE=Release ^
45+
-DCMAKE_USER_MAKE_RULES_OVERRIDE="%ROOTDIR%/zig/cmake/c_flag_overrides.cmake"
46+
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
47+
48+
cmake --build . %JOBS_ARG% --target install
49+
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
50+
51+
rem Build the libraries for Zig to link against, as well as native `llvm-tblgen` using msvc
52+
mkdir "%ROOTDIR%%OUTDIR%\build-llvm-host"
53+
cd "%ROOTDIR%%OUTDIR%\build-llvm-host"
54+
cmake "%ROOTDIR%/llvm" ^
55+
-G "Ninja" ^
56+
-DLLVM_ENABLE_PROJECTS="lld;clang" ^
57+
-DLLVM_ENABLE_LIBXML2=OFF ^
58+
-DLLVM_ENABLE_ZSTD=OFF ^
59+
-DCMAKE_INSTALL_PREFIX="%ROOTDIR%/%OUTDIR%/host" ^
60+
-DCMAKE_PREFIX_PATH="%ROOTDIR%/%OUTDIR%/host" ^
61+
-DLLVM_INCLUDE_TESTS=OFF ^
62+
-DLLVM_INCLUDE_GO_TESTS=OFF ^
63+
-DLLVM_INCLUDE_EXAMPLES=OFF ^
64+
-DLLVM_INCLUDE_BENCHMARKS=OFF ^
65+
-DLLVM_ENABLE_BINDINGS=OFF ^
66+
-DLLVM_ENABLE_OCAMLDOC=OFF ^
67+
-DLLVM_ENABLE_Z3_SOLVER=OFF ^
68+
-DCLANG_BUILD_TOOLS=OFF ^
69+
-DCLANG_INCLUDE_DOCS=OFF ^
70+
-DLLVM_INCLUDE_DOCS=OFF ^
71+
-DLLVM_USE_CRT_RELEASE=MT ^
72+
-DCMAKE_BUILD_TYPE=Release
73+
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
74+
cmake --build . %JOBS_ARG% --target install
75+
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
76+
77+
rem Build an x86_64-windows-msvc zig using msvc, linking against LLVM/Clang/LLD/zlib built by msvc
78+
mkdir "%ROOTDIR%%OUTDIR%\build-zig-host"
79+
cd "%ROOTDIR%%OUTDIR%\build-zig-host"
80+
cmake "%ROOTDIR%/zig" ^
81+
-G "Ninja" ^
82+
-DCMAKE_INSTALL_PREFIX="%ROOTDIR_CMAKE%%OUTDIR%/host" ^
83+
-DCMAKE_PREFIX_PATH="%ROOTDIR_CMAKE%%OUTDIR%/host" ^
84+
-DCMAKE_BUILD_TYPE=Release ^
85+
-DZIG_STATIC=ON ^
86+
-DZIG_STATIC_ZSTD=OFF ^
87+
-DZIG_TARGET_TRIPLE=x86_64-windows-msvc ^
88+
-DZIG_TARGET_MCPU=baseline
89+
90+
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
91+
cmake --build . %JOBS_ARG% --target install
92+
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
93+
94+
IF "%TARGET_ABI%"=="msvc" (
95+
echo Building a target with the msvc ABI isn't supported yet
96+
exit /b
97+
)
98+
99+
set ZIG=%ROOTDIR%%OUTDIR%\host\bin\zig.exe
100+
set "ZIG=%ZIG:\=/%"
101+
102+
rem CMP0091=NEW is required in order for the CMAKE_MSVC_RUNTIME_LIBRARY value to be respected,
103+
rem which we need to be set to MultiThreaded when building msvc ABI targets
104+
105+
rem Cross compile zlib for the target
106+
mkdir "%ROOTDIR%%OUTDIR%\build-zlib-%TARGET%-%MCPU%"
107+
cd "%ROOTDIR%%OUTDIR%\build-zlib-%TARGET%-%MCPU%"
108+
cmake "%ROOTDIR%/zlib" ^
109+
-G "Ninja" ^
110+
-DCMAKE_INSTALL_PREFIX="%ROOTDIR_CMAKE%%OUTDIR%/%TARGET%-%MCPU%" ^
111+
-DCMAKE_PREFIX_PATH="%ROOTDIR_CMAKE%%OUTDIR%/%TARGET%-%MCPU%" ^
112+
-DCMAKE_BUILD_TYPE=Release ^
113+
-DCMAKE_CROSSCOMPILING=True ^
114+
-DCMAKE_SYSTEM_NAME="%TARGET_OS_CMAKE%" ^
115+
-DCMAKE_C_COMPILER="%ZIG%;cc;-fno-sanitize=all;-s;-target;%TARGET%;-mcpu=%MCPU%" ^
116+
-DCMAKE_CXX_COMPILER="%ZIG%;c++;-fno-sanitize=all;-s;-target;%TARGET%;-mcpu=%MCPU%" ^
117+
-DCMAKE_ASM_COMPILER="%ZIG%;cc;-fno-sanitize=all;-s;-target;%TARGET%;-mcpu=%MCPU%" ^
118+
-DCMAKE_RC_COMPILER="%ROOTDIR_CMAKE%%OUTDIR%/host/bin/llvm-rc.exe" ^
119+
-DCMAKE_AR="%ROOTDIR_CMAKE%%OUTDIR%/host/bin/llvm-ar.exe" ^
120+
-DCMAKE_RANLIB="%ROOTDIR_CMAKE%%OUTDIR%/host/bin/llvm-ranlib.exe" ^
121+
-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded ^
122+
-DCMAKE_POLICY_DEFAULT_CMP0091=NEW
123+
cmake --build . %JOBS_ARG% --target install
124+
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
125+
126+
rem Cross compile zstd for the target
127+
mkdir "%ROOTDIR%%OUTDIR%\%TARGET%-%MCPU%\lib"
128+
copy "%ROOTDIR%\zstd\lib\zstd.h" "%ROOTDIR%%OUTDIR%\%TARGET%-%MCPU%\include\zstd.h"
129+
cd "%ROOTDIR%%OUTDIR%\%TARGET%-%MCPU%\lib"
130+
%ZIG% build-lib ^
131+
--name zstd ^
132+
-target %TARGET% ^
133+
-mcpu=%MCPU% ^
134+
-fstrip ^
135+
-OReleaseFast ^
136+
-lc ^
137+
"%ROOTDIR%\zstd\lib\decompress\zstd_ddict.c" ^
138+
"%ROOTDIR%\zstd\lib\decompress\zstd_decompress.c" ^
139+
"%ROOTDIR%\zstd\lib\decompress\huf_decompress.c" ^
140+
"%ROOTDIR%\zstd\lib\decompress\huf_decompress_amd64.S" ^
141+
"%ROOTDIR%\zstd\lib\decompress\zstd_decompress_block.c" ^
142+
"%ROOTDIR%\zstd\lib\compress\zstdmt_compress.c" ^
143+
"%ROOTDIR%\zstd\lib\compress\zstd_opt.c" ^
144+
"%ROOTDIR%\zstd\lib\compress\hist.c" ^
145+
"%ROOTDIR%\zstd\lib\compress\zstd_ldm.c" ^
146+
"%ROOTDIR%\zstd\lib\compress\zstd_fast.c" ^
147+
"%ROOTDIR%\zstd\lib\compress\zstd_compress_literals.c" ^
148+
"%ROOTDIR%\zstd\lib\compress\zstd_double_fast.c" ^
149+
"%ROOTDIR%\zstd\lib\compress\huf_compress.c" ^
150+
"%ROOTDIR%\zstd\lib\compress\fse_compress.c" ^
151+
"%ROOTDIR%\zstd\lib\compress\zstd_lazy.c" ^
152+
"%ROOTDIR%\zstd\lib\compress\zstd_compress.c" ^
153+
"%ROOTDIR%\zstd\lib\compress\zstd_compress_sequences.c" ^
154+
"%ROOTDIR%\zstd\lib\compress\zstd_compress_superblock.c" ^
155+
"%ROOTDIR%\zstd\lib\deprecated\zbuff_compress.c" ^
156+
"%ROOTDIR%\zstd\lib\deprecated\zbuff_decompress.c" ^
157+
"%ROOTDIR%\zstd\lib\deprecated\zbuff_common.c" ^
158+
"%ROOTDIR%\zstd\lib\common\entropy_common.c" ^
159+
"%ROOTDIR%\zstd\lib\common\pool.c" ^
160+
"%ROOTDIR%\zstd\lib\common\threading.c" ^
161+
"%ROOTDIR%\zstd\lib\common\zstd_common.c" ^
162+
"%ROOTDIR%\zstd\lib\common\xxhash.c" ^
163+
"%ROOTDIR%\zstd\lib\common\debug.c" ^
164+
"%ROOTDIR%\zstd\lib\common\fse_decompress.c" ^
165+
"%ROOTDIR%\zstd\lib\common\error_private.c" ^
166+
"%ROOTDIR%\zstd\lib\dictBuilder\zdict.c" ^
167+
"%ROOTDIR%\zstd\lib\dictBuilder\divsufsort.c" ^
168+
"%ROOTDIR%\zstd\lib\dictBuilder\fastcover.c" ^
169+
"%ROOTDIR%\zstd\lib\dictBuilder\cover.c"
170+
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
171+
172+
rem Ideally we could use ZLIB_USE_STATIC_LIBS here (which would detect zlib correctly),
173+
rem but this was added in 3.24 and the MSVC-bundled CMake is 3.20. Instead, for the msvc
174+
rem ABI the zlib path is specified explicitly.
175+
176+
IF "%TARGET_ABI%"=="msvc" (
177+
set ZLIB_LIBRARY=-DZLIB_LIBRARY="%ROOTDIR_CMAKE%%OUTDIR%/%TARGET%-%MCPU%/lib/z.lib"
178+
) else (
179+
set ZLIB_LIBRARY=
180+
)
181+
rem Cross compile LLVM for the target
182+
mkdir "%ROOTDIR%%OUTDIR%\build-llvm-%TARGET%-%MCPU%"
183+
cd "%ROOTDIR%%OUTDIR%\build-llvm-%TARGET%-%MCPU%"
184+
cmake "%ROOTDIR%/llvm" ^
185+
-G "Ninja" ^
186+
-DCMAKE_INSTALL_PREFIX="%ROOTDIR_CMAKE%%OUTDIR%/%TARGET%-%MCPU%" ^
187+
-DCMAKE_PREFIX_PATH="%ROOTDIR_CMAKE%%OUTDIR%/%TARGET%-%MCPU%" ^
188+
-DCMAKE_BUILD_TYPE=Release ^
189+
-DCMAKE_CROSSCOMPILING=True ^
190+
-DCMAKE_SYSTEM_NAME="%TARGET_OS_CMAKE%" ^
191+
-DCMAKE_C_COMPILER="%ZIG%;cc;-fno-sanitize=all;-s;-target;%TARGET%;-mcpu=%MCPU%" ^
192+
-DCMAKE_CXX_COMPILER="%ZIG%;c++;-fno-sanitize=all;-s;-target;%TARGET%;-mcpu=%MCPU%" ^
193+
-DCMAKE_ASM_COMPILER="%ZIG%;cc;-fno-sanitize=all;-s;-target;%TARGET%;-mcpu=%MCPU%" ^
194+
-DCMAKE_RC_COMPILER="%ROOTDIR_CMAKE%%OUTDIR%/host/bin/llvm-rc.exe" ^
195+
-DCMAKE_AR="%ROOTDIR_CMAKE%%OUTDIR%/host/bin/llvm-ar.exe" ^
196+
-DCMAKE_RANLIB="%ROOTDIR_CMAKE%%OUTDIR%/host/bin/llvm-ranlib.exe" ^
197+
-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded ^
198+
-DCMAKE_POLICY_DEFAULT_CMP0091=NEW ^
199+
-DLLVM_ENABLE_BACKTRACES=OFF ^
200+
-DLLVM_ENABLE_BINDINGS=OFF ^
201+
-DLLVM_ENABLE_CRASH_OVERRIDES=OFF ^
202+
-DLLVM_ENABLE_LIBEDIT=OFF ^
203+
-DLLVM_ENABLE_LIBPFM=OFF ^
204+
-DLLVM_ENABLE_LIBXML2=OFF ^
205+
-DLLVM_ENABLE_OCAMLDOC=OFF ^
206+
-DLLVM_ENABLE_PLUGINS=OFF ^
207+
-DLLVM_ENABLE_PROJECTS="lld;clang" ^
208+
-DLLVM_ENABLE_TERMINFO=OFF ^
209+
-DLLVM_ENABLE_Z3_SOLVER=OFF ^
210+
-DLLVM_ENABLE_ZLIB=FORCE_ON ^
211+
-DLLVM_ENABLE_ZSTD=FORCE_ON ^
212+
-DLLVM_USE_STATIC_ZSTD=ON ^
213+
-DLLVM_TABLEGEN="%ROOTDIR_CMAKE%%OUTDIR%/host/bin/llvm-tblgen.exe" ^
214+
-DLLVM_BUILD_TOOLS=OFF ^
215+
-DLLVM_BUILD_STATIC=ON ^
216+
-DLLVM_INCLUDE_UTILS=OFF ^
217+
-DLLVM_INCLUDE_TESTS=OFF ^
218+
-DLLVM_INCLUDE_GO_TESTS=OFF ^
219+
-DLLVM_INCLUDE_EXAMPLES=OFF ^
220+
-DLLVM_INCLUDE_BENCHMARKS=OFF ^
221+
-DLLVM_INCLUDE_DOCS=OFF ^
222+
-DLLVM_DEFAULT_TARGET_TRIPLE=%TARGET% ^
223+
-DLLVM_TOOL_LLVM_LTO2_BUILD=OFF ^
224+
-DLLVM_TOOL_LLVM_LTO_BUILD=OFF ^
225+
-DLLVM_TOOL_LTO_BUILD=OFF ^
226+
-DLLVM_TOOL_REMARKS_SHLIB_BUILD=OFF ^
227+
-DCLANG_TABLEGEN="%ROOTDIR_CMAKE%%OUTDIR%/build-llvm-host/bin/clang-tblgen.exe" ^
228+
-DCLANG_BUILD_TOOLS=OFF ^
229+
-DCLANG_INCLUDE_DOCS=OFF ^
230+
-DCLANG_INCLUDE_TESTS=OFF ^
231+
-DCLANG_ENABLE_ARCMT=ON ^
232+
-DCLANG_TOOL_CLANG_IMPORT_TEST_BUILD=OFF ^
233+
-DCLANG_TOOL_CLANG_LINKER_WRAPPER_BUILD=OFF ^
234+
-DCLANG_TOOL_C_INDEX_TEST_BUILD=OFF ^
235+
-DCLANG_TOOL_ARCMT_TEST_BUILD=OFF ^
236+
-DCLANG_TOOL_C_ARCMT_TEST_BUILD=OFF ^
237+
-DCLANG_TOOL_LIBCLANG_BUILD=OFF ^
238+
-DZLIB_USE_STATIC_LIBS=ON ^
239+
%ZLIB_LIBRARY% ^
240+
-DLIBCLANG_BUILD_STATIC=ON
241+
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
242+
cmake --build . %JOBS_ARG% --target install
243+
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
244+
245+
rem Finally, we can cross compile Zig itself, with Zig.
246+
cd "%ROOTDIR%\zig"
247+
%ZIG% build ^
248+
--prefix "%ROOTDIR%%OUTDIR%\zig-%TARGET%-%MCPU%" ^
249+
--search-prefix "%ROOTDIR%%OUTDIR%\%TARGET%-%MCPU%" ^
250+
-Dstatic-llvm ^
251+
-Drelease ^
252+
-Dstrip ^
253+
-Dtarget="%TARGET%" ^
254+
-Dcpu="%MCPU%" ^
255+
-Dversion-string="%ZIG_VERSION%"
256+
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
257+
258+
popd

llvm/cmake/modules/AddLLVM.cmake

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ function(add_llvm_symbol_exports target_name export_file)
118118
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
119119
LINK_FLAGS " -Wl,--version-script,\"${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}\"")
120120
endif()
121-
else()
121+
elseif(WIN32)
122122
set(native_export_file "${target_name}.def")
123123

124124
add_custom_command(OUTPUT ${native_export_file}
@@ -129,7 +129,18 @@ function(add_llvm_symbol_exports target_name export_file)
129129
COMMENT "Creating export file for ${target_name}")
130130
set(export_file_linker_flag "${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}")
131131
if(MSVC)
132+
# cl.exe or clang-cl, i.e. MSVC style command line interface
132133
set(export_file_linker_flag "/DEF:\"${export_file_linker_flag}\"")
134+
elseif(CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
135+
# clang in msvc mode, calling a link.exe/lld-link style linker
136+
set(export_file_linker_flag "-Wl,/DEF:\"${export_file_linker_flag}\"")
137+
elseif(MINGW)
138+
# ${export_file_linker_flag}, which is the plain file name, works as is
139+
# when passed to the compiler driver, which then passes it on to the
140+
# linker as an input file.
141+
set(export_file_linker_flag "\"${export_file_linker_flag}\"")
142+
else()
143+
message(FATAL_ERROR "Unsupported Windows toolchain")
133144
endif()
134145
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
135146
LINK_FLAGS " ${export_file_linker_flag}")

0 commit comments

Comments
 (0)