77
88set -euxo pipefail
99
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
2722
2823FRAMEWORK_EXECUTORCH=" executorch:\
2924libexecutorch.a,\
@@ -33,7 +28,7 @@ libextension_data_loader.a,\
3328libextension_flat_tensor.a,\
3429libextension_module.a,\
3530libextension_tensor.a,\
36- :$HEADERS_PATH :ExecuTorch"
31+ :$HEADERS_RELATIVE_PATH :ExecuTorch"
3732
3833FRAMEWORK_BACKEND_COREML=" backend_coreml:\
3934libcoreml_util.a,\
@@ -75,33 +70,51 @@ libquantized_ops_lib.a,\
7570:"
7671
7772usage () {
78- echo " Usage: $0 [SOURCE_ROOT_DIR] [ OPTIONS]"
73+ echo " Usage: $0 [OPTIONS]"
7974 echo " Build frameworks for Apple platforms."
80- echo " SOURCE_ROOT_DIR defaults to the current directory if not provided."
8175 echo
8276 echo " Options:"
83- echo " --output=DIR Output directory. Default: 'cmake-out'"
8477 echo " --Debug Build Debug version."
8578 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."
9586 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"
9887 exit 0
9988}
10089
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+
101115for arg in " $@ " ; do
102116 case $arg in
103117 -h|--help) usage ;;
104- --output=* ) OUTPUT=" ${arg#* =} " ;;
105118 --Release)
106119 if [[ ! " ${MODES[*]:- } " =~ \b Release\b ]]; then
107120 MODES+=(" Release" )
@@ -112,119 +125,50 @@ for arg in "$@"; do
112125 MODES+=(" Debug" )
113126 fi
114127 ;;
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" ;;
124135 * )
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
131138 ;;
132139 esac
133140done
134141
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-
173142echo " Building libraries"
174143
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
215146 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)
217161 done
218162done
219163
220164echo " Exporting headers"
221165
222- mkdir -p " $HEADERS_PATH "
166+ mkdir -p " $HEADERS_ABSOLUTE_PATH "
223167
224168" $SOURCE_ROOT_DIR " /scripts/print_exported_headers.py --buck2=$( realpath " $BUCK2 " ) --targets \
225169 //extension/module: \
226170 //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"
228172
229173# HACK: XCFrameworks don't appear to support exporting any build
230174# options, but we need the following:
@@ -234,13 +178,14 @@ mkdir -p "$HEADERS_PATH"
234178sed -i ' ' ' 1i\
235179#define C10_USING_CUSTOM_GENERATED_MACROS
236180' \
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"
239183
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 /"
241185
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 '
244189module ExecuTorch {
245190 umbrella header "ExecuTorch/ExecuTorch.h"
246191 export *
@@ -250,47 +195,56 @@ EOF
250195echo " Creating frameworks"
251196
252197append_framework_flag () {
253- local flag =" $1 "
198+ local option_name =" $1 "
254199 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
258212 local name spec
259213 name=$( echo " $framework " | cut -d: -f1)
260214 spec=$( echo " $framework " | cut -d: -f2-)
261215 framework=" ${name} _$( echo " $mode " | tr ' [:upper:]' ' [:lower:]' ) :${spec} "
262- fi
263- echo " Framework: $framework "
264- FRAMEWORK_FLAGS+=(" --framework=$framework " )
265216 fi
217+ echo " Adding framework: ${framework} "
218+ FRAMEWORK_FLAGS+=(" --framework=$framework " )
266219}
267220
268221for mode in " ${MODES[@]} " ; do
269222 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} " )
273226 done
274227
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 "
283236
237+ cd " ${OUTPUT_DIR} "
284238 " $SOURCE_ROOT_DIR " /scripts/create_frameworks.sh " ${FRAMEWORK_FLAGS[@]} "
285239done
286240
287241echo " Cleaning up"
288242
289- for platform in " ${PLATFORMS [@]} " ; do
290- rm -rf " $platform "
243+ for preset in " ${PRESETS [@]} " ; do
244+ rm -rf " ${OUTPUT_DIR} / ${preset} / $preset "
291245done
292246
293- rm -rf " $HEADERS_PATH "
247+ rm -rf " $HEADERS_ABSOLUTE_PATH "
294248
295249echo " Running tests"
296250
0 commit comments