1# Checking out and building Chromium for iOS 2 3There are instructions for other platforms linked from the 4[get the code](../get_the_code.md) page. 5 6## Instructions for Google Employees 7 8Are you a Google employee? See 9[go/building-chrome](https://goto.google.com/building-chrome) instead. 10 11[TOC] 12 13## System requirements 14 15* A 64-bit Mac running 10.12.6 or later. 16* [Xcode](https://developer.apple.com/xcode) 10.0+. 17* The current version of the JDK (required for the Closure compiler). 18 19## Install `depot_tools` 20 21Clone the `depot_tools` repository: 22 23```shell 24$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 25``` 26 27Add `depot_tools` to the end of your PATH (you will probably want to put this 28in your `~/.bashrc` or `~/.zshrc`). Assuming you cloned `depot_tools` to 29`/path/to/depot_tools`: 30 31```shell 32$ export PATH="$PATH:/path/to/depot_tools" 33``` 34 35## Get the code 36 37Create a `chromium` directory for the checkout and change to it (you can call 38this whatever you like and put it wherever you like, as 39long as the full path has no spaces): 40 41```shell 42$ mkdir chromium && cd chromium 43``` 44 45Run the `fetch` tool from `depot_tools` to check out the code and its 46dependencies. 47 48```shell 49$ fetch ios 50``` 51 52If you don't want the full repo history, you can save a lot of time by 53adding the `--no-history` flag to `fetch`. 54 55Expect the command to take 30 minutes on even a fast connection, and many 56hours on slower ones. 57 58When `fetch` completes, it will have created a hidden `.gclient` file and a 59directory called `src` in the working directory. The remaining instructions 60assume you have switched to the `src` directory: 61 62```shell 63$ cd src 64``` 65 66*Optional*: You can also [install API 67keys](https://www.chromium.org/developers/how-tos/api-keys) if you want your 68build to talk to some Google services, but this is not necessary for most 69development and testing purposes. 70 71## Setting up the build 72 73Since the iOS build is a bit more complicated than a desktop build, we provide 74`ios/build/tools/setup-gn.py`, which will create four appropriately configured 75build directories under `out` for Release and Debug device and simulator 76builds, and generates an appropriate Xcode workspace 77(`out/build/all.xcworkspace`) as well. 78 79You can customize the build by editing the file `$HOME/.setup-gn` (create it if 80it does not exist). Look at `src/ios/build/tools/setup-gn.config` for 81available configuration options. 82 83From this point, you can either build from Xcode or from the command line using 84`autoninja`. `setup-gn.py` creates sub-directories named 85`out/${configuration}-${platform}`, so for a `Debug` build for simulator use: 86 87```shell 88$ autoninja -C out/Debug-iphonesimulator gn_all 89``` 90 91(`autoninja` is a wrapper that automatically provides optimal values for the 92arguments passed to `ninja`.) 93 94Note: you need to run `setup-gn.py` script every time one of the `BUILD.gn` 95file is updated (either by you or after rebasing). If you forget to run it, 96the list of targets and files in the Xcode solution may be stale. 97 98You can also follow the manual instructions on the 99[Mac page](../mac_build_instructions.md), but make sure you set the 100GN arg `target_os="ios"`. 101 102## Building for device 103 104To be able to build and run Chromium and the tests for devices, you need to 105have an Apple developer account (a free one will work) and the appropriate 106provisioning profiles, then configure the build to use them. 107 108### Code signing identity 109 110Please refer to the Apple documentation on how to get a code signing identity 111and certificates. You can check that you have a code signing identity correctly 112installed by running the following command. 113 114```shell 115$ xcrun security find-identity -v -p codesigning 116 1) 0123456789ABCDEF0123456789ABCDEF01234567 "iPhone Developer: someone@example.com (XXXXXXXXXX)" 117 1 valid identities found 118``` 119 120If the command output says you have zero valid identities, then you do not 121have a code signing identity installed and need to get one from Apple. If 122you have more than one identity, the build system may select the wrong one 123automatically, and you can use the `ios_code_signing_identity` gn variable 124to control which one to use by setting it to the identity hash, e.g. to 125`"0123456789ABCDEF0123456789ABCDEF01234567"`. 126 127### Mobile provisioning profiles 128 129Once you have the code signing identity, you need to decide on a prefix 130for the application bundle identifier. This is controlled by the gn variable 131`ios_app_bundle_id_prefix` and usually corresponds to a reversed domain name 132(the default value is `"org.chromium"`). 133 134You then need to request provisioning profiles from Apple for your devices 135for the following bundle identifiers to build and run Chromium with these 136application extensions: 137 138- `${prefix}.chrome.ios.herebedragons` 139- `${prefix}.chrome.ios.herebedragons.ShareExtension` 140- `${prefix}.chrome.ios.herebedragons.TodayExtension` 141- `${prefix}.chrome.ios.herebedragons.SearchTodayExtension` 142 143All these certificates need to have the "App Groups" 144(`com.apple.security.application-groups`) capability enabled for 145the following groups: 146 147- `group.${prefix}.chrome` 148- `group.${prefix}.common` 149 150The `group.${prefix}.chrome` is only shared by Chromium and its extensions 151to share files and configurations while the `group.${prefix}.common` is shared 152with Chromium and other applications from the same organisation and can be used 153to send commands to Chromium. 154 155### Mobile provisioning profiles for tests 156 157In addition to that, you need a different provisioning profile for each 158test application. Those provisioning profile will have a bundle identifier 159matching the following pattern `${prefix}.gtest.${test-suite-name}` where 160`${test-suite-name}` is the name of the test suite with underscores changed 161to dashes (e.g. `base_unittests` app will use `${prefix}.gest.base-unittests` 162as bundle identifier). 163 164To be able to run the EarlGrey tests on a device, you'll need two provisioning 165profiles for EarlGrey and OCHamcrest frameworks: 166 167- `${prefix}.test.OCHamcrest` 168- `${prefix}.test.EarlGrey` 169 170In addition to that, then you'll need one additional provisioning profile for 171the XCTest module too. It must match the pattern: 172`${prefix}.gtest.${test-suite-name}-module`. 173 174### Other applications 175 176Other applications like `ios_web_shell` usually will require mobile provisioning 177profiles with bundle identifiers that may usually match the following pattern 178`${prefix}.${application-name}` and may require specific capabilities. 179 180Generally, if the mobile provisioning profile is missing then the code signing 181step will fail and will print the bundle identifier of the bundle that could not 182be signed on the command line, e.g.: 183 184```shell 185$ autoninja -C out/Debug-iphoneos ios_web_shell 186ninja: Entering directory `out/Debug-iphoneos' 187FAILED: ios_web_shell.app/ios_web_shell ios_web_shell.app/_CodeSignature/CodeResources ios_web_shell.app/embedded.mobileprovision 188python ../../build/config/ios/codesign.py code-sign-bundle -t=iphoneos -i=0123456789ABCDEF0123456789ABCDEF01234567 -e=../../build/config/ios/entitlements.plist -b=obj/ios/web/shell/ios_web_shell ios_web_shell.app 189Error: no mobile provisioning profile found for "org.chromium.ios-web-shell". 190ninja: build stopped: subcommand failed. 191``` 192 193Here, the build is failing because there are no mobile provisioning profiles 194installed that could sign the `ios_web_shell.app` bundle with the identity 195`0123456789ABCDEF0123456789ABCDEF01234567`. To fix the build, you'll need to 196request such a mobile provisioning profile from Apple. 197 198You can inspect the file passed via the `-e` flag to the `codesign.py` script 199to check which capabilites are required for the mobile provisioning profile 200(e.g. `src/build/config/ios/entitlements.plist` for the above build error, 201remember that the paths are relative to the build directory, not to the source 202directory). 203 204If the required capabilities are not enabled on the mobile provisioning profile, 205then it will be impossible to install the application on a device (Xcode will 206display an error stating that "The application was signed with invalid 207entitlements"). 208 209## Running apps from the commandline 210 211Any target that is built and runs on the bots (see [below](#Troubleshooting)) 212should run successfully in a local build. To run in the simulator from the 213command line, you can use `iossim`. For example, to run a debug build of 214`Chromium`: 215 216```shell 217$ out/Debug-iphonesimulator/iossim out/Debug-iphonesimulator/Chromium.app 218``` 219 220With Xcode 9, `iossim` no longer automatically launches the Simulator. This must now 221be done manually from within Xcode (`Xcode > Open Developer Tool > Simulator`), and 222also must be done *after* running `iossim`. 223 224### Passing arguments 225 226Arguments needed to be passed to the test application through `iossim`, such as 227`--gtest_filter=SomeTest.FooBar` should be passed through the `-c` flag: 228 229```shell 230$ out/Debug-iphonesimulator/iossim \ 231 -c "--gtest_filter=SomeTest.FooBar --gtest_repeat=3" \ 232 out/Debug-iphonesimulator/base_unittests.app 233``` 234 235### Running EarlGrey tests 236 237EarlGrey tests are run differently than other test targets, as there is an 238XCTest bundle that is injected into the target application. Therefore you must 239also pass in the test bundle: 240 241```shell 242$ out/Debug-iphonesimulator/iossim \ 243 out/Debug-iphonesimulator/ios_chrome_ui_egtests.app \ 244 out/Debug-iphonesimulator/ios_chrome_ui_egtests.app/PlugIns/ios_chrome_ui_egtests_module.xctest 245``` 246 247### Running on specific simulator 248 249By default, `iossim` will pick an arbitrary simulator to run the tests. If 250you want to run them on a specific simulator, you can use `-d` to pick the 251simulated device and `-s` to select the iOS version. 252 253For example, to run the tests on a simulated iPhone 6s running iOS 10.0, 254you would invoke `iossim` like this. 255 256```shell 257$ out/Debug-iphonesimulator/iossim -d 'iPhone 6s' -s '10.0' \ 258 out/Debug-iphonesimulator/base_unittests.app 259``` 260 261Please note that by default only a subset of simulator devices are installed 262with Xcode. You may have to install additional simulators in Xcode (or even 263an older version of Xcode) to be able to run on a specific configuration. 264 265Go to "Preferences > Components" tab in Xcode to install other simulator images 266(this is the location the setting is in Xcode 9.2; it may be different in other 267version of the tool). 268 269## Update your checkout 270 271To update an existing checkout, you can run 272 273```shell 274$ git rebase-update 275$ gclient sync 276``` 277 278The first command updates the primary Chromium source repository and rebases 279any of your local branches on top of tip-of-tree (aka the Git branch 280`origin/master`). If you don't want to use this script, you can also just use 281`git pull` or other common Git commands to update the repo. 282 283The second command syncs dependencies to the appropriate versions and re-runs 284hooks as needed. 285 286## Tips, tricks, and troubleshooting 287 288If you have problems building, join us in `#chromium` on `irc.freenode.net` and 289ask there. As mentioned above, be sure that the 290[waterfall](https://build.chromium.org/buildbot/waterfall/) is green and the tree 291is open before checking out. This will increase your chances of success. 292 293### Improving performance of `git status` 294 295#### Increase the vnode cache size 296 297`git status` is used frequently to determine the status of your checkout. Due 298to the large number of files in Chromium's checkout, `git status` performance 299can be quite variable. Increasing the system's vnode cache appears to help. 300By default, this command: 301 302```shell 303$ sysctl -a | egrep kern\..*vnodes 304``` 305 306Outputs `kern.maxvnodes: 263168` (263168 is 257 * 1024). To increase this 307setting: 308 309```shell 310$ sudo sysctl kern.maxvnodes=$((512*1024)) 311``` 312 313Higher values may be appropriate if you routinely move between different 314Chromium checkouts. This setting will reset on reboot, the startup setting can 315be set in `/etc/sysctl.conf`: 316 317```shell 318$ echo kern.maxvnodes=$((512*1024)) | sudo tee -a /etc/sysctl.conf 319``` 320 321Or edit the file directly. 322 323#### Configure git to use an untracked cache 324 325If `git --version` reports 2.8 or higher, try running 326 327```shell 328$ git update-index --test-untracked-cache 329``` 330 331If the output ends with `OK`, then the following may also improve performance of 332`git status`: 333 334```shell 335$ git config core.untrackedCache true 336``` 337 338If `git --version` reports 2.6 or higher, but below 2.8, you can instead run 339 340```shell 341$ git update-index --untracked-cache 342``` 343 344### Xcode license agreement 345 346If you're getting the error 347 348> Agreeing to the Xcode/iOS license requires admin privileges, please re-run as 349> root via sudo. 350 351the Xcode license hasn't been accepted yet which (contrary to the message) any 352user can do by running: 353 354```shell 355$ xcodebuild -license 356``` 357 358Only accepting for all users of the machine requires root: 359 360```shell 361$ sudo xcodebuild -license 362``` 363