android編譯-2 BP文件學(xué)習(xí)

1 概述

bp文件的由來在此之前你需要先了解mk文件
.mk 文件通常是 Makefile 文件,用于定義編譯系統(tǒng)的規(guī)則和操作材泄。在 Android 源代碼中,.mk 文件被用來描述如何構(gòu)建和編譯特定模塊或組件吨岭,包括定義依賴關(guān)系拉宗、編譯參數(shù)、鏈接庫等。這些文件通常用于使用 GNU Make 構(gòu)建系統(tǒng)進行項目的構(gòu)建旦事。

.bp 文件是 Blueprint 文件的縮寫魁巩,這是 Android 構(gòu)建系統(tǒng)(Soong)所采用的一種新的構(gòu)建描述語言。Blueprint 文件用于描述 Android 源代碼中的各種模塊姐浮,包括庫谷遂、應(yīng)用程序、插件等的信息卖鲤,例如模塊的依賴關(guān)系肾扰、編譯選項、安裝路徑等蛋逾。相比傳統(tǒng)的 Makefile 格式集晚,Blueprint 使用更加結(jié)構(gòu)化的語法,并且能夠更好地處理模塊間的依賴關(guān)系区匣。

也就是說mk文件和bp文件都是用來定義android系統(tǒng)的編譯規(guī)則和操作的

對比倆者
更現(xiàn)代化的構(gòu)建系統(tǒng):
1 Blueprint 是為了適應(yīng) Android 構(gòu)建系統(tǒng)(Soong)的需求而設(shè)計的偷拔,它提供了一種更現(xiàn)代化、更靈活的描述方式來定義模塊和構(gòu)建規(guī)則亏钩。相比較傳統(tǒng)的 Makefile 格式莲绰,Blueprint 提供了更加結(jié)構(gòu)化的語法,并且更容易閱讀和維護
第一點 bp文件相較于mk文件姑丑,語法更規(guī)范蛤签,更方便閱讀
該點在學(xué)習(xí)完bp文件后,我們也會找倆個文件進行對比

2 Blueprint 文件能夠更好地管理模塊之間的依賴關(guān)系彻坛,包括動態(tài)依賴顷啼、跨模塊依賴等,使得 Android 系統(tǒng)的各個模塊能夠更好地協(xié)同工作
該點在后續(xù)內(nèi)容中我們會提到

3 Android 構(gòu)建系統(tǒng)使用了基于 Blueprint 的描述文件昌屉,能夠更好地實現(xiàn)高度并行化的構(gòu)建钙蒙,從而提高構(gòu)建速度和效率。相比傳統(tǒng)的 Makefile 格式间驮,Blueprint 能夠更好地利用多核處理器進行并行構(gòu)建躬厌,加快整體構(gòu)建過程。
第三點主要指明BP文件在構(gòu)建的速度上領(lǐng)先與mk

4 Blueprint 提供了更靈活的方式來描述模塊的構(gòu)建規(guī)則竞帽,包括編譯選項扛施、鏈接庫、安裝路徑等屹篓,能夠更好地滿足復(fù)雜項目的定制化需求疙渣。

2 編譯結(jié)構(gòu)

如圖所示


image.png
  • 1 bp文件需要通過soong+blueprint解析為ninja文件
  • 2 mk文件需要通過kati解析為ninja文件
  • 3 ninja文件被系統(tǒng)編譯框架ninja解析構(gòu)建系統(tǒng)
  • 4 mk文件可以通過android工具androidmk 轉(zhuǎn)換為bp文件
    注意點 mk自動轉(zhuǎn)換bp文件的前提是mk文件沒有控制邏輯
    如果存在需要手動轉(zhuǎn)換

3 android.mk自動轉(zhuǎn)換android.bp

通過make androidmk 命令可以在out目錄下生成androidmk
然后執(zhí)行androidmk android.mk來生成bp文件
但是我本地編譯后,out目錄沒看到androidmk堆巧,所以就先當(dāng)了解一下吧

4 android.bp文件語法

介紹一些常用的bp命令

