Skip to content

Commit aa90fdb

Browse files
committed
Add bin folder to python targets, and adapt the regular python layout (save for the zip). Use the zip upload archive method in the github runner for macOS, too, to preserve permissions.
1 parent 093d987 commit aa90fdb

File tree

3 files changed

+43
-28
lines changed

3 files changed

+43
-28
lines changed

.github/workflows/build.yml

+4-12
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,15 @@ jobs:
6464
run: |
6565
scons platform=${{ matrix.platform }} arch=${{ matrix.arch }} single_source=true
6666
67-
- name: Create archive (Linux)
68-
if: matrix.os == 'ubuntu-latest'
67+
- name: Create archive (Linux, macOS)
68+
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
6969
run: |
7070
cd bin/
7171
zip -q -r ../godot-python-${{ matrix.platform }}-${{ matrix.arch }}.zip *
7272
cd ../
7373
74-
- name: Upload artifacts (Linux)
75-
if: matrix.os == 'ubuntu-latest'
74+
- name: Upload artifacts (Linux, macOS)
75+
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
7676
uses: actions/upload-artifact@v3
7777
with:
7878
name: godot-python-${{ matrix.platform }}-${{ matrix.arch }}
@@ -90,14 +90,6 @@ jobs:
9090
!bin/**/*.exp
9191
retention-days: 30
9292

93-
- name: Upload artifacts (macOS)
94-
if: matrix.os == 'macos-latest'
95-
uses: actions/upload-artifact@v3
96-
with:
97-
name: godot-python-${{ matrix.platform }}-${{ matrix.arch }}
98-
path: bin/**/*
99-
retention-days: 30
100-
10193
- name: Release artifact
10294
if: ${{ inputs.release }}
10395
run: |

