Skip to content

Commit d1808c1

Browse files
authored
Add a way to build swift code as part of the executorch runtime frame… (#11072)
1 parent 6357580 commit d1808c1

File tree

2 files changed

+76
-10
lines changed

2 files changed

+76
-10
lines changed

extension/apple/CMakeLists.txt

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,29 @@
1111

1212
cmake_minimum_required(VERSION 3.19)
1313

14+
enable_language(Swift)
15+
1416
# Source root directory for executorch.
1517
if(NOT EXECUTORCH_ROOT)
1618
set(EXECUTORCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..)
1719
endif()
1820

1921
add_library(extension_apple)
2022

21-
file(GLOB EXPORTED_SOURCES
23+
file(GLOB OBJC_SOURCES
2224
ExecuTorch/Exported/*.m
2325
ExecuTorch/Exported/*.mm
24-
)
25-
26-
file(GLOB INTERNAL_SOURCES
2726
ExecuTorch/Internal/*.m
2827
ExecuTorch/Internal/*.mm
2928
)
3029

30+
file(GLOB SWIFT_SOURCES
31+
ExecuTorch/Exported/*.swift
32+
)
33+
3134
target_sources(extension_apple PRIVATE
32-
${EXPORTED_SOURCES}
33-
${INTERNAL_SOURCES}
35+
${OBJC_SOURCES}
36+
${SWIFT_SOURCES}
3437
)
3538

3639
target_include_directories(extension_apple
@@ -43,9 +46,41 @@ target_link_libraries(extension_apple
4346
PRIVATE executorch ${FOUNDATION_FRAMEWORK}
4447
)
4548

46-
target_compile_options(extension_apple PUBLIC ${_common_compile_options})
47-
target_compile_options(extension_apple PRIVATE
49+
set_source_files_properties(${OBJC_SOURCES} PROPERTIES COMPILE_FLAGS
4850
"-fobjc-arc"
4951
"-fno-exceptions"
5052
"-fno-rtti"
5153
)
54+
55+
set(MODULE_MAP_DIR ${CMAKE_CURRENT_BINARY_DIR}/module)
56+
set(MODULE_MAP_FILE ${MODULE_MAP_DIR}/module.modulemap)
57+
58+
configure_file(
59+
"${CMAKE_CURRENT_SOURCE_DIR}/ExecuTorch/Exported/ExecuTorch.h"
60+
"${MODULE_MAP_DIR}/ExecuTorch.h"
61+
COPYONLY
62+
)
63+
64+
file(MAKE_DIRECTORY ${MODULE_MAP_DIR})
65+
file(WRITE ${MODULE_MAP_FILE}
66+
"module ExecuTorch {
67+
umbrella header \"ExecuTorch.h\"
68+
export *
69+
}
70+
")
71+
72+
set(SWIFT_CLANG_INTEROP_FLAGS "-Xcc -fmodule-map-file=${MODULE_MAP_FILE} -I ${MODULE_MAP_DIR}")
73+
74+
set_target_properties(extension_apple PROPERTIES
75+
Swift_MODULE_NAME "ExecuTorch"
76+
Swift_FLAGS "${SWIFT_CLANG_INTEROP_FLAGS}"
77+
XCODE_ATTRIBUTE_SWIFT_MODULE_NAME "ExecuTorch"
78+
XCODE_ATTRIBUTE_BUILD_LIBRARY_FOR_DISTRIBUTION YES
79+
XCODE_ATTRIBUTE_SWIFT_ENABLE_TESTABILITY YES
80+
XCODE_ATTRIBUTE_OTHER_SWIFT_FLAGS "${SWIFT_CLANG_INTEROP_FLAGS}"
81+
)
82+
83+
add_custom_command(
84+
TARGET extension_apple POST_BUILD
85+
COMMAND ${CMAKE_COMMAND} -E rm -rf ${MODULE_MAP_DIR}
86+
)

scripts/create_frameworks.sh

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ function usage() {
1313
echo ""
1414
echo "Usage: $0 --directory=<dir> --framework=<lib> [--output=<output>]"
1515
echo " --directory: Directory containing the libs"
16-
echo " --framework: Framework to create in the format 'target:lib1,lib2:headers'"
16+
echo " --framework: Framework to create in the format 'target:lib1,lib2:headers:swiftmodule'"
1717
echo " 'target' is the name of the target library."
1818
echo " 'lib1,lib2' is a comma-separated list of input libraries."
1919
echo " 'headers' is an optional path to a directory with headers."
20+
echo " ':swiftmodule' is an optional module name to embed its .swiftmodule folder"
2021
echo " --output: Optional output directory. Defaults to the current directory."
2122
echo ""
2223
echo "Example:"
23-
echo "$0 --directory=ios-arm64 --directory=ios-arm64-simulator --framework=\"mylib:lib1.a,lib2.a:include\" --output=output/dir"
24+
echo "$0 --directory=ios-arm64 --directory=ios-arm64-simulator --framework=\"mylib:lib1.a,lib2.a:include:MyModule\" --output=output/dir"
2425
exit 1
2526
}
2627

@@ -58,6 +59,8 @@ create_xcframework() {
5859
libraries_list=$(echo "$1" | cut -d: -f2 | tr ',' '\n')
5960
local headers_directory
6061
headers_directory=$(echo "$1" | cut -d: -f3)
62+
local swift_module
63+
swift_module=$(echo "$1" | cut -d: -f4)
6164
local dir
6265
local libraries=()
6366
local merged_libs=()
@@ -117,8 +120,36 @@ create_xcframework() {
117120

118121
echo -e "\nCreating XCFramework ${xcframework}"
119122

123+
# Create the new .xcframework.
120124
xcodebuild -create-xcframework "${libraries[@]}" -output "${xcframework}"
121125

126+
# Copy the .swiftmodule files into the .xcframework if applicable.
127+
if [[ -n "$swift_module" ]]; then
128+
echo -e "\nCopying Swift module ${swift_module}.swiftmodule into ${xcframework}"
129+
for dir in "${directories[@]}"; do
130+
local module_source_dir="${dir}/${swift_module}.swiftmodule"
131+
if [ ! -d "$module_source_dir" ]; then
132+
echo "Swiftmodule directory ${module_source_dir} does not exist"
133+
exit 1
134+
fi
135+
local swiftmodule_file
136+
swiftmodule_file=$(find "$module_source_dir" -maxdepth 1 -type f -name '*.swiftmodule' | head -n1)
137+
if [[ -z "$swiftmodule_file" ]]; then
138+
echo "No .swiftmodule file found in ${module_source_dir}"
139+
exit 1
140+
fi
141+
142+
local dir_suffix
143+
dir_suffix=$(echo "$dir" | cut -d'/' -f1 | tr '[:upper:]' '[:lower:]' | sed 's/[\/\.~]/_/g')
144+
for slice_path in "${xcframework}/${dir_suffix}-"*; do
145+
if [ -d "${slice_path}/Headers" ]; then
146+
echo " - Copying ${swiftmodule_file##*/} to ${slice_path}/Headers/${swift_module}.swiftmodule"
147+
cp "${swiftmodule_file}" "${slice_path}/Headers/${swift_module}.swiftmodule"
148+
fi
149+
done
150+
done
151+
fi
152+
122153
echo -e "\nDeleting intermediate libraries:"
123154
for merged_lib in "${merged_libs[@]}"; do
124155
if [[ -f "${merged_lib}" ]]; then

0 commit comments

Comments
 (0)