java_library 會把aidl java 等文件編譯成 .jar 庫
android_library 會把 xml 資源文件妄荔, aidl java 等文件 編譯成 .aar 庫
java_import 預(yù)編譯 .jar 庫 (引用 第三方 jar 庫)
android_library_import 這是預(yù)編譯 .aar 庫 (引用第三方aar庫)
android_app_import 這是 預(yù)編譯 apk泼菌,相當(dāng)于 BUILD_PREBUILT
android_app 編譯成apk,相當(dāng)于 BUILD_PACKAGE

這里提到了預(yù)編譯 apk和編譯成apk啦租,但是倆者是有區(qū)別的
相同點 倆者都生成了apk文件
不同點 預(yù)編譯會在編譯完apk后進行進一步操作例如代碼混淆哗伯,簽名等等
除此之外還有deafult cc_default java_default
default如何使用

# 定義默認(rèn)配置規(guī)則
defaults(
    name = "my_defaults",
    visibility = ["http://visibility:public"],
    # 設(shè)置通用屬性值,如編譯器選項等
    cpp_compile_flags = ["-Wall", "-O2"],
    java_source_version = "8",
)

# 定義 C/C++ 目標(biāo)
cc_library(
    name = "my_cc_lib",
    srcs = ["my_cc_lib.cpp"],
    deps = [":my_defaults"],
)

# 定義 Java 目標(biāo)
java_library(
    name = "my_java_lib",
    srcs = ["MyJavaClass.java"],
    deps = [":my_defaults"],
)

可以看到我在default中定義相關(guān)的配置項篷角,可見性焊刹,cpp編譯規(guī)則,java源碼版本
而我們在構(gòu)建其他的庫時可以直接通過deps來引用我們的默認(rèn)規(guī)則
作用
通過這種方式恳蹲,我們可以確保所有的 C/C++ 目標(biāo)和 Java 目標(biāo)都繼承了相同的默認(rèn)屬性設(shè)置虐块,避免了重復(fù)配置,并使得整個項目的構(gòu)建行為更加一致和可維護嘉蕾。
除了配置選項還可以引入依賴庫

# 定義默認(rèn)配置規(guī)則
cc_defaults(
    name = "my_cc_defaults",
    visibility = ["http://visibility:public"],
    deps = ["http://path/to:common_lib"],  # 加入庫依賴
    cpp_compile_flags = ["-Wall", "-O2"],
)

# 定義 C/C++ 目標(biāo)
cc_library(
    name = "my_cc_lib",
    srcs = ["my_cc_lib.cpp"],
    defaults = ["my_cc_defaults"],  # 引用默認(rèn)配置
)

# 定義 Java 目標(biāo)
java_defaults(
    name = "my_java_defaults",
    visibility = ["http://visibility:public"],
    deps = [":common_java_lib"],  # 加入庫依賴
    java_source_version = "8",
)

java_library(
    name = "my_java_lib",
    srcs = ["MyJavaClass.java"],
    defaults = ["my_java_defaults"],  # 引用默認(rèn)配置
)

這里我們定義c的默認(rèn)配置和java的默認(rèn)配置非凌,同時引入了相關(guān)依賴庫,其他庫在構(gòu)建時可以通過deps引用默認(rèn)配置荆针,來直接引用相關(guān)庫

這比較適用于你在編譯bp文件時存在大量模塊存在共通的配置才會這么做

5 android.bp與android.mk對比

Android.mk
include $(BUILD_JAVA_LIBRARY)

Android.bp
java_library {
......
}

mk生成jar包BUILD_JAVA_LIBRARY
bp生成jar包使用java_library

Android.mk
include $(BUILD_STATIC_JAVA_LIBRARY)

Android.bp
java_library_static {
......
}

mk生成java靜態(tài)庫 BUILD_STATIC_JAVA_LIBRARY
bp生成java靜態(tài)庫使用java_library_static

Android.mk
include $(BUILD_PACKAGE)

Android.bp
android_app {
......
}

