-
-
Notifications
You must be signed in to change notification settings - Fork 589
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Abstract apple framework creation behind a tool, which will
lipo
th…
…e input binaries together and create an appropriate `Info.plist`.
- Loading branch information
Showing
6 changed files
with
224 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 0 additions & 26 deletions
26
test/project/bin/libgdexample.macos.template_debug.framework/Resources/Info.plist
This file was deleted.
Oops, something went wrong.
26 changes: 0 additions & 26 deletions
26
test/project/bin/libgdexample.macos.template_release.framework/Resources/Info.plist
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import os | ||
import pathlib | ||
|
||
|
||
def exists(env): | ||
return True | ||
|
||
|
||
def options(opts): | ||
pass | ||
|
||
|
||
def generate( | ||
target, | ||
*, | ||
env, | ||
source, | ||
min_macos_version="10.12", | ||
min_ios_version="12.0", | ||
plist_keys=None, | ||
): | ||
""" | ||
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 binary sources to generate. | ||
: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. | ||
:param plist_keys: Additional keys to send to the plist generator. | ||
: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"LSMinimumSystemVersion={min_macos_version}" | ||
elif env["platform"] == "ios": | ||
dt_platform_name = "iphoneos" | ||
min_os_part = f"MinimumOSVersion={min_ios_version}" | ||
else: | ||
raise ValueError("Unsupported platform.") | ||
|
||
framework_path = pathlib.Path(target) | ||
assert framework_path.suffix == ".framework" | ||
framework_name = framework_path.name.removesuffix(".framework") | ||
|
||
plist_creation_script_path = (pathlib.Path(__file__).parent / "create_apple_framework_plist.sh").relative_to(os.getcwd()) | ||
plist_command = f"{plist_creation_script_path} $TARGET --set CFBundleExecutable={framework_name} --set DTPlatformName={dt_platform_name} --set {min_os_part}" | ||
if plist_keys: | ||
for key, value in plist_keys.items(): | ||
plist_command += f' --set "{key}={value}"' | ||
|
||
return [ | ||
# Create the binary itself. | ||
env.Command( | ||
str(framework_path / framework_name), | ||
source, | ||
action="lipo -create $SOURCE -output $TARGET", | ||
), | ||
# Create the Info.plist | ||
env.Command( | ||
str(framework_path / "Resources" / "Info.plist"), | ||
[str(plist_creation_script_path)], | ||
action=plist_command, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
#!/bin/bash | ||
|
||
USAGE_STRING="Usage: $0 plist_path --set CFBundleExecutable=executable [--set key=value]..." | ||
|
||
PLIST_PATH="" | ||
EXTRA_KEYS=() | ||
|
||
# Parse the command line arguments. | ||
while [[ $# -gt 0 ]]; do | ||
case $1 in | ||
--set) | ||
IFS='=' read -r key value <<< "$2" | ||
# Replace if key exists, otherwise add new key-value. | ||
found=false | ||
for ((i=0; i<${#EXTRA_KEYS[@]}; i++)); do | ||
if [[ "${EXTRA_KEYS[i]}" =~ ^$key= ]]; then | ||
EXTRA_KEYS[i]="$key=$value" | ||
found=true | ||
break | ||
fi | ||
done | ||
if [ "$found" = false ]; then | ||
EXTRA_KEYS+=("$key=$value") | ||
fi | ||
shift 2 | ||
;; | ||
*) | ||
# Assume positional argument is the plist path. | ||
if [ -n "$PLIST_PATH" ]; then | ||
# Cannot generate more than one plist; this was likely an error. | ||
echo "$USAGE_STRING" | ||
exit 1 | ||
fi | ||
PLIST_PATH="$1" | ||
shift | ||
;; | ||
esac | ||
done | ||
|
||
# Extract known keys from EXTRA_KEYS, for defaults and mandatory arguments. | ||
for ((i=0; i<${#EXTRA_KEYS[@]}; i++)); do | ||
IFS='=' read -r key value <<< "${EXTRA_KEYS[$i]}" | ||
case $key in | ||
CFBundleInfoDictionaryVersion) | ||
CFBundleInfoDictionaryVersion="$value" | ||
;; | ||
CFBundlePackageType) | ||
CFBundlePackageType="$value" | ||
;; | ||
CFBundleName) | ||
CFBundleName="$value" | ||
;; | ||
CFBundleExecutable) | ||
CFBundleExecutable="$value" | ||
;; | ||
CFBundleIdentifier) | ||
CFBundleIdentifier="$value" | ||
;; | ||
CFBundleVersion) | ||
CFBundleVersion="$value" | ||
;; | ||
CFBundleShortVersionString) | ||
CFBundleShortVersionString="$value" | ||
;; | ||
esac | ||
done | ||
|
||
# Check for mandatory arguments. | ||
if [ -z "$PLIST_PATH" ] || [ -z "$CFBundleExecutable" ]; then | ||
echo "$USAGE_STRING" | ||
exit 1 | ||
fi | ||
|
||
# Add defaults for missing arguments. | ||
if [ -z "$CFBundleInfoDictionaryVersion" ]; then | ||
CFBundleInfoDictionaryVersion="6.0" | ||
EXTRA_KEYS+=("CFBundleInfoDictionaryVersion=$CFBundleInfoDictionaryVersion") | ||
fi | ||
if [ -z "$CFBundlePackageType" ]; then | ||
CFBundlePackageType="FMWK" | ||
EXTRA_KEYS+=("CFBundlePackageType=$CFBundlePackageType") | ||
fi | ||
if [ -z "$CFBundleName" ]; then | ||
CFBundleName="$CFBundleExecutable" | ||
EXTRA_KEYS+=("CFBundleName=$CFBundleName") | ||
fi | ||
if [ -z "$CFBundleIdentifier" ]; then | ||
CFBundleIdentifier="com.example.$CFBundleName" | ||
EXTRA_KEYS+=("CFBundleIdentifier=$CFBundleIdentifier") | ||
fi | ||
if [ -z "$CFBundleVersion" ]; then | ||
CFBundleVersion="1.0.0" | ||
EXTRA_KEYS+=("CFBundleVersion=$CFBundleVersion") | ||
fi | ||
if [ -z "$CFBundleShortVersionString" ]; then | ||
CFBundleShortVersionString="$CFBundleVersion" | ||
EXTRA_KEYS+=("CFBundleShortVersionString=$CFBundleShortVersionString") | ||
fi | ||
|
||
# Ensure the directory exists. | ||
mkdir -p "$(dirname "$PLIST_PATH")" | ||
|
||
# Create the Info.plist file. | ||
{ | ||
echo '<?xml version="1.0" encoding="UTF-8"?>' | ||
echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' | ||
echo '<plist version="1.0">' | ||
echo '<dict>' | ||
|
||
for ((i=0; i<${#EXTRA_KEYS[@]}; i++)); do | ||
IFS='=' read -r key value <<< "${EXTRA_KEYS[$i]}" | ||
if [[ -n "$value" ]]; then | ||
echo " <key>$key</key>" | ||
echo " <string>$value</string>" | ||
fi | ||
done | ||
|
||
echo '</dict>' | ||
echo '</plist>' | ||
} > "$PLIST_PATH" | ||
|
||
# Confirm Info.plist was created. | ||
if [ -s "$PLIST_PATH" ]; then | ||
echo "$PLIST_PATH" | ||
else | ||
echo "Failed to create $PLIST_PATH." | ||
exit 1 | ||
fi |