LINUX.ORG.RU

Конфигурация сборки

 ,


0

3

Изучаю возможности сборки Android-приложения через Gradle, после CMake возникают элементарные вопросы по конфигурации. Собственно, есть ли вообще этап конфигурации в Gradle, наподобие ./configure <options> или cmake <options>?

Вот тривиальный пример: Android-плагин хочет знать где лежит SDK, но делает это странным способом. Нужно либо указать путь к SDK в переменной окружения ANDROID_HOME, либо создать файл local.properties со строкой sdk.dir=<path/to/sdk>. Первый вариант не годится по очевидной причине, что для каждого приложения необходимо создавать враппер для вызова сборки, в котором будет указана переменная ANDROID_HOME для текущего пользователя. Второй вариант тоже не подходит, потому как local.properties должен лежать в директории с исходным кодом вместо директории сборки, если нужно собирать приложение с разными SDK, то неясно как между ними переключаться. Естественно ни враппер, ни local.properties в систему контроля версий не сохраняются, потому как содержат локальные пути.

В Gradle можно передать параметры сборки в командной строке, но по каким-то причинам Android-плагин игнорирует этот способ.

В CMake путь к SDK указался бы при конфигурации в командной строке (или нашёлся бы автоматически) и сохранился один раз в кеш, после чего сборка проекта проходит простым вызовом ninja без аргументов и ненужных врапперов.

Какой идеологически верный способ конфигурировать проект в Gradle? Есть ли вообще способ экспортировать переменные наружу, чтобы пользователь при сборке мог их переопределить?

★★★★★

если нужно собирать приложение с разными SDK, то неясно как между ними переключаться.

Там путь к корню каталога с сдк для всех версий апи, на что ты там собрался переключаться?

F457 ★★★ ()
Ответ на: комментарий от F457

Хотя бы на SDK, собранный самостоятельно из исходников. Ну и SDK это всего-лишь один из множества возможных параметров, интересует общий подход.

Dendy ★★★★★ ()
Ответ на: комментарий от Dendy

Ну переопредели переменную гредл скрипте

F457 ★★★ ()
Ответ на: комментарий от F457

Какую переменную в каком скрипте? Тема изначально создана, чтобы узнать как это делать корректно, а не с помощью хардкода. Другими словами решения средствами Gradle нет?

Dendy ★★★★★ ()
Ответ на: комментарий от Dendy

Ты документацию не пробовал почитать?

Расказываю на примере дефолтного проекта андроид студии. Все что больше описано в доках и стековерфлоу. Открываешь build.gradle модуля app. Находишь там build type: prod и внутрь копируешь строку из local.properties которую студия сгенерировала - полный путь сдк который указан в настройках студии. Заменяешь путь на другой. Запускаешь сборку прод таргета. Собралось без ошибок идешь курить что такое билд тайпы и флейворы. И как менять конфигурацию меняя их при сборке.

Можешь ANDROID_HOME поменять при запуске гредл скрипта, если тебе билд тайпы не нравятся.

F457 ★★★ ()
Последнее исправление: F457 (всего исправлений: 1)
Ответ на: комментарий от F457

Ты документацию не пробовал почитать?

Да уже много чего перечитал, описаны варианты передачи параметров, их приоритет и возможности подпроектов. Ни слова про сохранение этих параметров в кеш, их экспорт и этап конфигурации вообще. Судя по ответу вы точно знаете какую именно документацию стоит читать, ссылку?

Открываешь build.gradle модуля app. Находишь там build type: prod и внутрь копируешь строку из local.properties которую студия сгенерировала - полный путь сдк который указан в настройках студии.

То-есть захардкодить локальный путь в скрипте сборки? Как это вообще будет работать на другой машине, где путь к SDK свой? Это именно та проблема, которую я хочу решить.

Можешь ANDROID_HOME поменять при запуске гредл скрипта, если тебе билд тайпы не нравятся.

Я же написал в изначальном посте почему это не подходит. ANDROID_HOME имеет смысл только если установлена глобально для пользователя, иначе нужно делать враппер над скриптом сборки, чего и хочется избежать.

Dendy ★★★★★ ()
Ответ на: комментарий от Dendy

Там нету автоконфигураторов, кэша и прочего. Есть переменный окружения, пара локальных файлов для переменных и сам гредл скрипт. Ну есть еще груви на котором можно попробовать написать то что ты хочешь.