mk使用BUILD_PACKAGE生成apk
bp使用android_app生成apk

Android.mk
include $(BUILD_SHARED_LIBRARY)

Android.bp
cc_library_shared {
......
}

mk BUILD_SHARED_LIBRARY 生成native庫
bp cc_library_shared 生成native庫

Android.mk
include $(BUILD_STATIC_LIBRARY)

Android.bp
cc_library_static {
......
}

mk BUILD_STATIC_LIBRARY 生成native靜態(tài)庫
bp cc_library_static 生成native靜態(tài)庫

Android.mk
include $(BUILD_EXECUTABLE)

Android.bp
cc_binary {
......
}

mk BUILD_EXECUTABLE native可執(zhí)行程序
bp cc_binary native可執(zhí)行程序

Android.mk
include $(BUILD_HEADER_LIBRARY)

Android.bp
cc_library_headers {
......
}

頭文件庫
mk BUILD_HEADER_LIBRARY
bp cc_library_headers

Android.mk
LOCAL_C_INCLUDES := 

Android.bp
local_include_dirs: ["xxx", ...]

本地頭文件路徑
mk LOCAL_C_INCLUDES
bp local_include_dirs

Android.mk
LOCAL_EXPORT_C_INCLUDE_DIRS := 

Android.bp
export_include_dirs: ["xxx", ...]

排除頭文件
mk LOCAL_EXPORT_C_INCLUDE_DIRS
bp export_include_dirs

Android.mk
LOCAL_RESOURCE_DIR := 

Android.bp
resource_dirs: ["xxx", ...]

資源文件
mk LOCAL_RESOURCE_DIR
bp resource_dirs

Android.mk
LOCAL_STATIC_LIBRARIES := 

Android.bp
static_libs: ["xxx", "xxx", ...]

依賴靜態(tài)庫

這里我們先了解靜態(tài)庫與動態(tài)庫的區(qū)別
對于靜態(tài)庫,如果其中的文件內(nèi)容發(fā)生了修改颁糟,你需要重新編譯整個項目航背,并且在鏈接階段將新的靜態(tài)庫文件鏈接到可執(zhí)行文件中。因為靜態(tài)庫的內(nèi)容在編譯時就被完全復(fù)制到可執(zhí)行文件中棱貌,所以任何對靜態(tài)庫的修改都需要重新構(gòu)建整個項目玖媚。

而對于動態(tài)庫,如果其中的文件內(nèi)容發(fā)生了修改婚脱,你只需要編譯動態(tài)庫本身今魔,并將新的動態(tài)庫文件替換掉舊的文件即可。由于動態(tài)庫是在運行時加載的障贸,因此不會影響到已經(jīng)編譯好的可執(zhí)行文件错森,只需確保新的動態(tài)庫文件和舊的動態(tài)庫文件保持二進制兼容性即可。

總的來說篮洁,動態(tài)庫的修改更加靈活涩维,只需要重新編譯動態(tài)庫本身,而不需要重新整編整個系統(tǒng)袁波。這也是動態(tài)庫在軟件開發(fā)中更常用的一個原因之一瓦阐。

Android.mk
LOCAL_SHARED_LIBRARIES := 

Android.bp
shared_libs: ["xxx", "xxx", ...]

依賴動態(tài)庫

Android.mk
LOCAL_HEADER_LIBRARIES := 

Android.bp
header_libs: ["xxx", "xxx", ...]

依賴頭文件庫
目前就更新這么多,后續(xù)我們在具體看幾個bp文件的時候篷牌,如果又不知道的我們在記錄

6 bp文件學(xué)習(xí)

下面舉出幾個android系統(tǒng)的bp文件
java側(cè)以/frameworks/base/services/core/android.bp為例

package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // all of the 'license_kinds' from "frameworks_base_license"
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["frameworks_base_license"],
}

filegroup {
    name: "services.core-sources-am-wm",
    srcs: [
        "java/com/android/server/am/**/*.java",
        "java/com/android/server/wm/**/*.java",
    ],
    path: "java",
    visibility: ["http://frameworks/base/services"],
}

