Я тот человек, который ненавидит ждать ⌛, и, кажется, мне повезло, что решил работать с приложениями iOS 🙃 (сарказм)
Но в любом случае я думаю, что вы должны знать эту боль 😞 При создании приложения iOS на CI
🖥 Давайте посмотрим на нашу настройку (Действия GitHub) :
OS: macOS 10.15.7 CPU: (4) x64 Intel(R) Xeon(R) CPU E5-1650 v2 @ 3.50GHz Memory: 8.11 GB / 12.00 GB
🗄 Размеры кэша:
node_modules: ~852 MB pods: ~115 MB pods derived data: ~1258 MB
⏲ Время строительства:
Так Как можно увидеть, я сохраняю 33M 08S 😲🎉💃!
Я надеюсь, что результаты произвели на вас впечатление, и вы хотите, чтобы получить эти результаты? 😉
Я прочитал 📖 много статей, которые описывают разные подходы:
1) ccache 2) Римский инструмент 3) Cocoapods-Binary-Cache — Работайте странно для меня, построил только 4 зависимости, которые не влияют на скорость сборки. 4) Кокопод-бинар — Требуется использовать use_frameworks!
Я заметил, что это обычно изменяются на стороне JS, но нативно изменяется редко. И большая часть времени сборки требует строительства местного кода.
Таким образом, основной идеей было кэшировать результат кэширования стручков до тех пор, пока ios/podfile.lock изменения
Если вы используете действия GitHub, ваш трубопровод будет выглядеть так:
jobs: build_ios: runs-on: macos-latest steps: # Checkout repo, Install deps (node.js, cocacpods, ruby gems) ... - uses: actions/cache@master with: # Path to Derived Data path: .local_derived_data # Restore cache by Podfile.lock hashsum key: ${{ runner.os }}-pods-derived-data-${{ hashFiles('**/Podfile.lock') }} # Run build
Также я использую Fastlane Инструмент для запуска сценариев сборки. Так что код без оптимизации выглядит так:
# Fastfile platform :ios do desc "Build iOS" lane :build do # Code sign ... gym( scheme: "MyApp", workspace: "./ios/MyApp.xcworkspace", export_method: "ad-hoc", configuration: "Release", clean: true ) # Publish to firebase... end end
Ничего особенного, верно? А теперь версия с оптимизацией:
platform :ios do desc "Build iOS" lane :build do scheme = "MyApp" build_configuration = "Release" # !!! Path to the folder that you will cache on CI !!! ios_derived_data_path = File.expand_path("../.local_derived_data") cache_folder = File.expand_path("#{ios_derived_data_path}/Build/Intermediates.noindex/ArchiveIntermediates/#{scheme}/BuildProductsPath/#{build_configuration}-iphoneos") # Code sign ... # Step 0) Check if cache exists if(File.exist?(cache_folder)) # Step 1) Apply a fix of "Copy Pods Resources" Build Phase # Before: # "${PODS_ROOT}/Target Support Files/Pods-MyApp/Pods-MyApp-resources.sh" # # After: # BUILT_PRODUCTS_DIR=/a/b/c "${PODS_ROOT}/Target Support Files/Pods-MyApp/Pods-MyApp-resources.sh" fastlane_require 'xcodeproj' project = Xcodeproj::Project.open("../ios/MyApp.xcodeproj") target = project.targets.select { |target| target.name == 'MyApp' }.first phase = target.shell_script_build_phases.select { |phase| phase.name && phase.name.include?('Copy Pods Resources') }.first if (!phase.shell_script.start_with?('BUILT_PRODUCTS_DIR')) phase.shell_script = "BUILT_PRODUCTS_DIR=#{cache_folder} #{phase.shell_script}" project.save() end # Step 2) Build only .xcodeproj gym( clean: false, project: './ios/MyApp.xcodeproj', scheme: scheme, configuration: build_configuration, export_method: "ad-hoc", destination: 'generic/platform=iOS', export_options: { compileBitcode: false, uploadBitcode: false, uploadSymbols: false }, xcargs: [ # Step 3) Provide paths where xcode can't find pods binaries "PODS_CONFIGURATION_BUILD_DIR=#{cache_folder}", "FRAMEWORK_SEARCH_PATHS='#{cache_folder} $(inherited)'", "LIBRARY_SEARCH_PATHS='#{cache_folder} $(inherited)'", "SWIFT_INCLUDE_PATHS=#{cache_folder}" ].join(" ") ) else # Step 4) Build full app .xcworkspace gym( scheme: "MyApp", workspace: "./ios/MyApp.xcworkspace", derived_data_path: ios_derived_data_path, export_method: "ad-hoc", configuration: build_configuration, clean: true ) # Step 5) Remove not a Pods binaries to reduce cache size require 'fileutils'; dirs = [ File.expand_path("#{ios_derived_data_path}/info.plist"), File.expand_path("#{ios_derived_data_path}/Logs"), File.expand_path("#{ios_derived_data_path}/SourcePackages"), File.expand_path("#{ios_derived_data_path}/ModuleCache.noindex"), File.expand_path("#{ios_derived_data_path}/Build/Intermediates.noindex/ArchiveIntermediates/MyApp/IntermediateBuildFilesPath/MyApp.build"), File.expand_path("#{ios_derived_data_path}/Build/Intermediates.noindex/ArchiveIntermediates/MyApp/IntermediateBuildFilesPath/XCBuildData"), File.expand_path("#{ios_derived_data_path}/Build/Intermediates.noindex/ArchiveIntermediates/MyApp/BuildProductsPath/SwiftSupport"), File.expand_path("#{ios_derived_data_path}/Build/Intermediates.noindex/ArchiveIntermediates/MyApp/PrecompiledHeaders") ] dirs.each { |dir| FileUtils.rm_rf(dir) } end # Publish to firebase... end end
Некоторые заметки, чтобы понять, что происходит:
Прежде всего, я проверяю, что кеш существует? (См.
Шаг 0
)Если это не существует, я буду призывать
тренажерный зал ()
С параметрами по умолчанию (см.Шаг 4
), но добавьте новые параметрыdefived_data_path: ...
. Затем немного очистите эту папку, удаляя не PODS -файлы. (См.Шаг 5
)Если кэш успешно восстановлен необходим для обновления фазы сборки
[CP] Копировать Pods Resources
Анкет (См.Шаг 1
)
[CP] Копировать Pods Resources
Запуск скрипта, который Cocoapods автоматически добавляет к вашему проекту. Он заботится о копировании ресурсов POD в правильный каталог, чтобы они стали частью последнего архива.
- Тогда я могу вызвать
тренажерный зал ()
Но он имеет другую конфигурацию (см.Шаг 2
). В настоящее время я буду строить не целый a Workspace, просто проект. По мере того, как я создаю проект приложения, мне также нужно предоставить некоторые важныеxcargs
Чтобы помочь линкеру, искать капсулы во время ссылки. (См.Шаг 3
)
gym( - workspace: "./ios/MyApp.xcworkspace", + project: './ios/MyApp.xcodeproj', + xcargs: [ + "PODS_CONFIGURATION_BUILD_DIR=#{cache_folder}", + "FRAMEWORK_SEARCH_PATHS='#{cache_folder} $(inherited)'", + "LIBRARY_SEARCH_PATHS='#{cache_folder} $(inherited)'", + "SWIFT_INCLUDE_PATHS=#{cache_folder}" + ].join(" ") - clean: true, + clean: false, # ... )
Если у вас есть какие -либо вопросы, я рад обсудить их в комментариях!
© Мурамур
Оригинал: «https://dev.to/retyui/react-native-how-speed-up-ios-build-4x-using-cache-pods-597c»