F457 ★★★ ()
Ответ на: комментарий от F457

Тут скорее вопрос что подсказывает здравый смысл и какой подход выстроился на протяжении многих лет опыта как систем сборок, так и систем контроля версий. Очевидно, что локальные параметры пользователя не сохраняются в систему контроля версий. Ещё очевиднее, что количество вариантов сборок увеличивается в геометрической прогрессии пропорционально количеству опций, предусмотреть их все невозможно, равно как и нельзя сделать всего несколько вариантов, которые подойдут всем.

Именно поэтому и существует двуэтапная сборка: конфигурация + ассемблер. Иначе если я попробую собрать из консоли проект, ранее собираемый из какой-нибудь Android Studio, то в итоге получится каша, ибо аргументы для Gradle были разные.

Если этапа конфигурации в Gradle нет, то что он предлагает взамен? Какие-то Groovy-классы, с помощью которых можно создать кеш? Или нужно писать враппер для сборки? Или делать корневой проект где-то за пределами дерева исходников, в котором каждый для себя захардкодит необходимые опции?

Dendy ★★★★★ ()
Ответ на: комментарий от Dendy

Я почти ничего на писал на груви для гредла в силу отсутствия какой либо необходимости ибо я не хочу делать странные вещи. Еслиб вдруг небеса разверзлись мне понадобилось менять путь к сдк, то задать пути в local.properties gradle.properties(на каждой машине свои) и переопределить для флейворов в скрипте меня устроило бы на 100%

F457 ★★★ ()
Ответ на: комментарий от F457

Да я уже понял, что вы не знаете как работать с Gradle. Вообще пока один на проекте, то можно работать без системы контроля версий и хардкодить напропалую, хотя и это до поры до времени. Как я понимаю build type и product flavor это детали самого Android-плагина. Меня же интересует общий подход. Вот есть у меня в проекте десяток опций, как в Gradle идеологически верно собрать определённую их комбинацию?

Dendy ★★★★★ ()
Ответ на: комментарий от Dendy

У меня 4 человека в команде и система контроля версий. Я видел проекты включающие билд сервер и непрерывную интеграцию. А вот каких-то вселенских проблем, которые тут описываеются - не видел. Т.е. я вообще не понимаю в чем у вас проблема. Создаем ххх.properties который не входит в контроль версий и добавляем скрипт его парсинга, если стандартных .properties не хватает. И храним там хоть 200 путей конкретной машины. Генератор по его заполнению нет - и не помню чтоб кто-то от этого сильно страдал. Точнее тот хотящий странного, которому это понадобится вызовет внешний генератор из гредл скрипта

В смысле как? В гредл скрипте для каждого флейвора можно задавать и менять переменные. Это и есть стандартный способ. Определить комбинацию значений переменных, которые описаны в доках и тех которые могут передаваться в код.

F457 ★★★ ()
Последнее исправление: F457 (всего исправлений: 2)
Ответ на: комментарий от F457

Предположим, у меня есть десяток булевских опций. Включить ли ассерты в некоем модуле. Использовать ли оптимизацию чего-либо. Собрать проект с определённой фичей или без. То-есть в какой-то момент я захочу собрать проект с произвольной комбинацией этих опций. Получается мне нужно создавать 1024 флейвора для всех вариантов, чтобы иметь их всех под рукой? Или добавлять нужный флейвор в момент необходимости? Но ведь они прописаны в общем скрипте, этот флейвор одноразовый и не должен сохраняться в контроль версий.

Dendy ★★★★★ ()
Ответ на: комментарий от Dendy

Если это одноразовая сбока то пропиши параметры в скрипте, в наиболее близкой из текущих конфигураций, собери и удали изменения. Это отличается от прописывания тогоже в командной строке только тем, что в истории команд не сохранится.

Причем вероятно этиже переменные можно передать из командной строки,лень уточнять в документации. И тогда вообще без разницы.

F457 ★★★ ()
Последнее исправление: F457 (всего исправлений: 1)

You can also add properties to your project objects using properties files. You can place a gradle.properties file in the Gradle user home directory (defined by the “GRADLE_USER_HOME” environment variable, which if not set defaults to USER_HOME/.gradle) or in your project directory. For multi-project builds you can place gradle.properties files in any subproject directory. The properties set in a gradle.properties file can be accessed via the project object. The properties file in the user's home directory has precedence over property files in the project directories.
You can also add properties directly to your project object via the -P command line option.