filegroup {
    name: "services.core-sources",
    srcs: ["java/**/*.java"],
    exclude_srcs: [
        ":services.core-sources-am-wm",
    ],
    path: "java",
    visibility: [
        "http://frameworks/base/services",
        "http://frameworks/base/core/java/com/android/internal/protolog",
    ],
}

genrule {
    name: "services.core.protologsrc",
    srcs: [
        ":protolog-groups",
        ":services.core-sources-am-wm",
    ],
    tools: ["protologtool"],
    cmd: "$(location protologtool) transform-protolog-calls " +
        "--protolog-class com.android.internal.protolog.common.ProtoLog " +
        "--protolog-impl-class com.android.internal.protolog.ProtoLogImpl " +
        "--protolog-cache-class 'com.android.server.wm.ProtoLogCache' " +
        "--loggroups-class com.android.internal.protolog.ProtoLogGroup " +
        "--loggroups-jar $(location :protolog-groups) " +
        "--output-srcjar $(out) " +
        "$(locations :services.core-sources-am-wm)",
    out: ["services.core.protolog.srcjar"],
}

genrule {
    name: "generate-protolog.json",
    srcs: [
        ":protolog-groups",
        ":services.core-sources-am-wm",
    ],
    tools: ["protologtool"],
    cmd: "$(location protologtool) generate-viewer-config " +
        "--protolog-class com.android.internal.protolog.common.ProtoLog " +
        "--loggroups-class com.android.internal.protolog.ProtoLogGroup " +
        "--loggroups-jar $(location :protolog-groups) " +
        "--viewer-conf $(out) " +
        "$(locations :services.core-sources-am-wm)",
    out: ["services.core.protolog.json"],
}

genrule {
    name: "checked-protolog.json",
    srcs: [
        ":generate-protolog.json",
        ":services.core.protolog.json",
    ],
    cmd: "cp $(location :generate-protolog.json) $(out) && " +
        "{ ! (diff $(out) $(location :services.core.protolog.json) | grep -q '^<') || " +
        "{ echo -e '\\n\\n################################################################\\n#\\n" +
        "#  ERROR: ProtoLog viewer config is stale.  To update it, run:\\n#\\n" +
        "#  cp $(location :generate-protolog.json) " +
        "$(location :services.core.protolog.json)\\n#\\n" +
        "################################################################\\n\\n' >&2 && false; } }",
    out: ["services.core.protolog.json"],
}

genrule {
    name: "statslog-art-java-gen",
    tools: ["stats-log-api-gen"],
    cmd: "$(location stats-log-api-gen) --java $(out) --module art" +
        " --javaPackage com.android.internal.art --javaClass ArtStatsLog --worksource",
    out: ["com/android/internal/art/ArtStatsLog.java"],
}

genrule {
    name: "statslog-contexthub-java-gen",
    tools: ["stats-log-api-gen"],
    cmd: "$(location stats-log-api-gen) --java $(out) --module contexthub" +
        " --javaPackage com.android.server.location.contexthub --javaClass ContextHubStatsLog",
    out: ["com/android/server/location/contexthub/ContextHubStatsLog.java"],
}

