Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for building on Windows ARM64 #2663

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,22 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-22.04, windows-2022, macos-13 ]
python-version: [ '3.9', '3.10', '3.11', '3.12', '3.13' ]
#os: [ ubuntu-22.04, windows-2022, macos-13 ]
#python-version: [ '3.9', '3.10', '3.11', '3.12', '3.13' ]
os: [ windows-2022 ]
python-version: [ '3.13' ]
architecture: [ 'x86', 'x64' ]
# Exclude x86 configs on non-Windows OSs
exclude:
- os: ubuntu-22.04
architecture: x86
- os: macos-13
architecture: x86
include:
- os: windows-2022
architecture: x64
python-version: '3.13'
msvc_arch: amd64_arm64

env:
VERSION: ${{ needs.build-source-dist.outputs.VERSION }}
Expand All @@ -139,6 +146,9 @@ jobs:
else
short_name=win32
fi
if [ ${{ matrix.msvc_arch }} != '' ]; then
build_opts="$build_opts --msvc_arch=${{ matrix.msvc_arch }} --python='C:\BlahPython\pythonarm64.3.13.0\tools\python.exe'"
fi
fi
echo "short_name=$short_name" >> "$GITHUB_OUTPUT"
echo "canonical_id=$short_name-py${{ matrix.python-version }}-${{ matrix.architecture}}" >> "$GITHUB_OUTPUT"
Expand All @@ -155,13 +165,24 @@ jobs:
name: wxPython-source
path: dist

- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
with:
detached: true

- name: Set up Python ${{ matrix.python-version }}-${{ matrix.architecture }}
uses: actions/setup-python@v5
with:
python-version: '${{ matrix.python-version }}'
architecture: '${{ matrix.architecture }}'
cache: 'pip'

- name: Install ARM64 Python
if: ${{ matrix.msvc_arch }}
run: |
nuget install pythonarm64 -Version ${{ matrix.python-version }} -OutputDirectory 'C:\BlahPython'
dir 'C:\BlahPython'

- name: Install Python dependencies
run: |
python -m pip install --upgrade -r requirements.txt
Expand Down Expand Up @@ -191,7 +212,7 @@ jobs:
- name: Setup MSVC
uses: ilammy/msvc-dev-cmd@v1
with:
arch: '${{ matrix.architecture }}'
arch: '${{ matrix.msvc_arch || matrix.architecture }}'

- name: Build the wxPython wheel
env:
Expand Down
44 changes: 30 additions & 14 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
PYSHORTVER = '27'
PYTHON = None # it will be set later
PYTHON_ARCH = 'UNKNOWN'
MSVC_ARCH = None

# convenience access to the wxPython version digits
version2 = "%d.%d" % (version.VER_MAJOR, version.VER_MINOR)
Expand Down Expand Up @@ -168,7 +169,7 @@ def usage():
def main(args):
setDevModeOptions(args)
options, commands = parseArgs(args)
setPythonVersion(args)
setPythonVersion(options, args)

os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '') + os.pathsep + phoenixDir()
os.environ['PYTHONUNBUFFERED'] = 'yes'
Expand Down Expand Up @@ -226,11 +227,12 @@ def main(args):
#---------------------------------------------------------------------------


def setPythonVersion(args):
def setPythonVersion(options, args):
global PYVER
global PYSHORTVER
global PYTHON
global PYTHON_ARCH
global MSVC_ARCH

havePyVer = False
havePyPath = False
Expand Down Expand Up @@ -313,13 +315,29 @@ def setPythonVersion(args):
PYTHON_ARCH = runcmd(
[PYTHON, '-c', 'import platform; print(platform.architecture()[0])'],
True, False)
if isWindows:
if options.msvc_arch:
MSVC_ARCH = options.msvc_arch
else:
machine = runcmd(
[PYTHON, '-c', 'import platform; print(platform.machine())'],
True, False)
if machine == 'ARM64':
MSVC_ARCH = 'arm64'
elif PYTHON_ARCH == '64bit':
MSVC_ARCH = 'x64'
else:
MSVC_ARCH = 'x86'

msg('Python\'s architecture is %s' % PYTHON_ARCH)
os.environ['PYTHON'] = PYTHON

if PYTHON_ARCH == '64bit':
# Make sure this is set in case it wasn't above.
os.environ['CPU'] = 'X64'
if isWindows:
os.environ['CPU'] = MSVC_ARCH.split('_')[-1].upper()
else:
os.environ['CPU'] = 'X64'



