Я тот человек, который ненавидит ждать ⌛, и, кажется, мне повезло, что решил работать с приложениями 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»