java_library_static {
    name: "services.core.unboosted",
    defaults: ["platform_service_defaults"],
    srcs: [
        ":android.hardware.biometrics.face-V2-java-source",
        ":statslog-art-java-gen",
        ":statslog-contexthub-java-gen",
        ":services.core-sources",
        ":services.core.protologsrc",
        ":dumpstate_aidl",
        ":framework_native_aidl",
        ":gsiservice_aidl",
        ":installd_aidl",
        ":storaged_aidl",
        ":vold_aidl",
        ":platform-compat-config",
        ":platform-compat-overrides",
        ":display-device-config",
        ":display-layout-config",
        ":device-state-config",
        "java/com/android/server/EventLogTags.logtags",
        "java/com/android/server/am/EventLogTags.logtags",
        "java/com/android/server/wm/EventLogTags.logtags",
        "java/com/android/server/policy/EventLogTags.logtags",
    ],

    libs: [
        "services.net",
        "android.hardware.common-V2-java",
        "android.hardware.light-V2.0-java",
        "android.hardware.gnss-V2-java",
        "android.hardware.vibrator-V2-java",
        "app-compat-annotations",
        "framework-tethering.stubs.module_lib",
        "service-permission.stubs.system_server",
        "service-sdksandbox.stubs.system_server",
    ],

    required: [
        "default_television.xml",
        "gps_debug.conf",
        "protolog.conf.json.gz",
    ],

    static_libs: [
        "time_zone_distro",
        "time_zone_distro_installer",
        "android.hardware.authsecret-V1.0-java",
        "android.hardware.boot-V1.0-java",
        "android.hardware.boot-V1.1-java",
        "android.hardware.boot-V1.2-java",
        "android.hardware.broadcastradio-V2.0-java",
        "android.hardware.health-V1.0-java", // HIDL
        "android.hardware.health-V2.0-java", // HIDL
        "android.hardware.health-V2.1-java", // HIDL
        "android.hardware.health-V1-java", // AIDL
        "android.hardware.health-translate-java",
        "android.hardware.light-V1-java",
        "android.hardware.tv.cec-V1.1-java",
        "android.hardware.weaver-V1.0-java",
        "android.hardware.biometrics.face-V1.0-java",
        "android.hardware.biometrics.fingerprint-V2.3-java",
        "android.hardware.biometrics.fingerprint-V2-java",
        "android.hardware.oemlock-V1.0-java",
        "android.hardware.configstore-V1.1-java",
        "android.hardware.ir-V1-java",
        "android.hardware.rebootescrow-V1-java",
        "android.hardware.soundtrigger-V2.3-java",
        "android.hardware.power.stats-V1-java",
        "android.hardware.power-V3-java",
        "android.hidl.manager-V1.2-java",
        "capture_state_listener-aidl-java",
        "icu4j_calendar_astronomer",
        "netd-client",
        "overlayable_policy_aidl-java",
        "SurfaceFlingerProperties",
        "com.android.sysprop.watchdog",
    ],
    javac_shard_size: 50,
}

java_genrule {
    name: "services.core.priorityboosted",
    srcs: [":services.core.unboosted"],
    tools: ["lockedregioncodeinjection"],
    cmd: "$(location lockedregioncodeinjection) " +
        "  --targets \"Lcom/android/server/am/ActivityManagerService;,Lcom/android/server/am/ActivityManagerGlobalLock;,Lcom/android/server/wm/WindowManagerGlobalLock;\" " +
        "  --pre \"com/android/server/am/ActivityManagerService.boostPriorityForLockedSection,com/android/server/am/ActivityManagerService.boostPriorityForProcLockedSection,com/android/server/wm/WindowManagerService.boostPriorityForLockedSection\" " +
        "  --post \"com/android/server/am/ActivityManagerService.resetPriorityAfterLockedSection,com/android/server/am/ActivityManagerService.resetPriorityAfterProcLockedSection,com/android/server/wm/WindowManagerService.resetPriorityAfterLockedSection\" " +
        "  -o $(out) " +
        "  -i $(in)",
    out: ["services.core.priorityboosted.jar"],
}

java_library {
    name: "services.core",
    static_libs: ["services.core.priorityboosted"],
}

java_library_host {
    name: "core_cts_test_resources",
    srcs: ["java/com/android/server/notification/SmallHash.java"],
}

prebuilt_etc {
    name: "gps_debug.conf",
    src: "java/com/android/server/location/gnss/gps_debug.conf",
}

genrule {
    name: "services.core.json.gz",
    srcs: [":checked-protolog.json"],
    out: ["services.core.protolog.json.gz"],
    cmd: "$(location minigzip) -c < $(in) > $(out)",
    tools: ["minigzip"],
}

prebuilt_etc {
    name: "protolog.conf.json.gz",
    src: ":services.core.json.gz",
}

首先了解package

package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // all of the 'license_kinds' from "frameworks_base_license"
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["frameworks_base_license"],
}

