7
7
8
8
set -euxo pipefail
9
9
10
- SOURCE_ROOT_DIR=" "
11
- OUTPUT=" cmake-out"
12
- MODES=()
13
- TOOLCHAIN=" "
14
- PYTHON=$( which python3)
15
- COREML=OFF
16
- CUSTOM=OFF
17
- MPS=OFF
18
- OPTIMIZED=OFF
19
- PORTABLE=OFF
20
- QUANTIZED=OFF
21
- XNNPACK=OFF
22
- HEADERS_PATH=" include"
23
-
24
- PLATFORMS=(" ios" " simulator" " macos" )
25
- PLATFORM_FLAGS=(" OS64" " SIMULATORARM64" " MAC_ARM64" )
26
- PLATFORM_TARGET=(" 17.0" " 17.0" " 10.15" )
10
+ MODES=(" Release" " Debug" )
11
+ PRESETS=(" ios" " ios-simulator" " macos" )
12
+
13
+ SOURCE_ROOT_DIR=$( git rev-parse --show-toplevel)
14
+ OUTPUT_DIR=" ${SOURCE_ROOT_DIR} /cmake-out"
15
+ HEADERS_RELATIVE_PATH=" include"
16
+ HEADERS_ABSOLUTE_PATH=" ${OUTPUT_DIR} /${HEADERS_RELATIVE_PATH} "
17
+
18
+ BUCK2=$( python3 " $SOURCE_ROOT_DIR /tools/cmake/resolve_buck.py" --cache_dir=" $SOURCE_ROOT_DIR /buck2-bin" )
19
+ if [[ " $BUCK2 " == " buck2" ]]; then
20
+ BUCK2=$( command -v buck2)
21
+ fi
27
22
28
23
FRAMEWORK_EXECUTORCH=" executorch:\
29
24
libexecutorch.a,\
@@ -33,7 +28,7 @@ libextension_data_loader.a,\
33
28
libextension_flat_tensor.a,\
34
29
libextension_module.a,\
35
30
libextension_tensor.a,\
36
- :$HEADERS_PATH :ExecuTorch"
31
+ :$HEADERS_RELATIVE_PATH :ExecuTorch"
37
32
38
33
FRAMEWORK_BACKEND_COREML=" backend_coreml:\
39
34
libcoreml_util.a,\
@@ -75,33 +70,51 @@ libquantized_ops_lib.a,\
75
70
:"
76
71
77
72
usage () {
78
- echo " Usage: $0 [SOURCE_ROOT_DIR] [ OPTIONS]"
73
+ echo " Usage: $0 [OPTIONS]"
79
74
echo " Build frameworks for Apple platforms."
80
- echo " SOURCE_ROOT_DIR defaults to the current directory if not provided."
81
75
echo
82
76
echo " Options:"
83
- echo " --output=DIR Output directory. Default: 'cmake-out'"
84
77
echo " --Debug Build Debug version."
85
78
echo " --Release Build Release version."
86
- echo " --toolchain=FILE CMake toolchain file. Default: '\$ SOURCE_ROOT_DIR/third-party/ios-cmake/ios.toolchain.cmake'"
87
- echo " --python=FILE Python executable path. Default: Path of python3 in \$ PATH"
88
- echo " --coreml Build the Core ML backend."
89
- echo " --custom Build the Custom kernels."
90
- echo " --mps Build the Metal Performance Shaders backend."
91
- echo " --optimized Build the Optimized kernels."
92
- echo " --portable Build the Portable kernels."
93
- echo " --quantized Build the Quantized kernels."
94
- echo " --xnnpack Build the XNNPACK backend."
79
+ echo " --coreml Only build the Core ML backend."
80
+ echo " --custom Only build the Custom kernels."
81
+ echo " --mps Only build the Metal Performance Shaders backend."
82
+ echo " --optimized Only build the Optimized kernels."
83
+ echo " --portable Only build the Portable kernels."
84
+ echo " --quantized Only build the Quantized kernels."
85
+ echo " --xnnpack Only build the XNNPACK backend."
95
86
echo
96
- echo " Example:"
97
- echo " $0 /path/to/source/root --output=cmake-out --toolchain=/path/to/toolchain --python=/path/to/python3 --coreml --mps --xnnpack"
98
87
exit 0
99
88
}
100
89
90
+ CMAKE_OPTIONS_OVERRIDE=()
91
+ set_cmake_options_override () {
92
+ local option_name=" $1 "
93
+
94
+ if [[ ${# CMAKE_OPTIONS_OVERRIDE[@]} -eq 0 ]]; then
95
+ # Since the user wants specific options, turn everything off
96
+ CMAKE_OPTIONS_OVERRIDE=(
97
+ " -DEXECUTORCH_BUILD_COREML=OFF"
98
+ " -DEXECUTORCH_BUILD_KERNELS_CUSTOM=OFF"
99
+ " -DEXECUTORCH_BUILD_MPS=OFF"
100
+ " -DEXECUTORCH_BUILD_KERNELS_OPTIMIZED=OFF"
101
+ " -DEXECUTORCH_BUILD_PORTABLE_OPS=OFF"
102
+ " -DEXECUTORCH_BUILD_KERNELS_QUANTIZED=OFF"
103
+ " -DEXECUTORCH_BUILD_XNNPACK=OFF"
104
+ )
105
+ fi
106
+
107
+ for i in " ${! CMAKE_OPTIONS_OVERRIDE[@]} " ; do
108
+ if [[ " ${CMAKE_OPTIONS_OVERRIDE[$i]} " =~ " -D${option_name} =OFF" ]]; then
109
+ CMAKE_OPTIONS_OVERRIDE[$i ]=" -D${option_name} =ON"
110
+ break
111
+ fi
112
+ done
113
+ }
114
+
101
115
for arg in " $@ " ; do
102
116
case $arg in
103
117
-h|--help) usage ;;
104
- --output=* ) OUTPUT=" ${arg#* =} " ;;
105
118
--Release)
106
119
if [[ ! " ${MODES[*]:- } " =~ \b Release\b ]]; then
107
120
MODES+=(" Release" )
@@ -112,119 +125,50 @@ for arg in "$@"; do
112
125
MODES+=(" Debug" )
113
126
fi
114
127
;;
115
- --toolchain=* ) TOOLCHAIN=" ${arg#* =} " ;;
116
- --python=* ) PYTHON=" ${arg#* =} " ;;
117
- --coreml) COREML=ON ;;
118
- --custom) CUSTOM=ON ;;
119
- --mps) MPS=ON ;;
120
- --optimized) OPTIMIZED=ON ;;
121
- --portable) PORTABLE=ON ;;
122
- --quantized) QUANTIZED=ON ;;
123
- --xnnpack) XNNPACK=ON ;;
128
+ --coreml) set_cmake_options_override " EXECUTORCH_BUILD_COREML" ;;
129
+ --custom) set_cmake_options_override " EXECUTORCH_BUILD_KERNELS_CUSTOM" ;;
130
+ --mps) set_cmake_options_override " EXECUTORCH_BUILD_MPS" ;;
131
+ --optimized) set_cmake_options_override " EXECUTORCH_BUILD_KERNELS_OPTIMIZED" ;;
132
+ --portable) set_cmake_options_override " EXECUTORCH_BUILD_PORTABLE_OPS" ;;
133
+ --quantized) set_cmake_options_override " EXECUTORCH_BUILD_KERNELS_QUANTIZED" ;;
134
+ --xnnpack) set_cmake_options_override " EXECUTORCH_BUILD_XNNPACK" ;;
124
135
* )
125
- if [[ -z " $SOURCE_ROOT_DIR " ]]; then
126
- SOURCE_ROOT_DIR=" $arg "
127
- else
128
- echo " Invalid argument: $arg "
129
- exit 1
130
- fi
136
+ echo -e " \033[31m[error] unknown option: ${arg} \033[0m"
137
+ exit 1
131
138
;;
132
139
esac
133
140
done
134
141
135
- if [ ${# MODES[@]} -eq 0 ]; then
136
- MODES=(" Release" )
137
- fi
138
-
139
- if [[ -z " $SOURCE_ROOT_DIR " ]]; then
140
- SOURCE_ROOT_DIR=$( pwd)
141
- fi
142
-
143
- if [[ -z " $TOOLCHAIN " ]]; then
144
- TOOLCHAIN=" $SOURCE_ROOT_DIR /third-party/ios-cmake/ios.toolchain.cmake"
145
- fi
146
- [[ -f " $TOOLCHAIN " ]] || { echo >&2 " Toolchain file $TOOLCHAIN does not exist." ; exit 1; }
147
-
148
- BUCK2=$( " $PYTHON " " $SOURCE_ROOT_DIR /tools/cmake/resolve_buck.py" --cache_dir=" $SOURCE_ROOT_DIR /buck2-bin" )
149
-
150
- if [[ " $BUCK2 " == " buck2" ]]; then
151
- BUCK2=$( command -v buck2)
152
- fi
153
-
154
- check_command () {
155
- if [[ " $1 " == * /* ]]; then
156
- if [[ ! -x " $1 " ]]; then
157
- echo " Error: Command not found or not executable at '$1 '" >&2
158
- exit 1
159
- fi
160
- else
161
- if ! command -v " $1 " > /dev/null 2>&1 ; then
162
- echo " Error: Command '$1 ' not found in PATH" >&2
163
- exit 1
164
- fi
165
- fi
166
- }
167
-
168
- check_command cmake
169
- check_command rsync
170
- check_command " $PYTHON "
171
- check_command " $BUCK2 "
172
-
173
142
echo " Building libraries"
174
143
175
- rm -rf " $OUTPUT " && mkdir -p " $OUTPUT " && cd " $OUTPUT " || exit 1
176
-
177
- cmake_build () {
178
- local platform=$1
179
- local platform_flag=$2
180
- local platform_target=$3
181
- local mode=$4
182
- echo " Building for $platform ($mode ) with flag $platform_flag "
183
- mkdir -p " $platform " && cd " $platform " || exit 1
184
- cmake " $SOURCE_ROOT_DIR " -G Xcode \
185
- -DCMAKE_BUILD_TYPE=" $mode " \
186
- -DCMAKE_TOOLCHAIN_FILE=" $TOOLCHAIN " \
187
- -DCMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD=" c++17" \
188
- -DCMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY=" libc++" \
189
- -DCMAKE_C_FLAGS=" -ffile-prefix-map=$SOURCE_ROOT_DIR =/executorch -fdebug-prefix-map=$SOURCE_ROOT_DIR =/executorch" \
190
- -DCMAKE_CXX_FLAGS=" -ffile-prefix-map=$SOURCE_ROOT_DIR =/executorch -fdebug-prefix-map=$SOURCE_ROOT_DIR =/executorch" \
191
- -DPYTHON_EXECUTABLE=" $PYTHON " \
192
- -DEXECUTORCH_BUILD_COREML=$COREML \
193
- -DEXECUTORCH_BUILD_MPS=$MPS \
194
- -DEXECUTORCH_BUILD_XNNPACK=$XNNPACK \
195
- -DEXECUTORCH_XNNPACK_SHARED_WORKSPACE=ON \
196
- -DEXECUTORCH_BUILD_EXECUTOR_RUNNER=OFF \
197
- -DEXECUTORCH_BUILD_EXTENSION_APPLE=ON \
198
- -DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \
199
- -DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
200
- -DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON \
201
- -DEXECUTORCH_BUILD_KERNELS_CUSTOM=$CUSTOM \
202
- -DEXECUTORCH_BUILD_KERNELS_OPTIMIZED=$OPTIMIZED \
203
- -DEXECUTORCH_BUILD_KERNELS_QUANTIZED=$QUANTIZED \
204
- -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=" $( pwd) " \
205
- ${platform_flag: +-DPLATFORM=$platform_flag } \
206
- ${platform_target: +-DDEPLOYMENT_TARGET=$platform_target } \
207
- --log-level=VERBOSE
208
- cmake --build . \
209
- --config " $mode " \
210
- --verbose
211
- cd -
212
- }
213
-
214
- for index in ${! PLATFORMS[*]} ; do
144
+ rm -rf " ${OUTPUT_DIR} "
145
+ for preset in " ${PRESETS[@]} " ; do
215
146
for mode in " ${MODES[@]} " ; do
216
- cmake_build " ${PLATFORMS[$index]} " " ${PLATFORM_FLAGS[$index]} " " ${PLATFORM_TARGET[$index]} " " $mode "
147
+ output_dir=" ${OUTPUT_DIR} /${preset} "
148
+ echo " Building preset ${preset} (${mode} ) in ${output_dir} ..."
149
+
150
+ # Do NOT add options here. Update the respective presets instead.
151
+ cmake -S " ${SOURCE_ROOT_DIR} " \
152
+ -B " ${output_dir} " \
153
+ -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=" ${output_dir} " \
154
+ -DCMAKE_BUILD_TYPE=" ${mode} " \
155
+ ${CMAKE_OPTIONS_OVERRIDE[@]:- } \
156
+ --preset " ${preset} "
157
+
158
+ cmake --build " ${output_dir} " \
159
+ --config " ${mode} " \
160
+ -j$( sysctl -n hw.ncpu)
217
161
done
218
162
done
219
163
220
164
echo " Exporting headers"
221
165
222
- mkdir -p " $HEADERS_PATH "
166
+ mkdir -p " $HEADERS_ABSOLUTE_PATH "
223
167
224
168
" $SOURCE_ROOT_DIR " /scripts/print_exported_headers.py --buck2=$( realpath " $BUCK2 " ) --targets \
225
169
//extension/module: \
226
170
//extension/tensor: \
227
- | rsync -av --files-from=- " $SOURCE_ROOT_DIR " " $HEADERS_PATH /executorch"
171
+ | rsync -av --files-from=- " $SOURCE_ROOT_DIR " " $HEADERS_ABSOLUTE_PATH /executorch"
228
172
229
173
# HACK: XCFrameworks don't appear to support exporting any build
230
174
# options, but we need the following:
@@ -234,13 +178,14 @@ mkdir -p "$HEADERS_PATH"
234
178
sed -i ' ' ' 1i\
235
179
#define C10_USING_CUSTOM_GENERATED_MACROS
236
180
' \
237
- " $HEADERS_PATH /executorch/runtime/core/portable_type/c10/c10/macros/Macros.h" \
238
- " $HEADERS_PATH /executorch/runtime/core/portable_type/c10/c10/macros/Export.h"
181
+ " $HEADERS_ABSOLUTE_PATH /executorch/runtime/core/portable_type/c10/c10/macros/Macros.h" \
182
+ " $HEADERS_ABSOLUTE_PATH /executorch/runtime/core/portable_type/c10/c10/macros/Export.h"
239
183
240
- cp -r $HEADERS_PATH /executorch/runtime/core/portable_type/c10/c10 " $HEADERS_PATH /"
184
+ cp -r $HEADERS_ABSOLUTE_PATH /executorch/runtime/core/portable_type/c10/c10 " $HEADERS_ABSOLUTE_PATH /"
241
185
242
- cp " $SOURCE_ROOT_DIR /extension/apple/ExecuTorch/Exported/" * .h " $HEADERS_PATH /executorch"
243
- cat > " $HEADERS_PATH /module.modulemap" << 'EOF '
186
+ cp " $SOURCE_ROOT_DIR /extension/apple/ExecuTorch/Exported/" * .h " $HEADERS_ABSOLUTE_PATH /executorch"
187
+
188
+ cat > " $HEADERS_ABSOLUTE_PATH /module.modulemap" << 'EOF '
244
189
module ExecuTorch {
245
190
umbrella header "ExecuTorch/ExecuTorch.h"
246
191
export *
@@ -250,47 +195,56 @@ EOF
250
195
echo " Creating frameworks"
251
196
252
197
append_framework_flag () {
253
- local flag =" $1 "
198
+ local option_name =" $1 "
254
199
local framework=" $2 "
255
- local mode=" ${3:- } "
256
- if [[ $flag == ON ]]; then
257
- if [[ -n " $mode " && " $mode " != " Release" ]]; then
200
+ local mode=" $3 "
201
+
202
+ if [[ ${# CMAKE_OPTIONS_OVERRIDE[@]} -gt 0 && -n " $option_name " ]]; then
203
+ for cmake_option in " ${CMAKE_OPTIONS_OVERRIDE[@]} " ; do
204
+ if [[ " $cmake_option " =~ " -D${option_name} =OFF" ]]; then
205
+ echo " Skipping framework: ${framework} "
206
+ return
207
+ fi
208
+ done
209
+ fi
210
+
211
+ if [[ -n " $mode " && " $mode " != " Release" ]]; then
258
212
local name spec
259
213
name=$( echo " $framework " | cut -d: -f1)
260
214
spec=$( echo " $framework " | cut -d: -f2-)
261
215
framework=" ${name} _$( echo " $mode " | tr ' [:upper:]' ' [:lower:]' ) :${spec} "
262
- fi
263
- echo " Framework: $framework "
264
- FRAMEWORK_FLAGS+=(" --framework=$framework " )
265
216
fi
217
+ echo " Adding framework: ${framework} "
218
+ FRAMEWORK_FLAGS+=(" --framework=$framework " )
266
219
}
267
220
268
221
for mode in " ${MODES[@]} " ; do
269
222
FRAMEWORK_FLAGS=()
270
- for platform in " ${PLATFORMS [@]} " ; do
271
- echo " Directory : $platform / $ mode"
272
- FRAMEWORK_FLAGS+=(" --directory=$platform / $ mode" )
223
+ for preset in " ${PRESETS [@]} " ; do
224
+ echo " Framework directory : ${preset} / ${ mode} "
225
+ FRAMEWORK_FLAGS+=(" --directory=${preset} / ${ mode} " )
273
226
done
274
227
275
- append_framework_flag " ON " " $FRAMEWORK_EXECUTORCH " " $mode "
276
- append_framework_flag " $COREML " " $FRAMEWORK_BACKEND_COREML " " $mode "
277
- append_framework_flag " $MPS " " $FRAMEWORK_BACKEND_MPS " " $mode "
278
- append_framework_flag " $XNNPACK " " $FRAMEWORK_BACKEND_XNNPACK " " $mode "
279
- append_framework_flag " $CUSTOM " " $FRAMEWORK_KERNELS_CUSTOM " " $mode "
280
- append_framework_flag " $OPTIMIZED " " $FRAMEWORK_KERNELS_OPTIMIZED " " $mode "
281
- append_framework_flag " $PORTABLE " " $FRAMEWORK_KERNELS_PORTABLE " " $mode "
282
- append_framework_flag " $QUANTIZED " " $FRAMEWORK_KERNELS_QUANTIZED " " $mode "
228
+ append_framework_flag " " " $FRAMEWORK_EXECUTORCH " " $mode "
229
+ append_framework_flag " EXECUTORCH_BUILD_COREML " " $FRAMEWORK_BACKEND_COREML " " $mode "
230
+ append_framework_flag " EXECUTORCH_BUILD_MPS " " $FRAMEWORK_BACKEND_MPS " " $mode "
231
+ append_framework_flag " EXECUTORCH_BUILD_XNNPACK " " $FRAMEWORK_BACKEND_XNNPACK " " $mode "
232
+ append_framework_flag " EXECUTORCH_BUILD_KERNELS_CUSTOM " " $FRAMEWORK_KERNELS_CUSTOM " " $mode "
233
+ append_framework_flag " EXECUTORCH_BUILD_KERNELS_OPTIMIZED " " $FRAMEWORK_KERNELS_OPTIMIZED " " $mode "
234
+ append_framework_flag " EXECUTORCH_BUILD_PORTABLE_OPS " " $FRAMEWORK_KERNELS_PORTABLE " " $mode "
235
+ append_framework_flag " EXECUTORCH_BUILD_KERNELS_QUANTIZED " " $FRAMEWORK_KERNELS_QUANTIZED " " $mode "
283
236
237
+ cd " ${OUTPUT_DIR} "
284
238
" $SOURCE_ROOT_DIR " /scripts/create_frameworks.sh " ${FRAMEWORK_FLAGS[@]} "
285
239
done
286
240
287
241
echo " Cleaning up"
288
242
289
- for platform in " ${PLATFORMS [@]} " ; do
290
- rm -rf " $platform "
243
+ for preset in " ${PRESETS [@]} " ; do
244
+ rm -rf " ${OUTPUT_DIR} / ${preset} / $preset "
291
245
done
292
246
293
- rm -rf " $HEADERS_PATH "
247
+ rm -rf " $HEADERS_ABSOLUTE_PATH "
294
248
295
249
echo " Running tests"
296
250
0 commit comments