美文网首页
Android系统编译常用配置及指令

Android系统编译常用配置及指令

作者: Amber_9 | 来源:发表于2023-10-09 12:16 被阅读0次

    有时间来整理一下Android系统编译的内容,本文从三方面展开:编译过程、常用的编译配置和命令

    一. 编译过程步骤

    1.初始化编译环境

    source ./build/envsetup.sh它主要作用:

    • 定义m\mm\mmm\lunch 等函数


      image.png
    • 添加编译目标:将以下文件搜索并source进来
      device//vendorsetup.sh
      vendor/
      /vendorsetup.sh
      product/*/vendorsetup.sh
      image.png

    2. 选择编译目标 lunch xxtarget

    image.png
    image.png
    • 可新建device/company/product/AndroidProducts.mk文件并在AndroidProducts.mk中通过COMMON_LUNCH_CHOICES新增编译目标选项,注意:编译目标需要有合法的配置信息。
    • lunch xxtarget选择编译目标后,会确定TARGET_PRODUCT、TARGET_BUILD_VARIANT、TARGET_PLATFORM_VERSION、TARGET_BUILD_TYPE等变量的值


      image.png

    3. 编译 make -j8

    Android根目录的Makefile include进来一个编译核心文件:build/make/core/main.mk
    main.mk主要功能:

    • include 包含众多mk文件;
    • include config.mk, config.mk中定义了在Android.mk中编译目标时会用到的常量
    • include /build/core/envsetup.sh,然后通过include product_config.mk检索所有Product,并做目标有效性检查,然后根据lunch时选择的目标设置TARGET_DEVICE,然后在envsetup.sh中根据TARGET_DEVICE查找BoardConfig.mk文件进行Board相关配置,查找KERNEL_HEADER,配置编译工具链
    • definitions.mk中定义了all_makefiles_under等用来检索文件的函数
    • 将所有子目录下的Android.mk文件收集并include进来,将相应的Android.mk中定义的目标包含进编译模块中。
    • include build/core/Makefile文件,定义bootimage,systemimage等依赖目标,然后通过make编译目标就可以编译系统了。

    二. 常用配置

    Android 7.0 之后逐渐用 Android.bp 替换 Android.mk

    1.编译动态库

    • Android.mk
    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_SRC_FILES:= \
    cJSON.c
    LOCAL_MODULE:= libmycjson
    include $(BUILD_SHARED_LIBRARY)
    
    • Android.bp
    cc_library_shared { //编译成动态库,类似于 Android.mk 中的 BUILD_SHARED_LIBRARY
    name: "libcamera_client",
    aidl: {
    export_aidl_headers: true, //是否导出 aidl 头文件路径
    local_include_dirs: ["aidl"], //将[指定的目录列表]加入 aidl 搜索头文件路径。
    // [“aidl”]表示当前目录下的 aidl 目录
    include_dirs: [ //指定搜索外部 aidl 头文件的路径
    "frameworks/native/aidl/gui",
    ],
    },
    srcs: [ //源文件,类似于 Android.mk 中的 LOCAL_SRC_FILES
    // AIDL files for camera interfaces
    // The headers for these interfaces will be available to any modules that
    // include libcamera_client, at the path "aidl/package/path/BnFoo.h"
    ":libcamera_client_aidl", //引用了另外一个模块中定义的源文件。在当前 bp 文件的第 81 行
    // Source for camera interface parcelables, and manually-written interfaces
    "Camera.cpp",
    "CameraMetadata.cpp",
    "CameraParameters.cpp",
    "CaptureResult.cpp",
    "CameraParameters2.cpp",
    "ICamera.cpp",
    "ICameraClient.cpp",
    "ICameraRecordingProxy.cpp",
    "ICameraRecordingProxyListener.cpp",
    "camera2/CaptureRequest.cpp",
    "camera2/OutputConfiguration.cpp",
    "camera2/SessionConfiguration.cpp",
    "camera2/SubmitInfo.cpp",
    "CameraBase.cpp",
    "CameraUtils.cpp",
    "VendorTagDescriptor.cpp",
    ],
    shared_libs: [ //编译所依赖的动态库,类似于 Android.mk 中的 LOCAL_SHARED_LIBRARIES
    "libcutils",
    "libutils",
    "liblog",
    "libbinder",
    "libgui",
    "libcamera_metadata",
    "libnativewindow",
    ],
    include_dirs: [//用户指定的头文件查找路径,类似于 Android.mk 中的 LOCAL_C_INCLUDES
    "system/media/private/camera/include",
    "frameworks/native/include/media/openmax",
    ],
    export_include_dirs: [//将当前的路径导出,如果有其他模块引用当前模块,就不需要指定头文件路径
    "include",
    "include/camera"
    ],
    export_shared_lib_headers: ["libcamera_metadata"],//将 libcamera_metadata 模块对应的头文件路径列表导出
    cflags: [//编译 flag,类似于 Android.mk 中的 LOCAL_CFLAGS
    "-Werror",
    "-Wall",
    "-Wextra",
    ],
    }
    

    2. 编译可执行程序

    • Android.mk
    LOCAL_PATH:= $(call my-dir)
    curdir=$(LOCAL_PATH)
    include $(CLEAR_VARS)
    LOCAL_SRC_FILES:= \
    main.c
    LOCAL_C_INCLUDES += \
    $(LOCAL_PATH)/libcjson
    LOCAL_SHARED_LIBRARIES += \
    libmycjson \
    LOCAL_CFLAGS += \
    -Wno-error \
    -Wno-unused-parameter
    LOCAL_MODULE:= cjson_test
    LOCAL_MODULE_TAGS := optional
    LOCAL_MULTILIB := 64
    include $(BUILD_EXECUTABLE)
    include $(curdir)/libcjson/Android.mk
    
    • Android.bp
    cc_binary {
    name: "reboot",
    srcs: ["reboot.c"],
    shared_libs: ["libcutils"],
    cflags: ["-Werror"],
    }
    

    3.编译Java动态库

    • Android.mk
    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_JAVA_LIBRARIES := libmytest
    LOCAL_SRC_FILES := $(call all-subdir-java-files)
    LOCAL_MODULE := TestDemo
    include $(BUILD_JAVA_LIBRARY)
    
    • Android.bp
    java_library { //编译成 java 库
    name: "services",//编译出的模块的名称
    dex_preopt: {
    app_image: true, //是否为当前模块生成 app image(.art)文件
    profile: "art-profile",//指定与当前 Android.bp 相关的配置文件路径
    },
    srcs: [ //源文件
    "java/**/*.java",
    ],
    // The convention is to name each service module 'services.$(module_name)'
    static_libs: [
    //编译所依赖的静态库
    "services.core",
    "services.accessibility",
    "services.appwidget",
    "services.autofill",
    "services.backup",
    "services.companion",
    "services.coverage",
    "services.devicepolicy",
    "services.midi",
    "services.net",
    "services.print",
    "services.restrictions",
    "services.usage",
    "services.usb",
    "services.voiceinteraction",
    "android.hidl.base-V1.0-java",
    ],
    libs: [//链接的动态库
    "android.hidl.manager-V1.0-java",
    ],
    // Uncomment to enable output of certain warnings (deprecated, unchecked)
    //javacflags: ["-Xlint"],
    }
    

    4. apk(含源码,不含源码的可参考预编译)

    • Android.mk
    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE_TAGS := optional
    LOCAL_SRC_FILES := $(call all-java-files-under, app/src/main/java)
    LOCAL_PACKAGE_NAME := StorageTest
    LOCAL_SDK_VERSION := current
    #LOCAL_PROGUARD_FLAG_FILES := proguard.flags
    LOCAL_CERTIFICATE := platform
    LOCAL_USE_AAPT2 := true
    # 指定 Manifest 文件
    LOCAL_MANIFEST_FILE := app/src/main/AndroidManifest.xml
    LOCAL_RESOURCE_DIR := \
    $(addprefix $(LOCAL_PATH)/, app/src/main/res)
    # 需要的 jar,否则无法找到系统相关资源
    LOCAL_STATIC_JAVA_LIBRARIES := \
    androidx.appcompat_appcompat \
    include $(BUILD_PACKAGE)
    include $(call all-makefiles-under,$(LOCAL_PATH))
    
    • Android.bp
    android_app {
    name: "Music",
    srcs: [
    "src/**/*.java",
    "src/com/android/music/IMediaPlaybackService.aidl",
    ],
    sdk_version: "current",
    product_specific: true, //安装到 product 分区
    optimize: {
    proguard_flags_files: ["proguard.flags"],
    },
    certificate: "platform",
    }
    

    5.预编译

    • Android.mk
    #预编译配置文件
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE_TAGS := optional
    LOCAL_MODULE := Vendor_5135_Product_0005.idc
    LOCAL_SRC_FILES := Vendor_5135_Product_0005.idc
    LOCAL_MODULE_CLASS := ETC
    LOCAL_MODULE_PATH := $(TARGET_OUT)/usr/idc
    include $(BUILD_PREBUILT)
    
    # 预编译动态库
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE_TAGS := optional
    LOCAL_SRC_FILES :=libglib-2.0.so
    LOCAL_MODULE_SUFFIX := .so
    LOCAL_MODULE := libglib-2.0
    LOCAL_MODULE_CLASS := SHARED_LIBRARIES
    LOCAL_MULTILIB := 32
    include $(BUILD_PREBUILT)
    
    # 预编译可执行程序
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_SRC_FILES := busybox_aarch64
    LOCAL_MODULE := busybox_aarch64
    LOCAL_MODULE_CLASS := EXECUTABLES
    LOCAL_MODULE_TAGS := optional
    include $(BUILD_PREBUILT)
    
    #预编译APK
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE := Hello
    LOCAL_MODULE_TAGS := optional
    LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
    #定义编译完成之后的类型:除了APPS,还有ETC,EXECUTABLES(.bin)SHARED_LIBRARIES(.so) 等选择值 
    LOCAL_MODULE_CLASS := APPS
    
    #定义编译完成之后模块的后缀
    LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
    
    #定义使用原app签名可用选择项platform,shared,media
    LOCAL_CERTIFICATE := PRESIGNED
    
    #将apk编进“/system/priv-app/目录”,如果为false,或者不加这句话,就会编进“/system/app” 目录, 二者区别在于前者的权限要高于后者,即不可卸载
    LOCAL_PRIVILEGED_MODULE := true
    
    #不进行odex化
    LOCAL_DEX_PREOPT := false
    
    # 定义编译出来的目标文件,如动态库,静态库,jar包以及apk
    include $(BUILD_PREBUILT)
    
    • Android.bp
    //预编译etc配置文件
    prebuilt_etc {
    name: "Vendor_my_idc",
    src: "Vendor_5135_Product_0005.idc",
    filename_from_src: true,
    sub_dir:"usr",
    }
    
    //预编译可执行文件
    cc_prebuilt_binary {
    name: "logpersist.start",
    srcs: ["logpersist"],
    init_rc: ["logcatd.rc"],
    required: ["logcatd"],
    symlinks: [
    "logpersist.stop",
    "logpersist.cat",
    ],
    strip: {
    none: true,
    },
    }
    
    //预编译动态库
    cc_prebuilt_library_shared {
    name: "libmycjson-pre.so",
    srcs: ["x86_64/libmycjson-pre.so"],
    compile_multilib : “64”,
    }
    

    三. 常用命令

    1. 编译命令

    1.1 m命令

    • m 源码树的根目录执行编译,编译的是根目录下所有的代码;
    • mm 编译当前路径下所有模块,但不包含依赖关系的模块;
    • mmm [module_path] 编译指定路径下的所有模块,但不包含依赖关系的模块;
    • mma 编译当前路径下所有模块,且包含依赖关系的模块;
    • mmma [module_path] 编译指定路径下的所有模块,且包含依赖关系的模块;

    1.2make命令

    • make [module_name] 无参数,则表示编译整个Android代码,如果有module_name,是会遍历module,编译指定的module;
      常见module编译例:
      {模块} make命令 | mmm命令
      {init} make init | mmm system/core/init
      {zygote} make app_process | mmm frameworks/base/cmds/app_process
      {system_server} make services | mmm frameworks/base/services
      {java framework} make framework | mmm frameworks/base
      {framework资源} make framework-res | mmm frameworks/base/core/res
      {jni framework} make libandroid_runtime | mmm frameworks/base/core/jni
      {binder} make libbinder | mmm frameworks/native/libs/binder
      {RefBase等} make libutils | mmm framworks/base/libs/utils
      {Looper等} make framework | mmm framworks/base
      {AudioTrack} make libmedia | mmm framworks/base/media/kibmedia
      {AudioFlinger} make libaudiofliginger | mmm framworks/base/libs/audioflinger
      {AudioPolicyService} make libaudiopolicy | mmm hardware/msm7k/libaudio-qsd8k
      {SurfaceFlinger} make libsurfaceflinger | mmm frameworks/base/libs/surfaceflinger
      {Vold} make vold | mmm system/vold
      {Rild} make rild | mmm hardware/ril/rild
      {MediaProvider} make MediaProvider | mmm packages/providers/MediaProvider
      {Phone} make phone | mmm packages/apps/Phone
    • make clean:执行清理操作,等价于 rm -rf out/
    • make update-api:更新API,在framework API改动后需执行该指令,Api记录在目录frameworks/base/api;
    • make sdk 编译出 Android 的 SDK;
    • make clean-sdk 清理 SDK 的编译产物;
    • make help 帮助信息,显示主要的 make 目标;
    • make snod 从已经编译出的包快速重建系统镜像;
    • make clean- 清理一个指定模块的编译结果;
    • make dump-products 显示所有产品的编译配置信息;
    • make libandroid_runtime 编译所有 JNI framework 内容
    • make framework 编译所有 Java framework 内容
    • make services 编译系统服务和相关内容。
    • make bootimage 生成 boot.img
    • make systemimage 编译生成system.img
    • make recoveryimage 生成 recovery.img
    • make userdataimage 生成 userdata.img
    • make cacheimage 生成 cache.img
    • make otapackage 生成升级包
    • make dist 执行 Build,并将 MAKECMDGOALS 变量定义的输出文件拷贝到 /out/dist 目录。

    2. 编译配置和搜索命令

    • add_lunch_combo [product] 将某个产品加入到用户选项中
    • print_lunch_menu 查询lunch可选的product
    • check_product [product] 检查产品是否有效
    • printconfig 打印当前选择的产品配置
    • get_build_var [build_var] 查找编译时各种变量值;
    • get_abs_build_var [build_var] 获取系统中的编译变量的值
    • cgrep [keyword] 所有 C/C++文件执行搜索操作
    • jgrep [keyword] 所有 Java 文件执行搜索操作
    • ggrep [keyword] 所有 Gradle 文件执行搜索操作
    • mgrep [keyword] 所有 Android.mk 文件执行搜索操作
    • mangrep [keyword] 所有AndroidManifest.xml文件执行搜索操作
    • sepgrep [keyword] 所有 sepolicy 文件执行搜索操作
    • resgrep [keyword] 所有本地res/*.xml文件执行搜索操作

    3. 导航命令

    • croot 切换至Android根目录
    • godir [filename] 跳转到包含某个文件的目录

    相关文章

      网友评论

          本文标题:Android系统编译常用配置及指令

          本文链接:https://www.haomeiwen.com/subject/suybbdtx.html