可以理解為構(gòu)建默認(rèn)許可證睡蟋,作用對知識產(chǎn)權(quán)的保護


filegroup {
    name: "services.core-sources",
    srcs: ["java/**/*.java"],
    exclude_srcs: [
        ":services.core-sources-am-wm",
    ],
    path: "java",
    visibility: [
        "http://frameworks/base/services",
        "http://frameworks/base/core/java/com/android/internal/protolog",
    ],
}

這里定義的文件組
name 文件組名稱 "services.core-sources
src 加載的文件路徑 "java/*/.java"
exclude_srcs 排除構(gòu)建的文件組,這里填入的是文件組的名字
path 指明文件組中的文件java文件夾下
visibility 定義該模塊對其他模塊的可見性

genrule {
    name: "services.core.protologsrc",
    srcs: [
        ":protolog-groups",
        ":services.core-sources-am-wm",
    ],
    tools: ["protologtool"],
    cmd: "$(location protologtool) transform-protolog-calls " +
        "--protolog-class com.android.internal.protolog.common.ProtoLog " +
        "--protolog-impl-class com.android.internal.protolog.ProtoLogImpl " +
        "--protolog-cache-class 'com.android.server.wm.ProtoLogCache' " +
        "--loggroups-class com.android.internal.protolog.ProtoLogGroup " +
        "--loggroups-jar $(location :protolog-groups) " +
        "--output-srcjar $(out) " +
        "$(locations :services.core-sources-am-wm)",
    out: ["services.core.protolog.srcjar"],
}

主要是定義bp編譯規(guī)則
name 規(guī)則名稱
srcs 編譯依賴的相關(guān)規(guī)則和文件組
tools 編譯工具
cmd 編譯工具執(zhí)行的相關(guān)命令
out 執(zhí)行命令生成的jar包
這個genrule的作用就是使用定義的工具執(zhí)行cmd指令生成目標(biāo)文件

java_library_static {
    name: "services.core.unboosted",
    defaults: ["platform_service_defaults"],
    srcs: [
        ":android.hardware.biometrics.face-V2-java-source",
        ":statslog-art-java-gen",
        ":statslog-contexthub-java-gen",
        ":services.core-sources",
        ":services.core.protologsrc",
        ":dumpstate_aidl",
        ":framework_native_aidl",
        ":gsiservice_aidl",
        ":installd_aidl",
        ":storaged_aidl",
        ":vold_aidl",
        ":platform-compat-config",
        ":platform-compat-overrides",
        ":display-device-config",
        ":display-layout-config",
        ":device-state-config",
        "java/com/android/server/EventLogTags.logtags",
        "java/com/android/server/am/EventLogTags.logtags",
        "java/com/android/server/wm/EventLogTags.logtags",
        "java/com/android/server/policy/EventLogTags.logtags",
    ],

    libs: [
        "services.net",
        "android.hardware.common-V2-java",
        "android.hardware.light-V2.0-java",
        "android.hardware.gnss-V2-java",
        "android.hardware.vibrator-V2-java",
        "app-compat-annotations",
        "framework-tethering.stubs.module_lib",
        "service-permission.stubs.system_server",
        "service-sdksandbox.stubs.system_server",
    ],

    required: [
        "default_television.xml",
        "gps_debug.conf",
        "protolog.conf.json.gz",
    ],

    static_libs: [
        "time_zone_distro",
        "time_zone_distro_installer",
        "android.hardware.authsecret-V1.0-java",
        "android.hardware.boot-V1.0-java",
        "android.hardware.boot-V1.1-java",
        "android.hardware.boot-V1.2-java",
        "android.hardware.broadcastradio-V2.0-java",
        "android.hardware.health-V1.0-java", // HIDL
        "android.hardware.health-V2.0-java", // HIDL
        "android.hardware.health-V2.1-java", // HIDL
        "android.hardware.health-V1-java", // AIDL
        "android.hardware.health-translate-java",
        "android.hardware.light-V1-java",
        "android.hardware.tv.cec-V1.1-java",
        "android.hardware.weaver-V1.0-java",
        "android.hardware.biometrics.face-V1.0-java",
        "android.hardware.biometrics.fingerprint-V2.3-java",
        "android.hardware.biometrics.fingerprint-V2-java",
        "android.hardware.oemlock-V1.0-java",
        "android.hardware.configstore-V1.1-java",
        "android.hardware.ir-V1-java",
        "android.hardware.rebootescrow-V1-java",
        "android.hardware.soundtrigger-V2.3-java",
        "android.hardware.power.stats-V1-java",
        "android.hardware.power-V3-java",
        "android.hidl.manager-V1.2-java",
        "capture_state_listener-aidl-java",
        "icu4j_calendar_astronomer",
        "netd-client",
        "overlayable_policy_aidl-java",
        "SurfaceFlingerProperties",
        "com.android.sysprop.watchdog",
    ],
    javac_shard_size: 50,
}

