From 45faf151c693b6f13f78926761caea6df7242024 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Fri, 28 Jan 2022 16:48:06 +0000 Subject: bpo-33125: Enables building traditional installer for Windows ARM64 (GH-30885) Also makes a few general improvements to the build process and removes some dead code. --- .azure-pipelines/windows-release.yml | 41 +++++++++-------- .azure-pipelines/windows-release/msi-steps.yml | 46 +++++++++++++++++-- .../windows-release/stage-publish-nugetorg.yml | 4 +- .../windows-release/stage-publish-pythonorg.yml | 5 ++- .../windows-release/stage-test-msi.yml | 8 ++-- .github/workflows/build_msi.yml | 8 ++++ .../2022-01-25-14-48-39.bpo-33125.5WyY_J.rst | 2 + PCbuild/openssl.props | 9 +++- PCbuild/tcltk.props | 1 + Tools/msi/appendpath/appendpath.wxs | 2 +- Tools/msi/build.bat | 23 +++++++--- Tools/msi/buildrelease.bat | 52 +++++++++++++++------- Tools/msi/bundle/Default.ARM64.xsl | 26 +++++++++++ Tools/msi/bundle/Default.thm | 10 ++--- Tools/msi/bundle/Default.wxl | 1 - .../bootstrap/PythonBootstrapperApplication.cpp | 34 ++++++++++++++ Tools/msi/bundle/bootstrap/pythonba.vcxproj | 11 +++-- Tools/msi/bundle/bundle.targets | 51 ++++++++++++++------- Tools/msi/bundle/bundle.wxs | 36 ++++++++++++--- Tools/msi/core/core.wxs | 2 +- Tools/msi/core/core_d.wxs | 2 +- Tools/msi/core/core_pdb.wxs | 2 +- Tools/msi/dev/dev.wxs | 2 +- Tools/msi/dev/dev_d.wxs | 2 +- Tools/msi/doc/doc.wxs | 2 +- Tools/msi/exe/exe.wxs | 2 +- Tools/msi/exe/exe_d.wxs | 2 +- Tools/msi/exe/exe_pdb.wxs | 2 +- Tools/msi/get_externals.bat | 2 +- Tools/msi/launcher/launcher.wxs | 2 +- Tools/msi/lib/lib.wxs | 2 +- Tools/msi/lib/lib_d.wxs | 2 +- Tools/msi/lib/lib_pdb.wxs | 2 +- Tools/msi/msi.props | 26 ++++++----- Tools/msi/msi.targets | 7 ++- Tools/msi/path/path.wxs | 2 +- Tools/msi/pip/pip.wxs | 2 +- Tools/msi/purge.py | 8 +++- Tools/msi/tcltk/tcltk.wxs | 2 +- Tools/msi/tcltk/tcltk_d.wxs | 2 +- Tools/msi/tcltk/tcltk_pdb.wxs | 2 +- Tools/msi/test/test.wxs | 2 +- Tools/msi/test/test_d.wxs | 2 +- Tools/msi/test/test_pdb.wxs | 2 +- Tools/msi/tools/tools.wxs | 2 +- Tools/msi/ucrt/ucrt.wxs | 2 +- Tools/msi/wix.props | 2 +- 47 files changed, 334 insertions(+), 127 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2022-01-25-14-48-39.bpo-33125.5WyY_J.rst create mode 100644 Tools/msi/bundle/Default.ARM64.xsl diff --git a/.azure-pipelines/windows-release.yml b/.azure-pipelines/windows-release.yml index 338c305..c038ccd 100644 --- a/.azure-pipelines/windows-release.yml +++ b/.azure-pipelines/windows-release.yml @@ -34,6 +34,10 @@ parameters: displayName: "Signature description" type: string default: 'Built: $(Build.BuildNumber)' +- name: DoARM64 + displayName: "Publish ARM64 build" + type: boolean + default: true - name: DoPGO displayName: "Run PGO" type: boolean @@ -64,25 +68,26 @@ parameters: default: '0' variables: - __RealSigningCertificate: 'Python Software Foundation' - ${{ if ne(parameters.GitRemote, '(Other)') }}: - GitRemote: ${{ parameters.GitRemote }} - ${{ else }}: - GitRemote: ${{ parameters.GitRemote_Other }} - SourceTag: ${{ parameters.SourceTag }} - DoPGO: ${{ parameters.DoPGO }} - ${{ if ne(parameters.SigningCertificate, 'Unsigned') }}: - SigningCertificate: ${{ parameters.SigningCertificate }} - SigningDescription: ${{ parameters.SigningDescription }} - DoLayout: ${{ parameters.DoLayout }} - DoMSIX: ${{ parameters.DoMSIX }} - DoNuget: ${{ parameters.DoNuget }} - DoEmbed: ${{ parameters.DoEmbed }} - DoMSI: ${{ parameters.DoMSI }} - DoPublish: ${{ parameters.DoPublish }} + __RealSigningCertificate: 'Python Software Foundation' + ${{ if ne(parameters.GitRemote, '(Other)') }}: + GitRemote: ${{ parameters.GitRemote }} + ${{ else }}: + GitRemote: ${{ parameters.GitRemote_Other }} + SourceTag: ${{ parameters.SourceTag }} + DoPGO: ${{ parameters.DoPGO }} + ${{ if ne(parameters.SigningCertificate, 'Unsigned') }}: + SigningCertificate: ${{ parameters.SigningCertificate }} + SigningDescription: ${{ parameters.SigningDescription }} + DoLayout: ${{ parameters.DoLayout }} + DoMSIX: ${{ parameters.DoMSIX }} + DoNuget: ${{ parameters.DoNuget }} + DoEmbed: ${{ parameters.DoEmbed }} + DoMSI: ${{ parameters.DoMSI }} + DoPublish: ${{ parameters.DoPublish }} + PublishARM64: ${{ parameters.DoARM64 }} # QUEUE TIME VARIABLES -# PyDotOrgUsername: '' -# PyDotOrgServer: '' +# PyDotOrgUsername: '' +# PyDotOrgServer: '' trigger: none pr: none diff --git a/.azure-pipelines/windows-release/msi-steps.yml b/.azure-pipelines/windows-release/msi-steps.yml index 307510a..ef98d56 100644 --- a/.azure-pipelines/windows-release/msi-steps.yml +++ b/.azure-pipelines/windows-release/msi-steps.yml @@ -46,6 +46,20 @@ steps: targetPath: $(Build.BinariesDirectory)\amd64 - task: DownloadPipelineArtifact@1 + displayName: 'Download artifact: bin_arm64' + condition: and(succeeded(), eq(variables['PublishARM64'], 'true')) + inputs: + artifactName: bin_arm64 + targetPath: $(Build.BinariesDirectory)\arm64 + + - task: DownloadPipelineArtifact@1 + displayName: 'Download artifact: bin_arm64_d' + condition: and(succeeded(), eq(variables['PublishARM64'], 'true')) + inputs: + artifactName: bin_arm64_d + targetPath: $(Build.BinariesDirectory)\arm64 + + - task: DownloadPipelineArtifact@1 displayName: 'Download artifact: tcltk_lib_win32' inputs: artifactName: tcltk_lib_win32 @@ -84,12 +98,12 @@ steps: - script: | %MSBUILD% Tools\msi\bundle\releaselocal.wixproj /t:Rebuild /p:RebuildAll=true - %MSBUILD% Tools\msi\bundle\releaseweb.wixproj /t:Rebuild /p:RebuildAll=false displayName: 'Build win32 installer' env: Platform: x86 Py_OutDir: $(Build.BinariesDirectory) PYTHON: $(Build.BinariesDirectory)\win32\python.exe + PythonForBuild: $(Build.BinariesDirectory)\win32\python.exe PYTHONHOME: $(Build.SourcesDirectory) TclTkLibraryDir: $(Build.BinariesDirectory)\tcltk_lib_win32 BuildForRelease: true @@ -97,19 +111,32 @@ steps: - script: | %MSBUILD% Tools\msi\bundle\releaselocal.wixproj /t:Rebuild /p:RebuildAll=true - %MSBUILD% Tools\msi\bundle\releaseweb.wixproj /t:Rebuild /p:RebuildAll=false displayName: 'Build amd64 installer' env: Platform: x64 Py_OutDir: $(Build.BinariesDirectory) PYTHON: $(Build.BinariesDirectory)\amd64\python.exe + PythonForBuild: $(Build.BinariesDirectory)\amd64\python.exe PYTHONHOME: $(Build.SourcesDirectory) TclTkLibraryDir: $(Build.BinariesDirectory)\tcltk_lib_amd64 BuildForRelease: true SuppressMinGWLib: true + - script: | + %MSBUILD% Tools\msi\bundle\releaselocal.wixproj /t:Rebuild /p:RebuildAll=true + displayName: 'Build arm64 installer' + condition: and(succeeded(), eq(variables['PublishARM64'], 'true')) + env: + Platform: ARM64 + Py_OutDir: $(Build.BinariesDirectory) + PYTHON: $(Build.BinariesDirectory)\win32\python.exe + PythonForBuild: $(Build.BinariesDirectory)\win32\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + BuildForRelease: true + SuppressMinGWLib: true + - task: CopyFiles@2 - displayName: 'Assemble artifact: msi (1/2)' + displayName: 'Assemble artifact: msi (win32)' inputs: sourceFolder: $(Build.BinariesDirectory)\win32\en-us targetFolder: $(Build.ArtifactStagingDirectory)\msi\win32 @@ -119,7 +146,7 @@ steps: *.exe - task: CopyFiles@2 - displayName: 'Assemble artifact: msi (2/2)' + displayName: 'Assemble artifact: msi (amd64)' inputs: sourceFolder: $(Build.BinariesDirectory)\amd64\en-us targetFolder: $(Build.ArtifactStagingDirectory)\msi\amd64 @@ -128,6 +155,17 @@ steps: *.cab *.exe + - task: CopyFiles@2 + displayName: 'Assemble artifact: msi (arm64)' + condition: and(succeeded(), eq(variables['PublishARM64'], 'true')) + inputs: + sourceFolder: $(Build.BinariesDirectory)\arm64\en-us + targetFolder: $(Build.ArtifactStagingDirectory)\msi\arm64 + contents: | + *.msi + *.cab + *.exe + - task: PublishPipelineArtifact@0 displayName: 'Publish MSI' inputs: diff --git a/.azure-pipelines/windows-release/stage-publish-nugetorg.yml b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml index 38f6772..a8855f0 100644 --- a/.azure-pipelines/windows-release/stage-publish-nugetorg.yml +++ b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml @@ -36,9 +36,9 @@ jobs: - powershell: 'gci pythonarm*.nupkg | %{ Write-Host "Not publishing: $($_.Name)"; gi $_ } | del' - displayName: 'Prevent publishing ARM/ARM64 packages' + displayName: 'Prevent publishing ARM64 packages' workingDirectory: '$(Build.BinariesDirectory)\nuget' - condition: and(succeeded(), not(variables['PublishArmPackages'])) + condition: and(succeeded(), eq(variables['PublishARM64'], 'true')) - task: NuGetCommand@2 displayName: Push packages diff --git a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml index ef95572..be4ef9e 100644 --- a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml +++ b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml @@ -77,10 +77,11 @@ jobs: downloadPath: $(Build.BinariesDirectory) + # Note that ARM64 MSIs are skipped at build when this option is specified - powershell: 'gci *embed-arm*.zip | %{ Write-Host "Not publishing: $($_.Name)"; gi $_ } | del' - displayName: 'Prevent publishing ARM/ARM64 packages' + displayName: 'Prevent publishing ARM64 packages' workingDirectory: '$(Build.BinariesDirectory)\embed' - condition: and(succeeded(), not(variables['PublishArmPackages'])) + condition: and(succeeded(), eq(variables['PublishARM64'], 'true')) - template: ./gpg-sign.yml diff --git a/.azure-pipelines/windows-release/stage-test-msi.yml b/.azure-pipelines/windows-release/stage-test-msi.yml index 4b02f47..a471d05 100644 --- a/.azure-pipelines/windows-release/stage-test-msi.yml +++ b/.azure-pipelines/windows-release/stage-test-msi.yml @@ -11,19 +11,19 @@ jobs: strategy: matrix: win32_User: - ExeMatch: 'python-[\dabrc.]+-webinstall\.exe' + ExeMatch: 'python-[\dabrc.]+\.exe' Logs: $(Build.ArtifactStagingDirectory)\logs\win32_User InstallAllUsers: 0 win32_Machine: - ExeMatch: 'python-[\dabrc.]+-webinstall\.exe' + ExeMatch: 'python-[\dabrc.]+\.exe' Logs: $(Build.ArtifactStagingDirectory)\logs\win32_Machine InstallAllUsers: 1 amd64_User: - ExeMatch: 'python-[\dabrc.]+-amd64-webinstall\.exe' + ExeMatch: 'python-[\dabrc.]+-amd64\.exe' Logs: $(Build.ArtifactStagingDirectory)\logs\amd64_User InstallAllUsers: 0 amd64_Machine: - ExeMatch: 'python-[\dabrc.]+-amd64-webinstall\.exe' + ExeMatch: 'python-[\dabrc.]+-amd64\.exe' Logs: $(Build.ArtifactStagingDirectory)\logs\amd64_Machine InstallAllUsers: 1 diff --git a/.github/workflows/build_msi.yml b/.github/workflows/build_msi.yml index 476a0b1..6e989b2 100644 --- a/.github/workflows/build_msi.yml +++ b/.github/workflows/build_msi.yml @@ -37,3 +37,11 @@ jobs: - uses: actions/checkout@v2 - name: Build CPython installer run: .\Tools\msi\build.bat -x64 + + build_win_arm64: + name: 'Windows (ARM64) Installer' + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: Build CPython installer + run: .\Tools\msi\build.bat -arm64 diff --git a/Misc/NEWS.d/next/Windows/2022-01-25-14-48-39.bpo-33125.5WyY_J.rst b/Misc/NEWS.d/next/Windows/2022-01-25-14-48-39.bpo-33125.5WyY_J.rst new file mode 100644 index 0000000..54811db --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-01-25-14-48-39.bpo-33125.5WyY_J.rst @@ -0,0 +1,2 @@ +The traditional EXE/MSI based installer for Windows is now available for +ARM64 diff --git a/PCbuild/openssl.props b/PCbuild/openssl.props index a7e1679..6081d3c 100644 --- a/PCbuild/openssl.props +++ b/PCbuild/openssl.props @@ -13,6 +13,7 @@ <_DLLSuffix>-1_1 <_DLLSuffix Condition="$(Platform) == 'ARM'">$(_DLLSuffix)-arm <_DLLSuffix Condition="$(Platform) == 'ARM64'">$(_DLLSuffix)-arm64 + $(_DLLSuffix) <_SSLDLL Include="$(opensslOutDir)\libcrypto$(_DLLSuffix).dll" /> @@ -20,10 +21,14 @@ <_SSLDLL Include="$(opensslOutDir)\libssl$(_DLLSuffix).dll" /> <_SSLDLL Include="$(opensslOutDir)\libssl$(_DLLSuffix).pdb" /> - + - + \ No newline at end of file diff --git a/PCbuild/tcltk.props b/PCbuild/tcltk.props index 16dc35d..72cffc3 100644 --- a/PCbuild/tcltk.props +++ b/PCbuild/tcltk.props @@ -29,6 +29,7 @@ $(tcltkDir)lib\tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).lib;$(tcltkDir)lib\tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib IX86 AMD64 + ARM64 TCL_MAJOR_VERSION=$(TclMajorVersion) TCL_MINOR_VERSION=$(TclMinorVersion) TCL_PATCH_LEVEL=$(TclPatchLevel) TCL_MAJOR=$(TclMajorVersion) TCL_MINOR=$(TclMinorVersion) TCL_PATCH=$(TclPatchLevel) TK_MAJOR_VERSION=$(TkMajorVersion) TK_MINOR_VERSION=$(TkMinorVersion) TK_PATCH_LEVEL=$(TkPatchLevel) diff --git a/Tools/msi/appendpath/appendpath.wxs b/Tools/msi/appendpath/appendpath.wxs index b972f61..e8d7a9d 100644 --- a/Tools/msi/appendpath/appendpath.wxs +++ b/Tools/msi/appendpath/appendpath.wxs @@ -1,7 +1,7 @@  - + diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat index 532cebc..755c887 100644 --- a/Tools/msi/build.bat +++ b/Tools/msi/build.bat @@ -5,6 +5,7 @@ set PCBUILD=%D%..\..\PCbuild\ set BUILDX86= set BUILDX64= +set BUILDARM64= set BUILDDOC= set BUILDTEST= set BUILDPACK= @@ -14,22 +15,23 @@ set REBUILD= if "%~1" EQU "-h" goto Help if "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts if "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if "%~1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts if "%~1" EQU "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts if "%~1" EQU "--test-marker" (set BUILDTEST=--test-marker) && shift && goto CheckOpts if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts -if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) +if not defined BUILDX86 if not defined BUILDX64 if not defined BUILDARM64 (set BUILDX86=1) && (set BUILDX64=1) call "%D%get_externals.bat" call "%PCBUILD%find_msbuild.bat" %MSBUILD% if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) if defined BUILDX86 ( - call "%PCBUILD%build.bat" -d -e %REBUILD% %BUILDTEST% + call "%PCBUILD%build.bat" -p Win32 -d -e %REBUILD% %BUILDTEST% if errorlevel 1 goto :eof - call "%PCBUILD%build.bat" -e %REBUILD% %BUILDTEST% + call "%PCBUILD%build.bat" -p Win32 -e %REBUILD% %BUILDTEST% if errorlevel 1 goto :eof ) if defined BUILDX64 ( @@ -38,6 +40,12 @@ if defined BUILDX64 ( call "%PCBUILD%build.bat" -p x64 -e %REBUILD% %BUILDTEST% if errorlevel 1 goto :eof ) +if defined BUILDARM64 ( + call "%PCBUILD%build.bat" -p ARM64 -d -e %REBUILD% %BUILDTEST% + if errorlevel 1 goto :eof + call "%PCBUILD%build.bat" -p ARM64 -e %REBUILD% %BUILDTEST% + if errorlevel 1 goto :eof +) if defined BUILDDOC ( call "%PCBUILD%..\Doc\make.bat" htmlhelp @@ -59,21 +67,26 @@ if defined REBUILD ( ) if defined BUILDX86 ( - %MSBUILD% %BUILD_CMD% + %MSBUILD% /p:Platform=x86 %BUILD_CMD% if errorlevel 1 goto :eof ) if defined BUILDX64 ( %MSBUILD% /p:Platform=x64 %BUILD_CMD% if errorlevel 1 goto :eof ) +if defined BUILDARM64 ( + %MSBUILD% /p:Platform=ARM64 %BUILD_CMD% + if errorlevel 1 goto :eof +) exit /B 0 :Help -echo build.bat [-x86] [-x64] [--doc] [-h] [--test-marker] [--pack] [-r] +echo build.bat [-x86] [-x64] [-arm64] [--doc] [-h] [--test-marker] [--pack] [-r] echo. echo -x86 Build x86 installers echo -x64 Build x64 installers +echo -ARM64 Build ARM64 installers echo --doc Build CHM documentation echo --test-marker Build with test markers echo --no-test-marker Build without test markers (default) diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index 4fbaf2c..722298f 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -34,6 +34,7 @@ set EXTERNALS=%D%..\..\externals\windows-installer\ set BUILDX86= set BUILDX64= +set BUILDARM64= set TARGET=Rebuild set TESTTARGETDIR= set PGO=-m test -q --pgo @@ -58,6 +59,7 @@ if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts if "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts if "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if "%1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts @@ -66,7 +68,7 @@ if "%1" EQU "--skip-msi" (set BUILDMSI=) && shift && goto CheckOpts if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1 -if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) +if not defined BUILDX86 if not defined BUILDX64 if not defined BUILDARM64 (set BUILDX86=1) && (set BUILDX64=1) if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc" if not exist "%GIT%" echo Cannot find Git on PATH && exit /B 1 @@ -83,14 +85,6 @@ call "%D%..\..\doc\make.bat" htmlhelp if errorlevel 1 goto :eof :skipdoc -where dlltool /q && goto skipdlltoolsearch -set _DLLTOOL_PATH= -where /R "%EXTERNALS%\" dlltool > "%TEMP%\dlltool.loc" 2> nul && set /P _DLLTOOL_PATH= < "%TEMP%\dlltool.loc" & del "%TEMP%\dlltool.loc" -if not exist "%_DLLTOOL_PATH%" echo Cannot find binutils on PATH or in external && exit /B 1 -for %%f in (%_DLLTOOL_PATH%) do set PATH=%PATH%;%%~dpf -set _DLLTOOL_PATH= -:skipdlltoolsearch - if defined BUILDX86 ( call :build x86 if errorlevel 1 exit /B @@ -101,6 +95,11 @@ if defined BUILDX64 ( if errorlevel 1 exit /B ) +if defined BUILDARM64 ( + call :build ARM64 + if errorlevel 1 exit /B +) + if defined TESTTARGETDIR ( call "%D%testrelease.bat" -t "%TESTTARGETDIR%" ) @@ -117,12 +116,21 @@ if "%1" EQU "x86" ( set BUILD_PLAT=Win32 set OUTDIR_PLAT=win32 set OBJDIR_PLAT=x86 -) else ( +) else if "%1" EQU "x64" ( set BUILD=%Py_OutDir%amd64\ set PGO=%~2 set BUILD_PLAT=x64 set OUTDIR_PLAT=amd64 set OBJDIR_PLAT=x64 +) else if "%1" EQU "ARM64" ( + set BUILD=%Py_OutDir%amd64\ + set PGO=%~2 + set BUILD_PLAT=ARM64 + set OUTDIR_PLAT=arm64 + set OBJDIR_PLAT=arm64 +) else ( + echo Unknown platform %1 + exit /B 1 ) if exist "%BUILD%en-us" ( @@ -179,18 +187,24 @@ set BUILDOPTS=/p:Platform=%1 /p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_UR if defined BUILDMSI ( %MSBUILD% "%D%bundle\releaselocal.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true if errorlevel 1 exit /B - %MSBUILD% "%D%bundle\releaseweb.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=false - if errorlevel 1 exit /B ) if defined BUILDZIP ( - %MSBUILD% "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% /p:OutputPath="%BUILD%en-us" - if errorlevel 1 exit /B + if "%BUILD_PLAT%" EQU "ARM64" ( + echo Skipping embeddable ZIP generation for ARM64 platform + ) else ( + %MSBUILD% "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% /p:OutputPath="%BUILD%en-us" + if errorlevel 1 exit /B + ) ) if defined BUILDNUGET ( - %MSBUILD% "%D%..\nuget\make_pkg.proj" /t:Build /p:Configuration=Release /p:Platform=%1 /p:OutputPath="%BUILD%en-us" - if errorlevel 1 exit /B + if "%BUILD_PLAT%" EQU "ARM64" ( + echo Skipping Nuget package generation for ARM64 platform + ) else ( + %MSBUILD% "%D%..\nuget\make_pkg.proj" /t:Build /p:Configuration=Release /p:Platform=%1 /p:OutputPath="%BUILD%en-us" + if errorlevel 1 exit /B + ) ) if not "%OUTDIR%" EQU "" ( @@ -205,7 +219,7 @@ if not "%OUTDIR%" EQU "" ( exit /B 0 :Help -echo buildrelease.bat [--out DIR] [-x86] [-x64] [--certificate CERTNAME] [--build] [--pgo COMMAND] +echo buildrelease.bat [--out DIR] [-x86] [-x64] [-arm64] [--certificate CERTNAME] [--build] [--pgo COMMAND] echo [--skip-build] [--skip-doc] [--skip-nuget] [--skip-zip] [--skip-pgo] echo [--download DOWNLOAD URL] [--test TARGETDIR] echo [-h] @@ -213,6 +227,7 @@ echo. echo --out (-o) Specify an additional output directory for installers echo -x86 Build x86 installers echo -x64 Build x64 installers +echo -arm64 Build ARM64 installers echo --build (-b) Incrementally build Python rather than rebuilding echo --skip-build (-B) Do not build Python (just do the installers) echo --skip-doc (-D) Do not build documentation @@ -231,6 +246,9 @@ echo. echo For the --pgo option, any Python command line can be used, or 'default' to echo use the default task (-m test --pgo). echo. +echo x86 and ARM64 builds will never use PGO. ARM64 builds will never generate +echo embeddable or Nuget packages. +echo. echo The following substitutions will be applied to the download URL: echo Variable Description Example echo {version} version number 3.5.0 diff --git a/Tools/msi/bundle/Default.ARM64.xsl b/Tools/msi/bundle/Default.ARM64.xsl new file mode 100644 index 0000000..0dd1c9e --- /dev/null +++ b/Tools/msi/bundle/Default.ARM64.xsl @@ -0,0 +1,26 @@ + + + + + + + + + + + + [TargetDir] + +Includes pip and documentation +Creates shortcuts but no file associations + + + + (The 'py' launcher is currently unavailable on ARM64.) + + + (tcl/tk and IDLE are currently unavailable on ARM64.) + + \ No newline at end of file diff --git a/Tools/msi/bundle/Default.thm b/Tools/msi/bundle/Default.thm index f5ba43d..d1b0f5b 100644 --- a/Tools/msi/bundle/Default.thm +++ b/Tools/msi/bundle/Default.thm @@ -52,16 +52,16 @@ #(loc.Custom1Header) - #(loc.Include_docLabel) + #(loc.Include_docLabel) #(loc.Include_docHelpLabel) - #(loc.Include_pipLabel) + #(loc.Include_pipLabel) #(loc.Include_pipHelpLabel) - #(loc.Include_tcltkLabel) - #(loc.Include_tcltkHelpLabel) + #(loc.Include_tcltkLabel) + #(loc.Include_tcltkHelpLabel) - #(loc.Include_testLabel) + #(loc.Include_testLabel) #(loc.Include_testHelpLabel) #(loc.Include_launcherLabel) diff --git a/Tools/msi/bundle/Default.wxl b/Tools/msi/bundle/Default.wxl index 053306b..70fb467 100644 --- a/Tools/msi/bundle/Default.wxl +++ b/Tools/msi/bundle/Default.wxl @@ -1,7 +1,6 @@  [WixBundleName] Setup - [WixBundleName] Installing Setup Updating diff --git a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp index fdc2a21..226416f 100644 --- a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp +++ b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp @@ -1501,6 +1501,9 @@ private: hr = UpdateUIStrings(_command.action); BalExitOnFailure(hr, "Failed to load UI strings."); + hr = FindProgramFilesArm(); + BalExitOnFailure(hr, "Fatal error locating Program Files (Arm)"); + GetBundleFileVersion(); // don't fail if we couldn't get the version info; best-effort only LExit: @@ -2181,6 +2184,37 @@ private: return hr; } + HRESULT FindProgramFilesArm() { + wchar_t buffer[MAX_PATH + 1]; + DWORD bufferLen = MAX_PATH; + LSTATUS res = RegGetValueW( + HKEY_LOCAL_MACHINE, + L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", + L"ProgramFilesDir (Arm)", + RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ | RRF_SUBKEY_WOW6464KEY, + NULL, + buffer, + &bufferLen + ); + if (res != ERROR_SUCCESS) { + // ProgramFilesArmFolder will default to ProgramFilesFolder. We only report + // an error if the value existed, as it will simply just be absent on non-ARM + // devices. + if (res != ERROR_FILE_NOT_FOUND) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to query 'ProgramFilesDir (Arm)': error code %d", res); + } + return S_OK; + } + if (buffer[0]) { + wchar_t *p = &buffer[bufferLen / sizeof(wchar_t) - 1]; + while (*p == L'\\' || *p == L'\0') { p -= 1; } + *++p = L'\\'; + *++p = L'\0'; + _engine->SetVariableString(L"ProgramFilesArmFolder", buffer); + } + return S_OK; + } + // // OnPlan - plan the detected changes. // diff --git a/Tools/msi/bundle/bootstrap/pythonba.vcxproj b/Tools/msi/bundle/bootstrap/pythonba.vcxproj index d90b5e3..bb383bf 100644 --- a/Tools/msi/bundle/bootstrap/pythonba.vcxproj +++ b/Tools/msi/bundle/bootstrap/pythonba.vcxproj @@ -21,11 +21,10 @@ Release Win32 - v142 + v143 + v142 v141 - v140 - v140 - v120 + v140 {7A09B132-B3EE-499B-A700-A4B2157FEA3D} PythonBA @@ -42,6 +41,7 @@ + ARM64=1;%(PreprocessorDefinitions) _CRT_STDIO_LEGACY_WIDE_SPECIFIERS=1;%(PreprocessorDefinitions) $(WixInstallPath)sdk\inc Use @@ -50,8 +50,7 @@ comctl32.lib;gdiplus.lib;msimg32.lib;shlwapi.lib;wininet.lib;dutil.lib;balutil.lib;version.lib;uxtheme.lib;%(AdditionalDependencies) - $(WixInstallPath)sdk\vs2017\lib\x86 - $(WixInstallPath)sdk\vs2017\lib\x86 + $(WixInstallPath)sdk\vs2017\lib\x86 $(WixInstallPath)sdk\vs2015\lib\x86 $(WixInstallPath)sdk\vs2013\lib\x86 pythonba.def diff --git a/Tools/msi/bundle/bundle.targets b/Tools/msi/bundle/bundle.targets index 5d8ae6c..4f4306f 100644 --- a/Tools/msi/bundle/bundle.targets +++ b/Tools/msi/bundle/bundle.targets @@ -3,25 +3,26 @@ 2.0 Bundle - + Release 1132;1135;1140 $(OutputName)-$(PythonVersion) $(OutputName)-$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber).$(RevisionNumber) $(OutputName)-amd64 + $(OutputName)-arm64 $(OutputName)-$(OutputSuffix) $(OutputName)-d $(OutputName) $(OutputPath)en-us\ $(OutputPath) - + $(DownloadUrlBase.TrimEnd(`/`))/{version}/{arch}{releasename}/{msi} $(DefineConstants);DownloadUrl=$(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseLevelName)`).Replace(`{msi}`, `{2}`)) $(DefineConstants);DownloadUrl={2} - + WixUtilExtension @@ -42,7 +43,6 @@ - @@ -54,7 +54,7 @@ - + BuildForRelease=$(BuildForRelease) @@ -69,40 +69,61 @@ - + - + - + Build - + Rebuild - + - + - + + Properties="Configuration=$(BootstrapConfiguration);Platform=Win32;BuildForPlatform=$(Platform)"> - + $(DefineConstants);BootstrapApp=$(BootstrapAppPath) - + + + + + + + $(DefineConstants);DefaultWxl=Default.wxl + + + + + + + + + $(DefineConstants);DefaultWxl=$(IntermediateOutputPath)Default.wxl + + + diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs index a145d84..5c9fd6d 100644 --- a/Tools/msi/bundle/bundle.wxs +++ b/Tools/msi/bundle/bundle.wxs @@ -12,7 +12,7 @@ dep:ProviderKey="CPython-$(var.MajorVersionNumber).$(var.MinorVersionNumber)$(var.PyArchExt)$(var.PyTestExt)"> - + @@ -26,6 +26,9 @@ + + + @@ -36,6 +39,9 @@ + + + @@ -43,7 +49,7 @@ - +