Google is committed to advancing racial equity for Black communities. See how.
This page was translated by the Cloud Translation API.
Switch to English

Система сборки Сунга

До выпуска Android 7.0 Android использовал GNU Make исключительно для описания и выполнения своих правил сборки. Система сборки Make широко поддерживается и используется, но в масштабе Android она стала медленной, подверженной ошибкам, не масштабируемой и сложной для тестирования. Система сборки Soong обеспечивает гибкость, необходимую для сборок Android.

По этой причине ожидается, что разработчики платформы как можно скорее откажутся от Make и примут Soong. Чтобы получить поддержку, отправьте вопросы в группу Google по созданию Android .

Что такое Сунг?

Система сборки Soong была представлена ​​в Android 7.0 (Nougat) взамен Make. Он использует инструмент Kati GNU Make clone и компонент системы сборки Ninja для ускорения сборки Android.

См. Описание Android Make Build System в Android Open Source Project (AOSP) для получения общих инструкций и Build System Changes для Android.mk Writers, чтобы узнать об изменениях, необходимых для адаптации Make к Soong.

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

Сравнение Make и Soong

Вот сравнение Make configuration с 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"]} )

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

Globs

Свойства, которые принимают список файлов, например srcs , также могут принимать шаблоны srcs . Шаблоны глобусов могут содержать обычные символы подстановки UNIX * , например *.java . Шаблоны глобуса также могут содержать один подстановочный знак ** в качестве элемента пути, который соответствует нулю или более элементам пути. Например, 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 ++.

Операторы

Строки, списки строк и карты могут быть добавлены с помощью оператора +. Целые числа можно суммировать с помощью оператора + . Добавление карты производит объединение ключей в обеих картах, добавляя значения любых ключей, которые присутствуют в обеих картах.

Условные

Soong не поддерживает условные Android.bp файлах 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 предоставляет возможность модулям в разных каталогах указывать одно и то же имя, если каждый модуль объявлен в отдельном пространстве имен. Пространство имен можно объявить так:

soong_namespace {
    imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"],
}

Обратите внимание, что пространство имен не имеет свойства имени; его путь автоматически назначается как его имя.

Каждому модулю Soong назначается пространство имен в зависимости от его положения в дереве. Считается, что каждый модуль Soong находится в пространстве имен, определяемом пространством имен soong_namespace находящимся в файле Android.bp в текущем каталоге или каталоге ближайшего предка. Если такой модуль soong_namespace не найден, считается, что модуль находится в неявном корневом пространстве имен.

Вот пример: Сунг пытается разрешить зависимость D, объявленную модулем M в пространстве имен N, которое импортирует пространства имен I1, I2, I3…

  1. Затем, если D является полностью определенным именем формы //namespace:module , только указанное пространство имен ищется для указанного имени модуля.
  2. В противном случае Сун сначала ищет модуль с именем D, объявленный в пространстве имен N.
  3. Если этот модуль не существует, Сунг ищет модуль с именем D в пространствах имен I1, I2, I3…
  4. Наконец, Сунг смотрит в корневое пространство имен.