4 :: build-all-msvc.bat --
6 :: Multi-Platform Build Tool for MSVC
10 REM This batch script is used to build the SQLite DLL for multiple platforms
11 REM and configurations using MSVC. The built SQLite DLLs, their associated
12 REM import libraries, and optionally their symbols files, are placed within
13 REM the directory specified on the command line, in sub-directories named for
14 REM their respective platforms and configurations. This batch script must be
15 REM run from inside a Visual Studio Command Prompt for the desired version of
16 REM Visual Studio ^(the initial platform configured for the command prompt does
17 REM not really matter^). Exactly one command line argument is required, the
18 REM name of an existing directory to be used as the final destination directory
19 REM for the generated output files, which will be placed in sub-directories
20 REM created therein. Ideally, the directory specified should be empty.
24 REM CD /D C:\dev\sqlite\core
25 REM tool\build-all-msvc.bat C:\Temp
27 REM In the example above, "C:\dev\sqlite\core" represents the root of the
28 REM source tree for SQLite and "C:\Temp" represents the final destination
29 REM directory for the generated output files.
31 REM There are several environment variables that may be set to modify the
32 REM behavior of this batch script and its associated Makefile. The list of
33 REM platforms to build may be overriden by using the PLATFORMS environment
34 REM variable, which should contain a list of platforms ^(e.g. x86 x86_amd64
35 REM x86_arm^). All platforms must be supported by the version of Visual Studio
36 REM being used. The list of configurations to build may be overridden by
37 REM setting the CONFIGURATIONS environment variable, which should contain a
38 REM list of configurations to build ^(e.g. Debug Retail^). Neither of these
39 REM variable values may contain any double quotes, surrounding or embedded.
40 REM Finally, the NCRTLIBPATH and NSDKLIBPATH environment variables may be set
41 REM to specify the location of the CRT and SDK, respectively, needed to compile
42 REM executables native to the architecture of the build machine during any
43 REM cross-compilation that may be necessary, depending on the platforms to be
44 REM built. These values in these two variables should be surrounded by double
45 REM quotes if they contain spaces.
47 REM Please note that the SQLite build process performed by the Makefile
48 REM associated with this batch script requires both Gawk ^(gawk.exe^) and Tcl
49 REM 8.5 ^(tclsh85.exe^) to be present in a directory contained in the PATH
50 REM environment variable unless a pre-existing amalgamation file is used.
57 IF NOT DEFINED _AECHO (SET _AECHO=REM)
58 IF NOT DEFINED _CECHO (SET _CECHO=REM)
59 IF NOT DEFINED _VECHO (SET _VECHO=REM)
61 %_AECHO% Running %0 %*
65 %_VECHO% DFlags = '%DFLAGS%'
67 SET FFLAGS=/V /F /G /H /I /R /Y /Z
69 %_VECHO% FFlags = '%FFLAGS%'
74 %_VECHO% Root = '%ROOT%'
77 REM NOTE: The first and only argument to this batch file should be the output
78 REM directory where the platform-specific binary directories should be
81 SET BINARYDIRECTORY=%1
83 IF NOT DEFINED BINARYDIRECTORY (
87 %_VECHO% BinaryDirectory = '%BINARYDIRECTORY%'
96 REM NOTE: From this point, we need a clean error level. Reset it now.
98 CALL :fn_ResetErrorLevel
101 REM NOTE: Change the current directory to the root of the source tree, saving
102 REM the current directory on the directory stack.
104 %__ECHO2% PUSHD "%ROOT%"
107 ECHO Could not change directory to "%ROOT%".
112 REM NOTE: This batch file requires the ComSpec environment variable to be set,
113 REM typically to something like "C:\Windows\System32\cmd.exe".
115 IF NOT DEFINED ComSpec (
116 ECHO The ComSpec environment variable must be defined.
121 REM NOTE: This batch file requires the VcInstallDir environment variable to be
122 REM set. Tyipcally, this means this batch file needs to be run from an
123 REM MSVC command prompt.
125 IF NOT DEFINED VCINSTALLDIR (
126 ECHO The VCINSTALLDIR environment variable must be defined.
131 REM NOTE: If the list of platforms is not already set, use the default list.
133 IF NOT DEFINED PLATFORMS (
134 SET PLATFORMS=x86 x86_amd64 x86_arm
137 %_VECHO% Platforms = '%PLATFORMS%'
140 REM NOTE: If the list of configurations is not already set, use the default
143 IF NOT DEFINED CONFIGURATIONS (
144 SET CONFIGURATIONS=Debug Retail
147 %_VECHO% Configurations = '%CONFIGURATIONS%'
150 REM NOTE: If the command used to invoke NMAKE is not already set, use the
153 IF NOT DEFINED NMAKE_CMD (
154 SET NMAKE_CMD=nmake -B -f Makefile.msc
157 %_VECHO% NmakeCmd = '%NMAKE_CMD%'
158 %_VECHO% NmakeArgs = '%NMAKE_ARGS%'
161 REM NOTE: Setup environment variables to translate between the MSVC platform
162 REM names and the names to be used for the platform-specific binary
169 SET x86_amd64_NAME=x64
173 %_VECHO% amd64_Name = '%amd64_NAME%'
174 %_VECHO% arm_Name = '%arm_NAME%'
175 %_VECHO% x64_Name = '%x64_NAME%'
176 %_VECHO% x86_Name = '%x86_NAME%'
177 %_VECHO% x86_amd64_Name = '%x86_amd64_NAME%'
178 %_VECHO% x86_arm_Name = '%x86_arm_NAME%'
179 %_VECHO% x86_x64_Name = '%x86_x64_NAME%'
182 REM NOTE: Check for the external tools needed during the build process ^(i.e.
183 REM those that do not get compiled as part of the build process itself^)
186 FOR %%T IN (gawk.exe tclsh85.exe) DO (
187 SET %%T_PATH=%%~dp$PATH:T
191 REM NOTE: The Gawk executable "gawk.exe" is required during the SQLite build
192 REM process unless a pre-existing amalgamation file is used.
194 IF NOT DEFINED gawk.exe_PATH (
195 ECHO The Gawk executable "gawk.exe" is required to be in the PATH.
200 REM NOTE: The Tcl 8.5 executable "tclsh85.exe" is required during the SQLite
201 REM build process unless a pre-existing amalgamation file is used.
203 IF NOT DEFINED tclsh85.exe_PATH (
204 ECHO The Tcl 8.5 executable "tclsh85.exe" is required to be in the PATH.
209 REM NOTE: Set the TOOLPATH variable to contain all the directories where the
210 REM external tools were found in the search above.
212 SET TOOLPATH=%gawk.exe_PATH%;%tclsh85.exe_PATH%
214 %_VECHO% ToolPath = '%TOOLPATH%'
217 REM NOTE: Check for MSVC 2012/2013 because the Windows SDK directory handling
218 REM is slightly different for those versions.
220 IF "%VisualStudioVersion%" == "11.0" (
222 REM NOTE: If the Windows SDK library path has already been set, do not set
223 REM it to something else later on.
225 IF NOT DEFINED NSDKLIBPATH (
226 SET SET_NSDKLIBPATH=1
228 ) ELSE IF "%VisualStudioVersion%" == "12.0" (
230 REM NOTE: If the Windows SDK library path has already been set, do not set
231 REM it to something else later on.
233 IF NOT DEFINED NSDKLIBPATH (
234 SET SET_NSDKLIBPATH=1
237 CALL :fn_UnsetVariable SET_NSDKLIBPATH
241 REM NOTE: Check if this is the Windows Phone SDK. If so, a different batch
242 REM file is necessary to setup the build environment. Since the variable
243 REM values involved here may contain parenthesis, using GOTO instead of
244 REM an IF block is required.
246 IF DEFINED WindowsPhoneKitDir GOTO set_vcvarsall_phone
247 SET VCVARSALL=%VCINSTALLDIR%\vcvarsall.bat
248 GOTO set_vcvarsall_done
250 SET VCVARSALL=%VCINSTALLDIR%\WPSDK\WP80\vcvarsphoneall.bat
252 SET VCVARSALL=%VCVARSALL:\\=\%
255 REM NOTE: This is the outer loop. There should be exactly one iteration per
258 FOR %%P IN (%PLATFORMS%) DO (
260 REM NOTE: Using the MSVC platform name, lookup the simpler platform name to
261 REM be used for the name of the platform-specific binary directory via
262 REM the environment variables setup earlier.
264 CALL :fn_CopyVariable %%P_NAME PLATFORMNAME
267 REM NOTE: This is the second loop. There should be exactly one iteration.
268 REM This loop is necessary because the PlatformName environment
269 REM variable was set above and that value is needed by some of the
270 REM commands contained in the inner loop. If these commands were
271 REM directly contained in the outer loop, the PlatformName environment
272 REM variable would be stuck with its initial empty value instead.
274 FOR /F "tokens=2* delims==" %%D IN ('SET PLATFORMNAME') DO (
276 REM NOTE: Attempt to clean the environment of all variables used by MSVC
277 REM and/or Visual Studio. This block may need to be updated in the
278 REM future to account for additional environment variables.
280 CALL :fn_UnsetVariable CommandPromptType
281 CALL :fn_UnsetVariable DevEnvDir
282 CALL :fn_UnsetVariable ExtensionSdkDir
283 CALL :fn_UnsetVariable Framework35Version
284 CALL :fn_UnsetVariable Framework40Version
285 CALL :fn_UnsetVariable FrameworkDir
286 CALL :fn_UnsetVariable FrameworkDir32
287 CALL :fn_UnsetVariable FrameworkVersion
288 CALL :fn_UnsetVariable FrameworkVersion32
289 CALL :fn_UnsetVariable FSHARPINSTALLDIR
290 CALL :fn_UnsetVariable INCLUDE
291 CALL :fn_UnsetVariable LIB
292 CALL :fn_UnsetVariable LIBPATH
293 CALL :fn_UnsetVariable Platform
294 REM CALL :fn_UnsetVariable VCINSTALLDIR
295 CALL :fn_UnsetVariable VSINSTALLDIR
296 CALL :fn_UnsetVariable WindowsPhoneKitDir
297 CALL :fn_UnsetVariable WindowsSdkDir
298 CALL :fn_UnsetVariable WindowsSdkDir_35
299 CALL :fn_UnsetVariable WindowsSdkDir_old
300 CALL :fn_UnsetVariable WindowsSDK_ExecutablePath_x86
301 CALL :fn_UnsetVariable WindowsSDK_ExecutablePath_x64
304 REM NOTE: Reset the PATH here to the absolute bare minimum required.
306 SET PATH=%TOOLPATH%;%SystemRoot%\System32;%SystemRoot%
309 REM NOTE: This is the inner loop. There are normally two iterations, one
310 REM for each supported build configuration, e.g. Debug or Retail.
312 FOR %%B IN (%CONFIGURATIONS%) DO (
314 REM NOTE: When preparing the debug build, set the DEBUG and MEMDEBUG
315 REM environment variables to be picked up by the MSVC makefile
318 %_AECHO% Building the %%B configuration for platform %%P with name %%D...
320 IF /I "%%B" == "Debug" (
324 CALL :fn_UnsetVariable DEBUG
325 CALL :fn_UnsetVariable MEMDEBUG
329 REM NOTE: Launch a nested command shell to perform the following steps:
331 REM 1. Setup the MSVC environment for this platform using the
332 REM official batch file.
334 REM 2. Make sure that no stale build output files are present.
336 REM 3. Build the "sqlite3.dll" and "sqlite3.lib" binaries for this
339 REM 4. Copy the "sqlite3.dll" and "sqlite3.lib" binaries for this
340 REM platform to the platform-specific directory beneath the
341 REM binary directory.
343 REM 5. Unless prevented from doing so, copy the "sqlite3.pdb"
344 REM symbols file for this platform to the platform-specific
345 REM directory beneath the binary directory.
349 REM NOTE: Attempt to setup the MSVC environment for this platform.
351 %__ECHO3% CALL "%VCVARSALL%" %%P
354 ECHO Failed to call "%VCVARSALL%" for platform %%P.
359 REM NOTE: If this batch file is not running in "what-if" mode, check to
360 REM be sure we were actually able to setup the MSVC environment
361 REM as current versions of their official batch file do not set
362 REM the exit code upon failure.
364 IF NOT DEFINED __ECHO3 (
365 IF NOT DEFINED WindowsPhoneKitDir (
366 IF NOT DEFINED WindowsSdkDir (
367 ECHO Cannot build, Windows SDK not found for platform %%P.
374 REM NOTE: When using MSVC 2012 and/or 2013, the native SDK path cannot
375 REM simply use the "lib" sub-directory beneath the location
376 REM specified in the WindowsSdkDir environment variable because
377 REM that location does not actually contain the necessary library
378 REM files for x86. This must be done for each iteration because
379 REM it relies upon the WindowsSdkDir environment variable being
380 REM set by the batch file used to setup the MSVC environment.
382 IF DEFINED SET_NSDKLIBPATH (
384 REM NOTE: The Windows Phone SDK has a slightly different directory
385 REM structure and must be handled specially here.
387 IF DEFINED WindowsPhoneKitDir (
388 CALL :fn_CopyVariable WindowsPhoneKitDir NSDKLIBPATH
389 CALL :fn_AppendVariable NSDKLIBPATH \lib\x86
390 ) ELSE IF DEFINED WindowsSdkDir (
391 CALL :fn_CopyVariable WindowsSdkDir NSDKLIBPATH
394 REM NOTE: The Windows 8.1 SDK has a slightly different directory
395 REM naming convention.
397 IF DEFINED USE_WINV63_NSDKLIBPATH (
398 CALL :fn_AppendVariable NSDKLIBPATH \lib\winv6.3\um\x86
399 ) ELSE IF "%VisualStudioVersion%" == "12.0" (
400 CALL :fn_AppendVariable NSDKLIBPATH \..\8.0\lib\win8\um\x86
402 CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86
408 REM NOTE: Unless prevented from doing so, invoke NMAKE with the MSVC
409 REM makefile to clean any stale build output from previous
410 REM iterations of this loop and/or previous runs of this batch
413 IF NOT DEFINED NOCLEAN (
414 %__ECHO% %NMAKE_CMD% clean
417 ECHO Failed to clean for platform %%P.
422 REM NOTE: Even when the cleaning step has been disabled, we still
423 REM need to remove the build output for the files we are
424 REM specifically wanting to build for each platform.
426 %_AECHO% Cleaning final output files only...
427 %__ECHO% DEL /Q *.lo sqlite3.dll sqlite3.lib sqlite3.pdb
431 REM NOTE: Call NMAKE with the MSVC makefile to build the "sqlite3.dll"
432 REM binary. The x86 compiler will be used to compile the native
433 REM command line tools needed during the build process itself.
434 REM Also, disable looking for and/or linking to the native Tcl
437 %__ECHO% %NMAKE_CMD% sqlite3.dll XCOMPILE=1 USE_NATIVE_LIBPATHS=1 NO_TCL=1 %NMAKE_ARGS%
440 ECHO Failed to build %%B "sqlite3.dll" for platform %%P.
445 REM NOTE: Copy the "sqlite3.dll" file to the appropriate directory for
446 REM the build and platform beneath the binary directory.
448 %__ECHO% XCOPY sqlite3.dll "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
451 ECHO Failed to copy "sqlite3.dll" to "%BINARYDIRECTORY%\%%B\%%D\".
456 REM NOTE: Copy the "sqlite3.lib" file to the appropriate directory for
457 REM the build and platform beneath the binary directory.
459 %__ECHO% XCOPY sqlite3.lib "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
462 ECHO Failed to copy "sqlite3.lib" to "%BINARYDIRECTORY%\%%B\%%D\".
467 REM NOTE: Copy the "sqlite3.pdb" file to the appropriate directory for
468 REM the build and platform beneath the binary directory unless we
469 REM are prevented from doing so.
471 IF NOT DEFINED NOSYMBOLS (
472 %__ECHO% XCOPY sqlite3.pdb "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
475 ECHO Failed to copy "sqlite3.pdb" to "%BINARYDIRECTORY%\%%B\%%D\".
484 REM NOTE: Handle any errors generated during the nested command shell.
492 REM NOTE: Restore the saved current directory from the directory stack.
497 ECHO Could not restore directory.
502 REM NOTE: If we get to this point, we have succeeded.
515 IF NOT DEFINED %1 GOTO :EOF
516 IF "%2" == "" GOTO :EOF
518 SET __ECHO_CMD=ECHO %%%1%%
519 FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
522 ENDLOCAL && SET %2=%VALUE%
528 CALL :fn_ResetErrorLevel
533 SET __ECHO_CMD=ECHO %%%1%%
535 FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
542 CALL :fn_ResetErrorLevel
547 ECHO Usage: %~nx0 ^<binaryDirectory^>
552 CALL :fn_SetErrorLevel
555 ECHO Failure, errors were encountered.
559 CALL :fn_ResetErrorLevel
562 ECHO Success, no errors were encountered.
566 %__ECHO% EXIT /B %ERRORLEVEL%