Skip to content

Commit f2c09ae

Browse files
committed
Add tests/3-pythonscript-cython-only
1 parent 60caf7b commit f2c09ae

File tree

9 files changed

+169
-0
lines changed

9 files changed

+169
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
res://pythonscript.gdextension
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import platform
2+
from pathlib import Path
3+
import subprocess
4+
import shutil
5+
6+
7+
PROJECT_DIR = Path(__file__).resolve().parent
8+
9+
10+
if platform.system() == "Windows":
11+
python_path = PROJECT_DIR / "addons/pythonscript/windows-x86_64/python.exe"
12+
lib_pattern = "my.*.pyd"
13+
elif platform.system() == "Darwin":
14+
python_path = PROJECT_DIR / "addons/pythonscript/macos-x86_64/bin/python3"
15+
lib_pattern = "my.*.dylib"
16+
else:
17+
assert platform.system() == "Linux"
18+
python_path = PROJECT_DIR / "addons/pythonscript/linux-x86_64/bin/python3"
19+
lib_pattern = "my.*.so"
20+
21+
cmd = [str(python_path), "setup.py", "build_ext", "--build-lib", str(PROJECT_DIR)]
22+
print(" ".join(cmd))
23+
subprocess.check_call(cmd, cwd=PROJECT_DIR)
24+
25+
26+
# Finally remove the platform info from the shared library, this is to avoid
27+
# annoying update everytime we change CPython embedded version.
28+
lib_candidates = list(PROJECT_DIR.glob(lib_pattern))
29+
assert len(lib_candidates) == 1, lib_candidates
30+
lib = lib_candidates[0]
31+
lib_new_name = f"my{lib.suffix}"
32+
print(f"rename {lib.name} -> {lib_new_name}")
33+
shutil.move(lib, lib.parent / lib_new_name)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
extends Node
2+
3+
func _ready():
4+
# Exit godot
5+
self.get_tree().quit()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[gd_scene load_steps=2 format=3 uid="uid://2mikyvxkygni"]
2+
3+
[ext_resource type="Script" path="res://main.gd" id="1_2fqr4"]
4+
5+
[node name="Node" type="Node"]
6+
script = ExtResource( "1_2fqr4" )
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# cython: language_level=3
2+
3+
from godot.hazmat.gdapi cimport *
4+
5+
6+
def initialize(level):
7+
print("MY initialize", level)
8+
9+
10+
def deinitialize(level):
11+
print("MY deinitialize", level)
12+
13+
14+
cdef public void _my_initialize(void *userdata, GDExtensionInitializationLevel p_level) with gil:
15+
print("==> _initialize")
16+
17+
18+
cdef extern void _my_deinitialize(void *userdata, GDExtensionInitializationLevel p_level) with gil:
19+
print("==> _deinitialize")
20+
21+
22+
cdef extern GDExtensionBool _my_init(
23+
const GDExtensionInterface *p_interface,
24+
const GDExtensionClassLibraryPtr p_library,
25+
GDExtensionInitialization *r_initialization
26+
) nogil:
27+
# print("==> _my_init")
28+
r_initialization.minimum_initialization_level = GDEXTENSION_INITIALIZATION_SERVERS
29+
r_initialization.userdata = NULL
30+
# r_initialization.initialize = _my_initialize
31+
# r_initialization.deinitialize = _my_deinitialize
32+
return True
33+
34+
35+
cdef extern from * nogil:
36+
"""
37+
#include <godot/gdextension_interface.h>
38+
#ifdef _WIN32
39+
# define DLL_EXPORT __declspec(dllexport)
40+
#else
41+
# define DLL_EXPORT
42+
#endif
43+
44+
GDExtensionBool _my_init(const GDExtensionInterface *, const GDExtensionClassLibraryPtr, GDExtensionInitialization *);
45+
DLL_EXPORT GDExtensionBool my_init(
46+
const GDExtensionInterface *p_interface,
47+
const GDExtensionClassLibraryPtr p_library,
48+
GDExtensionInitialization *r_initialization
49+
) {
50+
return _my_init(p_interface, p_library, r_initialization);
51+
}
52+
"""
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; Engine configuration file.
2+
; It's best edited using the editor UI and not directly,
3+
; since the parameters that go here are not all obvious.
4+
;
5+
; Format:
6+
; [section] ; section goes between []
7+
; param=value ; assign values to parameters
8+
9+
config_version=5
10+
11+
[application]
12+
13+
run/main_scene="res://main.tscn"
14+
config/features=PackedStringArray("4.0")
15+
name="TestProject"
16+
main_scene="res://main.tscn"
17+
18+
[python_script]
19+
20+
io_streams_capture=false
21+
verbose=true
22+
initialize_callback="my:initialize"
23+
deinitialize_callback="my:deinitialize"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[configuration]
2+
3+
entry_symbol = "pythonscript_init"
4+
5+
[libraries]
6+
7+
linux.64="res://addons/pythonscript/linux-x86_64/libpythonscript.so"
8+
linux.32="res://addons/pythonscript/linux-x86/libpythonscript.so"
9+
windows.64="res://addons/pythonscript/windows-x86_64/pythonscript.dll"
10+
windows.32="res://addons/pythonscript/windows-x86/pythonscript.dll"
11+
macos.64="res://addons/pythonscript/macos-x86_64/libpythonscript.dylib"
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import platform
2+
from setuptools import setup
3+
from Cython.Build import cythonize
4+
from pathlib import Path
5+
6+
7+
# Retrieve `Python.h`'s include dir.
8+
# In theory setuptools rely on `sysconfig` to find this information, `sysconfig` being
9+
# generated when Python is installed (typically `make install` after it compilation).
10+
# However we use python-build-standalone which (as it name imply) provide us with a
11+
# standalone Python distribution, hence the install step is part of the build process
12+
# and `sysconfig` provide irrelevant include paths (e.g. on Linux it is done on Docker
13+
# with install in `/install`)
14+
# See:
15+
# - https://github.com/indygreg/python-build-standalone/issues/152
16+
# - https://gregoryszorc.com/docs/python-build-standalone/main/quirks.html#references-to-build-time-paths
17+
if platform.system() in ("Linux", "Darwin"):
18+
python_include_dir = next(Path(".").parent.glob("addons/pythonscript/*-*/include/python*"))
19+
elif platform.system() == "Windows":
20+
python_include_dir = next(Path(".").parent.glob("addons/pythonscript/*-*/include"))
21+
else:
22+
raise RuntimeError(f"Unsupported platform `{platform.system()}`")
23+
24+
25+
# Work around cythonize's `include_path` parameter not configuring the C compiler
26+
# (see: https://github.com/cython/cython/issues/1480)
27+
gdextension_api_include_dir = Path("gdextension_api")
28+
29+
30+
ext_modules = cythonize("my.pyx")
31+
ext_modules[0].include_dirs = [
32+
python_include_dir,
33+
gdextension_api_include_dir,
34+
]
35+
setup(
36+
ext_modules=ext_modules,
37+
)

0 commit comments

Comments
 (0)