Expand Down Expand Up @@ -387,8 +405,9 @@ class MSWsettings(object):
pass
msw = MSWsettings()
msw.CPU = os.environ.get('CPU')
if msw.CPU in ['AMD64', 'X64'] or PYTHON_ARCH == '64bit':
msw.dllDir = posixjoin(wxDir(), "lib", "vc%s_x64_dll" % getVisCVersion())
if msw.CPU in ['AMD64', 'X64', 'ARM64'] or PYTHON_ARCH == '64bit':
msw.dllArch = 'arm64' if msw.CPU == 'ARM64' else 'x64'
msw.dllDir = posixjoin(wxDir(), "lib", "vc%s_%s_dll" % (getVisCVersion(), msw.dllArch))
else:
msw.dllDir = posixjoin(wxDir(), "lib", "vc%s_dll" % getVisCVersion())
msw.buildDir = posixjoin(wxDir(), "build", "msw")
Expand Down Expand Up @@ -456,7 +475,8 @@ def makeOptionParser():
("regenerate_sysconfig", (False, "Waf uses Python's sysconfig and related tools to configure the build. In some cases that info can be incorrect, so this option regenerates it. Must have write access to Python's lib folder.")),
("no_allmo", (False, "Skip regenerating the wxWidgets message catalogs")),
("no_msedge", (False, "Do not include the MS Edge backend for wx.html2.WebView. (Windows only)")),
("quiet", (False, "Silence some of the messages from build.py"))
("quiet", (False, "Silence some of the messages from build.py")),
("msvc_arch", ("", "The MSVC architecture to build for")),
]

parser = optparse.OptionParser("build options:")
Expand Down Expand Up @@ -799,8 +819,7 @@ def checkCompiler(quiet=False):
# needed info, so the target python shoudl have a recent version of
# setuptools installed.

arch = 'x64' if PYTHON_ARCH == '64bit' else 'x86'
info = getMSVCInfo(PYTHON, arch, set_env=True)
info = getMSVCInfo(PYTHON, MSVC_ARCH, set_env=True)

# # Just needed for debugging
# if not quiet:
Expand Down Expand Up @@ -1628,7 +1647,7 @@ def copyWxDlls(options):
cfg = Config()

ver = wxversion3_nodot if unstable_series else wxversion2_nodot
arch = 'x64' if PYTHON_ARCH == '64bit' else 'x86'
arch = msw.dllArch if PYTHON_ARCH == '64bit' else 'x86'
dlls = list()
if not options.debug or options.both:
dlls += glob.glob(os.path.join(msw.dllDir, "wx*%su_*.dll" % ver))
Expand Down Expand Up @@ -1741,10 +1760,7 @@ def _getWxCompiler(flag, compName, flagName):
if isDarwin and options.mac_arch:
build_options.append("--mac_arch=%s" % options.mac_arch)
if isWindows:
if PYTHON_ARCH == '64bit':
build_options.append('--msvc_arch=x64')
else:
build_options.append('--msvc_arch=x86')
build_options.append('--msvc_arch=%s' % MSVC_ARCH)
if not isWindows:
build_options.append('--wx_config=%s' % WX_CONFIG)
if options.jobs:
Expand Down Expand Up @@ -2025,7 +2041,7 @@ def cmd_clean_wx(options, args):
delFiles(glob.glob(opj(msw.dllDir, 'wx*%s%s*' % (wxversion2_nodot, msw.dll_type))))
delFiles(glob.glob(opj(msw.dllDir, 'wx*%s%s*' % (wxversion3_nodot, msw.dll_type))))
if PYTHON_ARCH == '64bit':
deleteIfExists(opj(msw.buildDir, 'vc%s_x64_msw%sdll' % (getVisCVersion(), msw.dll_type)))
deleteIfExists(opj(msw.buildDir, 'vc%s_%s_msw%sdll' % (getVisCVersion(), msw.dllArch, msw.dll_type)))
else:
deleteIfExists(opj(msw.buildDir, 'vc%s_msw%sdll' % (getVisCVersion(), msw.dll_type)))

Expand Down
5 changes: 3 additions & 2 deletions buildtools/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,9 @@ def finishSetup(self, wx_config=None, debug=None, compiler=None):
# will probably vary...
self.WXPLAT = '__WXMSW__'

if os.environ.get('CPU', None) in ['AMD64', 'X64']:
self.VCDLL = 'vc%s_x64_dll' % getVisCVersion()
if os.environ.get('CPU', None) in ['AMD64', 'X64', 'ARM64']:
arch_str = 'arm64' if os.environ['CPU'] == 'ARM64' else 'x64'
self.VCDLL = 'vc%s_%s_dll' % (getVisCVersion(), arch_str)
else:
self.VCDLL = 'vc%s_dll' % getVisCVersion()

Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added packaging/msw-webview2/arm64/WebView2Loader.dll
Binary file not shown.
2 changes: 1 addition & 1 deletion wscript
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def options(opt):
help='Set to use a MinGW toolchain')
opt.add_option('--msvc_arch', dest='msvc_arch', default='x86', action='store',
help='The architecture to target for MSVC builds. Supported values '
'are: "x86" or "x64"')
'are: "x86", "x64", or "arm64"')
opt.add_option('--msvc_relwithdebug', dest='msvc_relwithdebug', action='store_true', default=False,
help='Turn on debug info for release builds for MSVC builds.')

Expand Down
Loading