До выпуска Android 7.0 Android использовал GNU Make исключительно для описания и выполнения правил сборки. Система сборки Make широко поддерживается и используется, но в масштабах Android стала медленной, подверженной ошибкам, немасштабируемой и сложной для тестирования. Система сборки Soong обеспечивает гибкость, необходимую для сборки Android.
По этой причине ожидается, что разработчики платформы перейдут с Make на Soong как можно скорее. Отправляйте вопросы в группу Google по сборке Android, чтобы получить поддержку.
Что такое Сун?
Система сборки Soong была представлена в Android 7.0 (Nougat) вместо Make. Он использует инструмент клонирования Kati GNU Make и системный компонент сборки Ninja для ускорения сборки Android.
См. описание системы сборки Android Make в Android Open Source Project (AOSP) для получения общих инструкций и изменения системы сборки для авторов Android.mk , чтобы узнать об изменениях, необходимых для адаптации от Make к Soong.
См. связанные со сборкой записи в глоссарии для определений ключевых терминов и справочные файлы Soong для получения полной информации.
Сравнение Make и Soong
Вот сравнение конфигурации Make с Soong, выполняющей то же самое в файле конфигурации Soong (Blueprint или .bp
).
Сделать пример
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libxmlrpc++
LOCAL_MODULE_HOST_OS := linux
LOCAL_RTTI_FLAG := -frtti
LOCAL_CPPFLAGS := -Wall -Werror -fexceptions
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/src
LOCAL_SRC_FILES := $(call \
all-cpp-files-under,src)
include $(BUILD_SHARED_LIBRARY)
Сун пример
cc_library_shared {
name: “libxmlrpc++”,
rtti: true,
cppflags: [
“-Wall”,
“-Werror”,
“-fexceptions”,
],
export_include_dirs: [“src”],
srcs: [“src/**/*.cpp”],
target: {
darwin: {
enabled: false,
},
},
}
См. « Простая конфигурация сборки» для примеров конфигурации Soong для конкретных тестов.
Формат файла Android.bp
По своей структуре файлы Android.bp
просты. Они не содержат условных выражений или операторов управления потоком; вся сложность обрабатывается логикой сборки, написанной на Go. Когда это возможно, синтаксис и семантика файлов Android.bp
аналогичны файлам Bazel BUILD .
Модули
Модуль в файле Android.bp
начинается с типа модуля, за которым следует набор свойств в name: "value",
формат:
cc_binary {
name: "gzip",
srcs: ["src/test/minigzip.c"],
shared_libs: ["libz"],
stl: "none",
}
У каждого модуля должно быть свойство name
, и это значение должно быть уникальным во всех файлах Android.bp
, за исключением значений свойства name
в пространствах имен и готовых модулях, которые могут повторяться.
Свойство srcs
указывает исходные файлы, используемые для сборки модуля, в виде списка строк. Вы можете ссылаться на выходные данные других модулей, которые создают исходные файлы, такие как genrule
или filegroup
, используя синтаксис ссылки на модуль ":<module-name>"
.
Список допустимых типов модулей и их свойств см. в справочнике по модулям Soong .
Типы
Переменные и свойства строго типизированы, переменные динамически основаны на первом назначении, а свойства установлены статически типом модуля. Поддерживаемые типы:
- Булевы значения (
true
илиfalse
) - Целые числа (
int
) - Строки (
"string"
) - Списки строк (
["string1", "string2"]
) - Карты (
{key1: "value1", key2: ["value2"]}
)
Карты могут содержать значения любого типа, включая вложенные карты. Списки и карты могут иметь завершающие запятые после последнего значения.
шары
Свойства, принимающие список файлов, такие как srcs
, также могут принимать шаблоны глобусов. Шаблоны глобусов могут содержать обычный подстановочный знак UNIX *
, например *.java
. Шаблоны Glob также могут содержать один подстановочный знак **
в качестве элемента пути, который соответствует нулю или более элементам пути. Например, java/**/*.java
соответствует java/Main.java
и java/com/android/Main.java
.
Переменные
Файл Android.bp
может содержать назначения переменных верхнего уровня:
gzip_srcs = ["src/test/minigzip.c"],
cc_binary {
name: "gzip",
srcs: gzip_srcs,
shared_libs: ["libz"],
stl: "none",
}
Переменные ограничены остальной частью файла, в котором они объявлены, а также любыми дочерними файлами Blueprint. Переменные неизменяемы, за одним исключением: к ним можно добавить присваивание +=
, но только до того, как на них будет сделана ссылка.
Комментарии
Файлы Android.bp
могут содержать многострочные /* */
комментарии в стиле C и однострочные //
комментарии в стиле C++.
Операторы
Строки, списки строк и карты могут быть добавлены с помощью оператора +. Целые числа можно суммировать с помощью оператора +
. Добавление карты создает объединение ключей в обеих картах, добавляя значения любых ключей, которые присутствуют в обеих картах.
Условные
Сун не поддерживает условные операторы в файлах Android.bp
. Вместо этого сложные правила сборки, требующие условных выражений, обрабатываются в Go, где можно использовать языковые функции высокого уровня и отслеживать неявные зависимости, введенные условными выражениями. Большинство условных выражений преобразуются в свойство карты, где одно из значений карты выбирается и добавляется к свойствам верхнего уровня.
Например, для поддержки файлов, специфичных для архитектуры:
cc_library {
...
srcs: ["generic.cpp"],
arch: {
arm: {
srcs: ["arm.cpp"],
},
x86: {
srcs: ["x86.cpp"],
},
},
}
Форматтер
Soong включает канонический форматировщик для файлов Blueprint, похожий на gofmt . Чтобы рекурсивно переформатировать все файлы Android.bp
в текущем каталоге, запустите:
bpfmt -w .
Канонический формат включает отступы в четыре пробела, новые строки после каждого элемента многоэлементного списка и запятую в конце в списках и картах.
Специальные модули
Некоторые специальные группы модулей имеют уникальные характеристики.
Модули по умолчанию
Модуль по умолчанию можно использовать для повторения одних и тех же свойств в нескольких модулях. Например:
cc_defaults {
name: "gzip_defaults",
shared_libs: ["libz"],
stl: "none",
}
cc_binary {
name: "gzip",
defaults: ["gzip_defaults"],
srcs: ["src/test/minigzip.c"],
}
Готовые модули
Некоторые типы готовых модулей позволяют модулю иметь то же имя, что и его аналоги на основе исходного кода. Например, может быть cc_prebuilt_binary
с именем foo
, когда уже есть cc_binary
с таким же именем. Это дает разработчикам возможность выбирать, какую версию включить в конечный продукт. Если конфигурация сборки содержит обе версии, значение флага prefer
в предварительно созданном определении модуля указывает, какая версия имеет приоритет. Обратите внимание, что имена некоторых готовых модулей не начинаются с prebuilt
, например android_app_import
.
Модули пространства имен
Пока Android полностью не перейдет с Make на Soong, в конфигурации продукта Make должно быть указано значение PRODUCT_SOONG_NAMESPACES
. Его значение должно быть списком пространств имен, разделенных пробелами, которые Soong экспортирует в Make для построения с помощью команды m
. После завершения преобразования Android в Soong детали включения пространств имен могут измениться.
Сунг предоставляет модулям в разных каталогах возможность указывать одно и то же имя, если каждый модуль объявлен в отдельном пространстве имен. Пространство имен может быть объявлено следующим образом:
soong_namespace {
imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"],
}
Обратите внимание, что пространство имен не имеет свойства name; его путь автоматически назначается в качестве имени.
Каждому модулю Soong назначается пространство имен в зависимости от его местоположения в дереве. Считается, что каждый модуль Soong находится в пространстве имен, определяемом пространством имен soong_namespace
найденным в файле Android.bp
в текущем каталоге или каталоге ближайшего предка. Если такой модуль soong_namespace
не найден, модуль считается находящимся в неявном корневом пространстве имен.
Вот пример: Сун пытается разрешить зависимость D, объявленную модулем M в пространстве имен N, которое импортирует пространства имен I1, I2, I3…
- Затем, если D является полным именем в форме
//namespace:module
, поиск указанного имени модуля выполняется только в указанном пространстве имен. - В противном случае Сун сначала ищет модуль с именем D, объявленный в пространстве имен N.
- Если этот модуль не существует, Сунг ищет модуль с именем D в пространствах имен I1, I2, I3…
- Наконец, Сунг просматривает корневое пространство имен.