Skip to content

Commit 7f053b7

Browse files
committed
Add Python script for generating xcframeworks.
1 parent 34d8c45 commit 7f053b7

File tree

5 files changed

+122
-7
lines changed

5 files changed

+122
-7
lines changed

src/scripts/build_bulk_libldks.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ def parse_config() -> ScriptConfig:
2020
BuildConfig('macosx', '', ['arm64', 'x86_64']),
2121
BuildConfig('macosx', '-macabi', ['arm64', 'x86_64'])
2222
]
23-
2423
config.LIBLDK_BUILD_CONFIGURATIONS = individual_configurations
2524

2625
return config

src/scripts/build_individual_libldk.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
import shutil
23
import subprocess
34
import sys
45

@@ -35,13 +36,12 @@ def run(config: ScriptConfig):
3536
build_products_directory,
3637
config.RUST_CONFIGURATION,
3738
human_readable_platform,
38-
'raw'
39+
'architectures'
3940
)
4041
lipo_binary_directory = os.path.join(
4142
build_products_directory,
4243
config.RUST_CONFIGURATION,
43-
human_readable_platform,
44-
'lipo'
44+
human_readable_platform
4545
)
4646
if config.LIPO_BINARY_OUTPUT_DIRECTORY:
4747
lipo_binary_directory = config.LIPO_BINARY_OUTPUT_DIRECTORY
@@ -77,9 +77,9 @@ def run(config: ScriptConfig):
7777
print('Rust architecture:', rust_architecture)
7878
print('Rust target OS:', rust_target_os)
7979

