|
@@ -0,0 +1,879 @@
|
|
|
+:: Make sure the extensions are enabled
|
|
|
+@verify other 2>nul
|
|
|
+@setlocal EnableExtensions EnableDelayedExpansion
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :print_usage "Failed to enable extensions"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+
|
|
|
+::Change the code page to unicode
|
|
|
+@chcp 65001 1>nul 2>nul
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :print_usage "Failed to change the code page to unicode"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+
|
|
|
+:: Set up some global variables
|
|
|
+@set "script_name=%~nx0"
|
|
|
+@set "script_folder=%~dp0"
|
|
|
+@set "script_folder=%script_folder:~0,-1%"
|
|
|
+@set "dependency_path=%TEMP%\mingw-build-dependencies"
|
|
|
+
|
|
|
+:: Check the command line parameters
|
|
|
+@set logging_level=1
|
|
|
+:options_loop
|
|
|
+@if [%1] == [] goto :options_parsed
|
|
|
+@set "arg=%~1"
|
|
|
+@set one=%arg:~0,1%
|
|
|
+@set two=%arg:~0,2%
|
|
|
+@set three=%arg:~0,3%
|
|
|
+@if /i [%arg%] == [/?] (
|
|
|
+ @call :print_usage "Downloads a specific version of MinGW"
|
|
|
+ @exit /b 0
|
|
|
+)
|
|
|
+@if /i [%arg%] == [/q] set quiet=true
|
|
|
+@if /i [%two%] == [/v] @if /i not [%three%] == [/ve] @call :verbosity "!arg!"
|
|
|
+@if /i [%arg%] == [/version] set "version=%~2" & shift
|
|
|
+@if /i [%arg%] == [/arch] set "arch=%~2" & shift
|
|
|
+@if /i [%arg%] == [/exceptions] set "exceptions=%~2" & shift
|
|
|
+@if /i [%arg%] == [/threading] set "threading=%~2" & shift
|
|
|
+@if /i [%arg%] == [/revision] set "revision=%~2" & shift
|
|
|
+@if /i not [!one!] == [/] (
|
|
|
+ if not defined output_path (
|
|
|
+ set output_path=!arg!
|
|
|
+ ) else (
|
|
|
+ @call :print_usage "Too many output locations: !output_path! !arg!" ^
|
|
|
+ "There should only be one output location"
|
|
|
+ @exit /b 1
|
|
|
+ )
|
|
|
+)
|
|
|
+@shift
|
|
|
+@goto :options_loop
|
|
|
+:options_parsed
|
|
|
+@if defined quiet set logging_level=0
|
|
|
+@if not defined output_path set "output_path=%script_folder%\mingw-builds"
|
|
|
+@set "output_path=%output_path:/=\%"
|
|
|
+
|
|
|
+:: Set up the logging
|
|
|
+@set "log_folder=%output_path%\logs"
|
|
|
+@call :iso8601 timestamp
|
|
|
+@set "log_path=%log_folder%\%timestamp%.log"
|
|
|
+@set log_keep=10
|
|
|
+
|
|
|
+:: Get default architecture
|
|
|
+@if not defined arch @call :architecture arch
|
|
|
+
|
|
|
+:: Only keep a certain amount of logs
|
|
|
+@set /a "log_keep=log_keep-1"
|
|
|
+@if not exist %log_folder% @mkdir %log_folder%
|
|
|
+@for /f "skip=%log_keep%" %%f in ('dir /b /o-D /tc %log_folder%') do @(
|
|
|
+ @call :log 4 "Removing old log file %log_folder%\%%f"
|
|
|
+ del %log_folder%\%%f
|
|
|
+)
|
|
|
+
|
|
|
+:: Set up some more global variables
|
|
|
+@call :windows_version win_ver win_ver_major win_ver_minor win_ver_rev
|
|
|
+@call :script_source script_source
|
|
|
+@if [%script_source%] == [explorer] (
|
|
|
+ set /a "logging_level=logging_level+1"
|
|
|
+)
|
|
|
+
|
|
|
+:: Execute the main function
|
|
|
+@call :main "%arch%" "%version%" "%threading%" "%exceptions%" "%revision%"
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to download MinGW"
|
|
|
+ @call :log 0 "View the log at %log_path%"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+
|
|
|
+:: Stop the script if the user double clicked
|
|
|
+@if [%script_source%] == [explorer] (
|
|
|
+ pause
|
|
|
+)
|
|
|
+
|
|
|
+@endlocal
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:: -------------------------- Functions start here ----------------------------
|
|
|
+
|
|
|
+:main - Main function that performs the download
|
|
|
+:: %1 - Target architecture
|
|
|
+:: %2 - Version of MinGW to get [optional]
|
|
|
+:: %3 - Threading model [optional]
|
|
|
+:: %4 - Exception model [optional]
|
|
|
+:: %5 - Package revision [optional]
|
|
|
+@setlocal
|
|
|
+@call :log 6
|
|
|
+@call :log 2 "Welcome to the MinGW download script"
|
|
|
+@call :log 6 "------------------------------------"
|
|
|
+@call :log 6
|
|
|
+@call :log 2 "This script downloads a specific version of MinGW"
|
|
|
+@set "arch=%~1"
|
|
|
+@if "%arch%" == "" @exit /b 1
|
|
|
+@set "version=%~2"
|
|
|
+@set "threading=%~3"
|
|
|
+@set "exceptions=%~4"
|
|
|
+@set "revision=%~5"
|
|
|
+@call :log 3 "arch = %arch%"
|
|
|
+@call :log 3 "version = %version%"
|
|
|
+@call :log 3 "exceptions = %exceptions%"
|
|
|
+@call :log 3 "threading = %threading%"
|
|
|
+@call :log 3 "revision = %revision%"
|
|
|
+@call :repository repo
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to get the MinGW-builds repository information"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@call :resolve slug url "%repo%" "%arch%" "%version%" "%threading%" "%exceptions%" "%revision%"
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to resolve the correct URL of MinGW"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@call :unpack compiler_path "%url%" "%output_path%\mingw\%slug%"
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to unpack the MinGW archive"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@rmdir /s /q "%dependency_path%"
|
|
|
+@echo.%compiler_path%
|
|
|
+@endlocal
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:repository - Gets the MinGW-builds repository
|
|
|
+:: %1 - The return variable for the repository file path
|
|
|
+@verify other 2>nul
|
|
|
+@setlocal EnableDelayedExpansion
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to enable extensions"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@set "var=%~1"
|
|
|
+@if "%var%" == "" @exit /b 1
|
|
|
+@call :log 7
|
|
|
+@call :log 2 "Getting MinGW repository information"
|
|
|
+@set "url=http://downloads.sourceforge.net/project/mingw-w64/Toolchains targetting Win32/Personal Builds/mingw-builds/installer/repository.txt"
|
|
|
+@call :log 6
|
|
|
+@call :log 1 "Downloading MinGW repository"
|
|
|
+@set "file_path=%dependency_path%\mingw-repository.txt"
|
|
|
+@call :download "%url%" "%file_path%"
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to download the MinGW repository information"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@set "repository_path=%dependency_path%\repository.txt"
|
|
|
+@del "%repository_path%" 2>nul
|
|
|
+@for /f "delims=| tokens=1-6,*" %%a in (%file_path%) do @(
|
|
|
+ @set "version=%%~a"
|
|
|
+ @set "version=!version: =!"
|
|
|
+ @set "arch=%%~b"
|
|
|
+ @set "arch=!arch: =!"
|
|
|
+ @set "threading=%%~c"
|
|
|
+ @set "threading=!threading: =!"
|
|
|
+ @set "exceptions=%%~d"
|
|
|
+ @set "exceptions=!exceptions: =!"
|
|
|
+ @set "revision=%%~e"
|
|
|
+ @set "revision=!revision: =!"
|
|
|
+ @set "revision=!revision:rev=!"
|
|
|
+ @set "url=%%~f"
|
|
|
+ @set "url=!url:%%20= !"
|
|
|
+ @for /l %%a in (1,1,32) do @if "!url:~-1!" == " " set url=!url:~0,-1!
|
|
|
+ @echo !arch!^|!version!^|!threading!^|!exceptions!^|!revision!^|!url!>> "%repository_path%"
|
|
|
+)
|
|
|
+@del "%file_path%" 2>nul
|
|
|
+@endlocal & set "%var%=%repository_path%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:resolve - Gets the MinGW-builds repository
|
|
|
+:: %1 - The return variable for the MinGW slug
|
|
|
+:: %2 - The return variable for the MinGW URL
|
|
|
+:: %3 - The repository information to use
|
|
|
+:: %4 - Target architecture
|
|
|
+:: %5 - Version of MinGW to get [optional]
|
|
|
+:: %6 - Threading model [optional]
|
|
|
+:: %7 - Exception model [optional]
|
|
|
+:: %8 - Package revision [optional]
|
|
|
+@setlocal
|
|
|
+@set "slug_var=%~1"
|
|
|
+@if "%slug_var%" == "" @exit /b 1
|
|
|
+@set "url_var=%~2"
|
|
|
+@if "%url_var%" == "" @exit /b 1
|
|
|
+@set "repository=%~3"
|
|
|
+@if "%repository%" == "" @exit /b 1
|
|
|
+@set "arch=%~4"
|
|
|
+@if "%arch%" == "" @exit /b 1
|
|
|
+@call :resolve_version version "%repository%" "%arch%" "%~5"
|
|
|
+@if errorlevel 1 @exit /b 1
|
|
|
+@call :resolve_threading threading "%repository%" "%arch%" "%version%" "%~6"
|
|
|
+@if errorlevel 1 @exit /b 1
|
|
|
+@call :resolve_exceptions exceptions "%repository%" "%arch%" "%version%" "%threading%" "%~7"
|
|
|
+@if errorlevel 1 @exit /b 1
|
|
|
+@call :resolve_revision revision "%repository%" "%arch%" "%version%" "%threading%" "%exceptions%" "%~8"
|
|
|
+@if errorlevel 1 @exit /b 1
|
|
|
+@call :log 3 "Finding URL"
|
|
|
+@for /f "delims=| tokens=1-6" %%a in (%repository%) do @(
|
|
|
+ @if "%arch%" == "%%a" (
|
|
|
+ @if "%version%" == "%%b" (
|
|
|
+ @if "%threading%" == "%%c" (
|
|
|
+ @if "%exceptions%" == "%%d" (
|
|
|
+ @if "%revision%" == "%%e" (
|
|
|
+ @set "url=%%f"
|
|
|
+) ) ) ) ) )
|
|
|
+@if "%url%" == "" (
|
|
|
+ @call :log 0 "Failed to resolve URL"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@set slug=gcc-%version%-%arch%-%threading%-%exceptions%-rev%revision%
|
|
|
+@call :log 2 "Resolved slug: %slug%"
|
|
|
+@call :log 2 "Resolved url: %url%"
|
|
|
+@endlocal & set "%slug_var%=%slug%" & set "%url_var%=%url%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:unpack - Unpacks the MinGW archive
|
|
|
+:: %1 - The return variable name for the compiler path
|
|
|
+:: %2 - The filepath or URL of the archive
|
|
|
+:: %3 - The folder to unpack to
|
|
|
+@verify other 2>nul
|
|
|
+@setlocal EnableDelayedExpansion
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to enable extensions"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@set "var=%~1"
|
|
|
+@if "%var%" == "" @exit /b 1
|
|
|
+@set "archive_path=%~2"
|
|
|
+@if "%archive_path%" == "" @exit /b 1
|
|
|
+@set "folder_path=%~3"
|
|
|
+@if "%folder_path%" == "" @exit /b 1
|
|
|
+@set "compiler_path=%folder_path%\bin"
|
|
|
+@if exist "%compiler_path%" goto :unpack_done
|
|
|
+@call :log 7
|
|
|
+@call :log 2 "Unpacking MinGW archive"
|
|
|
+@set "http=%archive_path:~0,4%"
|
|
|
+@if "%http%" == "http" (
|
|
|
+ @set "url=%archive_path%"
|
|
|
+ @for /f %%a in ("!url: =-!") do @set "file_name=%%~na"
|
|
|
+ @for /f %%a in ("!url: =-!") do @set "file_ext=%%~xa"
|
|
|
+ @set "archive_path=%dependency_path%\!file_name!!file_ext!"
|
|
|
+ @if not exist "!archive_path!" (
|
|
|
+ @call :log 6
|
|
|
+ @call :log 1 "Downloading MinGW archive"
|
|
|
+ @call :download "!url!" "!archive_path!"
|
|
|
+ @if errorlevel 1 (
|
|
|
+ @del "!archive_path!" 2>nul
|
|
|
+ @call :log 0 "Failed to download: !file_name!!file_ext!"
|
|
|
+ @exit /b 1
|
|
|
+ )
|
|
|
+ )
|
|
|
+)
|
|
|
+@if not exist "%archive_path%" (
|
|
|
+ @call :log 0 "The archive did not exist to unpack: %archive_path%"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@for /f %%a in ("%archive_path: =-%") do @set "file_name=%%~na"
|
|
|
+@for /f %%a in ("%archive_path: =-%") do @set "file_ext=%%~xa"
|
|
|
+@call :log 6
|
|
|
+@call :log 1 "Unpacking MinGW %file_name%%file_ext%"
|
|
|
+@call :find_sevenzip sevenzip_executable
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Need 7zip to unpack the MinGW archive"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@call :iso8601 iso8601
|
|
|
+@for /f %%a in ("%folder_path%") do @set "tmp_path=%%~dpatmp-%iso8601%"
|
|
|
+@"%sevenzip_executable%" x -y "-o%tmp_path%" "%archive_path%" > nul
|
|
|
+@if errorlevel 1 (
|
|
|
+ @rmdir /s /q "%folder_path%"
|
|
|
+ @call :log 0 "Failed to unpack the MinGW archive"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@set "expected_path=%tmp_path%\mingw64"
|
|
|
+@if not exist "%expected_path%" (
|
|
|
+ @set "expected_path=%tmp_path%\mingw32"
|
|
|
+)
|
|
|
+@move /y "%expected_path%" "%folder_path%" > nul
|
|
|
+@if errorlevel 1 (
|
|
|
+ @rmdir /s /q "%tmp_path%" 2>nul
|
|
|
+ @call :log 0 "Failed to move MinGW folder"
|
|
|
+ @call :log 0 "%expected_path%"
|
|
|
+ @call :log 0 "%folder_path%"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@rmdir /s /q %tmp_path%
|
|
|
+@set "compiler_path=%folder_path%\bin"
|
|
|
+:unpack_done
|
|
|
+@if not exist "%compiler_path%\gcc.exe" (
|
|
|
+ @call :log 0 "Failed to find gcc: %compiler_path%"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@endlocal & set "%var%=%compiler_path%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:find_sevenzip - Finds (or downloads) the 7zip executable
|
|
|
+:: %1 - The return variable for the 7zip executable path
|
|
|
+@setlocal
|
|
|
+@set "var=%~1"
|
|
|
+@if "%var%" == "" @exit /b 1
|
|
|
+@call :log 2 "Finding 7zip"
|
|
|
+@call :find_in_path sevenzip_executable 7z.exe
|
|
|
+@if not errorlevel 1 goto :find_sevenzip_done
|
|
|
+@call :find_in_path sevenzip_executable 7za.exe
|
|
|
+@if not errorlevel 1 goto :find_sevenzip_done
|
|
|
+@set checksum=2FAC454A90AE96021F4FFC607D4C00F8
|
|
|
+@set "url=http://7-zip.org/a/7za920.zip"
|
|
|
+@for /f %%a in ("%url: =-%") do @set "file_name=%%~na"
|
|
|
+@for /f %%a in ("%url: =-%") do @set "file_ext=%%~xa"
|
|
|
+@set "archive_path=%dependency_path%\%file_name%%file_ext%"
|
|
|
+@if not exist "%archive_path%" (
|
|
|
+ @call :log 6
|
|
|
+ @call :log 1 "Downloading 7zip archive"
|
|
|
+ @call :download "%url%" "%archive_path%" %checksum%
|
|
|
+ @if errorlevel 1 (
|
|
|
+ @del "%archive_path%" 2>nul
|
|
|
+ @call :log 0 "Failed to download: %file_name%%file_ext%"
|
|
|
+ @exit /b 1
|
|
|
+ )
|
|
|
+)
|
|
|
+@set "sevenzip_path=%dependency_path%\sevenzip"
|
|
|
+@if not exist "%sevenzip_path%" (
|
|
|
+ @call :unzip "%archive_path%" "%sevenzip_path%"
|
|
|
+ @if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to unzip the7zip archive"
|
|
|
+ @exit /b 1
|
|
|
+ )
|
|
|
+)
|
|
|
+@set "sevenzip_executable=%sevenzip_path%\7za.exe"
|
|
|
+@if not exist "%sevenzip_executable%" (
|
|
|
+ @call :log 0 "Failed to find unpacked 7zip: %sevenzip_executable%"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+:find_sevenzip_done
|
|
|
+@call :log 2 "Found 7zip: %sevenzip_executable%"
|
|
|
+@endlocal & set "%var%=%sevenzip_executable%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:unzip - Unzips a .zip archive
|
|
|
+:: %1 - The archive to unzip
|
|
|
+:: %2 - The location to unzip to
|
|
|
+@setlocal
|
|
|
+@set "archive_path=%~1"
|
|
|
+@if "%archive_path%" == "" @exit /b 1
|
|
|
+@set "folder_path=%~2"
|
|
|
+@if "%folder_path%" == "" @exit /b 1
|
|
|
+@for /f %%a in ("%archive_path: =-%") do @set "file_name=%%~na"
|
|
|
+@for /f %%a in ("%archive_path: =-%") do @set "file_ext=%%~xa"
|
|
|
+@call :log 2 "Unzipping: %file_name%%file_ext%"
|
|
|
+@powershell ^
|
|
|
+ Add-Type -assembly "system.io.compression.filesystem"; ^
|
|
|
+ [io.compression.zipfile]::ExtractToDirectory(^
|
|
|
+ '%archive_path%', '%folder_path%') 2>nul
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to unzip: %file_name%%file_ext%"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@endlocal
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:resolve_version - Gets the version of the MinGW compiler
|
|
|
+:: %1 - The return variable for the version
|
|
|
+:: %2 - The repository information to use
|
|
|
+:: %3 - The architecture of the compiler
|
|
|
+:: %4 - Version of MinGW to get [optional]
|
|
|
+@verify other 2>nul
|
|
|
+@setlocal EnableDelayedExpansion
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to enable extensions"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@set "var=%~1"
|
|
|
+@if "%var%" == "" @exit /b 1
|
|
|
+@set "repository=%~2"
|
|
|
+@if "%repository%" == "" @exit /b 1
|
|
|
+@set "arch=%~3"
|
|
|
+@if "%arch%" == "" @exit /b 1
|
|
|
+@set "version=%~4"
|
|
|
+@if not "%version%" == "" goto :resolve_version_done
|
|
|
+:: Find the latest version
|
|
|
+@call :log 3 "Finding latest version"
|
|
|
+@set version=0.0.0
|
|
|
+@for /f "delims=| tokens=1-6" %%a in (%repository%) do @(
|
|
|
+ @if "%arch%" == "%%a" (
|
|
|
+ @call :version_compare result "%version%" "%%b"
|
|
|
+ @if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to compare versions: %version% %%a"
|
|
|
+ @exit /b 1
|
|
|
+ )
|
|
|
+ @if !result! lss 0 set version=%%b
|
|
|
+ )
|
|
|
+)
|
|
|
+:resolve_version_done
|
|
|
+@if "%version%" == "" (
|
|
|
+ @call :log 0 "Failed to resolve latest version number"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@call :log 2 "Resolved version: %version%"
|
|
|
+@endlocal & set "%var%=%version%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:resolve_threading - Gets the threading model of the MinGW compiler
|
|
|
+:: %1 - The return variable for the threading model
|
|
|
+:: %2 - The repository information to use
|
|
|
+:: %3 - The architecture of the compiler
|
|
|
+:: %4 - The version of the compiler
|
|
|
+:: %5 - threading model of MinGW to use [optional]
|
|
|
+@verify other 2>nul
|
|
|
+@setlocal EnableDelayedExpansion
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to enable extensions"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@set "var=%~1"
|
|
|
+@if "%var%" == "" @exit /b 1
|
|
|
+@set "repository=%~2"
|
|
|
+@if "%repository%" == "" @exit /b 1
|
|
|
+@set "arch=%~3"
|
|
|
+@if "%arch%" == "" @exit /b 1
|
|
|
+@set "version=%~4"
|
|
|
+@if "%version%" == "" @exit /b 1
|
|
|
+@set "threading=%~5"
|
|
|
+@if not "%threading%" == "" goto :resolve_threading_done
|
|
|
+@call :log 3 "Finding best threading model"
|
|
|
+@for /f "delims=| tokens=1-6" %%a in (%repository%) do @(
|
|
|
+ @if "%arch%" == "%%a" (
|
|
|
+ @if "%version%" == "%%b" (
|
|
|
+ @if not defined threading (
|
|
|
+ @set "threading=%%c"
|
|
|
+ )
|
|
|
+ @if "%%c" == "posix" (
|
|
|
+ @set "threading=%%c"
|
|
|
+) ) ) )
|
|
|
+:resolve_threading_done
|
|
|
+@if "%threading%" == "" (
|
|
|
+ @call :log 0 "Failed to resolve the best threading model"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@call :log 2 "Resolved threading model: %threading%"
|
|
|
+@endlocal & set "%var%=%threading%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:resolve_exceptions - Gets the exception model of the MinGW compiler
|
|
|
+:: %1 - The return variable for the exception model
|
|
|
+:: %2 - The repository information to use
|
|
|
+:: %3 - The architecture of the compiler
|
|
|
+:: %4 - The version of the compiler
|
|
|
+:: %4 - The threading model of the compiler
|
|
|
+:: %5 - exception model of MinGW to use [optional]
|
|
|
+@verify other 2>nul
|
|
|
+@setlocal EnableDelayedExpansion
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to enable extensions"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@set "var=%~1"
|
|
|
+@if "%var%" == "" @exit /b 1
|
|
|
+@set "repository=%~2"
|
|
|
+@if "%repository%" == "" @exit /b 1
|
|
|
+@set "arch=%~3"
|
|
|
+@if "%arch%" == "" @exit /b 1
|
|
|
+@set "version=%~4"
|
|
|
+@if "%version%" == "" @exit /b 1
|
|
|
+@set "threading=%~5"
|
|
|
+@if "%threading%" == "" @exit /b 1
|
|
|
+@set "exceptions=%~6"
|
|
|
+@if not "%exceptions%" == "" goto :resolve_exceptions_done
|
|
|
+@call :log 3 "Finding best exception model"
|
|
|
+@for /f "delims=| tokens=1-6" %%a in (%repository%) do @(
|
|
|
+ @if "%arch%" == "%%a" (
|
|
|
+ @if "%version%" == "%%b" (
|
|
|
+ @if "%threading%" == "%%c" (
|
|
|
+ @if not defined exceptions (
|
|
|
+ @set "exceptions=%%d"
|
|
|
+ )
|
|
|
+ @if "%%d" == "dwarf" (
|
|
|
+ @set "exceptions=%%d"
|
|
|
+ )
|
|
|
+ @if "%%d" == "seh" (
|
|
|
+ @set "exceptions=%%d"
|
|
|
+) ) ) ) )
|
|
|
+:resolve_exceptions_done
|
|
|
+@if "%exceptions%" == "" (
|
|
|
+ @call :log 0 "Failed to resolve the best exception model"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@call :log 2 "Resolved exception model: %exceptions%"
|
|
|
+@endlocal & set "%var%=%exceptions%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:resolve_revision - Gets the revision of the MinGW compiler
|
|
|
+:: %1 - The return variable for the revision
|
|
|
+:: %2 - The repository information to use
|
|
|
+:: %3 - The architecture of the compiler
|
|
|
+:: %4 - The version of the compiler
|
|
|
+:: %4 - The threading model of the compiler
|
|
|
+:: %4 - The exception model of the compiler
|
|
|
+:: %5 - revision of the MinGW package to use [optional]
|
|
|
+@verify other 2>nul
|
|
|
+@setlocal EnableDelayedExpansion
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to enable extensions"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@set "var=%~1"
|
|
|
+@if "%var%" == "" @exit /b 1
|
|
|
+@set "repository=%~2"
|
|
|
+@if "%repository%" == "" @exit /b 1
|
|
|
+@set "arch=%~3"
|
|
|
+@if "%arch%" == "" @exit /b 1
|
|
|
+@set "version=%~4"
|
|
|
+@if "%version%" == "" @exit /b 1
|
|
|
+@set "threading=%~5"
|
|
|
+@if "%threading%" == "" @exit /b 1
|
|
|
+@set "exceptions=%~6"
|
|
|
+@if "%exceptions%" == "" @exit /b 1
|
|
|
+@set "revision=%~7"
|
|
|
+@if not "%revision%" == "" goto :resolve_revision_done
|
|
|
+@call :log 3 "Finding latest revision"
|
|
|
+@for /f "delims=| tokens=1-6" %%a in (%repository%) do @(
|
|
|
+ @if "%arch%" == "%%a" (
|
|
|
+ @if "%version%" == "%%b" (
|
|
|
+ @if "%threading%" == "%%c" (
|
|
|
+ @if "%exceptions%" == "%%d" (
|
|
|
+ @if "%%e" gtr "%revision%" (
|
|
|
+ @set "revision=%%e"
|
|
|
+) ) ) ) ) )
|
|
|
+:resolve_revision_done
|
|
|
+@if "%revision%" == "" (
|
|
|
+ @call :log 0 "Failed to resolve latest revision"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@call :log 2 "Resolved revision: %revision%"
|
|
|
+@endlocal & set "%var%=%revision%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:version_compare - Compares two semantic version numbers
|
|
|
+:: %1 - The return variable:
|
|
|
+:: - < 0 : if %2 < %3
|
|
|
+:: - 0 : if %2 == %3
|
|
|
+:: - > 0 : if %2 > %3
|
|
|
+:: %2 - The first version to compare
|
|
|
+:: %3 - The second version to compare
|
|
|
+@setlocal
|
|
|
+@set "var=%~1"
|
|
|
+@if "%var%" == "" @exit /b 1
|
|
|
+@set "lhs=%~2"
|
|
|
+@if "%lhs%" == "" @exit /b 1
|
|
|
+@set "rhs=%~3"
|
|
|
+@if "%lhs%" == "" @exit /b 1
|
|
|
+@set result=0
|
|
|
+@for /f "delims=. tokens=1-6" %%a in ("%lhs%.%rhs%") do @(
|
|
|
+ @if %%a lss %%d (
|
|
|
+ set result=-1
|
|
|
+ goto :version_compare_done
|
|
|
+ ) else (
|
|
|
+ @if %%a gtr %%d (
|
|
|
+ set result=1
|
|
|
+ goto :version_compare_done
|
|
|
+ ) else (
|
|
|
+ @if %%b lss %%e (
|
|
|
+ set result=-1
|
|
|
+ goto :version_compare_done
|
|
|
+ ) else (
|
|
|
+ @if %%b gtr %%e (
|
|
|
+ set result=1
|
|
|
+ goto :version_compare_done
|
|
|
+ ) else (
|
|
|
+ @if %%c lss %%f (
|
|
|
+ set result=-1
|
|
|
+ goto :version_compare_done
|
|
|
+ ) else (
|
|
|
+ @if %%c gtr %%f (
|
|
|
+ set result=1
|
|
|
+ goto :version_compare_done
|
|
|
+ )
|
|
|
+ )
|
|
|
+ )
|
|
|
+ )
|
|
|
+ )
|
|
|
+ )
|
|
|
+)
|
|
|
+:version_compare_done
|
|
|
+@endlocal & set "%var%=%result%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:print_usage - Prints the usage of the script
|
|
|
+:: %* - message to print, each argument on it's own line
|
|
|
+@setlocal
|
|
|
+@for %%a in (%*) do @echo.%%~a
|
|
|
+@echo.
|
|
|
+@echo.build [/?][/v[v...]^|/q][/version][/arch a][/threading t]
|
|
|
+@echo. [/exceptions e][/revision r] location
|
|
|
+@echo.
|
|
|
+@echo. /version v The version of MinGW to download
|
|
|
+@echo. /arch a The target architecture [i686^|x86_64]
|
|
|
+@echo. /threading t
|
|
|
+@echo. Threading model to use [posix^|win32]
|
|
|
+@echo. /exceptions e
|
|
|
+@echo. Exception model to use [sjlj^|seh^|dwarf]
|
|
|
+@echo. /revision e Revision of the release to use
|
|
|
+@echo. /v Sets the output to be more verbose
|
|
|
+@echo. /v[v...] Extra verbosity, /vv, /vvv, etc
|
|
|
+@echo. /q Quiets the output
|
|
|
+@echo. /? Shows this usage message
|
|
|
+@echo.
|
|
|
+@endlocal
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:script_source - Determines if the script was ran from the cli or explorer
|
|
|
+:: %1 - The return variable [cli|explorer]
|
|
|
+@verify other 2>nul
|
|
|
+@setlocal EnableDelayedExpansion
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to enable extensions"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@call :log 3 "Attempting to detect the script source"
|
|
|
+@echo "The invocation command was: '%cmdcmdline%'" >> %log_path%
|
|
|
+@for /f "tokens=1-3,*" %%a in ("%cmdcmdline%") do @(
|
|
|
+ set cmd=%%~a
|
|
|
+ set arg1=%%~b
|
|
|
+ set arg2=%%~c
|
|
|
+ set rest=%%~d
|
|
|
+)
|
|
|
+@set quote="
|
|
|
+@if "!arg2:~0,1!" equ "!quote!" (
|
|
|
+ if "!arg2:~-1!" neq "!quote!" (
|
|
|
+ set "arg2=!arg2:~1!"
|
|
|
+ )
|
|
|
+)
|
|
|
+@call :log 4 "cmd = %cmd%"
|
|
|
+@call :log 4 "arg1 = %arg1%"
|
|
|
+@call :log 4 "arg2 = %arg2%"
|
|
|
+@call :log 4 "rest = %rest%"
|
|
|
+@call :log 4 "src = %~f0"
|
|
|
+@if /i "%arg2%" == "call" (
|
|
|
+ set script_source=cli
|
|
|
+) else (
|
|
|
+ @if /i "%arg1%" == "/c" (
|
|
|
+ set script_source=explorer
|
|
|
+ ) else (
|
|
|
+ set script_source=cli
|
|
|
+ )
|
|
|
+)
|
|
|
+@call :log 3 "The script was invoked from %script_source%"
|
|
|
+@endlocal & set "%~1=%script_source%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:architecture - Finds the system architecture
|
|
|
+:: %1 - The return variable [i686|x86_64]
|
|
|
+@setlocal
|
|
|
+@call :log 3 "Determining the processor architecture"
|
|
|
+@set "key=HKLM\System\CurrentControlSet\Control\Session Manager\Environment"
|
|
|
+@set "var=PROCESSOR_ARCHITECTURE"
|
|
|
+@for /f "skip=2 tokens=2,*" %%a in ('reg query "%key%" /v "%var%"') do @set "arch=%%b"
|
|
|
+@if "%arch%" == "AMD64" set arch=x86_64
|
|
|
+@if "%arch%" == "x64" set arch=i686
|
|
|
+@call :log 4 "arch = %arch%"
|
|
|
+@endlocal & set "%~1=%arch%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:md5 - Gets the MD5 checksum for a file
|
|
|
+:: %1 - The hash
|
|
|
+:: %2 - The file path
|
|
|
+@setlocal
|
|
|
+@set "var=%~1"
|
|
|
+@set "file_path=%~2"
|
|
|
+@if "%var%" == "" @exit /b 1
|
|
|
+@if "%file_path%" == "" @exit /b 1
|
|
|
+@if not exist "%file_path%" @exit /b 1
|
|
|
+@for /f "skip=3 tokens=1,*" %%a in ('powershell Get-FileHash -Algorithm MD5 "'%file_path%'"') do @set hash=%%b
|
|
|
+@if not defined hash (
|
|
|
+ @call :log 6
|
|
|
+ @call :log 0 "Failed to get MD5 hash for %file_path%"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@endlocal & set "%var%=%hash: =%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:windows_version - Checks the windows version
|
|
|
+:: %1 - The windows version
|
|
|
+:: %2 - The major version number return variable
|
|
|
+:: %3 - The minor version number return variable
|
|
|
+:: %4 - The revision version number return variable
|
|
|
+@setlocal
|
|
|
+@call :log 3 "Retrieving the Windows version"
|
|
|
+@for /f "tokens=2 delims=[]" %%x in ('ver') do @set win_ver=%%x
|
|
|
+@set win_ver=%win_ver:Version =%
|
|
|
+@set win_ver_major=%win_ver:~0,1%
|
|
|
+@set win_ver_minor=%win_ver:~2,1%
|
|
|
+@set win_ver_rev=%win_ver:~4%
|
|
|
+@call :log 4 "win_ver = %win_ver%"
|
|
|
+@endlocal & set "%~1=%win_ver%" ^
|
|
|
+ & set "%~2=%win_ver_major%" ^
|
|
|
+ & set "%~3=%win_ver_minor%" ^
|
|
|
+ & set "%~4=%win_ver_rev%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:find_in_path - Finds a program of file in the PATH
|
|
|
+:: %1 - return variable of the file path
|
|
|
+@setlocal
|
|
|
+@set "var=%~1"
|
|
|
+@if "%var%" == "" @exit /b 1
|
|
|
+@set "file=%~2"
|
|
|
+@if "%file%" == "" @exit /b 1
|
|
|
+@call :log 3 "Searching PATH for %file%"
|
|
|
+@for %%x in ("%file%") do @set "file_path=%%~f$PATH:x"
|
|
|
+@if not defined file_path @exit /b 1
|
|
|
+@endlocal & set "%var%=%file_path%"
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:log_append - Appends another file into the current logging file
|
|
|
+:: %1 - the file_path to the file to concatenate
|
|
|
+@setlocal
|
|
|
+@set "file_path=%~1"
|
|
|
+@if "%file_path%" == "" @exit /b 1
|
|
|
+@call :log 3 "Appending to log: %file_path%"
|
|
|
+@call :iso8601 iso8601
|
|
|
+@set temp_log=%temp%\append-%iso8601%.log
|
|
|
+@call :log 4 "Using temp file %temp_log%"
|
|
|
+@type "%log_path%" "%file_path%" > "%temp_log%" 2>nul
|
|
|
+@move /y "%temp_log%" "%log_path%" 1>nul
|
|
|
+@del "%file_path% 2>nul
|
|
|
+@del "%temp_log% 2>nul
|
|
|
+@endlocal
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:iso8601 - Returns the current time in ISO8601 format
|
|
|
+:: %1 - the return variable
|
|
|
+:: %2 - format [extended|basic*]
|
|
|
+:: iso8601 - contains the resulting timestamp
|
|
|
+@setlocal
|
|
|
+@wmic Alias /? >NUL 2>&1 || @exit /b 1
|
|
|
+@set "var=%~1"
|
|
|
+@if "%var%" == "" @exit /b 1
|
|
|
+@set "format=%~2"
|
|
|
+@if "%format%" == "" set format=basic
|
|
|
+@for /F "skip=1 tokens=1-6" %%g IN ('wmic Path Win32_UTCTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') do @(
|
|
|
+ @if "%%~l"=="" goto :iso8601_done
|
|
|
+ @set "yyyy=%%l"
|
|
|
+ @set "mm=00%%j"
|
|
|
+ @set "dd=00%%g"
|
|
|
+ @set "hour=00%%h"
|
|
|
+ @set "minute=00%%i"
|
|
|
+ @set "seconds=00%%k"
|
|
|
+)
|
|
|
+:iso8601_done
|
|
|
+@set mm=%mm:~-2%
|
|
|
+@set dd=%dd:~-2%
|
|
|
+@set hour=%hour:~-2%
|
|
|
+@set minute=%minute:~-2%
|
|
|
+@set seconds=%seconds:~-2%
|
|
|
+@if /i [%format%] == [extended] (
|
|
|
+ set iso8601=%yyyy%-%mm%-%dd%T%hour%:%minute%:%seconds%Z
|
|
|
+) else (
|
|
|
+ if /i [%format%] == [basic] (
|
|
|
+ set iso8601=%yyyy%%mm%%dd%T%hour%%minute%%seconds%Z
|
|
|
+ ) else (
|
|
|
+ @exit /b 1
|
|
|
+ )
|
|
|
+)
|
|
|
+@set iso8601=%iso8601: =0%
|
|
|
+@endlocal & set %var%=%iso8601%
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:verbosity - Processes the verbosity parameter '/v[v...]
|
|
|
+:: %1 - verbosity given on the command line
|
|
|
+:: logging_level - set to the number of v's
|
|
|
+@setlocal
|
|
|
+@set logging_level=0
|
|
|
+@set verbosity=%~1
|
|
|
+:verbosity_loop
|
|
|
+@set verbosity=%verbosity:~1%
|
|
|
+@if not [%verbosity%] == [] @(
|
|
|
+ set /a "logging_level=logging_level+1"
|
|
|
+ goto verbosity_loop
|
|
|
+)
|
|
|
+@endlocal & set logging_level=%logging_level%
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:log - Logs a message, depending on verbosity
|
|
|
+:: %1 - level
|
|
|
+:: [0-4] for CLI logging
|
|
|
+:: [5-9] for GUI logging
|
|
|
+:: %2 - message to print
|
|
|
+@setlocal
|
|
|
+@set "level=%~1"
|
|
|
+@set "msg=%~2"
|
|
|
+@if "%log_folder%" == "" (
|
|
|
+ echo Logging was used to early in the script, log_folder isn't set yet
|
|
|
+ goto :eof
|
|
|
+)
|
|
|
+@if "%log_path%" == "" (
|
|
|
+ echo Logging was used to early in the script, log_path isn't set yet
|
|
|
+ goto :eof
|
|
|
+)
|
|
|
+@if not exist "%log_folder%" mkdir "%log_folder%"
|
|
|
+@if not exist "%log_path%" echo. 1>nul 2>"%log_path%"
|
|
|
+@echo.%msg% >> "%log_path%"
|
|
|
+@if %level% geq 5 (
|
|
|
+ @if [%script_source%] == [explorer] (
|
|
|
+ set /a "level=level-5"
|
|
|
+ ) else (
|
|
|
+ @goto :eof
|
|
|
+ )
|
|
|
+)
|
|
|
+@if "%logging_level%" == "" (
|
|
|
+ echo Logging was used to early in the script, logging_level isn't set yet
|
|
|
+ goto :eof
|
|
|
+)
|
|
|
+@if %logging_level% geq %level% echo.%msg% 1>&2
|
|
|
+@endlocal
|
|
|
+@goto :eof
|
|
|
+
|
|
|
+:download - Downloads a file from the internet
|
|
|
+:: %1 - the url of the file to download
|
|
|
+:: %2 - the file to download to
|
|
|
+:: %3 - the MD5 checksum of the file (optional)
|
|
|
+@setlocal EnableDelayedExpansion
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :print_usage "Failed to enable extensions"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@set "url=%~1"
|
|
|
+@set "file_path=%~2"
|
|
|
+@set "checksum=%~3"
|
|
|
+@for %%a in (%file_path%) do @set dir_path=%%~dpa
|
|
|
+@for %%a in (%file_path%) do @set file_name=%%~nxa
|
|
|
+@if "%url%" == "" @exit /b 1
|
|
|
+@if "%file_path%" == "" @exit /b 1
|
|
|
+@if "%dir_path%" == "" @exit /b 1
|
|
|
+@if "%file_name%" == "" @exit /b 1
|
|
|
+@if not exist "%dir_path%" mkdir "%dir_path%"
|
|
|
+@call :log 2 "Downloading %url%"
|
|
|
+@call :iso8601 iso8601
|
|
|
+@set "temp_path=%temp%\download-%iso8601%-%file_name%"
|
|
|
+@call :log 4 "Using temp file %temp_path%"
|
|
|
+@powershell Invoke-WebRequest "'%url%'" ^
|
|
|
+ -OutFile "'%temp_path%'" ^
|
|
|
+ -UserAgent [Microsoft.PowerShell.Commands.PSUserAgent]::IE ^
|
|
|
+ 1> nul 2> nul
|
|
|
+@if errorlevel 1 (
|
|
|
+ @call :log 0 "Failed to download %url%"
|
|
|
+ @exit /b 1
|
|
|
+)
|
|
|
+@if [%checksum%] neq [] (
|
|
|
+ @call :log 4 "Checking %checksum% against %temp_path%"
|
|
|
+ @call :md5 hash "%temp_path%"
|
|
|
+ if "!hash!" neq "%checksum%" (
|
|
|
+ @call :log 0 "Failed to match checksum: %temp_path%"
|
|
|
+ @call :log 0 "Hash : !hash!"
|
|
|
+ @call :log 0 "Checksum: %checksum%"
|
|
|
+ @exit /b 1
|
|
|
+ ) else (
|
|
|
+ @call :log 3 "Checksum matched: %temp_path%"
|
|
|
+ @call :log 3 "Hash : !hash!"
|
|
|
+ @call :log 3 "Checksum: %checksum%"
|
|
|
+ )
|
|
|
+)
|
|
|
+@call :log 4 "Renaming %temp_path% to %file_path%"
|
|
|
+@move /y "%temp_path%" "%file_path%" 1>nul
|
|
|
+@endlocal
|
|
|
+@goto :eof
|