Fix potential crash for Encoder.Convert (#20522)
[mono-project.git] / msvc / build-external-llvm.bat
blobec35526969401b7e9641f8ec8cec72fd0af2e05c
1 :: --------------------------------------------------
2 :: Run full LLVM build using msvc toolchain and available cmake generator.
3 :: Script needs to be run from within a matching build environment, x86|x64.
4 :: When executed from withing Visual Studio build environment current
5 :: build environment will be inherited by script.
6 ::
7 :: %1 LLVM source root directory.
8 :: %2 LLVM build root directory.
9 :: %3 LLVM install root directory.
10 :: %4 Mono distribution root directory.
11 :: %5 VS CFLAGS.
12 :: %6 Additional CMake arguments.
13 :: %7 VS platform (Win32/x64).
14 :: %8 VS configuration (Debug/Release).
15 :: %9 VS target.
16 :: %9 VS PlatformToolSet, if used.
17 :: %10 Win SDK, if used.
18 :: %11 MsBuild bin path, if used.
19 :: %12 Force MSBuild (true/false), if used.
20 :: --------------------------------------------------
22 @echo off
23 setlocal
25 set BUILD_RESULT=1
27 set BUILD_EXTERNAL_LLVM_SCRIPT_PATH=%~dp0
29 set CL_BIN_NAME=cl.exe
30 set LINK_BIN_NAME=link.exe
31 set GIT_BIN_NAME=git.exe
32 set CMAKE_BIN_NAME=cmake.exe
33 set NINJA_BIN_NAME=ninja.exe
34 set PYTHON_BIN_NAME=python.exe
36 set LLVM_DIR=%~1
37 shift
38 set LLVM_BUILD_DIR=%~1
39 shift
40 set LLVM_INSTALL_DIR=%~1
41 shift
42 set MONO_DIST_DIR=%~1
43 shift
44 set VS_CFLAGS=%~1
45 shift
46 set LLVM_ADDITIONAL_CMAKE_ARGS=%~1
47 shift
48 set VS_PLATFORM=%~1
49 shift
50 set VS_CONFIGURATION=%~1
51 shift
52 set VS_TARGET=%~1
53 shift
54 set VS_PLATFORM_TOOL_SET=%~1
55 shift
56 set VS_WIN_SDK_VERSION=%~1
57 shift
58 set MSBUILD_BIN_PATH=%~1
59 shift
60 set FORCE_MSBUILD=%~1
62 :: Setup toolchain.
63 :: set GIT=
64 :: set CMAKE=
65 :: set NINJA=
66 set MSBUILD=%MSBUILD_BIN_PATH%msbuild.exe
68 if "%LLVM_DIR%" == "" (
69     echo Missing LLVM source directory argument.
70     goto ECHO_USAGE
73 if "%LLVM_BUILD_DIR%" == "" (
74     echo Missing LLVM build directory argument.
75     goto ECHO_USAGE
78 if "%LLVM_INSTALL_DIR%" == "" (
79     echo Missing LLVM install directory argument.
80     goto ECHO_USAGE
83 if "%MONO_DIST_DIR%" == "" (
84     echo Missing Mono dist directory argument.
85     goto ECHO_USAGE
88 if "%VS_CFLAGS%" == "" (
89     echo Missing CFLAGS argument.
90     goto ECHO_USAGE
93 if "%VS_PLATFORM%" == "" (
94     set VS_PLATFORM=x64
97 if "%VS_CONFIGURATION%" == "" (
98     set VS_CONFIGURATION=Release
101 if "%VS_TARGET%" == "" (
102     set VS_TARGET=Build
105 if "%VS_PLATFORM_TOOL_SET%" == "" (
106     set VS_PLATFORM_TOOL_SET=v142
109 if "%VS_WIN_SDK_VERSION%" == "" (
110     set VS_WIN_SDK_VERSION=10.0
113 if "%FORCE_MSBUILD%" == "" (
114     set FORCE_MSBUILD=false
117 set LLVM_CFLAGS=%VS_CFLAGS%
118 set LLVM_ARCH=x86_64
119 if /i "%VS_PLATFORM%" == "win32" (
120     set LLVM_ARCH=i386
123 :: VS2017/VS2019 includes vswhere.exe that can be used to locate current VS installation.
124 set VSWHERE_TOOLS_BIN=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe
125 set VS_COMMON_EXTENSION_TOOLS_PATHS=
127 :: Check if executed from VS2015/VS2017/2019 build environment.
128 if "%VisualStudioVersion%" == "14.0" (
129     if /i not "%VS_PLATFORM_TOOL_SET%" == "v140" (
130         echo VisualStudioVersion/PlatformToolchain missmatch, forcing msbuild.
131         set FORCE_MSBUILD=true
132     )
133     goto ON_ENV_OK
136 if "%VisualStudioVersion%" == "15.0" (
137     if /i not "%VS_PLATFORM_TOOL_SET%" == "v141" (
138         echo VisualStudioVersion/PlatformToolchain missmatch, forcing msbuild.
139         set FORCE_MSBUILD=true
140     )
141     goto ON_ENV_OK
144 if "%VisualStudioVersion%" == "16.0" (
145     if /i not "%VS_PLATFORM_TOOL_SET%" == "v142" (
146         echo VisualStudioVersion/PlatformToolchain missmatch, forcing msbuild.
147         set FORCE_MSBUILD=true
148     )
149     goto ON_ENV_OK
152 :: Executed outside VS2015/VS2017/VS2019 build environment, try to locate Visual Studio C/C++ compiler and linker.
153 call :FIND_PROGRAM "" "%CL_BIN_NAME%" CL_PATH
154 if "%CL_PATH%" == "" (
155     goto ON_ENV_WARNING
158 call :FIND_PROGRAM "" "%LINK_BIN_NAME%" LINK_PATH
159 if "%LINK_PATH%" == "" (
160     goto ON_ENV_WARNING
163 goto ON_ENV_OK
165 :ON_ENV_WARNING
167 set VSWHERE_TOOLS_BIN=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe
169 :: VS 2019.
170 if exist "%VSWHERE_TOOLS_BIN%" (
171     echo For VS2019 builds, make sure to run this from within Visual Studio build or using "x86|x64 Native Tools Command Prompt for VS2019" command prompt.
172     for /f "tokens=*" %%a IN ('"%VSWHERE_TOOLS_BIN%" -version [16.0^,17.0] -prerelease -property installationPath') do (
173         echo Setup a "x86|x64 Native Tools Command Prompt for VS2019" command prompt by using "%%a\VC\Auxiliary\Build\vcvars32.bat|vcvars64.bat".
174         goto ON_ENV_WARNING_DONE
175     )
178 :: VS 2017.
179 if exist "%VSWHERE_TOOLS_BIN%" (
180     echo For VS2017 builds, make sure to run this from within Visual Studio build or using "x86|x64 Native Tools Command Prompt for VS2017" command prompt.
181     for /f "tokens=*" %%a IN ('"%VSWHERE_TOOLS_BIN%" -version [15.0^,16.0] -property installationPath') do (
182         echo Setup a "x86|x64 Native Tools Command Prompt for VS2017" command prompt by using "%%a\VC\Auxiliary\Build\vcvars32.bat|vcvars64.bat".
183         goto ON_ENV_WARNING_DONE
184     )
187 :: VS 2015.
188 set VC_VARS_ALL_FILE=%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
189 IF EXIST "%VC_VARS_ALL_FILE%" (
190     echo For VS2015 builds, make sure to run this from within Visual Studio build or using "VS2015 x86|x64 Native Tools Command Prompt" command prompt.
191     echo Setup a "VS2015 x86|x64 Native Tools Command Prompt" command prompt by using "%VC_VARS_ALL_FILE% x86|amd64".
192     goto ON_ENV_WARNING_DONE
195 :ON_ENV_WARNING_DONE
197 echo Could not detect Visual Studio build environment. You may experience build problems if wrong toolchain is auto detected.
199 :ON_ENV_OK
201 :: Append paths to VS installed common extension tools at end of PATH (Vs2017/VS2019).
202 call :FIND_VS_COMMON_EXTENSION_TOOLS_PATHS VS_COMMON_EXTENSION_TOOLS_PATHS
203 if not "%VS_COMMON_EXTENSION_TOOLS_PATHS%" == "" (
204     set "PATH=%PATH%;%VS_COMMON_EXTENSION_TOOLS_PATHS%"
207 :: Setup all cmake related generator, tools and variables.
208 call :SETUP_CMAKE_ENVIRONMENT
209 if "%CMAKE%" == "" (
210     echo Failed to located working %CMAKE_BIN_NAME%, needs to be accessible in PATH or set using CMAKE environment variable.
211     goto ON_ERROR
214 if "%CMAKE_GENERATOR%" == "" (
215     echo Failed to setup cmake generator.
216     goto ON_ERROR
219 :: Check target.
220 if /i "%VS_TARGET%" == "build" (
221     goto ON_BUILD_LLVM
224 if /i "%VS_TARGET%" == "install" (
225     goto ON_INSTALL_LLVM
228 if /i "%VS_TARGET%" == "clean" (
229     goto ON_CLEAN_LLVM
232 :ON_BUILD_LLVM
234 :: If not set by caller, check environment for working git.exe.
235 call :FIND_PROGRAM "%GIT%" "%GIT_BIN_NAME%" GIT
236 if "%GIT%" == "" (
237     echo Failed to located working %GIT_BIN_NAME%, needs to be accessible in PATH or set using GIT environment variable.
238     goto ON_ERROR
241 :: Make sure llvm submodule is up to date.
242 echo Updating submodule "%LLVM_DIR%"
243 "%GIT%" submodule update --init -- "%LLVM_DIR%"
244 if not ERRORLEVEL == 0 (
245     "%GIT%" submodule init -- "%LLVM_DIR%"
246     "%GIT%" submodule update -- "%LLVM_DIR%"
247     if not ERRORLEVEL == 0 (
248         echo Git llvm submodules failed to updated. You may experience compilation problems if some submodules are out of date.
249     )
252 if not exist "%LLVM_DIR%" (
253     echo Could not find "%LLVM_DIR%".
254     goto ON_ERROR
257 if not exist "%LLVM_BUILD_DIR%" (
258     mkdir "%LLVM_BUILD_DIR%"
261 cd "%LLVM_BUILD_DIR%"
263 :: Make sure cmake pick up msvc toolchain regardless of selected generator (Visual Studio|Ninja)
264 set CC=%CL_BIN_NAME%
265 set CXX=%CL_BIN_NAME%
267 set CMAKE_GENERATOR_ARGS=
268 set CMAKE_GENERATOR_TOOLSET=
269 if /i "%CMAKE_GENERATOR%" == "ninja" (
270     set CMAKE_GENERATOR_ARGS=-DCMAKE_BUILD_TYPE=%VS_CONFIGURATION%
271 ) else (
272     set CMAKE_GENERATOR_ARGS=-Thost=x64
273     set CMAKE_GENERATOR_TOOLSET=%VS_PLATFORM_TOOL_SET%
276 if not "%CMAKE_GENERATOR_ARCH%" == "" (
277     set CMAKE_GENERATOR_ARCH=-A %CMAKE_GENERATOR_ARCH%
280 :: Check if LLVM_DIR is just repro root or if we should build
281 :: a llvm subfolder within that repository.
282 set "LLVM_SOURCE_DIR=%LLVM_DIR%"
283 if exist "%LLVM_SOURCE_DIR%\llvm\CMakeLists.txt" (
284         set "LLVM_SOURCE_DIR=%LLVM_DIR%\llvm"
287 :: Run cmake.
288 "%CMAKE%" ^
289 -DCMAKE_INSTALL_PREFIX="%LLVM_INSTALL_DIR%" ^
290 -DLLVM_TARGETS_TO_BUILD="X86;ARM;AArch64" ^
291 -DLLVM_BUILD_TESTS=Off ^
292 -DLLVM_INCLUDE_TESTS=Off ^
293 -DLLVM_BUILD_EXAMPLES=Off ^
294 -DLLVM_INCLUDE_EXAMPLES=Off ^
295 -DLLVM_TOOLS_TO_BUILD="opt;llc;llvm-config;llvm-dis;llvm-mc;llvm-as" ^
296 -DLLVM_ENABLE_LIBXML2=Off ^
297 -DCMAKE_SYSTEM_PROCESSOR="%LLVM_ARCH%" ^
298 -D CMAKE_SYSTEM_VERSION=%VS_WIN_SDK_VERSION% ^
299 %CMAKE_GENERATOR_TOOLSET% ^
300 %LLVM_ADDITIONAL_CMAKE_ARGS% ^
301 %CMAKE_GENERATOR_ARGS% ^
302 -G "%CMAKE_GENERATOR%" ^
303 %CMAKE_GENERATOR_ARCH% ^
304 "%LLVM_SOURCE_DIR%"
306 if not ERRORLEVEL == 0 (
307     goto ON_ERROR
310 if /i "%CMAKE_GENERATOR%" == "ninja" (
311     :: Build LLVM using ninja build system.
312     call "%NINJA%" -j4 || (
313         goto ON_ERROR
314     )
315 ) else (
316     :: Build LLVM using msbuild build system.
317     call "%MSBUILD%" llvm.sln /p:Configuration=%VS_CONFIGURATION% /p:Platform=%VS_PLATFORM% /t:%VS_TARGET% /v:m /nologo /m || (
318         goto ON_ERROR
319     )
322 :ON_INSTALL_LLVM
324 :: Make sure build install folder exists.
325 if not exist "%LLVM_INSTALL_DIR%" (
326     echo Could not find "%LLVM_INSTALL_DIR%", creating folder for build output.
327     mkdir "%LLVM_INSTALL_DIR%"
330 :: Make sure Mono dist folder exists.
331 if not exist "%MONO_DIST_DIR%" (
332     echo Could not find "%MONO_DIST_DIR%", creating folder for build output.
333     mkdir "%MONO_DIST_DIR%"
336 if exist "%LLVM_BUILD_DIR%\build.ninja" (
337     pushd
338     cd "%LLVM_BUILD_DIR%"
339     call "%NINJA%" install
340     popd
343 if exist "%LLVM_BUILD_DIR%\install.vcxproj" (
344     "%MSBUILD%" "%LLVM_BUILD_DIR%\install.vcxproj" /p:Configuration=%VS_CONFIGURATION% /p:Platform=%VS_PLATFORM% /v:m /nologo
347 call "%BUILD_EXTERNAL_LLVM_SCRIPT_PATH%\install-llvm-mono-build.bat" "%LLVM_INSTALL_DIR%" "%MONO_DIST_DIR%" || (
348     goto ON_ERROR
351 goto ON_SUCCESS
353 :ON_CLEAN_LLVM
355 if exist "%LLVM_BUILD_DIR%\build.ninja" (
356     pushd
357     cd "%LLVM_BUILD_DIR%"
358     call "%NINJA%" clean
359     popd
362 if exist "%LLVM_BUILD_DIR%\llvm.sln" (
363     "%MSBUILD%" "%LLVM_BUILD_DIR%\llvm.sln" /p:Configuration=%VS_CONFIGURATION% /p:Platform=%VS_PLATFORM% /t:Clean /v:m /nologo
366 goto ON_SUCCESS
368 :ON_SUCCESS
370 set BUILD_RESULT=0
371 goto ON_EXIT
373 :ECHO_USAGE:
374     ECHO Usage: build-external-llvm.bat [llvm_src_dir] [llvm_build_dir] [llvm_install_dir] [mono_dist_dir] [vs_cflags] [vs_plaform] [vs_configuration].
376 :ON_ERROR
377     echo Failed to build LLVM.
378     goto ON_EXIT
380 :ON_EXIT
381     exit /b %BUILD_RESULT%
383 :: ##############################################################################################################################
384 :: Functions
386 :: --------------------------------------------------
387 :: Locates PATHS to installed common extension tools.
388 :: %1 Output, variable including paths.
389 :: --------------------------------------------------
390 :FIND_VS_COMMON_EXTENSION_TOOLS_PATHS
392 set VS_COMMON_EXTENSION_PATH=
393 if exist "%VSWHERE_TOOLS_BIN%" (
394     for /f "tokens=*" %%a in ('"%VSWHERE_TOOLS_BIN%" -version [16.0^,17.0] -property installationPath') do (
395         set VS_COMMON_EXTENSION_PATH=%%a\Common7\IDE\CommonExtensions\Microsoft
396     )
399 if exist "%VS_COMMON_EXTENSION_PATH%" (
400     set "%~1=%VS_COMMON_EXTENSION_PATH%\TeamFoundation\Team Explorer\Git\cmd;%VS_COMMON_EXTENSION_PATH%\CMake\CMake\bin;%VS_COMMON_EXTENSION_PATH%\CMake\Ninja"
403 goto :EOF
405 :: --------------------------------------------------
406 :: Finds a program using environment.
408 :: %1 Existing program to check for.
409 :: %2 Name of binary to locate.
410 :: %3 Output, variable to set if found requested program.
411 :: --------------------------------------------------
412 :FIND_PROGRAM
414 :: If not set by caller, check environment for program.
415 if exist "%~1" (
416     goto :EOF
419 call where /q "%~2" && (
420     for /f "delims=" %%a in ('where "%~2"') do (
421         set "%~3=%%a"
422     )
423 ) || (
424     set "%~3="
427 goto :EOF
429 :: --------------------------------------------------
430 :: Setup up cmake build environment, including generator, build tools and variables.
431 :: --------------------------------------------------
432 :SETUP_CMAKE_ENVIRONMENT
434 :: If not set by caller, check environment for working cmake.exe.
435 call :FIND_PROGRAM "%CMAKE%" "%CMAKE_BIN_NAME%" CMAKE
436 if "%CMAKE%" == "" (
437     goto _SETUP_CMAKE_ENVIRONMENT_EXIT
440 if /i "%VS_TARGET%" == "build" (
441     echo Found CMake: "%CMAKE%"
444 if /i "%FORCE_MSBUILD%" == "true" (
445     goto _SETUP_CMAKE_ENVIRONMENT_VS_GENERATOR
448 :: Check for optional cmake generate and build tools.
449 call :FIND_PROGRAM "%NINJA%" "%NINJA_BIN_NAME%" NINJA
451 if not "%NINJA%" == "" (
452     goto _SETUP_CMAKE_ENVIRONMENT_NINJA_GENERATOR
455 :_SETUP_CMAKE_ENVIRONMENT_VS_GENERATOR
457 if /i "%VS_TARGET%" == "build" (
458     echo Using Visual Studio build generator.
461 set CMAKE_GENERATOR_ARCH=
463 :: Detect VS platform tool set to use matching cmake generator.
464 if /i "%VS_PLATFORM_TOOL_SET%" == "v140" (
465     if /i "%VS_PLATFORM%" == "x64" (
466         set CMAKE_GENERATOR=Visual Studio 14 2015 Win64
467     ) else (
468         set CMAKE_GENERATOR=Visual Studio 14 2015
469     )
472 if /i "%VS_PLATFORM_TOOL_SET%" == "v141" (
473     if /i "%VS_PLATFORM%" == "x64" (
474         set CMAKE_GENERATOR=Visual Studio 15 2017 Win64
475     ) else (
476         set CMAKE_GENERATOR=Visual Studio 15 2017
477     )
480 if /i "%VS_PLATFORM_TOOL_SET%" == "v142" (
481     set CMAKE_GENERATOR=Visual Studio 16 2019
482     if /i "%VS_PLATFORM%" == "x64" (
483         set CMAKE_GENERATOR_ARCH=x64
484     ) else (
485         set CMAKE_GENERATOR_ARCH=Win32
486     )
489 set LLVM_BUILD_OUTPUT_DIR=%LLVM_BUILD_DIR%\%VS_CONFIGURATION%
491 goto _SETUP_CMAKE_ENVIRONMENT_EXIT
493 :_SETUP_CMAKE_ENVIRONMENT_NINJA_GENERATOR
495 if /i "%VS_TARGET%" == "build" (
496     echo Found Ninja: "%NINJA%"
497     echo Using Ninja build generator.
500 set CMAKE_GENERATOR_ARCH=
501 set CMAKE_GENERATOR=Ninja
502 set LLVM_BUILD_OUTPUT_DIR=%LLVM_BUILD_DIR%
504 :_SETUP_CMAKE_ENVIRONMENT_EXIT
506 goto :EOF
508 @echo on