Skip to content

Conversation

@gr3vios
Copy link

@gr3vios gr3vios commented Apr 27, 2025

…ot project.

Changes include:

  • Adjustments to the build scripts to handle Windows ARM64 architecture.
  • Dependencies updated to align with the requirements for this platform.

Known limitations:

  • This implementation depends on Python 3.12.4 for Windows ARM64, which is not yet available.
  • As a temporary workaround, Python 3.9.7 from jay0lee/CPython-Windows-ARM64 has been considered.

This work follows the same approach as the Linux ARM64 support and is a draft implementation. Feedback is welcome, especially regarding compatibility and potential improvements.

…ot project.

Changes include:
- Adjustments to the build scripts to handle Windows ARM64 architecture.
- Dependencies updated to align with the requirements for this platform.

Known limitations:
- This implementation depends on Python 3.12.4 for Windows ARM64, which is not yet available.
- As a temporary workaround, Python 3.9.7 from jay0lee/CPython-Windows-ARM64 has been considered.

This work follows the same approach as the Linux ARM64 support and is a draft implementation. Feedback is welcome, especially regarding compatibility and potential improvements.
platform_dict = {"windows64": "x86_64-pc-windows-msvc-install_only_stripped", "windows32": "i686-pc-windows-msvc-install_only_stripped",
"linux64": "x86_64-unknown-linux-gnu-install_only_stripped", "darwin64":"aarch64-apple-darwin-install_only_stripped",
"linuxarm64":"armv7-unknown-linux-gnueabi-install_only_stripped"}
"linuxarm64":"armv7-unknown-linux-gnueabi-install_only_stripped", "windowsarm64":"aarch64-pc-windows-msvc-install_only_stripped"}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file does not exist yet, the version is in process: astral-sh/python-build-standalone#387

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, thank you very much for investigating it. I finally got it working by using the interpreter from nuget. and uploading it to my repo here: prebuilt-windowsarm64

Like this, i needed to adapt download_file like this:

    if platform != "linux32" and platform != "linux64" and platform != "windowsarm64":
        url = f'https://github.com/indygreg/python-build-standalone/releases/download/20240726/{python_ver}+20240726-{platform_dict[platform]}.tar.gz'
        python_file = f'{python_files_dir}/{python_ver}-{platform_dict[platform]}.tar.gz'
    elif platform == "linux64":
        url = f'https://github.com/niklas2902/prebuild-python-linux64/releases/download/release-0.1/{python_ver}-linux64.zip'
        python_file = f'{python_files_dir}/{python_ver}-linux64.zip'
    elif platform == "windowsarm64":
        url = f'https://github.com/niklas2902/prebuilt-windowsarm64/releases/download/release-0.1/{python_ver}-windowsarm64.zip'
        python_file = f'{python_files_dir}/{python_ver}-windowsarm64.zip'
    else :
        url = f'https://github.com/niklas2902/prebuild-python-linux32/releases/download/release-0.1/{python_ver}-linux32.zip'
        python_file = f'{python_files_dir}/{python_ver}-linux32.zip'

Copy link
Author

@gr3vios gr3vios Jun 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@niklas2902 Thanks for the implementation details and the NuGet-based approach - that's a solid solution for the ARM64 Python dependency issue.

I've implemented your suggested download_file() modification and the MSVC ARM64 build changes. I went with a simpler approach for the MSVC configuration compared to your winarm64 branch - just the essential x64_arm64 targeting. Let me know if you'd prefer the more robust Visual Studio detection approach from your branch.

Also added the remaining pieces needed for complete Windows ARM64 support (library entries, cross-compilation config).

I merged with the latest master and resolved conflicts, but would appreciate validation of the conflict resolutions.

Ready for your review when convenient.