Пункт 11.2, там есть пример. Или вам не то нужно? К подобным переменным можно получить доступ из кода. Например, так:

android {
    defaultConfig {
        buildConfigField "long",    "BUILD_DATE", "${System.currentTimeMillis()}L"
        otherOptions = commandLineProjectProp
    }
}

Weres ★★★ ()
Ответ на: комментарий от F457

Если это одноразовая сбока то пропиши параметры в скрипте, в наиболее близкой из текущих конфигураций, собери и удали изменения.

Я догадываюсь, что вы никогда не работали с конфигурацией проекта, судя по тому что не понимаете суть проблемы. Прописать параметры в скрипте не вариант, это начисто нарушает принцип работы с системой контроля версий.

Предположим, у меня проект собирается с некой либой libfoo версии 1.2.3. В некоторый момент времени выходит версия 1.2.4 с исправлениями, а потом и вообще 1.3.0 с новым функционалом. Проект в зависимости от версии может настроиться соответственно, к примеру добавить некий #define, но, естественно, заранее этот номер неизвестен и будет указан во время сборки.

Новые версии libfoo выходят постоянно и тестируются на протяжении какого-то времени. При этом подобных мелких опций множество, в какой-то момент нужно настроить их все вместе и посмотреть как проект себя ведёт, где проявилась ошибка, в куда нужно влепить воркероунд. То-есть конфигурация не есть что-то одноразовое, что можно вписать и тут же удалить.

Причем вероятно этиже переменные можно передать из командной строки,лень уточнять в документации. И тогда вообще без разницы.

Разница огромна, прийдётся писать враппер, в котором нужно будет забить все аргументы командной строки, к чему и была претензия в изначальном посте.

Dendy ★★★★★ ()
Ответ на: комментарий от Weres

Спасибо, но, к сожалению, gradle.properties это не то. Похоже это настройки глобальны для всего пользователя, либо для проекта. Та же Android Studio генерирует этот файл и включает его в систему контроля версий, что намекает.

Dendy ★★★★★ ()
Ответ на: комментарий от Dendy

То-есть конфигурация не есть что-то одноразовое, что можно вписать и тут же удалить.

этот флейвор одноразовый и не должен сохраняться в контроль версий.

Походу лучший совет тут для начала разобраться в своих желаниях. А когда вы поймёте одноразовая у вас конфигурация или постоянная мы может быть продолжим.

F457 ★★★ ()
Ответ на: комментарий от Dendy

Да, глобальны. Странно то, что переопределение параметров в local.properties в скрипте не видно. В таком случае я вижу только способ с передачей через командную строку. Хотя у меня таких потребностей не возникало, возможно кто-то более осведомленный укажет на рабочий способ.

Weres ★★★ ()
Ответ на: комментарий от F457

Хорошо, не одноразовый, временный и локальный. Суть в том, что подобных конфигураций множество и в систему контроля версий они не попадают.

Dendy ★★★★★ ()
Ответ на: комментарий от Weres

Странно то, что переопределение параметров в local.properties в скрипте не видно.

Насколько я понял, local.properties не является частью Gradle как такового. Он парсится отдельно самом скриптом сборки (Android-плаигном) и его содержимое не пересекается с параметрами проекта. Gradle просто предоставляет класс, которым можно распарсить подобные файлы.

При этом local.properties в единственном экземпляре. Необходимо нечно похожее, но что можно было бы закешировать. Или добавить некие локальные флейворы, которые будут дополнять общие. Возможно это и есть подход Gradle, если нужно закешировать параметры — напиши для этого плагин.

Dendy ★★★★★ ()
Последнее исправление: Dendy (всего исправлений: 1)
Ответ на: комментарий от Dendy

Сделай для этого флейвор MyKinkyBuild который будет парсить локальный файлик не попадающий в систему контроля и на его основе собирать билд. Аля

https://stackoverflow.com/questions/20562189/sign-apk-without-putting-keystor...

только получай там версии библиотек

F457 ★★★ ()
Ответ на: комментарий от Dendy

Я догадываюсь, что вы никогда не работали с конфигурацией проекта, судя по тому что не понимаете суть проблемы. Прописать параметры в скрипте не вариант, это начисто нарушает принцип работы с системой контроля версий.

Я пишу адроид апликухи с гредлом уже два года и кроме проектов моей команды видел и другие проекты. И никто не испытал каких-то мнимых трудностей вами описываемых.

