Статья о том, как исправить инкрементную компиляцию в проектах Xcode для Swift и ускорить этапы сборки Cocoapods и Carthage, ничего не нарушив.
Небольшой спойлер: на трех разных проектах нам удалось сократить время инкрементальной сборки в 9 раз! Урок носит чисто практический характер с минимумом воды.
Обязательно к прочтению нынешним разработчикам iOS.
Проблема
Наша компания ведет несколько параллельных проектов на Swift и почти везде были сложности с последовательной сборкой.Каждый повторный «Пробег» занимал от 30 до 50 секунд. Написание кода занимает минуту, и полминуты вы ждете, пока проект соберется.
У вас есть время пойти выпить чаю, покурить, заплатить налоги и иногда вздремнуть.
Что-то обязательно нужно было изменить.
В моих предыдущих статьях, описывающих текущие проблемы компилятора и способы их решения, нам удалось добиться определенного успеха.
Однако это не устранило трудностей с инкрементной компиляцией, которая съедала большую часть времени, постоянно подбивая рабочий процесс своей медлительностью.
Уверен, каждый с этим сталкивается регулярно, принимая это как часть рабочего процесса.
Но мы не стали с этим мириться, решив разобраться во всех обстоятельствах дела и в конечном итоге получив хороший результат. О чем я с удовольствием вам расскажу.
P.S. Картинка в шапке не означает, что мы «подкрутили» Xcode. Вот так мы якобы ускоряем его.
Инкрементная компиляция
Если кто-то не знаком с этим термином, это способ сборки только измененных частей кода без тотальной перекомпиляции всего проекта.Это также не работает должным образом в Xcode. В последнем посте товарищ Гкост предложил идею , что на некоторое время решило проблему.
Мы уже всей командой уже начали открывать шампанское и вешать портрет. император доставщик на стену, но, к сожалению, в этот момент проблема возобновилась.
Судя по всему, мы не одиноки.
Еще пишут о рецидивах на StackOverflow ниже ответа, а также в исходной теме на форумах Apple. Это ни в коем случае не палка в огороде.
Наоборот, благодарность, все это подтолкнуло меня продолжать копать.
Если, пусть и временно, проблему удалось решить, то истина где-то рядом.
Что именно представляет собой эта карта заголовков, для которой мы устанавливаем флаг согласно рекомендации Apple? Немного веб-археология Согласно документации Apple:
Карты заголовков (также известные как «карты заголовков») — это файлы, которые Xcode использует для компиляции местоположений заголовков, используемых в цели.Другими словами, карты заголовков — это индексный файл Xcode с расположением заголовков проекта.
Файл обо всех заголовках, которые мы используем.
Раз уж я обещал не углубляться в теорию, то вот она.
отличная статья об этой теме.
Легко читается, очень рекомендую.
Главное, что что-нибудь в этих картах заголовков (или в том, что их использует) провоцируется нечестная работа инкрементальной компиляции.
Если мы нашли такую техническую опухоль, то давайте действовать без полумер и просто отключать их.
Перейдите в настройки сборки и удалить ненужные детали установить существующий флаг USE_HEADER_MAPS В НЕТ :
Теперь нам нужно компенсировать утраченный функционал и вручную добавить расположение всех заголовков проекта.
Нигде настройки не оставляем и вручную прописываем пути к папкам с заголовками в поле «Пути поиска пользовательских заголовков»:
В проекте на Swift их должно быть немного, только ваши кастомные вещи Obj-C. Опять делаем полную очистку и пытаемся запустить проект. Если вы столкнулись со следующей ошибкой
это означает, что вы просто забыли указать путь к одному или нескольким файлам заголовков.
После их исправления все должно собраться без осложнений, так как кроме этого никаких изменений мы не вносили.
В качестве бонуса отметим, что инкрементная компиляция лучше всего работает, когда отключена оптимизация всего модуля (WMO), о чем мы говорили в разделе последний раз .
Это не значит, что решение не работает для полномодульной оптимизации, но без нее все идет на несколько секунд быстрее.
Пусть сборки с нуля занимают вечность.
Здесь каждый решает сам, что ему удобнее, быстрее и лучше подходит. Если вы решите отказаться от WMO, то просто уберите флаг SWIFT_WHOLE_MODULE_OPTIMIZATION из настроек проекта; никаких затруднений возникнуть не должно.
Результат : Мы успешно исправили инкрементальную компиляцию.
Отныне на сам факт сборки Swift следует тратить не более нескольких секунд, не считая коддизайна, линковки и различных скриптов сборки (о них мы поговорим ниже).
Внутренне мы протестировали этот метод на трех разных проектах, нескольких версиях OSX и вообще на множестве конфигураций в целом, что касается и Xcode. И сейчас мы уже давно не видим рецидивов.
Разгон Cocoapods и Carthage
Наверное, многие заметили, что помимо самой компиляции немало времени уходит на различные «шелл-скрипты»:При использовании какаопод и/или карфагена их бывает даже несколько.
Каждый раз они занимают от 3 до 10 секунд, в зависимости от скорости вашего диска, процессора и положения звезд на небе.
Cocoapods регистрируется там автоматически, но для Carthage это нужно сделать вручную .
Немного изучив контент, мы выяснили, что эти скрипты не делают ничего, кроме копирования своих ресурсов в каталог сборки проекта.
Однако их не волнует, были ли уже скопированы эти файлы или нет. Хотя гораздо логичнее было бы проверить наличие необходимых ресурсов перед их повторным копированием.
Вот что мы сделаем.
Начнем с Карфагена.
Это решение было вдохновлено недооцененным ответ на StackOverflow , где приняли одноразовый костыль и облепили лайками.
Кстати, если вы вдруг решите использовать одобренное решение, вы обнаружите дикие и горячие ошибки в Runtime; вам следует сделать полную очистку.
Мы не будем этого делать, поэтому пойдем правильным путем и изменим наш этап сборки Copy Carthage Frameworks:
Этот скрипт дополнительно копирует вместе с ресурсами еще один пустой файл, который служит маячком того, что операция прошла успешно.FILE="${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Carthage-Installation-Flag" if [ -f "$FILE" ]; then exit 0 fi touch "$FILE" /usr/local/bin/carthage copy-frameworks
Он не занимает места и не имеет побочных эффектов.
и разрешен детям от 3 лет .
При следующем запуске скрипта он сначала проверит наличие этого файла, и если файл есть, операция автоматически завершится без дальнейших возни.
Для уверенности вот скриншот результата, который мы должны получить:
Важный! Если вы решите добавить или удалить зависимость от Carthage, вам необходимо выполнить полную очистку перед сборкой проекта.
В противном случае скрипт подумает, что уже давно всё установил.
И вы будете в поте лица пытаться найти объяснение происходящему.
Кстати, функцию очистки вы можете найти в меню по пути Продукт → Очистить.
Если вы также удерживаете нажатой опцию (alt), вы можете сделать особенный чистый, что тоже изгоняет демонов из проекта удаляет разные локальные настройки, кэш и прочую лабуду, которая часто вылетает.
Теперь какаподы
Для бинов принцип тот же, но поскольку скрипты генерируются автоматически, вам придется добавить немного магии в Podfile. Для этого добавьте в самый конец файла следующие строки: post_install do |installer|
Dir.glob(installer.sandbox.target_support_files_root + "Pods-*/*.
sh").
each do |script|
flag_name = File.basename(script, ".
sh") + "-Installation-Flag"
folder = "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
file = File.join(folder, flag_name)
content = File.read(script)
content.gsub!(/set -e/, "set -e\nKG_FILE=\"#{file}\"\nif [ -f \"$KG_FILE\" ]; then exit 0; fi\nmkdir -p \"#{folder}\"\ntouch \"$KG_FILE\"")
File.write(script, content)
end
end
Принцип работы этого скрипта тот же: он добавляет проверку флага файла в скрипты копирования ресурсов.
При этом он не меняет фазы сборки, в отличие от Carthage, а сразу меняет сам скрипт Cocoapods. Кстати , если вы уже использовали блок post_install, то создавать еще один не нужно, достаточно поместить скрипт внутрь существующего.
Последние версии Cocoapods (1.1.1) предупредят вас, если вы ошибетесь, но более ранние версии просто молча проглотят ошибку, предоставляя вам удовольствие от отладки.
Теперь ты можешь сделать ' установка модуля ', чтобы изменения вступили в силу.
Как и в случае с Carthage, при редактировании подфайла вам также потребуется полная очистка проекта перед его запуском.
P.S. Руби не мой родной язык, придержите тапочки.
Заключение
Таким образом, нам удалось сократить время сборки проекта с 45 секунд до 5. Я чуть не забыл доказательства.
Время сборки до:
Скриншот взят с сайта видео к предыдущей статье.
Время сборки после:
На мой взгляд, это чрезвычайно значимый результат. Подход к сокращению затрат является обязательным для каждой компании и разработчика.
Я уверен, что среди вас найдутся люди с опытом оптимизации Xcode, готовые дополнить и поделиться своими мыслями.
И вообще, хотелось бы видеть вопросы в комментариях, чтобы в следующих статьях упоминать вас, ваш опыт, опыт ваших коллег и освещать тему, т. к.
для меня это хобби, жизнь и работа.
Наконец, я поделюсь утилитой, которую я использовал для измерения времени компиляции метода: https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode Показывает каждую функцию в отдельности и общее время, затраченное на ее сборку.
Теги: #iOS #xcode #Swift #программирование #разработка iOS #Разработка мобильных приложений #xcode #Swift
-
Домены Следующего `События`
19 Oct, 24 -
Иран Замедляет Ход
19 Oct, 24 -
Ebay В Отместку Обрушил Курс Акций Google
19 Oct, 24