Skip to content

Commit

Permalink
Default to platform-specific arch on macOS for now, as universal buil…
Browse files Browse the repository at this point in the history
…ds do not work anyway. Set the python library name to @rpath/LIBNAME, such that it is linked correctly, rather than patching post-create.
  • Loading branch information
Ivorforce committed Oct 26, 2024
1 parent 7e11e60 commit 2c76eff
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 21 deletions.
13 changes: 7 additions & 6 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,12 @@ elif env['platform'] == 'macos':
# For Objective-C++ files
env.Append(CCFLAGS = ['-ObjC++'])

# Need to set the rpath for relative loading of libpython to succeed.
# This doesn't work for some reason
# env.Replace(RPATH=['@loader_path'])
env.Append(LINKFLAGS=['-Wl,-rpath,@loader_path'])


env.Prepend(CPPPATH=['src', os.fspath(generated_path), 'extern/pybind11/include'])

env.Append(CPPDEFINES = [f'PYGODOT_PLATFORM=\\"{env["platform"]}\\"'])
Expand All @@ -370,6 +376,7 @@ def _append_python_config(env, target, **kwargs):
env.Append(CPPPATH = _config_vars.include_flags)

if env['platform'] != 'windows':
env['python_ldlibrary'] = _config_vars.ldlibrary
env.Append(CPPDEFINES = [f'PYTHON_LIBRARY_PATH=\\"{_config_vars.ldlibrary or ""}\\"'])

dest = pathlib.Path(target[0].path)
Expand Down Expand Up @@ -406,12 +413,6 @@ library = env.SharedLibrary(
source = sources,
)

if env['platform'] == 'macos':
# Change the expected lib directory of libpython to @loader-path using rpaths.
env.AddPostAction(library, env.Action(
"install_name_tool -add_rpath @loader_path bin/macos-universal/libgodot-python.macos.universal.dylib"
"&& install_name_tool -change /install/lib/libpython3.12.dylib @rpath/libpython3.12.dylib bin/macos-universal/libgodot-python.macos.universal.dylib"
))

Default(library)
Return("env")
Expand Down
2 changes: 1 addition & 1 deletion test/python.gdextension
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ entry_symbol = "python_extension_init"

[libraries]

macos = "res://bin/macos-universal/libgodot-python.macos.universal.dylib"
macos.x86_64 = "res://bin/macos-x86_64/libgodot-python.macos.x86_64.dylib"

windows.x86_32 = "res://bin/windows-x86_32/libgodot-python.windows.x86_32.dll"
windows.x86_64 = "res://bin/windows-x86_64/libgodot-python.windows.x86_64.dll"
Expand Down
6 changes: 3 additions & 3 deletions tools/build/build_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ def process_arch(env):
# No architecture specified. Default to arm64 if building for Android,
# universal if building for macOS or iOS, wasm32 if building for web,
# otherwise default to the host architecture.
if env["platform"] in ["macos", "ios"]:
env["arch"] = "universal"
elif env["platform"] == "android":
# if env["platform"] in ["macos", "ios"]:
# env["arch"] = "universal"
if env["platform"] == "android":
env["arch"] = "arm64"
elif env["platform"] == "web":
env["arch"] = "wasm32"
Expand Down
6 changes: 3 additions & 3 deletions tools/build/platform/godotcpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,9 +406,9 @@ def generate(env):
# No architecture specified. Default to arm64 if building for Android,
# universal if building for macOS or iOS, wasm32 if building for web,
# otherwise default to the host architecture.
if env["platform"] in ["macos", "ios"]:
env["arch"] = "universal"
elif env["platform"] == "android":
# if env["platform"] in ["macos", "ios"]:
# env["arch"] = "universal"
if env["platform"] == "android":
env["arch"] = "arm64"
elif env["platform"] == "web":
env["arch"] = "wasm32"
Expand Down
7 changes: 5 additions & 2 deletions tools/build/platform/ios.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ def exists(env):


def generate(env):
if env["arch"] not in ("universal", "arm64", "x86_64"):
raise ValueError("Only universal, arm64, and x86_64 are supported on iOS. Exiting.")
if env["arch"] == "universal":
print("Universal is currently not supported on iOS. Exiting.")
if env["arch"] not in ("arm64", "x86_64"):
print("Only arm64, and x86_64 are supported on iOS. Exiting.")
env.Exit(1)

if env["ios_simulator"]:
sdk_name = "iphonesimulator"
Expand Down
6 changes: 4 additions & 2 deletions tools/build/platform/macos.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ def exists(env):


def generate(env):
if env["arch"] not in ("universal", "arm64", "x86_64"):
print("Only universal, arm64, and x86_64 are supported on macOS. Exiting.")
if env["arch"] == "universal":
print("Universal is currently not supported on macOS. Exiting.")
if env["arch"] not in ("arm64", "x86_64"):
print("Only arm64, and x86_64 are supported on macOS. Exiting.")
env.Exit(1)

if sys.platform == "darwin":
Expand Down
15 changes: 11 additions & 4 deletions tools/build/prepare_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def add_platform_config(*args, **kwargs):

add_platform_config(
platform = 'macos',
arch = 'universal',
arch = 'x86_64',
source_url = 'https://github.com/indygreg/python-build-standalone/releases/download/'
'20231002/cpython-3.12.0+20231002-x86_64-apple-darwin-install_only.tar.gz',
so_suffixes = ['.os'],
Expand Down Expand Up @@ -93,14 +93,21 @@ def prepare_for_platform(platform: str, arch: str,
shutil.unpack_archive(src_dir / pathlib.Path(config.source_url).name, extract_dir = src_dir)

src = src_dir / 'python'
src_lib_path = src / config.so_path
lib_filename = pathlib.Path(config.so_path).name

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

dest_dir.mkdir(parents=True, exist_ok=True)
shutil.copy2(src_lib_path, dest_dir)

shutil.copy2(src / config.so_path, dest_dir)
if platform == 'macos':
subprocess.run(['strip', '-x', str(dest_dir / pathlib.Path(config.so_path).name)], check=True)
subprocess.run(['strip', '-x', dest_dir / lib_filename], check=True)
else:
subprocess.run(['strip', '-s', str(dest_dir / pathlib.Path(config.so_path).name)], check=True)
subprocess.run(['strip', '-s', dest_dir / lib_filename], check=True)

if (src / config.python_ext_dir).exists():
dest_ext_dir = dest_dir / 'python3.12' / 'lib-dynload'
Expand Down

0 comments on commit 2c76eff

Please sign in to comment.