Предположим, у меня проект собирается с некой либой libfoo версии 1.2.3. В некоторый момент времени выходит версия 1.2.4 с исправлениями, а потом и вообще 1.3.0 с новым функционалом.

Для этого не нужны никакие кеши, автоконфигураторы и прочий изврат который тут понаписали. Создается новый флейвор и он комитится в систему контроля, иногда в отдельную ветку, если он всем не нужен. Все тестится с новой либой. Потом конфиг или удаляется как не нужный или становится основным. И все у всех работало, но надо на ровном месте придумать какие-то фантомные проблемы.

F457 ★★★ ()
Ответ на: комментарий от F457

Я пишу адроид апликухи с гредлом уже два года и кроме проектов моей команды видел и другие проекты.

Мне вот интересно какой у вас опыт за пределами этих двух лет. Я вот тоже в молодые годы достаточно долго кодил без системы контроля версий, инкрементальных систем сборок, стиля кодирования, ревью и прочих общепринятых технологий. Было куча мёртвого кода, потеряных бекапов, ручного деплоймента и подобного, тем не менее проекты реализовывались, сдавались и я не ощущал проблем. Только сейчас я понимаю, что это подобный стиль ведения проекта был ужасен. Наподобие того, что вы мне предлагаете захадркодить опции и локальные пути в общем конфиге и держать это всё в отдельной ветке, которая не должна быть случайно слита с общим кодом.

Для этого не нужны никакие кеши, автоконфигураторы и прочий изврат который тут понаписали.

Да, но постом выше вы мне кинули ссылку на именно такой изврат, как решение типичной задачи переопделеления ключа подписи. Изврат потому что в том же CMake подобные хаки не нужны. То что лично у вас подобные задачи не возникают не значит что их нет. Хотя возможно рецепт по ссылке и есть правильный способ переопределения параметров в Gradle.

Dendy ★★★★★ ()
Ответ на: комментарий от Dendy

+3 года андроида(но тогда гредл для андроида еще не изобрели, я только с гредлом работаю два года)
+6 не андроида

как решение типичной задачи переопделеления ключа подписи.

это задача «не хранения ключа в системе контроля версий» его не надо переопределять

наподобие того, что вы мне предлагаете захадркодить опции и локальные пути в общем конфиге и держать это всё в отдельной ветке

До вас как-то плохо доходит. Я не предлагаю захардкодить что-то в общем конфиге. В общем конфиге будет только чтение локальных параметров.

F457 ★★★ ()
Последнее исправление: F457 (всего исправлений: 1)
Ответ на: комментарий от Dendy

Про бранч я писал если тебе вдруг приспичило на какие-то локальные эксперименты на своей машине. Никто твой локальный бранч не будет мержить в здравом уме ибо он локальный. У тебя как у пользователя через пост задача меняется. То хочу локально менять библиотеки, то нет это для всех. Я не успеваю за полетом мысли и походу отпишусь от треда. Удачного решения проблем.

F457 ★★★ ()
Ответ на: комментарий от F457

Задача всё время одна и та же, просто вы предлагая какое-то решение забываете про остальные критерии, которые я достаточно подробно разжевал.

Нет, локальная ветка с временными хаками под себя не будет работать. Для этого она должна быть текущей, следовательно все новые коммиты будут идти в неё и зависеть от временного паразитного коммита с хаком. Единственный способ такой работы это следить чтобы этот паразитный коммит всегда был наверху, регулярно делая ребейз. Почему такой способ работы ущербен объяснять думаю не надо.

Про чтение локальных параметров в общем конфиге я отписался, что наверное это и есть правильный способ переопределения параметров в Gradle, перечитайте пост.

это задача «не хранения ключа в системе контроля версий» его не надо переопределять

Это именно задача подмены ключа, автор достаточно чётко дал понять, что у других пользователей должно всё продолжать работать. То-есть по умолчанию используется дефолтый ключ или автогенерируемый, но при этом на локальной машине он может подмениться без правки скриптов сборки.

Dendy ★★★★★ ()
Ответ на: Мимокрокодил от Stil

Спасибо, скачал книгу. Вообще насколько я понял этап конфигурации в Gradle присутствует, только его результаты не кешируются и не сохраняются. Вместо этого конфигурация происходит всегда и её результаты доступны в рантайме, где их и можно переопределить.

Dendy ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.