xref: /llvm-project/llvm/utils/release/build_llvm_release.bat (revision b55c52c047a167f42abbde9a33356cfb96b82c7f)
1@echo off
2setlocal enabledelayedexpansion
3
4goto begin
5
6:usage
7echo Script for building the LLVM installer on Windows,
8echo used for the releases at https://github.com/llvm/llvm-project/releases
9echo.
10echo Usage: build_llvm_release.bat --version ^<version^> [--x86,--x64, --arm64] [--skip-checkout] [--local-python]
11echo.
12echo Options:
13echo --version: [required] version to build
14echo --help: display this help
15echo --x86: build and test x86 variant
16echo --x64: build and test x64 variant
17echo --arm64: build and test arm64 variant
18echo --skip-checkout: use local git checkout instead of downloading src.zip
19echo --local-python: use installed Python and does not try to use a specific version (3.10)
20echo.
21echo Note: At least one variant to build is required.
22echo.
23echo Example: build_llvm_release.bat --version 15.0.0 --x86 --x64
24exit /b 1
25
26:begin
27
28::==============================================================================
29:: parse args
30set version=
31set help=
32set x86=
33set x64=
34set arm64=
35set skip-checkout=
36set local-python=
37call :parse_args %*
38
39if "%help%" NEQ "" goto usage
40
41if "%version%" == "" (
42    echo --version option is required
43    echo =============================
44    goto usage
45)
46
47if "%arm64%" == "" if "%x64%" == "" if "%x86%" == "" (
48    echo nothing to build!
49    echo choose one or several variants from: --x86 --x64 --arm64
50    exit /b 1
51)
52
53::==============================================================================
54:: check prerequisites
55REM Note:
56REM   7zip versions 21.x and higher will try to extract the symlinks in
57REM   llvm's git archive, which requires running as administrator.
58
59REM Check 7-zip version and/or administrator permissions.
60for /f "delims=" %%i in ('7z.exe ^| findstr /r "2[1-9].[0-9][0-9]"') do set version_7z=%%i
61if not "%version_7z%"=="" (
62  REM Unique temporary filename to use by the 'mklink' command.
63  set "link_name=%temp%\%username%_%random%_%random%.tmp"
64
65  REM As the 'mklink' requires elevated permissions, the symbolic link
66  REM creation will fail if the script is not running as administrator.
67  mklink /d "!link_name!" . 1>nul 2>nul
68  if errorlevel 1 (
69    echo.
70    echo Script requires administrator permissions, or a 7-zip version 20.x or older.
71    echo Current version is "%version_7z%"
72    exit /b 1
73  ) else (
74    REM Remove the temporary symbolic link.
75    rd "!link_name!"
76  )
77)
78
79REM Prerequisites:
80REM
81REM   Visual Studio 2019, CMake, Ninja, GNUWin32, SWIG, Python 3,
82REM   NSIS with the strlen_8192 patch,
83REM   Perl (for the OpenMP run-time).
84REM
85REM
86REM   For LLDB, SWIG version 4.1.1 should be used.
87REM
88
89:: Detect Visual Studio
90set vsinstall=
91set vswhere=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe
92
93if "%VSINSTALLDIR%" NEQ "" (
94  echo using enabled Visual Studio installation
95  set "vsinstall=%VSINSTALLDIR%"
96) else (
97  echo using vswhere to detect Visual Studio installation
98  FOR /F "delims=" %%r IN ('^""%vswhere%" -nologo -latest -products "*" -all -property installationPath^"') DO set vsinstall=%%r
99)
100set "vsdevcmd=%vsinstall%\Common7\Tools\VsDevCmd.bat"
101
102if not exist "%vsdevcmd%" (
103  echo Can't find any installation of Visual Studio
104  exit /b 1
105)
106echo Using VS devcmd: %vsdevcmd%
107
108::==============================================================================
109:: start echoing what we do
110@echo on
111
112set python32_dir=C:\Users\%USERNAME%\AppData\Local\Programs\Python\Python310-32
113set python64_dir=C:\Users\%USERNAME%\AppData\Local\Programs\Python\Python310
114set pythonarm64_dir=C:\Users\%USERNAME%\AppData\Local\Programs\Python\Python311-arm64
115
116set revision=llvmorg-%version%
117set package_version=%version%
118set build_dir=%cd%\llvm_package_%package_version%
119
120echo Revision: %revision%
121echo Package version: %package_version%
122echo Build dir: %build_dir%
123echo.
124
125if exist %build_dir% (
126  echo Build directory already exists: %build_dir%
127  exit /b 1
128)
129mkdir %build_dir%
130cd %build_dir% || exit /b 1
131
132if "%skip-checkout%" == "true" (
133  echo Using local source
134  set llvm_src=%~dp0..\..\..
135) else (
136  echo Checking out %revision%
137  curl -L https://github.com/llvm/llvm-project/archive/%revision%.zip -o src.zip || exit /b 1
138  7z x src.zip || exit /b 1
139  mv llvm-project-* llvm-project || exit /b 1
140  set llvm_src=%build_dir%\llvm-project
141)
142
143curl -O https://gitlab.gnome.org/GNOME/libxml2/-/archive/v2.9.12/libxml2-v2.9.12.tar.gz || exit /b 1
144tar zxf libxml2-v2.9.12.tar.gz
145
146REM Setting CMAKE_CL_SHOWINCLUDES_PREFIX to work around PR27226.
147REM Common flags for all builds.
148set common_compiler_flags=-DLIBXML_STATIC
149set common_cmake_flags=^
150  -DCMAKE_BUILD_TYPE=Release ^
151  -DLLVM_ENABLE_ASSERTIONS=OFF ^
152  -DLLVM_INSTALL_TOOLCHAIN_ONLY=ON ^
153  -DLLVM_TARGETS_TO_BUILD="AArch64;ARM;X86" ^
154  -DLLVM_BUILD_LLVM_C_DYLIB=ON ^
155  -DCMAKE_INSTALL_UCRT_LIBRARIES=ON ^
156  -DPython3_FIND_REGISTRY=NEVER ^
157  -DPACKAGE_VERSION=%package_version% ^
158  -DLLDB_RELOCATABLE_PYTHON=1 ^
159  -DLLDB_EMBED_PYTHON_HOME=OFF ^
160  -DCMAKE_CL_SHOWINCLUDES_PREFIX="Note: including file: " ^
161  -DLLVM_ENABLE_LIBXML2=FORCE_ON ^
162  -DLLDB_ENABLE_LIBXML2=OFF ^
163  -DCLANG_ENABLE_LIBXML2=OFF ^
164  -DCMAKE_C_FLAGS="%common_compiler_flags%" ^
165  -DCMAKE_CXX_FLAGS="%common_compiler_flags%" ^
166  -DLLVM_ENABLE_RPMALLOC=ON ^
167  -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;compiler-rt;lldb;openmp"
168
169set cmake_profile_flags=""
170
171REM Preserve original path
172set OLDPATH=%PATH%
173
174REM Build the 32-bits and/or 64-bits binaries.
175if "%x86%" == "true" call :do_build_32 || exit /b 1
176if "%x64%" == "true" call :do_build_64 || exit /b 1
177if "%arm64%" == "true" call :do_build_arm64 || exit /b 1
178exit /b 0
179
180::==============================================================================
181:: Build 32-bits binaries.
182::==============================================================================
183:do_build_32
184call :set_environment %python32_dir% || exit /b 1
185call "%vsdevcmd%" -arch=x86 || exit /b 1
186@echo on
187mkdir build32_stage0
188cd build32_stage0
189call :do_build_libxml || exit /b 1
190
191REM Stage0 binaries directory; used in stage1.
192set "stage0_bin_dir=%build_dir%/build32_stage0/bin"
193set cmake_flags=^
194  %common_cmake_flags% ^
195  -DLLVM_ENABLE_RPMALLOC=OFF ^
196  -DLLDB_TEST_COMPILER=%stage0_bin_dir%/clang.exe ^
197  -DPYTHON_HOME=%PYTHONHOME% ^
198  -DPython3_ROOT_DIR=%PYTHONHOME% ^
199  -DLIBXML2_INCLUDE_DIR=%libxmldir%/include/libxml2 ^
200  -DLIBXML2_LIBRARIES=%libxmldir%/lib/libxml2s.lib
201
202cmake -GNinja %cmake_flags% %llvm_src%\llvm || exit /b 1
203ninja || ninja || ninja || exit /b 1
204REM ninja check-llvm || ninja check-llvm || ninja check-llvm || exit /b 1
205REM ninja check-clang || ninja check-clang || ninja check-clang || exit /b 1
206ninja check-lld || ninja check-lld || ninja check-lld || exit /b 1
207ninja check-sanitizer || ninja check-sanitizer || ninja check-sanitizer || exit /b 1
208REM ninja check-clang-tools || ninja check-clang-tools || ninja check-clang-tools || exit /b 1
209cd..
210
211REM CMake expects the paths that specifies the compiler and linker to be
212REM with forward slash.
213set all_cmake_flags=^
214  %cmake_flags% ^
215  -DCMAKE_C_COMPILER=%stage0_bin_dir%/clang-cl.exe ^
216  -DCMAKE_CXX_COMPILER=%stage0_bin_dir%/clang-cl.exe ^
217  -DCMAKE_LINKER=%stage0_bin_dir%/lld-link.exe ^
218  -DCMAKE_AR=%stage0_bin_dir%/llvm-lib.exe ^
219  -DCMAKE_RC=%stage0_bin_dir%/llvm-windres.exe
220set cmake_flags=%all_cmake_flags:\=/%
221
222mkdir build32
223cd build32
224cmake -GNinja %cmake_flags% %llvm_src%\llvm || exit /b 1
225ninja || ninja || ninja || exit /b 1
226REM ninja check-llvm || ninja check-llvm || ninja check-llvm || exit /b 1
227REM ninja check-clang || ninja check-clang || ninja check-clang || exit /b 1
228ninja check-lld || ninja check-lld || ninja check-lld || exit /b 1
229ninja check-sanitizer || ninja check-sanitizer || ninja check-sanitizer || exit /b 1
230REM ninja check-clang-tools || ninja check-clang-tools || ninja check-clang-tools || exit /b 1
231ninja package || exit /b 1
232cd ..
233
234exit /b 0
235::==============================================================================
236
237::==============================================================================
238:: Build 64-bits binaries.
239::==============================================================================
240:do_build_64
241call :set_environment %python64_dir% || exit /b 1
242call "%vsdevcmd%" -arch=amd64 || exit /b 1
243@echo on
244mkdir build64_stage0
245cd build64_stage0
246call :do_build_libxml || exit /b 1
247
248REM Stage0 binaries directory; used in stage1.
249set "stage0_bin_dir=%build_dir%/build64_stage0/bin"
250set cmake_flags=^
251  %common_cmake_flags% ^
252  -DLLDB_TEST_COMPILER=%stage0_bin_dir%/clang.exe ^
253  -DPYTHON_HOME=%PYTHONHOME% ^
254  -DPython3_ROOT_DIR=%PYTHONHOME% ^
255  -DLIBXML2_INCLUDE_DIR=%libxmldir%/include/libxml2 ^
256  -DLIBXML2_LIBRARIES=%libxmldir%/lib/libxml2s.lib
257
258cmake -GNinja %cmake_flags% %llvm_src%\llvm || exit /b 1
259ninja || ninja || ninja || exit /b 1
260ninja check-llvm || ninja check-llvm || ninja check-llvm || exit /b 1
261ninja check-clang || ninja check-clang || ninja check-clang || exit /b 1
262ninja check-lld || ninja check-lld || ninja check-lld || exit /b 1
263ninja check-sanitizer || ninja check-sanitizer || ninja check-sanitizer || exit /b 1
264ninja check-clang-tools || ninja check-clang-tools || ninja check-clang-tools || exit /b 1
265ninja check-clangd || ninja check-clangd || ninja check-clangd || exit /b 1
266cd..
267
268REM CMake expects the paths that specifies the compiler and linker to be
269REM with forward slash.
270set all_cmake_flags=^
271  %cmake_flags% ^
272  -DCMAKE_C_COMPILER=%stage0_bin_dir%/clang-cl.exe ^
273  -DCMAKE_CXX_COMPILER=%stage0_bin_dir%/clang-cl.exe ^
274  -DCMAKE_LINKER=%stage0_bin_dir%/lld-link.exe ^
275  -DCMAKE_AR=%stage0_bin_dir%/llvm-lib.exe ^
276  -DCMAKE_RC=%stage0_bin_dir%/llvm-windres.exe
277set cmake_flags=%all_cmake_flags:\=/%
278
279
280mkdir build64
281cd build64
282call :do_generate_profile || exit /b 1
283cmake -GNinja %cmake_flags% %cmake_profile_flags% %llvm_src%\llvm || exit /b 1
284ninja || ninja || ninja || exit /b 1
285ninja check-llvm || ninja check-llvm || ninja check-llvm || exit /b 1
286ninja check-clang || ninja check-clang || ninja check-clang || exit /b 1
287ninja check-lld || ninja check-lld || ninja check-lld || exit /b 1
288ninja check-sanitizer || ninja check-sanitizer || ninja check-sanitizer || exit /b 1
289ninja check-clang-tools || ninja check-clang-tools || ninja check-clang-tools || exit /b 1
290ninja check-clangd || ninja check-clangd || ninja check-clangd || exit /b 1
291ninja package || exit /b 1
292
293:: generate tarball with install toolchain only off
294set filename=clang+llvm-%version%-x86_64-pc-windows-msvc
295cmake -GNinja %cmake_flags% %cmake_profile_flags% -DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^
296  -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ..\llvm-project\llvm || exit /b 1
297ninja install || exit /b 1
298:: check llvm_config is present & returns something
299%build_dir%/%filename%/bin/llvm-config.exe --bindir || exit /b 1
300cd ..
3017z a -ttar -so %filename%.tar %filename% | 7z a -txz -si %filename%.tar.xz
302
303exit /b 0
304::==============================================================================
305
306::==============================================================================
307:: Build arm64 binaries.
308::==============================================================================
309:do_build_arm64
310call :set_environment %pythonarm64_dir% || exit /b 1
311call "%vsdevcmd%" -host_arch=x64 -arch=arm64 || exit /b 1
312@echo on
313mkdir build_arm64_stage0
314cd build_arm64_stage0
315call :do_build_libxml || exit /b 1
316
317REM Stage0 binaries directory; used in stage1.
318set "stage0_bin_dir=%build_dir%/build_arm64_stage0/bin"
319set cmake_flags=^
320  %common_cmake_flags% ^
321  -DCLANG_DEFAULT_LINKER=lld ^
322  -DLIBXML2_INCLUDE_DIR=%libxmldir%/include/libxml2 ^
323  -DLIBXML2_LIBRARIES=%libxmldir%/lib/libxml2s.lib ^
324  -DPython3_ROOT_DIR=%PYTHONHOME% ^
325  -DCOMPILER_RT_BUILD_PROFILE=OFF ^
326  -DCOMPILER_RT_BUILD_SANITIZERS=OFF
327
328REM We need to build stage0 compiler-rt with clang-cl (msvc lacks some builtins).
329cmake -GNinja %cmake_flags% ^
330  -DCMAKE_C_COMPILER=clang-cl.exe ^
331  -DCMAKE_CXX_COMPILER=clang-cl.exe ^
332  %llvm_src%\llvm || exit /b 1
333ninja || exit /b 1
334::ninja check-llvm || exit /b 1
335::ninja check-clang || exit /b 1
336::ninja check-lld || exit /b 1
337::ninja check-sanitizer || exit /b 1
338::ninja check-clang-tools || exit /b 1
339::ninja check-clangd || exit /b 1
340cd..
341
342REM CMake expects the paths that specifies the compiler and linker to be
343REM with forward slash.
344REM CPACK_SYSTEM_NAME is set to have a correct name for installer generated.
345set all_cmake_flags=^
346  %cmake_flags% ^
347  -DCMAKE_C_COMPILER=%stage0_bin_dir%/clang-cl.exe ^
348  -DCMAKE_CXX_COMPILER=%stage0_bin_dir%/clang-cl.exe ^
349  -DCMAKE_LINKER=%stage0_bin_dir%/lld-link.exe ^
350  -DCMAKE_AR=%stage0_bin_dir%/llvm-lib.exe ^
351  -DCMAKE_RC=%stage0_bin_dir%/llvm-windres.exe ^
352  -DCPACK_SYSTEM_NAME=woa64
353set cmake_flags=%all_cmake_flags:\=/%
354
355mkdir build_arm64
356cd build_arm64
357cmake -GNinja %cmake_flags% %llvm_src%\llvm || exit /b 1
358ninja || exit /b 1
359REM Check but do not fail on errors.
360ninja check-lldb
361::ninja check-llvm || exit /b 1
362::ninja check-clang || exit /b 1
363::ninja check-lld || exit /b 1
364::ninja check-sanitizer || exit /b 1
365::ninja check-clang-tools || exit /b 1
366::ninja check-clangd || exit /b 1
367ninja package || exit /b 1
368cd ..
369
370exit /b 0
371::==============================================================================
372::
373::==============================================================================
374:: Set PATH and some environment variables.
375::==============================================================================
376:set_environment
377REM Restore original path
378set PATH=%OLDPATH%
379
380set python_dir=%1
381
382REM Set Python environment
383if "%local-python%" == "true" (
384  FOR /F "delims=" %%i IN ('where python.exe ^| head -1') DO set python_exe=%%i
385  set PYTHONHOME=!python_exe:~0,-11!
386) else (
387  %python_dir%/python.exe --version || exit /b 1
388  set PYTHONHOME=%python_dir%
389)
390set PATH=%PYTHONHOME%;%PATH%
391
392set "VSCMD_START_DIR=%build_dir%"
393
394exit /b 0
395
396::=============================================================================
397
398::==============================================================================
399:: Build libxml.
400::==============================================================================
401:do_build_libxml
402mkdir libxmlbuild
403cd libxmlbuild
404cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install ^
405  -DBUILD_SHARED_LIBS=OFF -DLIBXML2_WITH_C14N=OFF -DLIBXML2_WITH_CATALOG=OFF ^
406  -DLIBXML2_WITH_DEBUG=OFF -DLIBXML2_WITH_DOCB=OFF -DLIBXML2_WITH_FTP=OFF ^
407  -DLIBXML2_WITH_HTML=OFF -DLIBXML2_WITH_HTTP=OFF -DLIBXML2_WITH_ICONV=OFF ^
408  -DLIBXML2_WITH_ICU=OFF -DLIBXML2_WITH_ISO8859X=OFF -DLIBXML2_WITH_LEGACY=OFF ^
409  -DLIBXML2_WITH_LZMA=OFF -DLIBXML2_WITH_MEM_DEBUG=OFF -DLIBXML2_WITH_MODULES=OFF ^
410  -DLIBXML2_WITH_OUTPUT=ON -DLIBXML2_WITH_PATTERN=OFF -DLIBXML2_WITH_PROGRAMS=OFF ^
411  -DLIBXML2_WITH_PUSH=OFF -DLIBXML2_WITH_PYTHON=OFF -DLIBXML2_WITH_READER=OFF ^
412  -DLIBXML2_WITH_REGEXPS=OFF -DLIBXML2_WITH_RUN_DEBUG=OFF -DLIBXML2_WITH_SAX1=OFF ^
413  -DLIBXML2_WITH_SCHEMAS=OFF -DLIBXML2_WITH_SCHEMATRON=OFF -DLIBXML2_WITH_TESTS=OFF ^
414  -DLIBXML2_WITH_THREADS=ON -DLIBXML2_WITH_THREAD_ALLOC=OFF -DLIBXML2_WITH_TREE=ON ^
415  -DLIBXML2_WITH_VALID=OFF -DLIBXML2_WITH_WRITER=OFF -DLIBXML2_WITH_XINCLUDE=OFF ^
416  -DLIBXML2_WITH_XPATH=OFF -DLIBXML2_WITH_XPTR=OFF -DLIBXML2_WITH_ZLIB=OFF ^
417  -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded ^
418  ../../libxml2-v2.9.12 || exit /b 1
419ninja install || exit /b 1
420set libxmldir=%cd%\install
421set "libxmldir=%libxmldir:\=/%"
422cd ..
423exit /b 0
424
425::==============================================================================
426:: Generate a PGO profile.
427::==============================================================================
428:do_generate_profile
429REM Build Clang with instrumentation.
430mkdir instrument
431cd instrument
432cmake -GNinja %cmake_flags% -DLLVM_TARGETS_TO_BUILD=Native ^
433  -DLLVM_BUILD_INSTRUMENTED=IR %llvm_src%\llvm || exit /b 1
434ninja clang || ninja clang || ninja clang || exit /b 1
435set instrumented_clang=%cd:\=/%/bin/clang-cl.exe
436cd ..
437REM Use that to build part of llvm to generate a profile.
438mkdir train
439cd train
440cmake -GNinja %cmake_flags% ^
441  -DCMAKE_C_COMPILER=%instrumented_clang% ^
442  -DCMAKE_CXX_COMPILER=%instrumented_clang% ^
443  -DLLVM_ENABLE_PROJECTS=clang ^
444  -DLLVM_TARGETS_TO_BUILD=Native ^
445  %llvm_src%\llvm || exit /b 1
446REM Drop profiles generated from running cmake; those are not representative.
447del ..\instrument\profiles\*.profraw
448ninja tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/Sema.cpp.obj
449cd ..
450set profile=%cd:\=/%/profile.profdata
451%stage0_bin_dir%\llvm-profdata merge -output=%profile% instrument\profiles\*.profraw || exit /b 1
452set common_compiler_flags=%common_compiler_flags% -Wno-backend-plugin
453set cmake_profile_flags=-DLLVM_PROFDATA_FILE=%profile% ^
454  -DCMAKE_C_FLAGS="%common_compiler_flags%" ^
455  -DCMAKE_CXX_FLAGS="%common_compiler_flags%"
456exit /b 0
457
458::=============================================================================
459:: Parse command line arguments.
460:: The format for the arguments is:
461::   Boolean: --option
462::   Value:   --option<separator>value
463::     with <separator> being: space, colon, semicolon or equal sign
464::
465:: Command line usage example:
466::   my-batch-file.bat --build --type=release --version 123
467:: It will create 3 variables:
468::   'build' with the value 'true'
469::   'type' with the value 'release'
470::   'version' with the value '123'
471::
472:: Usage:
473::   set "build="
474::   set "type="
475::   set "version="
476::
477::   REM Parse arguments.
478::   call :parse_args %*
479::
480::   if defined build (
481::     ...
482::   )
483::   if %type%=='release' (
484::     ...
485::   )
486::   if %version%=='123' (
487::     ...
488::   )
489::=============================================================================
490:parse_args
491  set "arg_name="
492  :parse_args_start
493  if "%1" == "" (
494    :: Set a seen boolean argument.
495    if "%arg_name%" neq "" (
496      set "%arg_name%=true"
497    )
498    goto :parse_args_done
499  )
500  set aux=%1
501  if "%aux:~0,2%" == "--" (
502    :: Set a seen boolean argument.
503    if "%arg_name%" neq "" (
504      set "%arg_name%=true"
505    )
506    set "arg_name=%aux:~2,250%"
507  ) else (
508    set "%arg_name%=%1"
509    set "arg_name="
510  )
511  shift
512  goto :parse_args_start
513
514:parse_args_done
515exit /b 0
516