構(gòu)建java靜態(tài)庫
name services.core.unboosted
srcs 構(gòu)建需要的文件組或者編譯規(guī)則
libs 動態(tài)庫
required 構(gòu)建必需的配置文件枷颊,或者參數(shù),在構(gòu)建時會去查找這些文件是否存在
static_libs 靜態(tài)庫

prebuilt_etc {
    name: "gps_debug.conf",
    src: "java/com/android/server/location/gnss/gps_debug.conf",
}

可以理解為預(yù)構(gòu)建戳杀,prebuilt_etc 規(guī)則的作用是將指定的文件復(fù)制到輸出目錄中该面,以便在編譯后的系統(tǒng)鏡像或其他環(huán)境中使用該文件。這有助于將特定的配置文件或數(shù)據(jù)文件集成到編譯系統(tǒng)的構(gòu)建流程中

java_library_host {
    name: "core_cts_test_resources",
    srcs: ["java/com/android/server/notification/SmallHash.java"],
}

豺瘤,主機端 Java 庫通常用于在開發(fā)機器上進行本地測試吆倦、集成測試、工具開發(fā)或模擬數(shù)據(jù)生成等場景下坐求。這些庫有助于提高開發(fā)人員的工作效率蚕泽,并支持在開發(fā)過程中進行快速迭代和測試

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市桥嗤,隨后出現(xiàn)的幾起案子须妻,更是在濱河造成了極大的恐慌,老刑警劉巖泛领,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荒吏,死亡現(xiàn)場離奇詭異,居然都是意外死亡渊鞋,警方通過查閱死者的電腦和手機绰更,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锡宋,“玉大人儡湾,你說我怎么就攤上這事≈戳” “怎么了徐钠?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長役首。 經(jīng)常有香客問我尝丐,道長,這世上最難降的妖魔是什么衡奥? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任爹袁,我火速辦了婚禮,結(jié)果婚禮上杰赛,老公的妹妹穿的比我還像新娘呢簸。我一直安慰自己,他們只是感情好乏屯,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布根时。 她就那樣靜靜地躺著,像睡著了一般辰晕。 火紅的嫁衣襯著肌膚如雪蛤迎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天含友,我揣著相機與錄音替裆,去河邊找鬼校辩。 笑死,一個胖子當(dāng)著我的面吹牛辆童,可吹牛的內(nèi)容都是我干的宜咒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼把鉴,長吁一口氣:“原來是場噩夢啊……” “哼故黑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起庭砍,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤场晶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后怠缸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诗轻,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年揭北,在試婚紗的時候發(fā)現(xiàn)自己被綠了扳炬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡搔体,死狀恐怖鞠柄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嫉柴,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布奉呛,位于F島的核電站计螺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏瞧壮。R本人自食惡果不足惜登馒,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咆槽。 院中可真熱鬧陈轿,春花似錦、人聲如沸秦忿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灯谣。三九已至潜秋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胎许,已是汗流浹背峻呛。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工罗售, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钩述。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓寨躁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親牙勘。 傳聞我的和親對象是個殘疾皇子职恳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容