80+
cargo_target_directory = os.path.join(config.LDK_C_BINDINGS_DIRECTORY, 'target')
8081
cargo_raw_binary_origin = os.path.join(
81-
config.LDK_C_BINDINGS_DIRECTORY,
82-
'target',
82+
cargo_target_directory,
8383
f'{rust_architecture}-apple-{rust_target_os}',
8484
config.RUST_CONFIGURATION,
8585
'libldk.a'
@@ -90,6 +90,8 @@ def run(config: ScriptConfig):
9090
# create the directory if it doesn't exist
9191
os.makedirs(current_architecture_binary_directory, exist_ok=True)
9292

93+
# stop the complaints about directories not being empty
94+
shutil.rmtree(cargo_target_directory)
9395
subprocess.check_call([CARGO_PATH, 'clean'], cwd=config.LDK_C_BINDINGS_DIRECTORY)
9496

9597
# cargo build -Z build-std=panic_abort,std --features "std" --target "${RUST_ARCH}-apple-${RUST_TARGET_OS}" $RUST_CONFIGURATION_FLAG

src/scripts/generate_xcframework.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import os
2+
import shutil
3+
import subprocess
4+
5+
from script_config import ScriptConfig, ArchiveConfig
6+
7+
8+
def parse_config() -> ScriptConfig:
9+
config = ScriptConfig.parse(allow_ldk_argument=True, parse_configuration=True)
10+
11+
individual_configurations: [ArchiveConfig] = [
12+
ArchiveConfig('iOS Simulator', 'iphonesimulator'),
13+
ArchiveConfig('iOS', 'iphoneos'),
14+
ArchiveConfig('OS X', 'macosx'),
15+
ArchiveConfig('macOS,variant=Mac Catalyst', 'catalyst'),
16+
]
17+
config.XCARCHIVE_GENERATION_CONFIGURATIONS = individual_configurations
18+
19+
return config
20+
21+
22+
def run(config: ScriptConfig):
23+
build_products_directory = os.path.realpath(os.path.join(os.path.dirname(__file__), '../../bindings/bin'))
24+
xcode_project_path = os.path.realpath(
25+
os.path.join(os.path.dirname(__file__), '../../xcode/LDKFramework/LDKFramework.xcodeproj')
26+
)
27+
framework_input_flags: [str] = []
28+
xcframework_output_path = os.path.join(
29+
build_products_directory,
30+
config.RUST_CONFIGURATION,
31+
'LDKFramework.xcframework'
32+
)
33+
34+
child_environment = dict(os.environ)
35+
child_environment['LDK_C_BINDINGS_BASE'] = config.LDK_C_BINDINGS_BASE
36+
37+
archive_configurations = config.XCARCHIVE_GENERATION_CONFIGURATIONS
38+
for current_configuration in archive_configurations:
39+
current_destination = current_configuration.destination
40+
current_human_readable_platform = current_configuration.human_readable_platform
41+
42+
lipo_binary_directory = os.path.join(
43+
build_products_directory,
44+
config.RUST_CONFIGURATION,
45+
current_human_readable_platform,
46+
)
47+
derived_data_directory = os.path.join(
48+
build_products_directory,
49+
config.RUST_CONFIGURATION,
50+
current_human_readable_platform,
51+
'DerivedData'
52+
)
53+
xcarchive_output_path = os.path.join(
54+
build_products_directory,
55+
config.RUST_CONFIGURATION,
56+
current_human_readable_platform,
57+
current_human_readable_platform # the last component is the filename excluding .xcarchive
58+
)
59+
60+
# create clean derived data directory
61+
if os.path.exists(derived_data_directory):
62+
shutil.rmtree(derived_data_directory)
63+
os.makedirs(derived_data_directory, exist_ok=False)
64+
65+
child_environment['LDK_C_BINDINGS_BINARY_DIRECTORY'] = lipo_binary_directory
66+
67+
# xcodebuild archive -verbose -project "${BASEDIR}/LDKFramework/LDKFramework.xcodeproj" -scheme LDKFramework -destination "generic/platform=${CURRENT_DESTINATION_NAME}" -derivedDataPath "${CURRENT_DERIVED_DATA_DIRECTORY}" -archivePath "${CURRENT_ARCHIVE_PATH}" ENABLE_BITCODE=NO EXCLUDED_ARCHS="i386 armv7" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES LDK_C_BINDINGS_BASE="${LDK_DIRECTORY}" LDK_C_BINDINGS_BINARY_DIRECTORY="${CURRENT_LIPO_DIRECTORY_PATH}"
68+
subprocess.check_call(
69+
[
70+
'xcodebuild',
71+
'archive',
72+
'-verbose',
73+
'-project',
74+
xcode_project_path,
75+
'-scheme',
76+
'LDKFramework',
77+
'-destination',
78+
f'generic/platform={current_destination}',
79+
'-derivedDataPath',
80+
derived_data_directory,
81+
'-archivePath',
82+
xcarchive_output_path,
83+
'ENABLE_BITCODE=NO',
84+
'EXCLUDED_ARCHS="i386 armv7"',
85+
'SKIP_INSTALL=NO',
86+
'BUILD_LIBRARY_FOR_DISTRIBUTION=YES',
87+
f'LDK_C_BINDINGS_BASE="{config.LDK_C_BINDINGS_BASE}"',
88+
f'LDK_C_BINDINGS_BINARY_DIRECTORY="{lipo_binary_directory}"',
89+
f'LDK_C_BINDINGS_BINARY_DIRECTORY_OVERRIDE=""',
90+
], env=child_environment
91+
)
92+
93+
# clean up the derived data
94+
shutil.rmtree(derived_data_directory)
95+
96+
# XCFRAMEWORK_INPUT_FLAGS="${XCFRAMEWORK_INPUT_FLAGS}-framework ${CURRENT_ARCHIVE_PATH}.xcarchive/Products/Library/Frameworks/LDKFramework.framework "
97+
framework_input_flags += ['-framework', f'{xcarchive_output_path}.xcarchive/Products/Library/Frameworks/LDKFramework.framework']
98+
99+
# xcodebuild -create-xcframework ${XCFRAMEWORK_INPUT_FLAGS} -output ${XCFRAMEWORK_OUTPUT_PATH}"
100+
if os.path.exists(xcframework_output_path):
101+
shutil.rmtree(xcframework_output_path)
102+
subprocess.check_call(['xcodebuild', '-create-xcframework', *framework_input_flags, '-output', xcframework_output_path])
103+
104+
105+
if __name__ == '__main__':
106+
script_config = parse_config()
107+
run(script_config)

src/scripts/script_config.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,18 @@ def __init__(self, platform: str, llvm_target_triple_suffix: str, architectures:
1616
self.human_readable_platform = 'catalyst'
1717

1818

19+
class ArchiveConfig:
20+
def __init__(self, destination: str, human_readable_platform: str):
21+
self.destination = destination
22+
self.human_readable_platform = human_readable_platform
23+
24+
1925
class ScriptConfig:
2026
def __init__(self):
2127
self.LDK_C_BINDINGS_BASE: str = ''
2228
self.LDK_C_BINDINGS_DIRECTORY: str = ''
2329
self.LIBLDK_BUILD_CONFIGURATIONS: [BuildConfig] = []
30+
self.XCARCHIVE_GENERATION_CONFIGURATIONS: [ArchiveConfig] = []
2431
self.CONFIGURATION: str = ''
2532
self.RUST_CONFIGURATION: str = ''
2633
self.RUST_CONFIGURATION_FLAG: str = ''

xcode/LDKFramework/LDKFramework.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,7 @@
13521352
);
13531353
runOnlyForDeploymentPostprocessing = 0;
13541354
shellPath = /bin/sh;
1355-
shellScript = "SCRIPT_PATH=\"${PROJECT_DIR}/../../src/scripts/prepare_headers.py\"\n# copy headers\n/usr/bin/python3 \"${SCRIPT_PATH}\"\n\necho \"Building LDK binaries if necessary.\"\necho \"LDK_C_BINDINGS_BINARY_DIRECTORY: ${LDK_C_BINDINGS_BINARY_DIRECTORY}\"\n\nif [[ -z \"${LDK_C_BINDINGS_BINARY_DIRECTORY}\" ]]; then\n echo \"LDK_C_BINDINGS_BINARY_DIRECTORY undefined, building deemed necessary\"\n if [[ -z \"${LDK_C_BINDINGS_BINARY_DIRECTORY_OVERRIDE}\" ]]; then\n echo \"LDK_C_BINDINGS_BINARY_DIRECTORY_OVERRIDE undefined, build impossible without destination\"\n exit 1\n fi\n export LDK_C_BINDINGS_BINARY_DIRECTORY=\"${LDK_C_BINDINGS_BINARY_DIRECTORY_OVERRIDE}\"\n SCRIPT_PATH=\"${PROJECT_DIR}/../../src/scripts/build_individual_libldk.py\"\n # build binary\n /usr/bin/python3 \"${SCRIPT_PATH}\"\nfi\n";
1355+
shellScript = "echo \"Copying headers…\"\necho \"LDK_C_BINDINGS_BASE: ${LDK_C_BINDINGS_BASE}\"\nSCRIPT_PATH=\"${PROJECT_DIR}/../../src/scripts/prepare_headers.py\"\n# copy headers\n/usr/bin/python3 \"${SCRIPT_PATH}\"\n\necho \"Building LDK binaries if necessary…\"\necho \"LDK_C_BINDINGS_BINARY_DIRECTORY: ${LDK_C_BINDINGS_BINARY_DIRECTORY}\"\necho \"LDK_C_BINDINGS_BINARY_DIRECTORY_OVERRIDE: ${LDK_C_BINDINGS_BINARY_DIRECTORY_OVERRIDE}\"\n\nif [[ -z \"${LDK_C_BINDINGS_BINARY_DIRECTORY}\" ]]; then\n echo \"LDK_C_BINDINGS_BINARY_DIRECTORY undefined, building deemed necessary\"\n if [[ -z \"${LDK_C_BINDINGS_BINARY_DIRECTORY_OVERRIDE}\" ]]; then\n echo \"LDK_C_BINDINGS_BINARY_DIRECTORY_OVERRIDE undefined, build impossible without destination\"\n exit 1\n fi\n export LDK_C_BINDINGS_BINARY_DIRECTORY=\"${LDK_C_BINDINGS_BINARY_DIRECTORY_OVERRIDE}\"\n SCRIPT_PATH=\"${PROJECT_DIR}/../../src/scripts/build_individual_libldk.py\"\n # build binary\n /usr/bin/python3 \"${SCRIPT_PATH}\"\nelse\n echo \"LDK_C_BINDINGS_BINARY_DIRECTORY is set, building unnecessary.\"\nfi\n";
13561356
};
13571357
/* End PBXShellScriptBuildPhase section */
13581358

0 commit comments

Comments
 (0)