|
1 |
| -# Build and cross-compilation |
| 1 | +# Building with CMake |
2 | 2 |
|
3 |
| -TBA |
| 3 | +Although buck2 is the main build system for the ExecuTorch project, it's also |
| 4 | +possible to build core pieces of the runtime using [CMake](https://cmake.org/) |
| 5 | +for easier integration with other build systems. Even if you don't use CMake |
| 6 | +directly, CMake can emit scripts for other format like Make or Ninja. For information, see |
| 7 | +[cmake-generators(7)](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html). |
| 8 | + |
| 9 | +## Targets Built by the CMake Build System |
| 10 | + |
| 11 | +ExecuTorch's CMake build system doesn't cover everything that the buck2 build |
| 12 | +system covers. It can only build pieces of the runtime that are likely to be |
| 13 | +useful to embedded systems users. |
| 14 | + |
| 15 | +- `libexecutorch.a`: The core of the ExecuTorch runtime. Does not contain any |
| 16 | + operator/kernel definitions or backend definitions. |
| 17 | +- `libportable_kernels.a`: The implementations of ATen-compatible operators, |
| 18 | + following the signatures in `//kernels/portable/functions.yaml`. |
| 19 | +- `libportable_kernels_bindings.a`: Generated code that registers the contents |
| 20 | + of `libportable_kernels.a` with the runtime. |
| 21 | + - NOTE: This must be linked into your application with a flag like |
| 22 | + `-Wl,-force_load` or `-Wl,--whole-archive`. It contains load-time functions |
| 23 | + that automatically register the kernels, but linkers will often prune those |
| 24 | + functions by default because there are no direct calls to them. |
| 25 | +- `executor_runner`: An example tool that runs a `.pte` program file using all |
| 26 | + `1` values as inputs, and prints the outputs to stdout. It is linked with |
| 27 | + `libportable_kernels.a`, so the program may use any of the operators it |
| 28 | + implements. |
| 29 | + |
| 30 | +## One-time setup to prepare for CMake Build |
| 31 | + |
| 32 | +Follow the steps below to have the tools ready before using CMake to build on your machine. |
| 33 | + |
| 34 | +1. Clone the repo and install buck2 as described in the "Runtime Setup" section |
| 35 | + of [Setting Up ExecuTorch](getting-started-setup.md#building-a-runtime) |
| 36 | + - `buck2` is necessary because the CMake build system runs `buck2` commands |
| 37 | + to extract source lists from the primary build system. It will be possible |
| 38 | + to configure the CMake system to avoid calling `buck2`, though. |
| 39 | +2. If your system's version of python3 is older than 3.11: |
| 40 | + - Run `pip install tomli` |
| 41 | + - This provides an import required by a script that the CMake build system |
| 42 | + calls to extract source lists from `buck2`. Consider doing this `pip |
| 43 | + install` inside your conda environment if you created one during ExecuTorch setup. see [Setting up |
| 44 | + ExecuTorch](getting-started-setup.md). |
| 45 | +3. Install CMake version 3.19 or later |
| 46 | + - conda install cmake |
| 47 | + |
| 48 | + |
| 49 | +## Configure the CMake Build |
| 50 | + |
| 51 | +Follow these steps after cloning or pulling the upstream repo, since the build |
| 52 | +dependencies may have changed. |
| 53 | + |
| 54 | +```bash |
| 55 | +# cd to the root of the executorch repo |
| 56 | +cd executorch |
| 57 | + |
| 58 | +# Clean and configure the CMake build system. It's good practice to do this |
| 59 | +# whenever cloning or pulling the upstream repo. |
| 60 | +# |
| 61 | +# NOTE: If your `buck2` binary is not on the PATH, you can change this line to |
| 62 | +# say something like `-DBUCK2=/tmp/buck2` to point directly to the tool. |
| 63 | +(rm -rf cmake-out && mkdir cmake-out && cd cmake-out && cmake -DBUCK2=buck2 ..) |
| 64 | +``` |
| 65 | + |
| 66 | +Once this is done, you don't need to do it again until you pull from the upstream repo again, or if you modify any CMake-related files. |
| 67 | + |
| 68 | +## Build the runtime components |
| 69 | + |
| 70 | +Build all targets with |
| 71 | + |
| 72 | +```bash |
| 73 | +# cd to the root of the executorch repo |
| 74 | +cd executorch |
| 75 | + |
| 76 | +# Build using the configuration that you previously generated under the |
| 77 | +# `cmake-out` directory. |
| 78 | +# |
| 79 | +# NOTE: The `-j` argument specifies how many jobs/processes to use when |
| 80 | +# building, and tends to speed up the build significantly. It's typical to use |
| 81 | +# "core count + 1" as the `-j` value. |
| 82 | +cmake --build cmake-out -j9 |
| 83 | +``` |
| 84 | + |
| 85 | +## Use an example app `executor_runner` to execute a .pte file |
| 86 | + |
| 87 | +First, generate an `add.pte` or other ExecuTorch program file using the |
| 88 | +instructions as described in |
| 89 | +[Setting up ExecuTorch](getting-started-setup.md#building-a-runtime). |
| 90 | + |
| 91 | +Then, pass it to the command line tool: |
| 92 | + |
| 93 | +```bash |
| 94 | +./cmake-out/executor_runner --model_path path/to/add.pte |
| 95 | +``` |
| 96 | + |
| 97 | +If it worked, you should see the message "Model executed successfully" followed |
| 98 | +by the output values. |
| 99 | + |
| 100 | +``` |
| 101 | +I 00:00:00.002052 executorch:executor_runner.cpp:75] Model file add.pte is loaded. |
| 102 | +I 00:00:00.002086 executorch:executor_runner.cpp:85] Running method forward |
| 103 | +I 00:00:00.002092 executorch:executor_runner.cpp:140] Setting up non-const buffer 1, size 48. |
| 104 | +I 00:00:00.002149 executorch:executor_runner.cpp:181] Method loaded. |
| 105 | +I 00:00:00.002154 executorch:util.h:105] input already initialized, refilling. |
| 106 | +I 00:00:00.002157 executorch:util.h:105] input already initialized, refilling. |
| 107 | +I 00:00:00.002159 executorch:executor_runner.cpp:186] Inputs prepared. |
| 108 | +I 00:00:00.011684 executorch:executor_runner.cpp:195] Model executed successfully. |
| 109 | +I 00:00:00.011709 executorch:executor_runner.cpp:210] 8.000000 |
| 110 | +``` |
| 111 | + |
| 112 | + |
| 113 | +## Cross compilation |
| 114 | + |
| 115 | +Follwing are instruction on how to perform cross compilation for Android and iOS. |
| 116 | + |
| 117 | +### Android |
| 118 | +- Prerequisite: [Android NDK](https://developer.android.com/ndk), choose one of the following: |
| 119 | + - Option 1: Download Android Studio by following the instructions to [install ndk](https://developer.android.com/studio/projects/install-ndk). |
| 120 | + - Option 2: Download Android NDK directly from [here](https://developer.android.com/ndk/downloads). |
| 121 | + |
| 122 | +Assuming Android NDK is available, run: |
| 123 | +```bash |
| 124 | +# Run the following lines from the `executorch/` folder |
| 125 | +rm -rf cmake-android-out && mkdir cmake-android-out && cd cmake-android-out |
| 126 | + |
| 127 | +# point -DCMAKE_TOOLCHAIN_FILE to the location where ndk is installed |
| 128 | +# Run `which buck2`, if it returns empty (meaning the system doesn't know where buck2 is installed), pass in pass in this flag `-DBUCK2=/path/to/buck2` pointing to buck2 |
| 129 | +cmake -DCMAKE_TOOLCHAIN_FILE=/Users/{user_name}/Library/Android/sdk/ndk/25.2.9519653/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a .. |
| 130 | + |
| 131 | +cd .. |
| 132 | +cmake --build cmake-android-out -j9 |
| 133 | + |
| 134 | +# push the binary to an Android device |
| 135 | +adb push cmake-android-out/executor_runner /data/local/tmp/executorch |
| 136 | + |
| 137 | +adb shell "/data/local/tmp/executorch/executor_runner --model_path /data/local/tmp/executorch/add.ff" |
| 138 | +``` |
| 139 | + |
| 140 | +### IOS |
| 141 | +```{note} |
| 142 | + While we're working on making it a smoother experience, here is an early workflow to try out cross compilation for iOS. |
| 143 | +``` |
| 144 | +Only supported in macOS: |
| 145 | + |
| 146 | +Prerequisites: |
| 147 | +- [XCode](https://developer.apple.com/xcode/) |
| 148 | + |
| 149 | +After XCode is installed, |
| 150 | + |
| 151 | +1. Get the iOS cmake toolchain by using one of the following options: |
| 152 | + - Option 1 [recommended] : use the `ios.toolchain.cmake` from the following github repo: |
| 153 | + |
| 154 | + ```bash |
| 155 | + git clone https://github.com/leetal/ios-cmake.git |
| 156 | + ``` |
| 157 | + |
| 158 | + - Option2 [wip], use the `iOS.cmake` from PyTorch, the |
| 159 | + toolchain is located in `executorch/third-party/pytorch/pytorch/blob/main/cmake/iOS.cmake` |
| 160 | + |
| 161 | + |
| 162 | +2. Use the tool chain provided in the repro to build the ExecuTorch library. |
| 163 | + ```bash |
| 164 | + rm -rf cmake-ios-out && mkdir cmake-ios-out && cd cmake-ios-out |
| 165 | +
|
| 166 | + # change the platform accordingly, please refer to the table listed in Readme |
| 167 | + cmake . -G Xcode -DCMAKE_TOOLCHAIN_FILE=~/ios-cmake/ios.toolchain.cmake -DPLATFORM=SIMULATOR |
| 168 | +
|
| 169 | + # Create an include folder in cmake-ios-out to include all header files |
| 170 | + mkdir include |
| 171 | + cp -r ../runtime include |
| 172 | + cp -r ../extension include |
| 173 | + cp -r ../utils include |
| 174 | + ``` |
| 175 | + |
| 176 | + |
| 177 | +3. XCode setup |
| 178 | + |
| 179 | +If using the iOS cmake tool chain from `https://github.com/leetal/ios-cmake.git`, after build is complete, perform the following steps: |
| 180 | + |
| 181 | +1. Open the project in XCode, drag the `executorch.xcodeproj` generated from Step 2 to `Frameworks`. |
| 182 | +1. Go to project Target’s `Build Phases` - `Link Binaries With Libraries`, click the **+** sign and add all the library files located in `cmake-ios-out/build`. |
| 183 | +1. Navigate to the project `Build Settings`: |
| 184 | + - Set the value **Header Search Paths** to `cmake-ios-out/include`. |
| 185 | + - Set **Library Search Paths** to `cmake-ios-out/build`. |
| 186 | + - In **other linker flags**, add a custom linker flag `-all_load.` |
0 commit comments