Skip to content

Commit

Permalink
Abstract apple framework creation behind a tool, which will also gene…
Browse files Browse the repository at this point in the history
…rate an appropriate Info.plist file.
  • Loading branch information
Ivorforce committed Jan 2, 2025
1 parent 47f11bc commit 39ab389
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 75 deletions.
38 changes: 19 additions & 19 deletions test/SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,29 @@ if env["target"] in ["editor", "template_debug"]:
doc_data = env.GodotCPPDocData("src/gen/doc_data.gen.cpp", source=Glob("doc_classes/*.xml"))
sources.append(doc_data)

if env["platform"] == "macos":
library = env.SharedLibrary(
"project/bin/libgdexample.{}.{}.framework/libgdexample.{}.{}".format(
env["platform"], env["target"], env["platform"], env["target"]
),
if env["platform"] == "macos" or env["platform"] == "ios":
# Static libraries (.dylib) are not supported on the iOS app store.
# For consistency, both macOS and iOS will generate .xcframework instead.
framework_tool = Tool("apple_framework", toolpath=["../tools"])

framework_name = f"gdexample.{env['platform']}.{env['target']}"
if env["ios_simulator"]:
framework_name += ".simulator"

library_targets = framework_tool.generate(
f"bin/{framework_name}.xcframework",
env=env,
source=sources,
bundle_identifier=f"org.godotengine.{framework_name}"
)
elif env["platform"] == "ios":
if env["ios_simulator"]:
library = env.StaticLibrary(
"project/bin/libgdexample.{}.{}.simulator.a".format(env["platform"], env["target"]),
source=sources,
)
else:
library = env.StaticLibrary(
"project/bin/libgdexample.{}.{}.a".format(env["platform"], env["target"]),
source=sources,
)
else:
library = env.SharedLibrary(
library_targets = env.SharedLibrary(
"project/bin/libgdexample{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),
source=sources,
)

env.NoCache(library)
Default(library)
# Keep the binary intact for as long as possible.
env.Precious(library_targets)

env.NoCache(library_targets)
Default(library_targets)

This file was deleted.

This file was deleted.

8 changes: 4 additions & 4 deletions test/project/example.gdextension
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ compatibility_minimum = "4.1"

[libraries]

macos.debug = "res://bin/libgdexample.macos.template_debug.framework"
macos.release = "res://bin/libgdexample.macos.template_release.framework"
macos.debug = "res://bin/gdexample.macos.template_debug.xcframework"
macos.release = "res://bin/gdexample.macos.template_release.xcframework"
windows.debug.x86_32 = "res://bin/libgdexample.windows.template_debug.x86_32.dll"
windows.release.x86_32 = "res://bin/libgdexample.windows.template_release.x86_32.dll"
windows.debug.x86_64 = "res://bin/libgdexample.windows.template_debug.x86_64.dll"
Expand All @@ -29,8 +29,8 @@ android.debug.arm64 = "res://bin/libgdexample.android.template_debug.arm64.so"
android.release.arm64 = "res://bin/libgdexample.android.template_release.arm64.so"
ios.debug = "res://bin/libgdexample.ios.template_debug.xcframework"
ios.release = "res://bin/libgdexample.ios.template_release.xcframework"
web.debug.threads.wasm32 = "res://bin/libgdexample.web.template_debug.wasm32.wasm"
web.release.threads.wasm32 = "res://bin/libgdexample.web.template_release.wasm32.wasm"
web.debug.threads.wasm32 = "res://bin/gdexample.web.template_debug.wasm32.wasm"
web.release.threads.wasm32 = "res://bin/gdexample.web.template_release.wasm32.wasm"
web.debug.wasm32 = "res://bin/libgdexample.web.template_debug.wasm32.nothreads.wasm"
web.release.wasm32 = "res://bin/libgdexample.web.template_release.wasm32.nothreads.wasm"

Expand Down
84 changes: 84 additions & 0 deletions tools/apple_framework.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import pathlib


def exists(env):
return True


def options(opts):
pass


def generate(target, *, env, source, bundle_identifier: str, min_macos_version="10.12", min_ios_version="12.0"):
"""
Generates an Apple .framework folder, containing the binary.
:param target: Folder name of the framework, usually ending in `.framework`.
:param env: The environment.
:param source: A list of sources to pass to SharedLibrary.
:param bundle_identifier: A bundle identifier, like `org.godotengine.gdexample.macos.template_debug`.
:param min_macos_version: The minimum macOS version supported by the framework, if the platform is macos.
:param min_ios_version: The minimum iOS version supported by the framework, if the platform is iOS.
:return: A list of files to be created, the first of which is the binary path.
"""
if env["platform"] == "macos":
dt_platform_name = "macosx"
min_os_part = f"""
<key>LSMinimumSystemVersion</key>
<string>{min_macos_version}</string>\
"""
plist_subpath = pathlib.Path("Resources/Info.plist")
elif env["platform"] == "ios":
dt_platform_name = "iphoneos"
min_os_part = f"""
<key>MinimumOSVersion</key>
<string>{min_ios_version}</string>\
"""
plist_subpath = pathlib.Path("Info.plist")
else:
raise ValueError("Unsupported platform.")

framework_path = pathlib.Path(target)
framework_name = framework_path.name.removesuffix(".framework")

# This is required because they affect the binary name, which we need to be equal to the framework name.
env["SHLIBPREFIX"] = ""
env["SHLIBSUFFIX"] = ""

def create_info_plist(target, source, env):
pathlib.Path(target[0].path).write_text(f"""\
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>{framework_name}</string>
<key>CFBundleName</key>
<string>NumDot</string>
<key>CFBundleDisplayName</key>
<string>NumDot</string>
<key>CFBundleIdentifier</key>
<string>{bundle_identifier}</string>
<key>NSHumanReadableCopyright</key>
<string>Unlicensed</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>DTPlatformName</key>
<string>{dt_platform_name}</string>{min_os_part}
</dict>
</plist>
""")

return [
env.SharedLibrary(str(framework_path / framework_name), source=source),
env.Command(str(framework_path / plist_subpath), [], action=create_info_plist),
]

0 comments on commit 39ab389

Please sign in to comment.