]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
1 | :: Make sure the extensions are enabled |
2 | @verify other 2>nul | |
3 | @setlocal EnableDelayedExpansion | |
4 | @if errorlevel 1 ( | |
5 | call :print_usage "Failed to enable extensions" | |
6 | exit /b 1 | |
7 | ) | |
8 | ||
9 | ::Change the code page to unicode | |
10 | @chcp 65001 1>nul 2>nul | |
11 | @if errorlevel 1 ( | |
12 | call :print_usage "Failed to change the code page to unicode" | |
13 | exit /b 1 | |
14 | ) | |
15 | ||
16 | :: Set up some global variables | |
17 | @set project=civetweb | |
18 | @set "script_name=%~nx0" | |
19 | @set "script_folder=%~dp0" | |
20 | @set "script_folder=%script_folder:~0,-1%" | |
21 | @set "output_path=%script_folder%\output" | |
22 | @set "build_path=%output_path%\build" | |
23 | @set "install_path=%output_path%\install" | |
24 | @set build_shared=OFF | |
25 | @set build_type=Release | |
26 | @set dependency_path=%TEMP%\%project%-build-dependencies | |
27 | ||
28 | :: Check the command line parameters | |
29 | @set logging_level=1 | |
30 | @set "options=%* " | |
31 | @if not "!options!"=="!options:/? =!" set usage="Convenience script to build %project% with CMake" | |
32 | @for %%a in (%options%) do @( | |
33 | @set arg=%%~a | |
34 | @set arg=!arg: =! | |
35 | @set one=!arg:~0,1! | |
36 | @set two=!arg:~0,2! | |
37 | @if /i [!arg!] == [/q] set quiet=true | |
38 | @if /i [!two!] == [/v] call :verbosity "!arg!" | |
39 | @if /i [!arg!] == [/s] set build_shared=ON | |
40 | @if /i [!arg!] == [/d] set build_type=Debug | |
41 | @if /i not [!one!] == [/] ( | |
42 | if not defined generator ( | |
43 | set generator=!arg! | |
44 | ) else ( | |
45 | set usage="Too many generators: !method! !arg!" ^ | |
46 | "There should only be one generator parameter" | |
47 | ) | |
48 | ) | |
49 | ) | |
50 | @if defined quiet ( | |
51 | set logging_level=0 | |
52 | ) | |
53 | @if not defined generator ( | |
54 | set generator=MSVC | |
55 | ) | |
56 | @if /i not [%generator%] == [MinGW] ( | |
57 | if /i not [%generator%] == [MSVC] ( | |
58 | call :print_usage "Invalid argument: %generator%" | |
59 | exit /b 1 | |
60 | ) | |
61 | ) | |
62 | ||
63 | :: Set up the logging | |
64 | @set log_folder=%output_path%\logs | |
65 | @call :iso8601 timestamp | |
66 | @set log_path=%log_folder%\%timestamp%.log | |
67 | @set log_keep=10 | |
68 | ||
69 | :: Only keep a certain amount of logs | |
70 | @set /a "log_keep=log_keep-1" | |
71 | @if not exist %log_folder% @mkdir %log_folder% | |
72 | @for /f "skip=%log_keep%" %%f in ('dir /b /o-D /tc %log_folder%') do @( | |
73 | call :log 4 "Removing old log file %log_folder%\%%f" | |
74 | del %log_folder%\%%f | |
75 | ) | |
76 | ||
77 | :: Set up some more global variables | |
78 | @call :architecture arch | |
79 | @call :windows_version win_ver win_ver_major win_ver_minor win_ver_rev | |
80 | @call :script_source script_source | |
81 | @if [%script_source%] == [explorer] ( | |
82 | set /a "logging_level=logging_level+1" | |
83 | ) | |
84 | ||
85 | :: Print the usage or start the script | |
86 | @set exit_code=0 | |
87 | @if defined usage ( | |
88 | call :print_usage %usage% | |
89 | ) else ( | |
90 | call :main | |
91 | @if errorlevel 1 ( | |
92 | @call :log 0 "Failed to build the %project% project" | |
93 | @set exit_code=1 | |
94 | ) | |
95 | ) | |
96 | ||
97 | :: Tell the user where the built files are | |
98 | @call :log 5 | |
99 | @call :log 0 "The built files are available in %install_path%" | |
100 | ||
101 | :: Stop the script if the user double clicked | |
102 | @if [%script_source%] == [explorer] ( | |
103 | pause | |
104 | ) | |
105 | ||
106 | @exit /b %exit_code% | |
107 | @endlocal | |
108 | @goto :eof | |
109 | ||
110 | :: -------------------------- Functions start here ---------------------------- | |
111 | ||
112 | :main - Main function that performs the build | |
113 | @setlocal | |
114 | @call :log 6 | |
115 | @call :log 2 "Welcome to the %project% build script" | |
116 | @call :log 6 "------------------------------------" | |
117 | @call :log 6 | |
118 | @call :log 2 "This script builds the project using CMake" | |
119 | @call :log 6 | |
120 | @call :log 2 "Generating %generator%..." | |
121 | @call :log 6 | |
122 | @set methods=dependencies ^ | |
123 | generate ^ | |
124 | build ^ | |
125 | install | |
126 | @for %%m in (%methods%) do @( | |
127 | call :log 3 "Excuting the '%%m' method" | |
128 | call :log 8 | |
129 | call :%%~m | |
130 | if errorlevel 1 ( | |
131 | call :log 0 "Failed to complete the '%%~m' dependency routine" | |
132 | call :log 0 "View the log at %log_path%" | |
133 | exit /b 1 | |
134 | ) | |
135 | ) | |
136 | @call :log 6 "------------------------------------" | |
137 | @call :log 2 "Build complete" | |
138 | @call :log 6 | |
139 | @endlocal | |
140 | @goto :eof | |
141 | ||
142 | :print_usage - Prints the usage of the script | |
143 | :: %* - message to print, each argument on it's own line | |
144 | @setlocal | |
145 | @for %%a in (%*) do @echo.%%~a | |
146 | @echo. | |
147 | @echo.build [/?][/v[v...]^|/q][MinGW^|MSVC] | |
148 | @echo. | |
149 | @echo. [MinGW^|(MSVC)] | |
150 | @echo. Builds the library with one of the compilers | |
151 | @echo. /s Builds shared libraries | |
152 | @echo. /d Builds a debug variant of the project | |
153 | @echo. /v Sets the output to be more verbose | |
154 | @echo. /v[v...] Extra verbosity, /vv, /vvv, etc | |
155 | @echo. /q Quiets the output | |
156 | @echo. /? Shows this usage message | |
157 | @echo. | |
158 | @endlocal | |
159 | @goto :eof | |
160 | ||
161 | :dependencies - Installs any prerequisites for the build | |
162 | @setlocal EnableDelayedExpansion | |
163 | @if errorlevel 1 ( | |
164 | call :log 0 "Failed to enable extensions" | |
165 | exit /b 1 | |
166 | ) | |
167 | @call :log 5 | |
168 | @call :log 0 "Installing dependencies for %generator%" | |
169 | @if /i [%generator%] == [MinGW] ( | |
170 | call :mingw compiler_path | |
171 | @if errorlevel 1 ( | |
172 | @call :log 5 | |
173 | @call :log 0 "Failed to find MinGW" | |
174 | @exit /b 1 | |
175 | ) | |
176 | set "PATH=!compiler_path!;%PATH%" | |
177 | @call :find_in_path gcc_executable gcc.exe | |
178 | @if errorlevel 1 ( | |
179 | @call :log 5 | |
180 | @call :log 0 "Failed to find gcc.exe" | |
181 | @exit /b 1 | |
182 | ) | |
183 | ) | |
184 | @if [%reboot_required%] equ [1] call :reboot | |
185 | @endlocal & set "PATH=%PATH%" | |
186 | @goto :eof | |
187 | ||
188 | :generate - Uses CMake to generate the build files | |
189 | @setlocal EnableDelayedExpansion | |
190 | @if errorlevel 1 ( | |
191 | call :log 0 "Failed to enable extensions" | |
192 | exit /b 1 | |
193 | ) | |
194 | @call :log 5 | |
195 | @call :log 0 "Generating CMake files for %generator%" | |
196 | @call :cmake cmake_executable | |
197 | @if errorlevel 1 ( | |
198 | @call :log 5 | |
199 | @call :log 0 "Need CMake to create the build files" | |
200 | @exit /b 1 | |
201 | ) | |
202 | @if /i [%generator%] == [MinGW] @( | |
203 | @set "generator_var=-G "MinGW Makefiles^"" | |
204 | ) | |
205 | @if /i [%generator%] == [MSVC] @( | |
206 | rem We could figure out the correct MSVS generator here | |
207 | ) | |
208 | @call :iso8601 iso8601 | |
209 | @set output=%temp%\cmake-%iso8601%.log | |
210 | @if not exist %build_path% mkdir %build_path% | |
211 | @cd %build_path% | |
212 | @"%cmake_executable%" ^ | |
213 | !generator_var! ^ | |
214 | -DCMAKE_BUILD_TYPE=!build_type! ^ | |
215 | -DBUILD_SHARED_LIBS=!build_shared! ^ | |
216 | "%script_folder%" > "%output%" | |
217 | @if errorlevel 1 ( | |
218 | @call :log 5 | |
219 | @call :log 0 "Failed to generate build files with CMake" | |
220 | @call :log_append "%output%" | |
221 | @cd %script_folder% | |
222 | @exit /b 1 | |
223 | ) | |
224 | @cd %script_folder% | |
225 | @endlocal | |
226 | @goto :eof | |
227 | ||
228 | :build - Builds the library | |
229 | @setlocal EnableDelayedExpansion | |
230 | @if errorlevel 1 ( | |
231 | call :log 0 "Failed to enable extensions" | |
232 | exit /b 1 | |
233 | ) | |
234 | @call :log 5 | |
235 | @call :log 0 "Building %project% with %generator%" | |
236 | @if /i [%generator%] == [MinGW] @( | |
237 | @call :find_in_path mingw32_make_executable mingw32-make.exe | |
238 | @if errorlevel 1 ( | |
239 | @call :log 5 | |
240 | @call :log 0 "Failed to find mingw32-make" | |
241 | @exit /b 1 | |
242 | ) | |
243 | @set "build_command=^"!mingw32_make_executable!^" all test" | |
244 | ) | |
245 | @if /i [%generator%] == [MSVC] @( | |
246 | @call :msbuild msbuild_executable | |
247 | @if errorlevel 1 ( | |
248 | @call :log 5 | |
249 | @call :log 0 "Failed to find MSBuild" | |
250 | @exit /b 1 | |
251 | ) | |
252 | @set "build_command=^"!msbuild_executable!^" /m:4 /p:Configuration=%build_type% %project%.sln" | |
253 | ) | |
254 | @if not defined build_command ( | |
255 | @call :log 5 | |
256 | @call :log 0 "No build command for %generator%" | |
257 | @exit /b 1 | |
258 | ) | |
259 | @cd %build_path% | |
260 | @call :iso8601 iso8601 | |
261 | @set output=%temp%\build-%iso8601%.log | |
262 | @call :log 7 | |
263 | @call :log 2 "Build command: %build_command:"=%" | |
264 | @%build_command% > "%output%" | |
265 | @if errorlevel 1 ( | |
266 | @call :log_append "%output%" | |
267 | @call :log 5 | |
268 | @call :log 0 "Failed to complete the build" | |
269 | @exit /b 1 | |
270 | ) | |
271 | @call :log_append "%output%" | |
272 | @cd %script_folder% | |
273 | @endlocal | |
274 | @goto :eof | |
275 | ||
276 | :install - Installs the built files | |
277 | @setlocal | |
278 | @call :log 5 | |
279 | @call :log 0 "Installing built files" | |
280 | @call :cmake cmake_executable | |
281 | @if errorlevel 1 ( | |
282 | @call :log 5 | |
283 | @call :log 0 "Need CMake to install the built files" | |
284 | @exit /b 1 | |
285 | ) | |
286 | @call :iso8601 iso8601 | |
287 | @set output=%temp%\install-%iso8601%.log | |
288 | @"%cmake_executable%" ^ | |
289 | "-DCMAKE_INSTALL_PREFIX=%install_path%" ^ | |
290 | -P "%build_path%/cmake_install.cmake" ^ | |
291 | > "%output%" | |
292 | @if errorlevel 1 ( | |
293 | @call :log_append "%output%" | |
294 | @call :log 5 | |
295 | @call :log 0 "Failed to install the files" | |
296 | @exit /b 1 | |
297 | ) | |
298 | @call :log_append "%output%" | |
299 | @endlocal | |
300 | @goto :eof | |
301 | ||
302 | :script_source - Determines if the script was ran from the cli or explorer | |
303 | :: %1 - The return variable [cli|explorer] | |
304 | @verify other 2>nul | |
305 | @setlocal EnableDelayedExpansion | |
306 | @if errorlevel 1 ( | |
307 | call :log 0 "Failed to enable extensions" | |
308 | exit /b 1 | |
309 | ) | |
310 | @call :log 3 "Attempting to detect the script source" | |
311 | @echo "The invocation command was: '%cmdcmdline%'" >> %log_path% | |
312 | @for /f "tokens=1-3,*" %%a in ("%cmdcmdline%") do @( | |
313 | set cmd=%%~a | |
314 | set arg1=%%~b | |
315 | set arg2=%%~c | |
316 | set rest=%%~d | |
317 | ) | |
318 | @set quote=" | |
319 | @if "!arg2:~0,1!" equ "!quote!" ( | |
320 | if "!arg2:~-1!" neq "!quote!" ( | |
321 | set "arg2=!arg2:~1!" | |
322 | ) | |
323 | ) | |
324 | @call :log 4 "cmd = %cmd%" | |
325 | @call :log 4 "arg1 = %arg1%" | |
326 | @call :log 4 "arg2 = %arg2%" | |
327 | @call :log 4 "rest = %rest%" | |
328 | @call :log 4 "src = %~f0" | |
329 | @if /i "%arg2%" == "call" ( | |
330 | set script_source=cli | |
331 | ) else ( | |
332 | @if /i "%arg1%" == "/c" ( | |
333 | set script_source=explorer | |
334 | ) else ( | |
335 | set script_source=cli | |
336 | ) | |
337 | ) | |
338 | @call :log 3 "The script was invoked from %script_source%" | |
339 | @endlocal & set "%~1=%script_source%" | |
340 | @goto :eof | |
341 | ||
342 | :architecture - Finds the system architecture | |
343 | :: %1 - The return variable [x86|x86_64] | |
344 | @setlocal | |
345 | @call :log 3 "Determining the processor architecture" | |
346 | @set "key=HKLM\System\CurrentControlSet\Control\Session Manager\Environment" | |
347 | @set "var=PROCESSOR_ARCHITECTURE" | |
348 | @for /f "skip=2 tokens=2,*" %%a in ('reg query "%key%" /v "%var%"') do @set "arch=%%b" | |
349 | @if "%arch%" == "AMD64" set arch=x86_64 | |
350 | @call :log 4 "arch = %arch%" | |
351 | @endlocal & set "%~1=%arch%" | |
352 | @goto :eof | |
353 | ||
354 | :md5 - Gets the MD5 checksum for a file | |
355 | :: %1 - The hash | |
356 | :: %2 - The file path | |
357 | @setlocal | |
358 | @set var=%~1 | |
359 | @set file_path=%~2 | |
360 | @if [%var%] == [] exit /b 1 | |
361 | @if "%file_path%" == "" exit /b 1 | |
362 | @if not exist "%file_path%" exit /b 1 | |
363 | @for /f "skip=3 tokens=1,*" %%a in ('powershell Get-FileHash -Algorithm MD5 "'%file_path%'"') do @set hash=%%b | |
364 | @if not defined hash ( | |
365 | call :log 6 | |
366 | call :log 0 "Failed to get MD5 hash for %file_path%" | |
367 | exit /b 1 | |
368 | ) | |
369 | @endlocal & set "%var%=%hash: =%" | |
370 | @goto :eof | |
371 | ||
372 | :windows_version - Checks the windows version | |
373 | :: %1 - The windows version | |
374 | :: %2 - The major version number return variable | |
375 | :: %3 - The minor version number return variable | |
376 | :: %4 - The revision version number return variable | |
377 | @setlocal | |
378 | @call :log 3 "Retrieving the Windows version" | |
379 | @for /f "tokens=2 delims=[]" %%x in ('ver') do @set win_ver=%%x | |
380 | @set win_ver=%win_ver:Version =% | |
381 | @set win_ver_major=%win_ver:~0,1% | |
382 | @set win_ver_minor=%win_ver:~2,1% | |
383 | @set win_ver_rev=%win_ver:~4% | |
384 | @call :log 4 "win_ver = %win_ver%" | |
385 | @endlocal & set "%~1=%win_ver%" ^ | |
386 | & set "%~2=%win_ver_major%" ^ | |
387 | & set "%~3=%win_ver_minor%" ^ | |
388 | & set "%~4=%win_ver_rev%" | |
389 | @goto :eof | |
390 | ||
391 | :find_in_path - Finds a program of file in the PATH | |
392 | @setlocal | |
393 | @set var=%~1 | |
394 | @set file=%~2 | |
395 | @if [%var%] == [] exit /b 1 | |
396 | @if [%file%] == [] exit /b 1 | |
397 | @call :log 3 "Searching PATH for %file%" | |
398 | @for %%x in ("%file%") do @set "file_path=%%~f$PATH:x" | |
399 | @if not defined file_path exit /b 1 | |
400 | @endlocal & set "%var%=%file_path%" | |
401 | @goto :eof | |
402 | ||
403 | :administrator_check - Checks for administrator priviledges | |
404 | @setlocal | |
405 | @call :log 2 "Checking for administrator priviledges" | |
406 | @set "key=HKLM\Software\VCA\Tool Chain\Admin Check" | |
407 | @reg add "%key%" /v Elevated /t REG_DWORD /d 1 /f > nul 2>&1 | |
408 | @if errorlevel 1 exit /b 1 | |
409 | @reg delete "%key%" /va /f > nul 2>&1 | |
410 | @endlocal | |
411 | @goto :eof | |
412 | ||
413 | :log_append - Appends another file into the current logging file | |
414 | :: %1 - the file_path to the file to concatenate | |
415 | @setlocal | |
416 | @set "file_path=%~1" | |
417 | @if [%file_path%] == [] exit /b 1 | |
418 | @call :log 3 "Appending to log: %file_path%" | |
419 | @call :iso8601 iso8601 | |
420 | @set "temp_log=%temp%\append-%iso8601%.log" | |
421 | @call :log 4 "Using temp file %temp_log%" | |
422 | @type "%log_path%" "%file_path%" > "%temp_log%" 2>nul | |
423 | @move /y "%temp_log%" "%log_path%" 1>nul | |
424 | @del "%file_path%" 2>nul | |
425 | @del "%temp_log%" 2>nul | |
426 | @endlocal | |
427 | @goto :eof | |
428 | ||
429 | :iso8601 - Returns the current time in ISO8601 format | |
430 | :: %1 - the return variable | |
431 | :: %2 - format [extended|basic*] | |
432 | :: iso8601 - contains the resulting timestamp | |
433 | @setlocal | |
434 | @wmic Alias /? >NUL 2>&1 || @exit /b 1 | |
435 | @set "var=%~1" | |
436 | @if "%var%" == "" @exit /b 1 | |
437 | @set "format=%~2" | |
438 | @if "%format%" == "" set format=basic | |
439 | @for /F "skip=1 tokens=1-6" %%g IN ('wmic Path Win32_UTCTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') do @( | |
440 | @if "%%~l"=="" goto :iso8601_done | |
441 | @set "yyyy=%%l" | |
442 | @set "mm=00%%j" | |
443 | @set "dd=00%%g" | |
444 | @set "hour=00%%h" | |
445 | @set "minute=00%%i" | |
446 | @set "seconds=00%%k" | |
447 | ) | |
448 | :iso8601_done | |
449 | @set mm=%mm:~-2% | |
450 | @set dd=%dd:~-2% | |
451 | @set hour=%hour:~-2% | |
452 | @set minute=%minute:~-2% | |
453 | @set seconds=%seconds:~-2% | |
454 | @if /i [%format%] == [extended] ( | |
455 | set iso8601=%yyyy%-%mm%-%dd%T%hour%:%minute%:%seconds%Z | |
456 | ) else ( | |
457 | if /i [%format%] == [basic] ( | |
458 | set iso8601=%yyyy%%mm%%dd%T%hour%%minute%%seconds%Z | |
459 | ) else ( | |
460 | @exit /b 1 | |
461 | ) | |
462 | ) | |
463 | @set iso8601=%iso8601: =0% | |
464 | @endlocal & set %var%=%iso8601% | |
465 | @goto :eof | |
466 | ||
467 | :verbosity - Processes the verbosity parameter '/v[v...] | |
468 | :: %1 - verbosity given on the command line | |
469 | :: logging_level - set to the number of v's | |
470 | @setlocal | |
471 | @set logging_level=0 | |
472 | @set verbosity=%~1 | |
473 | :verbosity_loop | |
474 | @set verbosity=%verbosity:~1% | |
475 | @if not [%verbosity%] == [] @( | |
476 | set /a "logging_level=logging_level+1" | |
477 | goto verbosity_loop | |
478 | ) | |
479 | @endlocal & set logging_level=%logging_level% | |
480 | @goto :eof | |
481 | ||
482 | :log - Logs a message, depending on verbosity | |
483 | :: %1 - level | |
484 | :: [0-4] for CLI logging | |
485 | :: [5-9] for GUI logging | |
486 | :: %2 - message to print | |
487 | @setlocal | |
488 | @set "level=%~1" | |
489 | @set "msg=%~2" | |
490 | @if "%log_folder%" == "" ( | |
491 | echo Logging was used to early in the script, log_folder isn't set yet | |
492 | goto :eof | |
493 | ) | |
494 | @if "%log_path%" == "" ( | |
495 | echo Logging was used to early in the script, log_path isn't set yet | |
496 | goto :eof | |
497 | ) | |
498 | @if not exist "%log_folder%" mkdir "%log_folder%" | |
499 | @if not exist "%log_path%" echo. 1>nul 2>"%log_path%" | |
500 | @echo.%msg% >> "%log_path%" | |
501 | @if %level% geq 5 ( | |
502 | @if [%script_source%] == [explorer] ( | |
503 | set /a "level=level-5" | |
504 | ) else ( | |
505 | @goto :eof | |
506 | ) | |
507 | ) | |
508 | @if "%logging_level%" == "" ( | |
509 | echo Logging was used to early in the script, logging_level isn't set yet | |
510 | goto :eof | |
511 | ) | |
512 | @if %logging_level% geq %level% echo.%msg% 1>&2 | |
513 | @endlocal | |
514 | @goto :eof | |
515 | ||
516 | ||
517 | :start_browser - Opens the default browser to a URL | |
518 | :: %1 - the url to open | |
519 | @setlocal | |
520 | @set url=%~1 | |
521 | @call :log 4 "Opening default browser: %url%" | |
522 | @start %url% | |
523 | @endlocal | |
524 | @goto :eof | |
525 | ||
526 | :find_cmake - Finds cmake on the command line or in the registry | |
527 | :: %1 - the cmake file path | |
528 | @setlocal | |
529 | @set var=%~1 | |
530 | @if [%var%] == [] exit /b 1 | |
531 | @call :log 6 | |
532 | @call :log 6 "Finding CMake" | |
533 | @call :log 6 "--------------" | |
534 | @call :find_in_path cmake_executable cmake.exe | |
535 | @if not errorlevel 1 goto found_cmake | |
536 | @for /l %%i in (5,-1,0) do @( | |
537 | @for /l %%j in (9,-1,0) do @( | |
538 | @for /l %%k in (9,-1,0) do @( | |
539 | @for %%l in (HKCU HKLM) do @( | |
540 | @for %%m in (SOFTWARE SOFTWARE\Wow6432Node) do @( | |
541 | @reg query "%%l\%%m\Kitware\CMake %%i.%%j.%%k" /ve > nul 2>nul | |
542 | @if not errorlevel 1 ( | |
543 | @for /f "skip=2 tokens=2,*" %%a in ('reg query "%%l\%%m\Kitware\CMake %%i.%%j.%%k" /ve') do @( | |
544 | @if exist "%%b\bin\cmake.exe" ( | |
545 | @set "cmake_executable=%%b\bin\cmake.exe" | |
546 | goto found_cmake | |
547 | ) | |
548 | ) | |
549 | ) | |
550 | ))))) | |
551 | @call :log 5 | |
552 | @call :log 0 "Failed to find cmake" | |
553 | @exit /b 1 | |
554 | :found_cmake | |
555 | @endlocal & set "%var%=%cmake_executable%" | |
556 | @goto :eof | |
557 | ||
558 | :cmake - Finds cmake and installs it if necessary | |
559 | :: %1 - the cmake file path | |
560 | @setlocal | |
561 | @set var=%~1 | |
562 | @if [%var%] == [] exit /b 1 | |
563 | @call :log 6 | |
564 | @call :log 6 "Checking for CMake" | |
565 | @call :log 6 "------------------" | |
566 | @call :find_cmake cmake_executable cmake.exe | |
567 | @if not errorlevel 1 goto got_cmake | |
568 | @set checksum=C00267A3D3D9619A7A2E8FA4F46D7698 | |
569 | @set version=3.2.2 | |
570 | @call :install_nsis cmake http://www.cmake.org/files/v%version:~0,3%/cmake-%version%-win32-x86.exe %checksum% | |
571 | @if errorlevel 1 ( | |
572 | call :log 5 | |
573 | call :log 0 "Failed to install cmake" | |
574 | @exit /b 1 | |
575 | ) | |
576 | @call :find_cmake cmake_executable cmake.exe | |
577 | @if not errorlevel 1 goto got_cmake | |
578 | @call :log 5 | |
579 | @call :log 0 "Failed to check for cmake" | |
580 | @exit /b 1 | |
581 | :got_cmake | |
582 | @endlocal & set "%var%=%cmake_executable%" | |
583 | @goto :eof | |
584 | ||
585 | :mingw - Finds MinGW, installing it if needed | |
586 | :: %1 - the compiler path that should be added to PATH | |
587 | @setlocal EnableDelayedExpansion | |
588 | @if errorlevel 1 ( | |
589 | @call :log 5 | |
590 | @call :log 0 "Failed to enable extensions" | |
591 | @exit /b 1 | |
592 | ) | |
593 | @set var=%~1 | |
594 | @if [%var%] == [] exit /b 1 | |
595 | @call :log 6 | |
596 | @call :log 6 "Checking for MinGW" | |
597 | @call :log 6 "------------------" | |
598 | @call :find_in_path gcc_executable gcc.exe | |
599 | @if not errorlevel 1 ( | |
600 | @for %%a in ("%gcc_executable%") do @set "compiler_path=%%~dpa" | |
601 | goto got_mingw | |
602 | ) | |
603 | @call :log 7 | |
604 | @call :log 2 "Downloading MinGW" | |
605 | @if %logging_level% leq 1 set "logging=/q" | |
606 | @if %logging_level% gtr 1 set "logging=/v" | |
607 | @set output_path= | |
608 | @for /f %%a in ('call | |
609 | "%script_folder%\mingw.cmd" | |
610 | %logging% | |
611 | /arch "%arch%" | |
612 | "%dependency_path%"' | |
613 | ) do @set "compiler_path=%%a\" | |
614 | @if not defined compiler_path ( | |
615 | @call :log_append "%output%" | |
616 | @call :log 5 | |
617 | @call :log 0 "Failed to download MinGW" | |
618 | @exit /b 1 | |
619 | ) | |
620 | :got_mingw | |
621 | @call :log 5 | |
622 | @call :log 0 "Found MinGW: %compiler_path%gcc.exe" | |
623 | @endlocal & set "%var%=%compiler_path%" | |
624 | @goto :eof | |
625 | ||
626 | :msbuild - Finds MSBuild | |
627 | :: %1 - the path to MSBuild executable | |
628 | @setlocal | |
629 | @set var=%~1 | |
630 | @if [%var%] == [] exit /b 1 | |
631 | @call :find_in_path msbuild_executable msbuild.exe | |
632 | @if not errorlevel 1 goto got_msbuild | |
633 | @for /l %%i in (20,-1,4) do @( | |
634 | @for /l %%j in (9,-1,0) do @( | |
635 | @for %%k in (HKCU HKLM) do @( | |
636 | @for %%l in (SOFTWARE SOFTWARE\Wow6432Node) do @( | |
637 | @reg query "%%k\%%l\Microsoft\MSBuild\%%i.%%j" /v MSBuildOverrideTasksPath > nul 2>nul | |
638 | @if not errorlevel 1 ( | |
639 | @for /f "skip=2 tokens=2,*" %%a in ('reg query "%%k\%%l\Microsoft\MSBuild\%%i.%%j" /v MSBuildOverrideTasksPath') do @( | |
640 | @if exist "%%bmsbuild.exe" ( | |
641 | @set "msbuild_executable=%%bmsbuild.exe" | |
642 | goto got_msbuild | |
643 | ) | |
644 | ) | |
645 | ) | |
646 | )))) | |
647 | @call :log 5 | |
648 | @call :log 0 "Failed to check for MSBuild" | |
649 | @exit /b 1 | |
650 | :got_msbuild | |
651 | @endlocal & set "%var%=%msbuild_executable%" | |
652 | @goto :eof | |
653 | ||
654 | :download - Downloads a file from the internet | |
655 | :: %1 - the url of the file to download | |
656 | :: %2 - the file to download to | |
657 | :: %3 - the MD5 checksum of the file (optional) | |
658 | @setlocal EnableDelayedExpansion | |
659 | @if errorlevel 1 ( | |
660 | call :print_usage "Failed to enable extensions" | |
661 | exit /b 1 | |
662 | ) | |
663 | @set url=%~1 | |
664 | @set file_path=%~2 | |
665 | @set checksum=%~3 | |
666 | @for %%a in (%file_path%) do @set dir_path=%%~dpa | |
667 | @for %%a in (%file_path%) do @set file_name=%%~nxa | |
668 | @if [%url%] == [] exit /b 1 | |
669 | @if [%file_path%] == [] exit /b 1 | |
670 | @if [%dir_path%] == [] exit /b 1 | |
671 | @if [%file_name%] == [] exit /b 1 | |
672 | @if not exist "%dir_path%" mkdir "%dir_path%" | |
673 | @call :log 1 "Downloading %url%" | |
674 | @call :iso8601 iso8601 | |
675 | @set temp_path=%temp%\download-%iso8601%-%file_name% | |
676 | @call :log 3 "Using temp file %temp_path%" | |
677 | @powershell Invoke-WebRequest "%url%" -OutFile %temp_path% | |
678 | @if errorlevel 1 ( | |
679 | call :log 0 "Failed to download %url%" | |
680 | exit /b 1 | |
681 | ) | |
682 | @if [%checksum%] neq [] ( | |
683 | @call :log 4 "Checking %checksum% against %temp_path%" | |
684 | @call :md5 hash "%temp_path%" | |
685 | if "!hash!" neq "%checksum%" ( | |
686 | call :log 0 "Failed to match checksum: %temp_path%" | |
687 | call :log 0 "Hash : !hash!" | |
688 | call :log 0 "Checksum: %checksum%" | |
689 | exit /b 1 | |
690 | ) else ( | |
691 | call :log 3 "Checksum matched: %temp_path%" | |
692 | call :log 3 "Hash : !hash!" | |
693 | call :log 3 "Checksum: %checksum%" | |
694 | ) | |
695 | ) | |
696 | @call :log 4 "Renaming %temp_path% to %file_path%" | |
697 | @move /y "%temp_path%" "%file_path%" 1>nul | |
698 | @endlocal | |
699 | @goto :eof | |
700 | ||
701 | :install_msi - Installs a dependency from an Microsoft Installer package (.msi) | |
702 | :: %1 - [string] name of the project to install | |
703 | :: %2 - The location of the .msi, a url must start with 'http://' or file_path | |
704 | :: %3 - The checksum of the msi (optional) | |
705 | @setlocal | |
706 | @set name=%~1 | |
707 | @set file_path=%~2 | |
708 | @set checksum=%~3 | |
709 | @set msi=%~nx2 | |
710 | @set msi_path=%dependency_path%\%msi% | |
711 | @if [%name%] == [] exit /b 1 | |
712 | @if [%file_path%] == [] exit /b 1 | |
713 | @if [%msi%] == [] exit /b 1 | |
714 | @if [%msi_path%] == [] exit /b 1 | |
715 | @for %%x in (msiexec.exe) do @set "msiexec_path=%%~f$PATH:x" | |
716 | @if "msiexec_path" == "" ( | |
717 | call :log 0 "Failed to find the Microsoft package installer (msiexec.exe)" | |
718 | call :log 6 | |
719 | call :log 0 "Please install it from the Microsoft Download center" | |
720 | call :log 6 | |
721 | choice /C YN /T 60 /D N /M "Would you like to go there now?" | |
722 | if !errorlevel! equ 1 call :start_browser ^ | |
723 | "http://search.microsoft.com/DownloadResults.aspx?q=Windows+Installer" | |
724 | exit /b 1 | |
725 | ) | |
726 | @call :log 6 | |
727 | @call :log 1 "Installing the '%name%' dependency" | |
728 | @call :log 6 "-------------------------------------" | |
729 | @call :administrator_check | |
730 | @if errorlevel 1 ( | |
731 | call :log 0 "You must run %~nx0 in elevated mode to install '%name%'" | |
732 | call :log 5 "Right-Click and select 'Run as Administrator' | |
733 | call :log 0 "Install the dependency manually by running %file_path%" | |
734 | @exit /b 740 | |
735 | ) | |
736 | @if [%file_path:~0,4%] == [http] ( | |
737 | if not exist "%msi_path%" ( | |
738 | call :download "%file_path%" "%msi_path%" %checksum% | |
739 | if errorlevel 1 ( | |
740 | call :log 0 "Failed to download the %name% dependency" | |
741 | exit /b 1 | |
742 | ) | |
743 | ) | |
744 | ) else ( | |
745 | call :log 2 "Copying MSI %file_path% to %msi_path%" | |
746 | call :log 7 | |
747 | if not exist "%msi_path%" ( | |
748 | xcopy /q /y /z "%file_path%" "%msi_path%" 1>nul | |
749 | if errorlevel 1 ( | |
750 | call :log 0 "Failed to copy the Microsoft Installer" | |
751 | exit /b 1 | |
752 | ) | |
753 | ) | |
754 | ) | |
755 | @call :log 1 "Running the %msi%" | |
756 | @call :log 6 | |
757 | @set msi_log=%temp%\msiexec-%timestamp%.log | |
758 | @call :log 3 "Logging to: %msi_log%" | |
759 | @msiexec /i "%msi_path%" /passive /log "%msi_log%" ALLUSERS=1 | |
760 | @set msi_errorlevel=%errorlevel% | |
761 | @call :log_append "%msi_log%" | |
762 | @if %msi_errorlevel% equ 0 goto install_msi_success | |
763 | @if %msi_errorlevel% equ 3010 goto install_msi_success_reboot | |
764 | @if %msi_errorlevel% equ 1641 goto install_msi_success_reboot | |
765 | @if %msi_errorlevel% equ 3015 goto install_msi_in_progress_reboot | |
766 | @if %msi_errorlevel% equ 1615 goto install_msi_in_progress_reboot | |
767 | @call :log 0 "Microsoft Installer failed: %msi_errorlevel%" | |
768 | @call :log 0 "Install the dependency manually by running %msi_path%" | |
769 | @exit /b 1 | |
770 | :install_msi_in_progress_reboot | |
771 | @call :log 0 "The installation requires a reboot to continue" | |
772 | @call :log 5 | |
773 | @call :reboot | |
774 | @exit /b 1 | |
775 | :install_msi_success_reboot | |
776 | @call :log 3 "The installation requires a reboot to be fully functional" | |
777 | @set reboot_required=1 | |
778 | :install_msi_success | |
779 | @call :log 2 "Successfully installed %name%" | |
780 | @call :log 7 | |
781 | @endlocal & set reboot_required=%reboot_required% | |
782 | @goto :eof | |
783 | ||
784 | :install_nsis - Installs a dependency from an Nullsoft Installer package (.exe) | |
785 | :: %1 - [string] name of the project to install | |
786 | :: %2 - The location of the .exe, a url must start with 'http://' or file_path | |
787 | :: %3 - The checksum of the exe (optional) | |
788 | @setlocal | |
789 | @set name=%~1 | |
790 | @set file_path=%~2 | |
791 | @set checksum=%~3 | |
792 | @set exe=%~nx2 | |
793 | @set exe_path=%dependency_path%\%exe% | |
794 | @if [%name%] == [] exit /b 1 | |
795 | @if [%file_path%] == [] exit /b 1 | |
796 | @if [%exe%] == [] exit /b 1 | |
797 | @if [%exe_path%] == [] exit /b 1 | |
798 | @call :log 6 | |
799 | @call :log 1 "Installing the '%name%' dependency" | |
800 | @call :log 6 "-------------------------------------" | |
801 | @call :administrator_check | |
802 | @if errorlevel 1 ( | |
803 | call :log 0 "You must run %~nx0 in elevated mode to install '%name%'" | |
804 | call :log 5 "Right-Click and select 'Run as Administrator' | |
805 | call :log 0 "Install the dependency manually by running %file_path%" | |
806 | @exit /b 740 | |
807 | ) | |
808 | @if [%file_path:~0,4%] == [http] ( | |
809 | if not exist "%exe_path%" ( | |
810 | call :download "%file_path%" "%exe_path%" %checksum% | |
811 | if errorlevel 1 ( | |
812 | call :log 0 "Failed to download the %name% dependency" | |
813 | exit /b 1 | |
814 | ) | |
815 | ) | |
816 | ) else ( | |
817 | call :log 2 "Copying installer %file_path% to %exe_path%" | |
818 | call :log 7 | |
819 | if not exist "%exe_path%" ( | |
820 | xcopy /q /y /z "%file_path%" "%exe_path%" 1>nul | |
821 | if errorlevel 1 ( | |
822 | call :log 0 "Failed to copy the Nullsoft Installer" | |
823 | exit /b 1 | |
824 | ) | |
825 | ) | |
826 | ) | |
827 | @call :log 1 "Running the %exe%" | |
828 | @call :log 6 | |
829 | @"%exe_path%" /S | |
830 | @set nsis_errorlevel=%errorlevel% | |
831 | @if %nsis_errorlevel% equ 0 goto install_nsis_success | |
832 | @if %nsis_errorlevel% equ 3010 goto install_nsis_success_reboot | |
833 | @if %nsis_errorlevel% equ 1641 goto install_nsis_success_reboot | |
834 | @if %nsis_errorlevel% equ 3015 goto install_nsis_in_progress_reboot | |
835 | @if %nsis_errorlevel% equ 1615 goto install_nsis_in_progress_reboot | |
836 | @call :log 0 "Nullsoft Installer failed: %nsis_errorlevel%" | |
837 | @call :log 0 "Install the dependency manually by running %exe_path%" | |
838 | @exit /b 1 | |
839 | :install_nsis_in_progress_reboot | |
840 | @call :log 0 "The installation requires a reboot to continue" | |
841 | @call :log 5 | |
842 | @call :reboot | |
843 | @exit /b 1 | |
844 | :install_nsis_success_reboot | |
845 | @call :log 3 "The installation requires a reboot to be fully functional" | |
846 | @set reboot_required=1 | |
847 | :install_nsis_success | |
848 | @call :log 2 "Successfully installed %name%" | |
849 | @call :log 7 | |
850 | @endlocal & set reboot_required=%reboot_required% | |
851 | @goto :eof | |
852 | ||
853 | :reboot - Asks the user if they would like to reboot then stops the script | |
854 | @setlocal | |
855 | @call :log 6 "-------------------------------------------" | |
856 | @choice /C YN /T 60 /D N /M "The %method% requires a reboot, reboot now?" | |
857 | @set ret=%errorlevel% | |
858 | @call :log 6 | |
859 | @if %ret% equ 1 ( | |
860 | @shutdown /r | |
861 | ) else ( | |
862 | @call :log 0 "You will need to reboot to complete the %method%" | |
863 | @call :log 5 | |
864 | ) | |
865 | @endlocal | |
866 | @goto :eof |