platform_dict = {"windows64": "x86_64-pc-windows-msvc-install_only_stripped", "windows32": "i686-pc-windows-msvc-install_only_stripped",
"linux64": "x86_64-unknown-linux-gnu-install_only_stripped", "darwin64":"aarch64-apple-darwin-install_only_stripped",
"linuxarm64":"armv7-unknown-linux-gnueabi-install_only_stripped"}
"linuxarm64":"armv7-unknown-linux-gnueabi-install_only_stripped", "windowsarm64":"aarch64-pc-windows-msvc-install_only_stripped"}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, thank you very much for investigating it. I finally got it working by using the interpreter from nuget. and uploading it to my repo here: prebuilt-windowsarm64

Like this, i needed to adapt download_file like this:

    if platform != "linux32" and platform != "linux64" and platform != "windowsarm64":
        url = f'https://github.com/indygreg/python-build-standalone/releases/download/20240726/{python_ver}+20240726-{platform_dict[platform]}.tar.gz'
        python_file = f'{python_files_dir}/{python_ver}-{platform_dict[platform]}.tar.gz'
    elif platform == "linux64":
        url = f'https://github.com/niklas2902/prebuild-python-linux64/releases/download/release-0.1/{python_ver}-linux64.zip'
        python_file = f'{python_files_dir}/{python_ver}-linux64.zip'
    elif platform == "windowsarm64":
        url = f'https://github.com/niklas2902/prebuilt-windowsarm64/releases/download/release-0.1/{python_ver}-windowsarm64.zip'
        python_file = f'{python_files_dir}/{python_ver}-windowsarm64.zip'
    else :
        url = f'https://github.com/niklas2902/prebuild-python-linux32/releases/download/release-0.1/{python_ver}-linux32.zip'
        python_file = f'{python_files_dir}/{python_ver}-linux32.zip'

@niklas2902
Copy link
Owner

niklas2902 commented Jun 8, 2025

Thank you very much for your work and sorry for the late response.

It all looks, very good. I have finally managed to get a github action to work with windows arm64. During this, I also noticed, that I have to adapt my build.py like you can see here: https://github.com/niklas2902/py4godot/blob/winarm64/build.py, so that it enables msvc for windows arm

gr3vios added 3 commits June 11, 2025 09:03
- Update download_file() to use niklas2902/prebuilt-windowsarm64 repository
- Add Windows ARM64 entries to python.gdextension
- Fix MSVC initialization to use x64_arm64 for Windows ARM64 builds
# Conflicts:
#	meson_scripts/copy_tools.py
#	meson_scripts/download_python.py
#	meson_scripts/platform_check.py
#	py4godot/godot_bindings/pythonscript.cpp
Implement comprehensive Windows ARM64 support for py4godot based on extensive testing and debugging of compiled plugin builds.

Core ARM64 implementation:
- Add symbol export fix via py4godot/godot_bindings/main.def for proper DLL initialization
- Update meson.build to use module definition file for Windows builds
- Fix ARM64 library loading in pythonscript.cpp with path corrections and enhanced logging
- Add ARM64 platform configuration in platforms/windowsarm64.cross
- Update build_resources/plugin.cfg and python.gdextension for ARM64 compatibility

Key technical fixes:
- Resolve Error 126 library loading failures through dependency management
- Ensure py4godot_init symbol is properly exported from main.dll
- Add ARM64-specific path handling and library resolution
- Configure MSVC cross-compilation settings for ARM64 target

Testing and diagnostic infrastructure:
Based on extensive testing of compiled ARM64 builds, create comprehensive diagnostic tools:
- Developer tools in tools/arm64/ for build verification and troubleshooting
- End-user tools in build_resources/plugin_tools/ for plugin distribution
- Automated test project creation and dependency verification utilities

Build system enhancements:
- Support windowsarm64 platform in cross-compilation configuration
- Integrate ARM64 dependency detection and copying workflows
- Add plugin configuration updates for ARM64 library paths

These changes result from thorough testing of ARM64 compiled builds and resolve all identified compatibility issues, enabling native py4godot
execution on Windows ARM64 devices.
@gr3vios
Copy link
Author

gr3vios commented Jun 14, 2025

Hi @niklas2902!

