diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 245aacf5..7590bc71 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -39,6 +39,25 @@ jobs: run: bun install working-directory: example + - name: Set up Ruby + uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 # v1.327.0 + with: + ruby-version: '4.0' + bundler-cache: true + working-directory: example + + # Mirrors RN's scripts/xcode/ccache.conf, which only applies to its CC + # wrapper, not to the compiler launcher used here. + - name: Install and configure ccache + run: | + brew install ccache + ccache --set-config max_size=2G + ccache --set-config base_dir="$GITHUB_WORKSPACE" + ccache --set-config sloppiness=clang_index_store,file_stat_matches,include_file_ctime,include_file_mtime,ivfsoverlay,pch_defines,modules,system_headers,time_macros + ccache --set-config depend_mode=true + ccache --set-config file_clone=true + ccache --set-config inode_cache=true + - name: Cache Pods id: cache-pods uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 @@ -48,9 +67,20 @@ jobs: path: example/ios/Pods key: ${{ hashFiles('example/ios/Podfile.lock') }} + # Sets ccache as Xcode's C_COMPILER_LAUNCHER, see example/ios/Podfile. - name: Install example Pods run: bun pods working-directory: example + env: + USE_CCACHE_LAUNCHER: 1 + + - name: Restore ccache + uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + path: ~/Library/Caches/ccache + key: ccache-ios-Release-${{ github.sha }}-${{ github.run_attempt }} + restore-keys: | + ccache-ios-Release- # Simulator.app attaches the Mac keyboard by default, which hides the # software keyboard and leaves no Return key for the keyboard tests. @@ -59,7 +89,20 @@ jobs: - name: Build iOS App run: | - bun example:ios:release + ccache --zero-stats + bun example:ios:release --extra-params "COMPILER_INDEX_STORE_ENABLE=NO" + ccache --show-stats -v + + # Only main saves, PRs restore from it. Saved right after the build so a + # failing e2e run still warms the cache. + # TODO: drop the pull_request condition before merging, it's only here to + # measure warm builds on this PR. + - name: Save ccache + if: ${{ !cancelled() && (github.ref == 'refs/heads/main' || github.event_name == 'pull_request') }} + uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + path: ~/Library/Caches/ccache + key: ccache-ios-Release-${{ github.sha }}-${{ github.run_attempt }} - name: Install e2e dependencies run: bun install diff --git a/example/ios/Podfile b/example/ios/Podfile index ab7e80f1..44469836 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -31,6 +31,26 @@ target 'PagerViewExample' do # :ccache_enabled => true ) + # Xcode's compiler launcher keeps explicit modules enabled, unlike RN's + # ccache CC wrapper (USE_CCACHE), so don't combine the two. + if ENV['USE_CCACHE_LAUNCHER'] == '1' + ccache_path = `command -v ccache`.strip + if ccache_path.empty? + Pod::UI.warn('[Ccache] USE_CCACHE_LAUNCHER=1 but ccache was not found on PATH') + else + Pod::UI.puts("[Ccache] Using #{ccache_path} as C_COMPILER_LAUNCHER") + projects = [installer.pods_project] + projects += installer.aggregate_targets.map(&:user_project).compact + projects.uniq { |project| project.path }.each do |project| + project.build_configurations.each do |config| + config.build_settings['C_COMPILER_LAUNCHER'] = ccache_path + config.build_settings['CLANG_ENABLE_EXPLICIT_MODULES_WITH_COMPILER_LAUNCHER'] = 'YES' + end + project.save + end + end + end + # Xcode rejects deployment targets below 15.0, and RN's own post_install # skips resource-bundle targets, so RNSVG's bundles keep the podspec's 12.4. installer.pods_project.targets.each do |target|