引言
Android編譯知識的梳理文章共三篇:
- Android 編譯之make基礎
- Android 編譯之android.mk
- Android 編譯之android.bp
本文是最后一篇掠拳,主要介紹android.bp债沮。
1. Ninja
1.1 Ninja簡介
Ninja 是一個專注于速度的小型構建系統(tǒng)。它與其他構建系統(tǒng)在兩個主要方面不同:
- Ninja的輸入文件被設計為由更高級的構建系統(tǒng)生成。
- Ninja被設計為盡可能快地運行構建, 其他構建系統(tǒng)基于高級語言,而Ninja基于匯編。
Ninja基于匯編妻导,專注于速度,不支持分支诀蓉、循環(huán)等流程控制栗竖,也不支持邏輯運算暑脆,但它允許以其它語言如來維護這些復雜的編譯流程和邏輯渠啤。例如,我們可以采用Makefile, go, python等等來維護編譯的流程和邏輯添吗。
1.2 Ninja的構建文件
雖然Ninja的構建文件是可讀的(human-readable)沥曹,但是手寫不是特別方便。我們可以先來看一段ninja文件的內容:
# This file is used to build ninja itself.
# It is generated by configure.py.
ninja_required_version = 1.3
# The arguments passed to configure.py, for rerunning it.
configure_args =
root = .
builddir = build
cxx = g++
ar = ar
cflags = -g -Wall -Wextra -Wno-deprecated -Wno-missing-field-initializers $
-Wno-unused-parameter -fno-rtti -fno-exceptions -fvisibility=hidden $
-pipe '-DNINJA_PYTHON="python"' -O2 -DNDEBUG -DUSE_PPOLL $
-DNINJA_HAVE_BROWSE -I.
ldflags = -L$builddir
rule cxx
command = $cxx -MMD -MT $out -MF $out.d $cflags -c $in -o $out
description = CXX $out
depfile = $out.d
deps = gcc
rule ar
command = rm -f $out && $ar crs $out $in
description = AR $out
rule link
command = $cxx $ldflags -o $out $in $libs
description = LINK $out
可以看到碟联,ninja的構建文件妓美,書寫起來是不很方便的,所以鲤孵,我們需要一些ninja構建文件的生成器壶栋。這些生成器就是一些元構建系統(tǒng)(meta-build system),例如Blueprint普监、CMake等等贵试。Ninja的基于底層實現(xiàn)使其非常適合嵌入到這些功能更強大的構建系統(tǒng)中琉兜。更多ninja構建文件的生成器,可參考:List of generators producing ninja build files毙玻。
Ninja用于構建Google Chrome瀏覽器豌蟋,Android,LLVM的一部分桑滩。由于CMake可在大多數平臺上運行梧疲,并且可以生成多種格式的項目文件,包括Ninja运准。所以Ninja也可以作為CMake的底層實現(xiàn)幌氮,在許多其他項目中使用。
1.3 Ninja的下載和使用
Ninja的最新版本為v1.10.2戳吝,于2020年11月23日發(fā)布:Ninja release v1.10.2浩销。
當然我們也可以下載ninja源碼自行編譯:
$ git clone git://github.com/ninja-build/ninja.git && cd ninja
$ git checkout release
$ cat README
Ninja的設計哲學和設計背景,是否以及如何在項目中使用Ninja听哭,Ninja的平臺支持以及Ninja詳細的語言語義等等更多Ninja相關的知識慢洋,請參考:
Ninjia使用手冊
2. Blueprint
2.1 Blueprint簡介
Blueprint 是一個元構建系統(tǒng),該系統(tǒng)讀取Blueprint文件來描述需要構建的模塊陆盘,并生成一個Ninja清單來描述需要運行的命令及其依賴項普筹。 在大多數構建系統(tǒng)使用內置規(guī)則或特定領域語言來描述將模塊描述轉換為構建規(guī)則的邏輯。Blueprint將其委托給使用Go編寫的針對每個項目的構建邏輯隘马。 對于大型太防,異構項目,這允許以高級語言維護固有酸员、復雜的構建邏輯蜒车,同時仍可以通過修改易于理解的Blueprint文件來對單個模塊進行簡單更改。
2.2 android中的Blueprint
前面在Ninja的構建文件一節(jié)我們提到了幔嗦,Blueprint是ninja構建文件的生成器酿愧。android編譯系統(tǒng)soong集成了Blueprint,Blueprint可將我們編寫的android.bp解析生成一個ninja構建文件邀泉。我們在編譯一個模塊時嬉挡,只需要將這個模塊的android.bp文件配置好,編譯系統(tǒng)會自動為這個模塊生成ninja清單汇恤,最終使用ninja來調用gcc庞钢、clang、java因谎、dex基括、aapt2等等命令來構建模塊。
3. kati
kati 是Google開發(fā)的一個實驗性的GNU make clone财岔,kati的主要目標是加快Android的增量構建风皿。目前饭冬,kati本身并不能提供更快的構建。 而是將Makefile轉換為ninja揪阶。一開始kati是用go語言開發(fā)的昌抠,但作者發(fā)現(xiàn)使用go寫的有性能問題,后來作者又用C++進行了重寫鲁僚,也就是kati變成了ckati(作者的原文描述可以查看android源碼目錄下的:build/kati/INTERNALS.md)炊苫。后續(xù)提到kati時,如不特別指出冰沙,即是指ckati侨艾。
簡單點說,kati就是一個轉換工具拓挥,它可以將Makefile和.mk文件轉換為ninja唠梨。
android源碼目錄下的:prebuilts/build-tools下有預置的kati,Android 7.0及以上版本侥啤,編譯源碼時會自動使用kati当叭。大多數情況下,我們不會直接使用kati盖灸,但如果你還想了解更多kati的相關信息蚁鳖,可以訪問:https://github.com/google/kati。也可以查看android源碼目錄下的 build/kati/INTERNALS.md 和 build/kati/README.md赁炎。
4. soong
4.1 soong簡介
在android 6.0版本之前醉箕,編譯android源碼采用的是基于make的編譯系統(tǒng)(make-based build system),也就是android的各個庫徙垫、APK等等目標文件都是采用make來構建的讥裤。 但是,由于make在編譯時表現(xiàn)出效率不夠高姻报、增量編譯速度慢等問題己英,Google在android 7.0版本引進了編譯速度更快的soong來替代make。
Soong集成了Ninja, 而Ninja專注于速度逗抑,沒有條件或流程控制語句剧辐,也不支持邏輯運算寒亥。但它允許以其它語言如來維護這些復雜的編譯流程和邏輯邮府。例如,我們可以繼續(xù)采用makefile, 或者采用go語言來維護編譯流程和邏輯溉奕。上面已經提到了Ninja褂傀,Blueprint, kati等等好幾種工具加勤,為了完整仙辟、快速的構建一個android系統(tǒng)同波,就需要一個“管家”來協(xié)調這些工具。例如叠国,將.bp轉換成ninja時使用Blueprint, 將Makefile轉換成ninja時使用kati未檩。這個選擇轉換工具、選擇解析框架粟焊、解析維護構建邏輯的“管家”就是soong冤狡。
編譯android源碼時,soong也會被自動使用项棠,我們可以和原來一樣:
- 首先悲雳,source build/envsetup.sh。
- 然后香追,lunch選擇target合瓢。
- 最后,使用m透典、mm晴楔、mmm或者make來編譯指定的模塊或者整個系統(tǒng)。
但是峭咒,m滥崩、mm、mmm或者make最終都會使用soong來編譯讹语。因為source之后钙皮,build/envsetup.sh中已經將make指向soong了:
function get_make_command()
{
# If we're in the top of an Android tree, use soong_ui.bash instead of make
if [ -f build/soong/soong_ui.bash ]; then
# Always use the real make if -C is passed in
for arg in "$@"; do
if [[ $arg == -C* ]]; then
echo command make
return
fi
done
echo build/soong/soong_ui.bash --make-mode
else
echo command make
fi
}
function make()
{
_wrap_build $(get_make_command "$@") "$@"
}
function m()
{
local T=$(gettop)
if [ "$T" ]; then
_wrap_build $T/build/soong/soong_ui.bash --make-mode $@
else
echo "Couldn't locate the top of the tree. Try setting TOP."
return 1
fi
}
function mm()
{
local T=$(gettop)
# If we're sitting in the root of the build tree, just do a
# normal build.
if [ -f build/soong/soong_ui.bash ]; then
_wrap_build $T/build/soong/soong_ui.bash --make-mode $@
else
# Find the closest Android.mk file.
local M=$(findmakefile)
local MODULES=
local GET_INSTALL_PATH=
local ARGS=
# Remove the path to top as the makefilepath needs to be relative
local M=`echo $M|sed 's:'$T'/::'`
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP."
return 1
elif [ ! "$M" ]; then
echo "Couldn't locate a makefile from the current directory."
return 1
else
local ARG
for ARG in $@; do
case $ARG in
GET-INSTALL-PATH) GET_INSTALL_PATH=$ARG;;
esac
done
if [ -n "$GET_INSTALL_PATH" ]; then
MODULES=
ARGS=GET-INSTALL-PATH-IN-$(dirname ${M})
ARGS=${ARGS//\//-}
else
MODULES=MODULES-IN-$(dirname ${M})
# Convert "/" to "-".
MODULES=${MODULES//\//-}
ARGS=$@
fi
if [ "1" = "${WITH_TIDY_ONLY}" -o "true" = "${WITH_TIDY_ONLY}" ]; then
MODULES=tidy_only
fi
ONE_SHOT_MAKEFILE=$M _wrap_build $T/build/soong/soong_ui.bash --make-mode $MODULES $ARGS
fi
fi
}
function mmm()
{
local T=$(gettop)
if [ "$T" ]; then
local MAKEFILE=
local MODULES=
local MODULES_IN_PATHS=
local ARGS=
local DIR TO_CHOP
local DIR_MODULES
local GET_INSTALL_PATH=
local GET_INSTALL_PATHS=
local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
for DIR in $DIRS ; do
DIR_MODULES=`echo $DIR | sed -n -e 's/.*:\(.*$\)/\1/p' | sed 's/,/ /'`
DIR=`echo $DIR | sed -e 's/:.*//' -e 's:/$::'`
# Remove the leading ./ and trailing / if any exists.
DIR=${DIR#./}
DIR=${DIR%/}
if [ -f $DIR/Android.mk -o -f $DIR/Android.bp ]; then
local TO_CHOP=`(\cd -P -- $T && pwd -P) | wc -c | tr -d ' '`
local TO_CHOP=`expr $TO_CHOP + 1`
local START=`PWD= /bin/pwd`
local MDIR=`echo $START | cut -c${TO_CHOP}-`
if [ "$MDIR" = "" ] ; then
MDIR=$DIR
else
MDIR=$MDIR/$DIR
fi
MDIR=${MDIR%/.}
if [ "$DIR_MODULES" = "" ]; then
MODULES_IN_PATHS="$MODULES_IN_PATHS MODULES-IN-$MDIR"
GET_INSTALL_PATHS="$GET_INSTALL_PATHS GET-INSTALL-PATH-IN-$MDIR"
else
MODULES="$MODULES $DIR_MODULES"
fi
MAKEFILE="$MAKEFILE $MDIR/Android.mk"
else
case $DIR in
showcommands | snod | dist | *=*) ARGS="$ARGS $DIR";;
GET-INSTALL-PATH) GET_INSTALL_PATH=$DIR;;
*) if [ -d $DIR ]; then
echo "No Android.mk in $DIR.";
else
echo "Couldn't locate the directory $DIR";
fi
return 1;;
esac
fi
done
if [ -n "$GET_INSTALL_PATH" ]; then
ARGS=${GET_INSTALL_PATHS//\//-}
MODULES=
MODULES_IN_PATHS=
fi
if [ "1" = "${WITH_TIDY_ONLY}" -o "true" = "${WITH_TIDY_ONLY}" ]; then
MODULES=tidy_only
MODULES_IN_PATHS=
fi
# Convert "/" to "-".
MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}
ONE_SHOT_MAKEFILE="$MAKEFILE" _wrap_build $T/build/soong/soong_ui.bash --make-mode $DASH_ARGS $MODULES $MODULES_IN_PATHS $ARGS
else
echo "Couldn't locate the top of the tree. Try setting TOP."
return 1
fi
}
使用make構建項目,主要工作是編寫Makefile顽决;類似的短条,使用soong構建項目,主要工作是編寫bp文件才菠。關于bp文件我們會在接下來的第5節(jié)中詳細介紹茸时。
4.2 androidmk
soong中還集成了一個非常有用的工具androidmk。androidmk可以將android.mk轉換成android.bp赋访。我們可以使用androidmk來轉換代碼中已有的android.mk可都,以此來減少重寫android.bp的工作量。例如蚓耽,我們將一個Android.mk轉換成Android.bp:
androidmk Android.mk > Android.bp
注意:androidmk工具可以轉換變量渠牲,模塊,注釋和某些條件步悠,但是自定義的Makefile規(guī)則签杈,復雜的條件語句或其它的額外的include語句,必須手動轉換鼎兽。
在現(xiàn)有版本答姥,由于kati工具的存在铣除,繼續(xù)使用android.mk也是沒有問題的。但是鹦付,也許在將來的某一天尚粘,Google可能會不再支持Makefile。因此敲长,建議新增的模塊采用android.bp背苦,存量的android.mk,在條件允許的情況下潘明,也應當盡量轉換成android.bp行剂。
4.3 bpfmt
為了方便格式化,Soong還包含了一個用于格式化Android.bp文件的工具bpfmt钳降,類似于gofmt厚宰。 以一個簡單的bp文件為例:
cc_binary {
name: "gzip",
srcs: [
"src/test/minigzip.c",
"src/test/utils.c",
],
shared_libs: ["libz"],
stl: "none",
}
Android.bp的規(guī)范格式包括:
- 4個空格縮進。
- 多元素列表的每個元素后的換行符遂填。
- 在lists和maps的結尾處始終包含一個逗號铲觉。
我們可以使用bpfmt工具來規(guī)范格式化Android.bp文件。例如吓坚,要遞歸地格式化當前目錄中的所有Android.bp文件:
bpfmt -w .
4.4 ninja撵幽,Blueprint,kati礁击,androidmk與Soong的關系和作用
- kati可以將Android.mk文件轉換成ninja文件盐杂。
- androidmk可以將Android.mk文件轉換成Android.bp文件
- Blueprint可以將Android.bp文件轉換成ninja文件。
- Blueprint哆窿,kati链烈,androidmk由Soong調用和協(xié)調,一起合作完成android源碼的構建挚躯。
它們的關系示意圖如下:
5. Android.bp
5.1 bp文件的命名與文件格式
soong的編譯配置文件以.bp結尾强衡,通常命名為Android.bp,但也有少數情況不以Android.bp命名码荔。例如:frameworks/rs/support.bp漩勤。與Makefile一樣,使用soong編譯前缩搅,會遍歷所有以bp為后綴名的文件越败。因此,soong的編譯配置文件只要以.bp結尾即可誉己。
5.2 模塊(module)
bp文件中的模塊(module) 以模塊類型(module type)開頭眉尸,后面跟著一系列的屬性(property)域蜗。每個模塊都必須具有一個屬性名為name的屬性巨双,并且name的屬性值在所有Android.bp文件中必須是唯一的噪猾。bp文件的內容與JSON、Bazel BUILD很像筑累,模塊的格式為:
[module type] {
name: "[name value]",
[property1 name]:"[property1 value]",
[property2 name]:"[property2 value]",
}
一個簡單的bp文件:
cc_binary {
name: "gzip",
srcs: ["src/test/minigzip.c"],
shared_libs: ["libz"],
stl: "none",
}
常見的模塊類型有:
cc_library,
cc_library_headers,
cc_library_shared,
cc_library_static,
android_app,
android_app_certificate,
java_library,
java_library_static,
java_sdk_library等等袱蜡。
soong預置了一系列的模塊類型和屬性,芯片原廠也會添加一些自定義的模塊類型和屬性慢宗,例如坪蚁,MTK平臺就定義了一些以mtk開頭的模塊類型。如果想了解更多镜沽,已有源碼并且已編譯的可以查看:out/soong/docs/soong_build.html敏晤。如果沒有源碼,也可查看AOSP的在線文檔:$AOSP/out/soong/docs/soong_build.html
5.2.1 默認模塊(defaults)
soong提供了一系列xx_defaults模塊類型缅茉,例如:cc_defaults, java_defaults, doc_defaults, stub_defaults等等嘴脾。模塊類型為xx_defaults的模塊提供了一組可由其它模塊繼承的屬性。其它模塊可以通過添加屬性`defaults:[“ <:default_module_name>”]“來指定繼承xx_defaults類型的模塊定義的屬性蔬墩。因此译打,我們定義一個新模塊時,可以通過將默認模塊的屬性放在name屬性之后拇颅,其它屬性之前奏司,來合并兩個模塊的屬性。
例如:
java_defaults {
name: "framework-defaults",
installable: true,
srcs: [
// From build/make/core/pathmap.mk FRAMEWORK_BASE_SUBDIRS
"core/java/**/*.java",
"graphics/java/**/*.java",
"location/java/**/*.java",
"lowpan/java/**/*.java",
"media/java/**/*.java",
]
//......省略無關
}
java_library {
name: "framework",
defaults: ["framework-defaults"],
javac_shard_size: 150,
}
java_library {
name: "framework-annotation-proc",
defaults: ["framework-defaults"],
// Use UsedByApps annotation processor
plugins: ["unsupportedappusage-annotation-processor"],
}
這個例子中樟插,模塊aidl_mapping在srcs屬性中引用了framework-defaults韵洋。
5.2.2 引用模塊
一個模塊可以通過它的模塊名來引用。在默認模塊這一小節(jié)中黄锤,其實我們已經引用過了其它模塊了麻献。這里我們再來一個例子:
cc_binary {
name: "app",
shared_libs: ["libfoo"],
}
例子中,libfoo模塊必須存在才有效猜扮,并且在構建樹中有且僅有一個libfoo模塊時才有效勉吻。
5.3 文件列表
一個屬性的屬性值為一系列文件時,屬性值也可以采用全局匹配模式和輸出路徑擴展旅赢。
全局匹配模式可以包含普通的Unix通配符*齿桃,例如“ * .java”。
全局匹配模式也可以包含單個**通配符作為路徑元素煮盼,它將匹配零個或多個路徑元素短纵。 例如,java / ** / *僵控。java將匹配 java/Main.java 和 java/com/android/Main.java香到。
輸出路徑擴展采用:module或:module {.tag}格式,其中module是生成輸出文件的模塊的名稱,并且擴展為這些輸出文件的列表悠就。 使用可選的{.tag}后綴千绪,模塊可以根據tag生成不同的輸出列表。
例如:
// AIDL interface between storaged and framework.jar
filegroup {
name: "storaged_aidl",
srcs: [
"binder/android/os/IStoraged.aidl",
],
path: "binder",
}
java_library_static {
name: "services.core.unboosted",
srcs: [
"java/**/*.java",
":storaged_aidl",
],
//......省略無關
}
5.4 類型和變量
Android.bp文件中梗脾,變量和屬性是強類型的荸型,變量是基于首次分配動態(tài)地創(chuàng)建的,屬性是根據模塊類型靜態(tài)地創(chuàng)建的炸茧。 支持的類型有:
- Bool (true or false)
- Integers (int)
- Strings ("string")
- Lists of strings (["string1", "string2"])
- Maps ({key1: "value1", key2: ["value2"]})
maps可以是任何類型的值瑞妇,包括嵌套maps。 Lists和Map的最后一個值后面可能帶有逗號梭冠。
字符串可以使用\“包含雙引號辕狰,例如” cat \“ a b \”“。
5.5 注釋
Android.bp文件可以和C/C++的注釋類似控漠,可以包含多行注釋和單行注釋柳琢。
- 多行注釋:/ * 注釋 * /
- 單行注釋://注釋。
5.6 運算符
Android.bp文件可以使用+運算符附加字符串润脸,字符串列表和映射柬脸。 整數可以使用+運算符求和。 追加映射會在兩個映射中生成鍵的并集毙驯,并追加兩個映射中都存在的任何鍵的值倒堕。
例如:
cc_test {
name: "libandroidfw_tests",
host_supported: true,
defaults: ["libandroidfw_defaults"],
cppflags: [
// This is to suppress warnings/errors from gtest
"-Wno-unnamed-type-template-args",
],
srcs: [
// Helpers/infra for testing.
"tests/CommonHelpers.cpp",
"tests/TestHelpers.cpp",
"tests/TestMain.cpp",
// 省略無關部分
],
static_libs: ["libgmock"],
target: {
android: {
srcs: [
"tests/BackupData_test.cpp",
"tests/ObbFile_test.cpp",
],
shared_libs: common_test_libs + ["libui"],
},
host: {
static_libs: common_test_libs + ["liblog", "libz"],
},
},
data: ["tests/data/**/*.apk"],
}
注意:
除了上述介紹的內容之外,Soong還包含了包爆价、命名空間垦巴、名稱解析、可見性铭段、soong配置變量等等內容骤宣。但是,我在Android 9.0和Android 10.0兩份源碼中都沒有找到合適的例子序愚,本人也不是很理解憔披,為避免誤導他人,這些內容就不介紹了爸吮,如果想了解更多芬膝,請參考:https://android.googlesource.com/platform/build/soong/
6. Android.mk和Android.bp的區(qū)別
Android.mk文件通常可以包含多個同名模塊(例如形娇,用于庫的靜態(tài)(static)和共享(shared)版本锰霜,用于不同主機(host)的版本,用于不同設備(device)版本)桐早。
Android.bp文件的每個模塊都需要唯一的名稱癣缅,但是單個模塊可以構建為多個變體厨剪。例如,通過添加host_supported:true友存。 包含多個同名模塊的Android.mk被androidmk轉換成Android.bp之后祷膳,將生成多個沖突的模塊,這些模塊必須手動處理爬立,將同名模塊改為一個具有多個變體的模塊钾唬,這些在target:{android:{}万哪,host:{}}塊內的變體可以有區(qū)別侠驯,例如,引用不同的源文件奕巍,不同架構的共享庫文件等等吟策。
Soong故意不支持Android.bp文件中的大多數條件。 Google建議從構建中刪除大多數條件的止。Soong將本地支持的大多數條件將轉換為map屬性檩坚。 構建模塊時,將選擇map中的屬性之一诅福,并且將其值追加到模塊頂層的同名屬性中匾委。
例如,要支持特定于體系結構的文件:
cc_library {
...
srcs: ["generic.cpp"],
arch: {
arm: {
srcs: ["arm.cpp"],
},
x86: {
srcs: ["x86.cpp"],
},
},
}
為arm平臺構建時氓润,將構建generic.cpp和arm.cpp赂乐。 在為x86平臺構建時,將構建generic.cpp和x86.cpp咖气。
7.Android.bp實戰(zhàn)
7.1 編譯APP
以DocumentsUI為例(為看起來清晰挨措,有整理和部分刪減):
android_app {
name: "DocumentsUI",
manifest: "AndroidManifest.xml",
srcs: [
"src/**/*.java",
],
resource_dirs: [
"res",
],
static_libs: [
"androidx.appcompat_appcompat",
"androidx.recyclerview_recyclerview",
],
privileged: true,
certificate: "platform",
optimize: {
proguard_flags_files: ["proguard.flags"],
},
sdk_version: "system_current",
min_sdk_version: "28",
target_sdk_version: "28",
required: ["privapp_whitelist_com.android.documentsui"],
}
可以看到,Android.bp非常簡潔崩溪,而且命名很清晰浅役,基本上看屬性名就知道是起什么作用的。這里只列出了android_app的常用屬性伶唯,并沒有將它的所有屬性列出來觉既,開發(fā)過程中如果需要配置APP的其它屬性,請參考:out/soong/docs/soong_build.html乳幸。如果沒有源碼奋救,也可查看AOSP的在線文檔:$AOSP/out/soong/docs/soong_build.html
7.2 編譯java庫
java_library {
name: "updatable-media",
srcs: [
":updatable-media-srcs",
],
aidl: {
export_include_dirs: [
"apex/java",
],
// It would be great if we don't need to add include_dirs for public
// parcelable classes. Find a better way.
include_dirs: [
// To refer:
// android.os.Bundle
// android.os.ResultReceiver
"frameworks/base/core/java",
],
},
permitted_packages: [
"android.media",
],
installable: true,
// Make sure that the implementaion only relies on SDK or system APIs.
no_framework_libs: true,
libs: [
// The order matters. android_system_* library should come later.
"framework_media_annotation",
"android_system_stubs_current",
],
}
7.3 編譯java靜態(tài)庫
java_library_static {
name: "services.core.unboosted",
aidl: {
include_dirs: [
"frameworks/native/aidl/binder",
"system/core/storaged/binder",
"system/netd/server/binder",
"system/vold/binder",
],
},
srcs: [
"java/**/*.java",
":netd_aidl",
":netd_metrics_aidl",
":installd_aidl",
":storaged_aidl",
":vold_aidl",
":mediaupdateservice_aidl",
"java/com/android/server/EventLogTags.logtags",
"java/com/android/server/am/EventLogTags.logtags",
],
libs: [
"services.net",
"android.hardware.light-V2.0-java",
"android.hardware.power-V1.0-java",
"android.hardware.tv.cec-V1.0-java",
"android.hidl.manager-V1.0-java",
],
static_libs: [
"time_zone_distro",
"time_zone_distro_installer",
"android.hardware.authsecret-V1.0-java",
"android.hardware.broadcastradio-V2.0-java",
"android.hardware.health-V1.0-java",
"android.hardware.health-V2.0-java",
"android.hardware.weaver-V1.0-java",
"android.hardware.biometrics.fingerprint-V2.1-java",
"android.hardware.oemlock-V1.0-java",
"android.hardware.tetheroffload.control-V1.0-java",
"android.hardware.vibrator-V1.0-java",
"android.hardware.configstore-V1.0-java",
"android.hardware.contexthub-V1.0-java",
],
}
7.4 編譯共享庫(shared)
cc_library_shared {
name: "libbluetooth_jni",
compile_multilib: "first",
srcs: [
"bluetooth_socket_manager.cc",
"com_android_bluetooth_btservice_AdapterService.cpp",
"com_android_bluetooth_hfp.cpp",
"com_android_bluetooth_hfpclient.cpp",
"com_android_bluetooth_a2dp.cpp",
"com_android_bluetooth_a2dp_sink.cpp",
"com_android_bluetooth_avrcp_controller.cpp",
"com_android_bluetooth_avrcp_target.cpp",
"com_android_bluetooth_hid_host.cpp",
"com_android_bluetooth_hid_device.cpp",
"com_android_bluetooth_hearing_aid.cpp",
"com_android_bluetooth_pan.cpp",
"com_android_bluetooth_gatt.cpp",
"com_android_bluetooth_sdp.cpp",
"IUserManager.cc",
"permission_helpers.cc",
],
header_libs: ["libbluetooth_headers"],
include_dirs: [
"libnativehelper/include/nativehelper",
"system/bt/types",
],
shared_libs: [
"libandroid_runtime",
"libbinder",
"libbluetooth-binder",
"libchrome",
"libnativehelper",
"liblog",
"libutils",
],
static_libs: [
"libbluetooth-types",
"libcutils",
],
cflags: [
"-Wall",
"-Werror",
"-Wextra",
"-Wno-unused-parameter",
],
sanitize: {
scs: true,
},
}
7.5 編譯靜態(tài)庫(static)
cc_library_static {
name: "libmedia_player2_util",
defaults: [ "libmedia_defaults" ],
srcs: [
"AudioParameter.cpp",
"BufferingSettings.cpp",
"DataSourceDesc.cpp",
"MediaCodecBuffer.cpp",
"Metadata.cpp",
"NdkWrapper.cpp",
],
shared_libs: [
"libbinder",
"libcutils",
"liblog",
"libmediandk",
"libnativewindow",
"libmediandk_utils",
"libstagefright_foundation",
"libui",
"libutils",
],
export_shared_lib_headers: [
"libbinder",
"libmediandk",
],
header_libs: [
"media_plugin_headers",
],
include_dirs: [
"frameworks/av/media/ndk",
],
static_libs: [
"libstagefright_rtsp",
"libstagefright_timedtext",
],
export_include_dirs: [
"include",
],
cflags: [
"-Werror",
"-Wno-error=deprecated-declarations",
"-Wall",
],
sanitize: {
misc_undefined: [
"unsigned-integer-overflow",
"signed-integer-overflow",
],
cfi: true,
},
}
8. 結語
Google在Android N就引入了Soong,目的是替換make反惕。但是尝艘,很遺憾的是截止到Android Q,甚至Android R姿染,它們的源碼中都還存在大量的Makefile背亥。也許make就是構建語言里的C語言秒际,無論世界如何發(fā)展變化,它的生命力依然旺盛狡汉。未來的很長一段時間內Android.bp和Android.mk可能會一直共存娄徊,一起完成Android系統(tǒng)源碼的構建。這并不代表我們可以不用去學習Android.bp盾戴,技術總是不斷的發(fā)展寄锐,我們則需要不斷的學習才能適應技術的發(fā)展。
9.本文參考
https://android.googlesource.com/platform/build/soong/
https://android.googlesource.com/platform/build/soong/+/HEAD/docs/best_practices.md#network-access