I wanted to provide you with a comprehensive update on the Windows ARM64 implementation. After the initial development, I've spent extensive time testing the compiled plugin builds on actual ARM64 hardware, I've made significant progress but also I'm facing with maybe a runtime issue.

TL;DR

Started with complete failure (Error 126: Cannot load library) → discovered missing ARM64 dependencies and symbol export issues → created diagnostic tools to understand the problem → fixed library loading with main.def and dependency management → py4godot now successfully loads and initializes on Windows ARM64! Currently investigating why _ready() methods aren't executing (placeholder logic bug?) and working around path resolution requiring Godot exe in project directory.

The full history

When I first tried running py4godot on Windows ARM64, I was greeted with the dreaded "Error 126: Cannot load library." The plugin wouldn't even start - complete failure. After diving deep into the codebase and your NuGet-based Python approach, I realized we had two fundamental problems lurking beneath the surface.

I created a suite of diagnostic tools to understand what was going wrong:

  • Built comprehensive dependency analyzers
  • Created DLL loading testers using Python ctypes
  • Developed automated project creators for testing

The investigation revealed the culprits:

  • Missing ARM64 runtime libraries (msvcp140.dll, ucrtbase.dll)
  • Symbol export failure - py4godot_init wasn't being exported from main.dll
  • Path resolution issues in the library loading chain

After testing on ARM64 hardware(Qualcomm Adreno 8cx Gen 3). I implemented the fixes:

  • The Symbol Export Fix: Created py4godot/godot_bindings/main.def and updated meson.build to properly export symbols:
    LIBRARY main
    EXPORTS
    py4godot_init

  • Built an dependency management system that automatically finds and copies the required ARM64 runtime libraries.

  • Enhanced Logging: Added detailed logging throughout pythonscript.cpp to track exactly what was happening during library loading.

And then... it worked!

[py4godot] Library loaded successfully. Looking for 'py4godot_init' symbol...
py4godot version loaded successfully!
Available items: ['Engine', 'Node2D', 'SignalArg', 'gdclass', 'signal', ...]

The plugin now successfully loads and initializes on Windows ARM64! No more Error 126! The Python interpreter starts, classes import correctly, and the basic infrastructure is fully functional. But here's where the story gets interesting... While celebrating the successful plugin loading, I noticed something odd. The _ready() methods in Python scripts weren't executing - print statements inside them never appeared.

Digging deeper, I discovered maybe a bug (not sure yet) in the placeholder instance logic:
// In PyScriptExtension.cpp:377
gd_instance->is_placeholder = !transfer_object.is_tool;

This maybe incorrectly marks all non-tool scripts as placeholders, and placeholders are blocked from calling lifecycle methods in instance.h:82-84. (again not sure at all..)

The Current State

What Works:

  • Complete ARM64 compilation (1043 targets!)
  • Plugin loading without any errors
  • Python interpreter initialization
  • Import system functional
  • Basic py4godot infrastructure operational

What Needs Investigation:

  • Script lifecycle methods need the placeholder logic fix
  • Path resolution still requires Godot exe in project directory (investigating)

Known Limitations

  • Path Resolution: Godot executable must be placed in project directory for correct DLL loading (not yet resolved)
  • Script Execution: Requires placeholder logic fix for full functionality

Tools Created️

Throughout this journey, I created a toolkit that maybe will help to others devs:

  • Developer tools (tools/arm64/) - Diagnostic suite for contributors
  • User-Friendly Helpers (build_resources/plugin_tools/) - Simplified troubleshooting for end users
  • Complete Documentation - Step-by-step guides and workflows (build_resources/README.md)

Thanks for your guidance throughout this process!

@gr3vios gr3vios changed the title This commit introduces support for Windows ARM64 builds in the py4godot Support for Windows ARM64 builds in py4godot Jun 14, 2025
@niklas2902
Copy link
Owner

Hey,

Thanks so much for the extensive work you did. I'll look into it and see if I can figure out why the lifecycle methods aren't working. Normally, they should work when you start the game, but not in the editor. That's why we have this condition for the placeholder. So maybe there's still an issue with the Python interpreter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants