|
| 1 | +# iOS Prebuild Scripts Documentation |
| 2 | + |
| 3 | +This folder contains scripts for creating precompiled XCFrameworks for React Native's dependencies. These scripts automate the process of downloading, building, and packaging third-party libraries into distributable XCFramework bundles for iOS. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The iOS prebuild system creates precompiled frameworks to reduce build times for React Native iOS apps. Instead of compiling dependencies from source during every build, these scripts package them as ready-to-use XCFrameworks. |
| 8 | + |
| 9 | +The prebuild process creates a Swift package that builds frameworks for the following 3rd party libraries: |
| 10 | + |
| 11 | +- boost |
| 12 | +- folly |
| 13 | +- glog |
| 14 | +- fmt |
| 15 | +- double-conversion |
| 16 | +- socketrocket |
| 17 | +- fast-float |
| 18 | + |
| 19 | +## Main Scripts |
| 20 | + |
| 21 | +### `cli.js` |
| 22 | + |
| 23 | +Command-line interface for the prebuild system. Provides the following options: |
| 24 | + |
| 25 | +```bash |
| 26 | +# Setup: Download and prepare dependencies |
| 27 | +node cli.js --setup |
| 28 | + |
| 29 | +# Build: Compile dependencies for specified platforms |
| 30 | +node cli.js --build --platforms ios,macos |
| 31 | + |
| 32 | +# Compose: Create XCFrameworks from built artifacts |
| 33 | +node cli.js --compose |
| 34 | + |
| 35 | +# Create Swift Package: Generate Package.swift file |
| 36 | +node cli.js --swiftpackage |
| 37 | +``` |
| 38 | + |
| 39 | +**Options:** |
| 40 | +- `--setup` / `-s`: Download and setup dependencies |
| 41 | +- `--build` / `-b`: Build dependencies for target platforms |
| 42 | +- `--compose` / `-c`: Compose XCFrameworks from built artifacts |
| 43 | +- `--swiftpackage` / `-w`: Generate Package.swift file |
| 44 | +- `--platforms` / `-p`: Target platforms (ios, macos, catalyst, tvos, visionos) |
| 45 | +- `--configurations` / `-g`: Build configurations (Debug, Release) |
| 46 | +- `--dependencies` / `-d`: Specific dependencies to process |
| 47 | +- `--clean`: Clean build folder before building |
| 48 | +- `--identity` / `-i`: Signing identity for frameworks |
| 49 | + |
| 50 | +### `setupDependencies.js` |
| 51 | + |
| 52 | +Handles downloading and preparing third-party dependencies defined in `configuration.js`. |
| 53 | + |
| 54 | +**Functions:** |
| 55 | +- Downloads dependencies from specified URLs |
| 56 | +- Extracts archives (tar.gz, zip) |
| 57 | +- Runs preparation scripts for each dependency |
| 58 | +- Organizes source files in the build directory |
| 59 | + |
| 60 | +### `build.js` |
| 61 | + |
| 62 | +Compiles dependencies using Xcode for specified platforms and configurations. |
| 63 | + |
| 64 | +**Key features:** |
| 65 | +- Builds for multiple platforms: iOS, macOS, Catalyst, tvOS, visionOS |
| 66 | +- Supports both Debug and Release configurations |
| 67 | +- Creates universal binaries for device and simulator |
| 68 | +- Handles architecture-specific builds (arm64, x86_64) |
| 69 | + |
| 70 | +### `compose-framework.js` |
| 71 | + |
| 72 | +Creates the final XCFramework from built artifacts. |
| 73 | + |
| 74 | +**Functions:** |
| 75 | + |
| 76 | +#### `createFramework(scheme, configuration, dependencies, rootFolder, buildFolder, identity)` |
| 77 | +Composes XCFrameworks from platform-specific builds using `xcodebuild -create-xcframework`. |
| 78 | + |
| 79 | +#### `copyHeaders(scheme, dependencies, rootFolder)` |
| 80 | +Copies public headers from dependencies to the framework's Headers folder based on settings in `configuration.js`. |
| 81 | + |
| 82 | +#### `copyBundles(scheme, dependencies, outputFolder, frameworkPaths)` |
| 83 | +Copies resource bundles into the XCFramework's Resources folder. |
| 84 | + |
| 85 | +#### `copySymbols(scheme, outputFolder, frameworkPaths)` |
| 86 | +Copies debug symbols (dSYM files) to enable symbolication of crash reports. |
| 87 | + |
| 88 | +#### `signXCFramework(identity, xcframeworkPath)` |
| 89 | +Code signs the XCFramework with the specified identity. |
| 90 | + |
| 91 | +### `configuration.js` |
| 92 | + |
| 93 | +Defines all dependencies and their build settings. |
| 94 | + |
| 95 | +**Configuration structure:** |
| 96 | +```javascript |
| 97 | +{ |
| 98 | + name: 'boost', |
| 99 | + version: '1.84.0', |
| 100 | + url: new URL('https://...'), |
| 101 | + files: { |
| 102 | + sources: ['boost/**/*.hpp'], |
| 103 | + headers: ['boost/**/*.hpp'], |
| 104 | + resources: ['PrivacyInfo.xcprivacy'] |
| 105 | + }, |
| 106 | + settings: { |
| 107 | + publicHeaderFiles: './', |
| 108 | + headerSearchPaths: ['./'], |
| 109 | + cCompilerFlags: ['-Wno-documentation'], |
| 110 | + cxxCompilerFlags: ['-std=c++20'] |
| 111 | + } |
| 112 | +} |
| 113 | +``` |
| 114 | + |
| 115 | +### `swift-package.js` |
| 116 | + |
| 117 | +Generates a Package.swift file for Swift Package Manager distribution. |
| 118 | + |
| 119 | +**Functions:** |
| 120 | +- `createSwiftPackageFile(dependencies, version, outputPath)`: Creates Package.swift with binary target definitions |
| 121 | + |
| 122 | +### `folders.js` |
| 123 | + |
| 124 | +Utility functions for folder operations. |
| 125 | + |
| 126 | +**Functions:** |
| 127 | +- `cleanFolder(folderPath)`: Removes and recreates a directory |
| 128 | +- `ensureFolder(folderPath)`: Creates directory if it doesn't exist |
| 129 | + |
| 130 | +### `constants.js` |
| 131 | + |
| 132 | +Defines shared constants used across scripts: |
| 133 | +- `HEADERS_FOLDER`: Location for extracted headers |
| 134 | +- `TARGET_FOLDER`: Build output location |
| 135 | +- `CPP_STANDARD`: C++ standard version to use |
| 136 | + |
| 137 | +### `types.js` |
| 138 | + |
| 139 | +Flow type definitions for TypeScript-style type checking: |
| 140 | +- `Platform`: Supported platform types |
| 141 | +- `Configuration`: Build configuration types |
| 142 | +- `Dependency`: Dependency configuration structure |
| 143 | + |
| 144 | +## Workflow |
| 145 | + |
| 146 | +The typical workflow for creating prebuilt frameworks: |
| 147 | + |
| 148 | +1. **Setup Phase** (`setupDependencies.js`) |
| 149 | + - Downloads third-party dependencies |
| 150 | + - Extracts archives |
| 151 | + - Runs preparation scripts |
| 152 | + - Organizes files in build directory |
| 153 | + |
| 154 | +2. **Build Phase** (`build.js`) |
| 155 | + - Compiles each dependency for target platforms |
| 156 | + - Creates fat binaries for device + simulator |
| 157 | + - Generates build artifacts in platform-specific folders |
| 158 | + |
| 159 | +3. **Compose Phase** (`compose-framework.js`) |
| 160 | + - Combines platform builds into XCFramework |
| 161 | + - Copies headers and resources |
| 162 | + - Includes debug symbols (dSYM) |
| 163 | + - Code signs if identity provided |
| 164 | + |
| 165 | +4. **Package Phase** (`swift-package.js`) |
| 166 | + - Generates Package.swift for SPM distribution |
| 167 | + - Defines binary targets with checksums |
| 168 | + |
| 169 | +## Integration |
| 170 | + |
| 171 | +The prebuilt frameworks are consumed via CocoaPods or Swift Package Manager. |
| 172 | + |
| 173 | +Related files: |
| 174 | +- `packages/react-native/scripts/cocoapods/rndependencies.rb` - CocoaPods integration |
| 175 | +- `packages/react-native/React-Core-prebuilt.podspec` - Prebuilt React Core podspec |
| 176 | + |
| 177 | +## Entry Point |
| 178 | + |
| 179 | +The main entry point is `prepare-ios-prebuilds.js` which orchestrates the entire prebuild process: |
| 180 | + |
| 181 | +```javascript |
| 182 | +const {buildDepenencies} = require('./ios-prebuild/build'); |
| 183 | +const {createFramework} = require('./ios-prebuild/compose-framework'); |
| 184 | +const {setupDependencies} = require('./ios-prebuild/setupDependencies'); |
| 185 | +``` |
| 186 | + |
| 187 | +## Environment Variables |
| 188 | + |
| 189 | +- `RCT_USE_RN_DEP`: Use prebuilt dependencies instead of building from source |
| 190 | +- `RCT_USE_LOCAL_RN_DEP`: Use local tarball for testing |
| 191 | +- `RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS`: Download and install dSYMs for symbolication |
| 192 | + |
| 193 | +See `packages/react-native/scripts/cocoapods/rncore.rb` for implementation details. |
| 194 | + |
| 195 | +## Usage |
| 196 | + |
| 197 | +To use the prebuilt React Native XCFrameworks in your iOS project, run pod install with the environment variable `RCT_USE_PREBUILT_RNCORE` set to `1`: |
| 198 | + |
| 199 | +```bash |
| 200 | +RCT_USE_PREBUILT_RNCORE=1 bundle exec pod install |
| 201 | +``` |
| 202 | + |
| 203 | +This can be combined with `RCT_USE_RN_DEP=1` to use both React Native and its dependencies as prebuilt frameworks. |
| 204 | + |
| 205 | +For debugging and troubleshooting the Cocoapods scripts, you can use the following environment variables: |
| 206 | + |
| 207 | +- `RCT_TESTONLY_RNCORE_TARBALL_PATH`: **TEST ONLY** If set, it will use a local tarball of RNCore if it exists. |
| 208 | +- `RCT_TESTONLY_RNCORE_VERSION`: **TEST ONLY** If set, it will override the version of RNCore to be used. |
| 209 | +- `RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS`: If set to 1, it will download the dSYMs for the prebuilt RNCore frameworks and install these in the framework folders |
0 commit comments