![Как я делаю build больших Android/iOS проектов со 128 GB памяти на старом Mac Как я делаю build больших Android/iOS проектов со 128 GB памяти на старом Mac](https://habrastorage.org/getpro/habr/upload_files/60b/5c2/3a0/60b5c23a0e5123078697ab163bada6cc.png)
✦ Introduction
Всем привет! Наверняка вы не раз сталкивались с проблемой нехватки памяти на вашем ПК при билде проектов? Недавно мне стало не хватать основной памяти на диске, где установлена система MacOS. На моем Mac Mini всего 128 GB основной памяти, чего хватает только для основных программ. Не говоря, что система сама по себе сжирает больше 30 GB. Пока новая техника не приобретена, приходится выкручиваться.
Решением проблемы послужило приобретение внешнего SSD диска на 512 GB Netac ZX20. (Это не реклама, поэтому ссылки не будет, но диск реально рекомендую). Диск подключил к системе по type-C, но систему на него переустанавливать не хочу (кстати, это возможно).
Как же настроить работу билдов Android и iOS на внешнем диске и перенести все проекты и приложения? Об этом и пойдет речь в этой статье. Приятного чтения!
✦ Подготовка
Для начала стоит форматировать диск через стандартную дисковую утилиту MacOS. В качестве файловой системы стоит выбрать именно APFS
, потому что она максимально оптимизирована для работы с Mac.
Далее мы будем работать только с Finder, Android Studio и Xcode, поэтому ничего лишнего не потребуется.
✦ Переносим программы
На нашем диске создадим папку Applications
в соответствии с домашней папкой пользователя. Сюда нужно перекинуть все приложения, которые это позволят. Прямо берем и переносим иконку (пакет) приложения на диск. Я думаю, это ни для кого не секрет, что при установке новых приложений через dmg
можно проигнорировать инструкции и перенести файл приложения не в user/Applications
, а в нашу новую папку на внешнем диске. Все программы также будут отображаться через Spotlight без проблем. Вместе со всеми программами можно перенести и Android Studio. Также переносим все проекты и прочие файлы.
✦ Что занимает память во время билда Android?
Для того чтобы решить проблему нехватки памяти, давайте сначала разберемся, а что же занимает эту драгоценную память?
Во время сборки Android проекта создается множество файлов и директорий, которые используются для различных целей, таких как компиляция исходного кода, хранение зависимостей, кэширование промежуточных данных и генерация конечного APK или AAB файла. Под спойлером скрыто описание того, что и где занимает память во время билда.
Директории и файлы в проекте
app/build/:
outputs/: Здесь находятся конечные артефакты сборки, такие как APK или AAB файлы.
intermediates/: Промежуточные файлы, такие как скомпилированные классы, ресурсы и другие артефакты, которые используются на различных этапах сборки.
generated/: Сгенерированные файлы, такие как R.java, скомпилированные ресурсы и другие вспомогательные файлы.
tmp/: Временные файлы, используемые во время сборки.
app/src/main/:
java/: Исходный код Java или Kotlin.
res/: Ресурсы, такие как XML файлы разметки, изображения, строки и т.д.
assets/: Статические файлы, которые включаются в APK.
build/ (в корне проекта):
outputs/: Артефакты сборки всех модулей проекта.
intermediates/: Промежуточные файлы сборки всех модулей.
generated/: Сгенерированные файлы всех модулей.
gradle/:
caches/: Кэшированные данные, используемые Gradle для ускорения сборки.
daemon/: Кэшированные данные и файлы демонов Gradle, которые ускоряют последующие сборки.
wrapper/: Файлы для управления версиями Gradle.
~/.gradle/ (Глобальная директория кэша Gradle):
caches/: Кэшированные зависимости и данные сборки, чтобы избежать повторного скачивания и обработки.
daemon/: Данные демона Gradle.
wrapper/: Версии Gradle, используемые проектами.
native/: Кэшированные нативные библиотеки.
По схеме можно сделать вывод, что большинство промежуточных данных хранится в самой папке проекта. Нас интересует последний пункт – глобальная директория Gradle, где может копиться приличное количество данных, особенно, если вы работаете сразу над несколькими проектами с разными версиями Gradle.
✦ Настраиваем работу с Android Studio
1. Переносим Android SDK:
По аналогии с Applications
создаем папку Library
и переносим туда папку, которая находится по пути: /Users/username/Library/Android/
. В Android Studio в настройках указываем путь в Android SDK Location.
![Android Studio - Settings - Android SDK Android Studio - Settings - Android SDK](https://habrastorage.org/getpro/habr/upload_files/e08/8ee/12f/e088ee12f758c75e893aef07131a9454.png)
В моем случае имя диска NetacAPFS – у вас может быть любое другое.
2. Меняем домашнюю директорию gradle
Раньше домашняя папка Gradle находилась по пути: /Users/username/.gradle/
. Мы переносим папку в любое удобное место на внешнем диске или просто удаляем исходную папку. Я перенес .gradle
в папку внешнего диска Applications
. Далее в Android Studio в настройках указываем нужный путь в Gradle user home.
![Android Studio - Settings - Gradle Android Studio - Settings - Gradle](https://habrastorage.org/getpro/habr/upload_files/2c1/d62/78b/2c1d6278b817c4aa0290909862b9f828.png)
Не забываем обновить новое местоположение JDK. Если используется JDK из пакета Android Studio, то путь останется таким же, только поменяется начало до Android Studio.app
, как у меня. Если вы используете вручную установленный JDK, его можно тоже разместить на внешнем диске, например, в Library
и указать путь до него.
3. Настраиваем проект
В проекте в файле local.properties
нужно указать местоположение до Android SDK.
В gradle.properties
нужно указать путь до домашней директории Gradle.
![local.properties local.properties](https://habrastorage.org/getpro/habr/upload_files/71a/455/d87/71a455d879ab5de3f2af68e4f4eba96a.png)
![gradle.properties gradle.properties](https://habrastorage.org/getpro/habr/upload_files/bb5/0aa/659/bb50aa6590f687e644d005566eb2a53c.png)
4. Переменные окружения
На самом деле все уже будет работать корректно, но для надежности стоит указать в системе явно пути к нашим папкам. Для этого нужно в файл вашего профиля консоли вписать дополнительные команды. Если вы используете zsh, то нужный файл будет находиться по пути: /Users/username/.zshrc
. Просто открываем и вставляем в конец эти строки:
export GRADLE_USER_HOME="/Volumes/NetacAPFS/Applications/.gradle"
export GRADLE_HOME="/Volumes/NetacAPFS/Applications/.gradle"
export ANDROID_HOME="/Volumes/NetacAPFS/Library/Android/sdk"
export JAVA_HOME="/Volumes/NetacAPFS/Applications/Android Studio.app/Contents/jbr/Contents/Home"
export PATH="ANDROID_HOME/tools/bin:PATH"
Внимание! Измените имя диска с NetacAPFS на нужное.
✦ Что занимает память во время билда iOS?
Так же как и Gradle сборщик iOS проекта требует выделения памяти для хранения временных файлов и результатов компиляций. Сборка проекта iOS или Kotlin Multiplatform (KMP) проекта с iOS target приводит к созданию нескольких файлов и директорий, которые содержат код, ресурсы, кеш и промежуточные файлы. Под спойлером приводится подробное описание этих директорий и файлов.
Директории и файлы в проекте
iOS Проект
Build Directory (Каталог сборки):
~/Library/Developer/Xcode/DerivedData/: Это основная директория, в которой Xcode хранит промежуточные файлы и выходные данные сборки. Здесь создается поддиректория для каждого проекта, содержащая файлы сборки, такие как объектные файлы (.o), промежуточные двоичные файлы, файлы кеша компилятора и т.д.
Build: Внутри проекта Xcode можно указать, чтобы build directory создавался в другом месте. Если это так, то в указанной директории будут создаваться поддиректории для разных сборок (например, Debug, Release).
Архивные файлы (Archive files):
~/Library/Developer/Xcode/Archives/: Когда вы архивируете проект для отправки в App Store или для создания IPA файла, архивные файлы сохраняются здесь.
Simulator Cache (Кеш симулятора):
~/Library/Developer/CoreSimulator/Caches/: Здесь хранится кеш симулятора iOS, включая снапшоты и данные приложений.
App Data (Данные приложения):
~/Library/Developer/CoreSimulator/Devices/: Если вы запускаете приложение на симуляторе, данные приложения будут храниться здесь. Каждое устройство симулятора имеет свою поддиректорию.
KMP Проект с iOS target
Gradle Build Cache (Кеш сборки Gradle):
~/.gradle/caches/: Gradle использует эту директорию для кеширования зависимостей, промежуточных файлов и результатов сборки. Это уменьшает время сборки, повторно используя ранее построенные элементы.
Xcode Derived Data (Производные данные Xcode):
Как и в обычном iOS проекте, KMP проект также будет использовать ~/Library/Developer/Xcode/DerivedData/ для хранения данных сборки iOS части проекта.
Kotlin/Native Cache (Кеш Kotlin/Native):
~/.konan/: Kotlin/Native компилятор может использовать эту директорию для кеширования объектных файлов и других промежуточных результатов.
Build Directory (Каталог сборки):
Подобно iOS проекту, KMP проект также будет использовать директорию сборки, указанную в настройках проекта или Gradle, для хранения выходных файлов и промежуточных файлов.
Можно увидеть, что Xcode старается максимально засорить наше дорогое пространство на основном диске, поэтому нужно перенести все директории на внешний диск.
✦ Настраиваем работу с Xcode
Начнем с того, что Xcode и CoreSimulator мы не можем просто перенести на внешний диск в силу ограничений. По крайней мере у меня не получилось, сыпались ошибки. Поэтому будем делать то, что получается оптимизировать.
1. Переносим DerivedData и Archives
DerivedData
– одна из самых тяжелых директорий, где хранится почти все данные сборки. В папке Library
на внешнем диске создаем следующие папки: /Developer/Xcode/DerivedData/
и /Developer/Xcode/Archives/
. Удаляем соответствующие ненужные данные на основном диске (в Users/username/Library/Xcode/
). Заходим в настройки Xcode и указываем новые пути до них.
![Xcode - Settings - Locations - Locations Xcode - Settings - Locations - Locations](https://habrastorage.org/getpro/habr/upload_files/909/f7a/b87/909f7ab87d4f19d72de2c1ad8a1084c1.png)
2. Переносим konan
При работе с Koltin/Native будет создана папка /Users/username/.konan/
. Эта директория создается автоматически во время первой сборки проекта Kotlin/Native и используется для улучшения производительности сборки за счет кеширования результатов компиляции. По аналогии с .gradle
создаем на внешнем диске папку .konan
в Applications
.
Указываем изменения в переменную системы в /Users/username/.zshrc
как в пунктах ранее:
export KONAN_DATA_DIR="/Volumes/NetacAPFS/Applications/.konan"
Внимание! Измените имя диска с NetacAPFS на нужное.
Добавляем настройку в gradle.properties
проекта.
![gradle.properties gradle.properties](https://habrastorage.org/getpro/habr/upload_files/b53/f74/5ea/b53f745ea4ac01c35e6560c2f85ee1ba.png)
3. Настройка переменных окружения
Сейчас при запуске проекта через Xcode вы можете удивиться, увидев создание .gradle
на прежнем месте. Это происходит, потому, что Xcode старательно игнорирует наши переменные и их нужно задать самостоятельно. Сюда просто переносим данные из файла .zshrc
.
![Xcode - Settings - Locations - Custom Paths Xcode - Settings - Locations - Custom Paths](https://habrastorage.org/getpro/habr/upload_files/d27/2e9/b24/d272e9b249567fd4e061cf27a09cf84f.png)
✦ Заключение
Вот таким нехитрым способом у меня получается экономить основную память системы и хранить все кэши на внешнем диске. Надеюсь, что данный материал поможет некоторым в оптимизации памяти на устройстве. Спасибо за прочтение! Предлагайте свои варианты экономии места в комментариях, обсудим.