src/extension/extension.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ static struct runtime_config_t {
9393

9494
// `python_home_path`
9595
if(likely_running_from_editor) {
96-
python_home_path = lib_dir_path;
96+
python_home_path = lib_dir_path / "python";
9797
}
9898
else {
9999
auto platform_arch = std::string(PYGODOT_PLATFORM) + "-" + std::string(PYGODOT_ARCH);
100-
python_home_path = lib_dir_path / "lib" / platform_arch;
100+
python_home_path = lib_dir_path / "lib" / platform_arch / "python";
101101
}
102102
}
103103
} runtime_config;
@@ -171,12 +171,13 @@ static bool init_python_isolated() {
171171
auto py_version = py_major + "." + py_minor;
172172
auto py_version_no_dot = py_major + py_minor;
173173
auto python_zip_name = "python" + py_version_no_dot + ".zip";
174+
auto python_lib_path = runtime_config.python_home_path / "lib";
174175
auto python_lib_name = "python" + py_version;
175176

176177
add_module_search_path((runtime_config.python_home_path / python_zip_name).string());
177-
add_module_search_path((runtime_config.python_home_path / python_lib_name).string());
178-
add_module_search_path((runtime_config.python_home_path / python_lib_name / "lib-dynload").string());
179-
add_module_search_path((runtime_config.python_home_path / python_lib_name / "site-packages").string());
178+
add_module_search_path((python_lib_path / python_lib_name).string());
179+
add_module_search_path((python_lib_path / python_lib_name / "lib-dynload").string());
180+
add_module_search_path((python_lib_path / python_lib_name / "site-packages").string());
180181

181182
config.module_search_paths_set = 1;
182183

tools/build/prepare_python.py

+33-11
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class PlatformConfig:
1717
ext_suffixes: list[str]
1818
so_path: str
1919
python_lib_dir: str
20+
python_bin_paths: list[str]
2021
python_ext_dir: str
2122
executable: str
2223

@@ -42,6 +43,7 @@ def add_platform_config(*args, **kwargs):
4243
ext_suffixes = ['.so'],
4344
so_path = 'lib/libpython3.12.so.1.0',
4445
python_lib_dir = 'lib/python3.12',
46+
python_bin_paths = ['bin'],
4547
python_ext_dir = 'lib/python3.12/lib-dynload',
4648
executable = 'bin/python3.12',
4749
)
@@ -55,6 +57,7 @@ def add_platform_config(*args, **kwargs):
5557
ext_suffixes = ['.dll', '.pyd'],
5658
so_path = 'python312.dll',
5759
python_lib_dir = 'Lib',
60+
python_bin_paths = ['python.exe', 'pythonw.exe'],
5861
python_ext_dir = 'DLLs',
5962
executable = 'python.exe',
6063
)
@@ -68,6 +71,7 @@ def add_platform_config(*args, **kwargs):
6871
ext_suffixes = ['.so'],
6972
so_path = 'lib/libpython3.12.dylib',
7073
python_lib_dir = 'lib/python3.12',
74+
python_bin_paths = ['bin'],
7175
python_ext_dir = 'lib/python3.12/lib-dynload',
7276
executable = 'bin/python3.12',
7377
)
@@ -81,6 +85,7 @@ def add_platform_config(*args, **kwargs):
8185
ext_suffixes = ['.so'],
8286
so_path = 'lib/libpython3.12.dylib',
8387
python_lib_dir = 'lib/python3.12',
88+
python_bin_paths = ['bin'],
8489
python_ext_dir = 'lib/python3.12/lib-dynload',
8590
executable = 'bin/python3.12',
8691
)
@@ -105,32 +110,49 @@ def prepare_for_platform(platform: str, arch: str,
105110

106111
shutil.unpack_archive(src_dir / pathlib.Path(config.source_url).name, extract_dir = src_dir)
107112

108-
src = src_dir / 'python'
109-
src_lib_path = src / config.so_path
113+
src_python = src_dir / 'python'
114+
src_lib_path = src_python / config.so_path
110115
lib_filename = pathlib.Path(config.so_path).name
111116

112117
if platform == 'macos':
113118
# Rename the library id (which we depend on) to be in @rpath.
114119
# (it defaults to /install/lib/)
115-
subprocess.run(['install_name_tool', '-id', f'@rpath/{lib_filename}', src_lib_path], check=True)
120+
subprocess.run(['install_name_tool', '-id', f'@rpath/python/lib/{lib_filename}', src_lib_path], check=True)
121+
116122

117-
dest_dir.mkdir(parents=True, exist_ok=True)
118-
shutil.copy2(src_lib_path, dest_dir)
123+
dest_dir_python = dest_dir / 'python'
124+
dest_dir_python_lib = dest_dir_python / 'lib'
125+
dest_dir_python_lib.mkdir(parents=True, exist_ok=True)
119126

127+
shutil.copy2(src_lib_path, dest_dir_python_lib)
120128
if platform == 'macos':
121-
subprocess.run(['strip', '-x', dest_dir / lib_filename], check=True)
129+
subprocess.run(['strip', '-x', dest_dir_python_lib / lib_filename], check=True)
122130
else:
123-
subprocess.run(['strip', '-s', dest_dir / lib_filename], check=True)
131+
subprocess.run(['strip', '-s', dest_dir_python_lib / lib_filename], check=True)
132+
133+
for bin_path in config.python_bin_paths:
134+
src_path: pathlib.Path = src_python / bin_path
135+
136+
if src_path.is_file():
137+
shutil.copy2(src_path, dest_dir_python / bin_path)
138+
elif src_path.is_dir():
139+
shutil.copytree(src_path, dest_dir_python / bin_path, dirs_exist_ok=True)
140+
else:
141+
raise RuntimeError(f"Cannot find file: {src_path}")
142+
143+
if bin_path == 'bin':
144+
# Ignore the bin path in Godot.
145+
open(dest_dir_python / bin_path / '.gdignore', 'a').close()
124146

125-
if (src / config.python_ext_dir).exists():
126-
dest_ext_dir = dest_dir / 'python3.12' / 'lib-dynload'
147+
if (src_python / config.python_ext_dir).exists():
148+
dest_ext_dir = dest_dir_python_lib / 'python3.12' / 'lib-dynload'
127149
dest_ext_dir.mkdir(parents=True, exist_ok=True)
128150

129-
for path in (src / config.python_ext_dir).iterdir():
151+
for path in (src_python / config.python_ext_dir).iterdir():
130152
if any(suffix in path.suffixes for suffix in config.ext_suffixes):
131153
shutil.copy2(path, dest_ext_dir)
132154

133-
shutil.make_archive(dest_dir / 'python312', 'zip', root_dir=src / config.python_lib_dir, base_dir='')
155+
shutil.make_archive(dest_dir / 'python312', 'zip', root_dir=src_python / config.python_lib_dir, base_dir='')
134156

135157

136158
def get_python_for_platform(platform: str, arch: str, src_dir: pathlib.Path) -> pathlib.Path:

0 commit comments

Comments
 (0)