IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android make 命令探索 -> 正文阅读

[移动开发]Android make 命令探索

编译 Android aosp 源码的步骤一般为

source build/envsetup.sh
lunch //选择对应的device
make -j12

如果切换了 device 或者代码有改动,一般会执行 make installclean ;make -j12
如果编译报错,排除语法问题,则需要 make clean ; make -j12

这些 make 命令具体做了什么,探索记录下。

基于 Android 11 ,make 命令可直接用 m 。

涉及的文件:

build/soong/ui/build/build.go
build/make/help.sh
build/make/core/build-system.html
build/soong/ui/build/cleanbuild.go

make 参数追踪

make 后面的不同参数,是在 build/soong/ui/build/build.go 中区分的,

// Build the tree. The 'what' argument can be used to chose which components of
// the build to run.
func Build(ctx Context, config Config, what int) {
	ctx.Verboseln("Starting build with args:", config.Arguments())
	ctx.Verboseln("Environment:", config.Environment().Environ())

	if totalRAM := config.TotalRAM(); totalRAM != 0 {
		ram := float32(totalRAM) / (1024 * 1024 * 1024)
		ctx.Verbosef("Total RAM: %.3vGB", ram)

		if ram <= 16 {
			ctx.Println("************************************************************")
			ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
			ctx.Println("")
			ctx.Println("The minimum required amount of free memory is around 16GB,")
			ctx.Println("and even with that, some configurations may not work.")
			ctx.Println("")
			ctx.Println("If you run into segfaults or other errors, try reducing your")
			ctx.Println("-j value.")
			ctx.Println("************************************************************")
		} else if ram <= float32(config.Parallel()) {
			ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
			ctx.Println("If you run into segfaults or other errors, try a lower -j value")
		}
	}

	ctx.BeginTrace(metrics.Total, "total")
	defer ctx.EndTrace()

	if config.SkipMake() {
		ctx.Verboseln("Skipping Make/Kati as requested")
		what = what & (BuildSoong | BuildNinja)
	}

	if inList("help", config.Arguments()) { //注释1
		help(ctx, config, what)
		return
	} else if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) { //注释2
		clean(ctx, config, what)
		return
	}

	// Make sure that no other Soong process is running with the same output directory
	buildLock := BecomeSingletonOrFail(ctx, config)
	defer buildLock.Unlock()

	checkProblematicFiles(ctx)

	SetupOutDir(ctx, config)

	checkCaseSensitivity(ctx, config)

	ensureEmptyDirectoriesExist(ctx, config.TempDir())

	SetupPath(ctx, config)

	if config.StartGoma() {
		// Ensure start Goma compiler_proxy
		startGoma(ctx, config)
	}

	if config.StartRBE() {
		// Ensure RBE proxy is started
		startRBE(ctx, config)
	}

	if what&BuildProductConfig != 0 {
		// Run make for product config
		runMakeProductConfig(ctx, config)
	}

	if inList("installclean", config.Arguments()) ||
		inList("install-clean", config.Arguments()) { //注释3
		installClean(ctx, config, what)
		ctx.Println("Deleted images and staging directories.")
		return
	} else if inList("dataclean", config.Arguments()) ||
		inList("data-clean", config.Arguments()) { //注释4
		dataClean(ctx, config, what)
		ctx.Println("Deleted data files.")
		return
	}

	if what&BuildSoong != 0 {
		// Run Soong
		runSoong(ctx, config)
	}

	if what&BuildKati != 0 {
		// Run ckati
		genKatiSuffix(ctx, config)
		runKatiCleanSpec(ctx, config)
		runKatiBuild(ctx, config)
		runKatiPackage(ctx, config)

		ioutil.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0777)
	} else {
		// Load last Kati Suffix if it exists
		if katiSuffix, err := ioutil.ReadFile(config.LastKatiSuffixFile()); err == nil {
			ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
			config.SetKatiSuffix(string(katiSuffix))
		}
	}

	// Write combined ninja file
	createCombinedBuildNinjaFile(ctx, config)

	if what&RunBuildTests != 0 {
		testForDanglingRules(ctx, config)
	}

	if what&BuildNinja != 0 {
		if !config.SkipMake() {
			installCleanIfNecessary(ctx, config)
		}

		// Run ninja
		runNinja(ctx, config)
	}
}

注释1 :对应 make help
注释2 :对应 make clean
注释3 :对应 make installclean
注释4 :对应 make dataclean

make help

build/soong/ui/build/build.go 中定义如下,实际是索引到 build/make/help.sh

func help(ctx Context, config Config, what int) {
	cmd := Command(ctx, config, "help.sh", "build/make/help.sh")
	cmd.Sandbox = dumpvarsSandbox
	cmd.RunAndPrintOrFatal()
}

运行结果,

source build/envsetup.sh    # Add "lunch" (and other utilities and variables)
                            # to the shell environment.
lunch [<product>-<variant>] # Choose the device to target.
m -j [<goals>]              # Execute the configured build.

Usage of "m" imitates usage of the program "make".
See /home/luoanhao/make_9632R/2000_MT9632_R_ANR/build/make/Usage.txt for more info about build usage and concepts.

Common goals are:

    clean                   (aka clobber) equivalent to rm -rf out/
    checkbuild              Build every module defined in the source tree
    droid                   Default target
    nothing                 Do not build anything, just parse and validate the build structure

    java                    Build all the java code in the source tree
    native                  Build all the native code in the source tree

    host                    Build all the host code (not to be run on a device) in the source tree
    target                  Build all the target code (to be run on the device) in the source tree

    (java|native)-(host|target)
    (host|target)-(java|native)
                            Build the intersection of the two given arguments

    snod                    Quickly rebuild the system image from built packages
                            Stands for "System, NO Dependencies"
    vnod                    Quickly rebuild the vendor image from built packages
                            Stands for "Vendor, NO Dependencies"
    pnod                    Quickly rebuild the product image from built packages
                            Stands for "Product, NO Dependencies"
    senod                   Quickly rebuild the system_ext image from built packages
                            Stands for "SystemExt, NO Dependencies"
    onod                    Quickly rebuild the odm image from built packages
                            Stands for "ODM, NO Dependencies"


So, for example, you could run:

cd /home/luoanhao/make_9632R/2000_MT9632_R_ANR
source build/envsetup.sh
lunch aosp_arm-userdebug
m -j java

to build all of the java code for the userdebug variant of the aosp_arm device.

make installclean

清除上一次编译的产物,具体清除什么呢?

build/make/core/build-system.html 中有对应的说明,

<p>
If you build one flavor and then want to build another, you should run
"<code>make installclean</code>" between the two makes to guarantee that
you don't pick up files installed by the previous flavor.  "<code>make
clean</code>" will also suffice, but it takes a lot longer.
</p>

搜索后找到 build/soong/ui/build/cleanbuild.go

// installClean deletes all of the installed files -- the intent is to remove
// files that may no longer be installed, either because the user previously
// installed them, or they were previously installed by default but no longer
// are.
//
// This is faster than a full clean, since we're not deleting the
// intermediates.  Instead of recompiling, we can just copy the results.
func installClean(ctx Context, config Config, what int) {
	dataClean(ctx, config, what)

	if hostCrossOutPath := config.hostCrossOut(); hostCrossOutPath != "" {
		hostCrossOut := func(path string) string {
			return filepath.Join(hostCrossOutPath, path)
		}
		removeGlobs(ctx,
			hostCrossOut("bin"),
			hostCrossOut("coverage"),
			hostCrossOut("lib*"),
			hostCrossOut("nativetest*"))
	}

	hostOutPath := config.HostOut()
	hostOut := func(path string) string {
		return filepath.Join(hostOutPath, path)
	}

	productOutPath := config.ProductOut()
	productOut := func(path string) string {
		return filepath.Join(productOutPath, path)
	}

    ctx.Printf("[TEST] in installClean , productOutPath :%q", productOutPath)  // 注释 1

	// Host bin, frameworks, and lib* are intentionally omitted, since
	// otherwise we'd have to rebuild any generated files created with
	// those tools.
	removeGlobs(ctx,
		hostOut("apex"),
		hostOut("obj/NOTICE_FILES"),
		hostOut("obj/PACKAGING"),
		hostOut("coverage"),
		hostOut("cts"),
		hostOut("nativetest*"),
		hostOut("sdk"),
		hostOut("sdk_addon"),
		hostOut("testcases"),
		hostOut("vts"),
		hostOut("vts10"),
		hostOut("vts-core"),
		productOut("*.img"),
		productOut("*.zip"),
		productOut("android-info.txt"),
		productOut("apex"),
		productOut("kernel"),
		productOut("data"),
		productOut("skin"),
		productOut("obj/APPS"),//注释2
		productOut("obj/NOTICE_FILES"),
		productOut("obj/PACKAGING"),
		productOut("ramdisk"),
		productOut("debug_ramdisk"),
		productOut("vendor-ramdisk"),
		productOut("vendor-ramdisk-debug.cpio.gz"),
		productOut("vendor_debug_ramdisk"),
		productOut("test_harness_ramdisk"),
		productOut("recovery"),
		productOut("root"),
		productOut("system"),
		productOut("system_other"),
		productOut("vendor"),
		productOut("product"),
		productOut("system_ext"),
		productOut("oem"),
		productOut("obj/FAKE"),
		productOut("breakpad"),
		productOut("cache"),
		productOut("coverage"),
		productOut("installer"),
		productOut("odm"),
		productOut("sysloader"),
		productOut("testcases"))
}

注释1 处 :打印出来就是 out/target/product/xxx , xxx 就是 lunch 时选择的 device 。
注释2 处 :自己加的,把这个目录也清除了。这个目录是编译应用生成的中间产物,如 Bluetooth_intermediatesQuickSearchBox_intermediates

运行 log 如下,

11:11:17 [TEST] in removeGlobs , remove "out/host/windows-x86/lib" 
11:11:17 [TEST] in removeGlobs , remove "out/host/windows-x86/lib64" 
11:11:17 [TEST] in installClean , productOutPath :"out/target/product/xxx"
11:11:17 [TEST] in removeGlobs , remove "out/host/linux-x86/obj/NOTICE_FILES" 
11:11:17 [TEST] in removeGlobs , remove "out/target/product/xxx/boot-debug.img" 
11:11:17 [TEST] in removeGlobs , remove "out/target/product/xxx/boot.img" 
11:11:17 [TEST] in removeGlobs , remove "out/target/product/xxx/cache.img" 
11:11:17 [TEST] in removeGlobs , remove "out/target/product/xxx/dtb.img" 
11:11:17 [TEST] in removeGlobs , remove "out/target/product/xxx/ramdisk-debug.img" 
11:11:17 [TEST] in removeGlobs , remove "out/target/product/xxx/ramdisk-recovery.img" 
11:11:17 [TEST] in removeGlobs , remove "out/target/product/xxx/ramdisk.img" 
11:11:17 [TEST] in removeGlobs , remove "out/target/product/xxx/recovery.img" 
11:11:18 [TEST] in removeGlobs , remove "out/target/product/xxx/super.img" 
11:11:18 [TEST] in removeGlobs , remove "out/target/product/xxx/system.img" 
11:11:18 [TEST] in removeGlobs , remove "out/target/product/xxx/tvconfig.img" 
11:11:18 [TEST] in removeGlobs , remove "out/target/product/xxx/userdata.img" 
11:11:18 [TEST] in removeGlobs , remove "out/target/product/xxx/vendor.img" 
11:11:18 [TEST] in removeGlobs , remove "out/target/product/xxx/android-info.txt" 
11:11:18 [TEST] in removeGlobs , remove "out/target/product/xxx/apex" 
11:11:18 [TEST] in removeGlobs , remove "out/target/product/xxx/kernel" 
11:11:18 [TEST] in removeGlobs , remove "out/target/product/xxx/data" 
11:11:19 [TEST] in removeGlobs , remove "out/target/product/xxx/obj/NOTICE_FILES" 
11:11:20 [TEST] in removeGlobs , remove "out/target/product/xxx/obj/PACKAGING" 
11:11:20 [TEST] in removeGlobs , remove "out/target/product/xxx/ramdisk" 
11:11:20 [TEST] in removeGlobs , remove "out/target/product/xxx/debug_ramdisk" 
11:11:20 [TEST] in removeGlobs , remove "out/target/product/xxx/recovery" 
11:11:20 [TEST] in removeGlobs , remove "out/target/product/xxx/root" 
11:11:27 [TEST] in removeGlobs , remove "out/target/product/xxx/system" 
11:11:27 [TEST] in removeGlobs , remove "out/target/product/xxx/vendor" 
11:11:28 [TEST] in removeGlobs , remove "out/target/product/xxx/obj/FAKE" 
11:11:28 [TEST] in removeGlobs , remove "out/target/product/xxx/cache"

make clean && make clobber

build/make/core/build-system.html 中有对应的说明,等同于删除 out/ 目录。

<li><b>clean</b> - <code>make clean</code> deletes all of the output and
intermediate files for this configuration.  This is the same as <code>rm -rf
out/&lt;configuration&gt;/</code></li>
<li><b>clobber</b> - <code>make clobber</code> deletes all of the output
and intermediate files for all configurations.  This is the same as
<code>rm -rf out/</code>.</li>
<li><b>dataclean</b> - <code>make dataclean</code> deletes contents of the data 
directory inside the current combo directory.  This is especially useful on the
simulator and emulator, where the persistent data remains present between 
builds.</li>

对应 build/soong/ui/build/cleanbuild.go

// Remove everything under the out directory. Don't remove the out directory
// itself in case it's a symlink.
func clean(ctx Context, config Config, what int) {
	removeGlobs(ctx, filepath.Join(config.OutDir(), "*"))
	ctx.Println("Entire build directory removed.")
}

make LOCAL_MODULE

build/make/core/build-system.html 中有对应的说明,编译某个模块,单编某个模块,代码需要全编译过。

<li><b>LOCAL_MODULE</b> - Anything you specify as a <code>LOCAL_MODULE</code>
in an Android.mk is made into a pseudotarget.  For example, <code>make
runtime</code> might be shorthand for <code>make
out/linux-x86-debug/system/bin/runtime</code> (which would work), and
<code>make libkjs</code> might be shorthand for <code>make
out/linux-x86-debug/system/lib/libkjs.so</code> (which would also work).</li>
<li><b>targets</b> - <code>make targets</code> will print a list of all of
the LOCAL_MODULE names you can make.</li>
</ul>

make clean-$(LOCAL_MODULE)

build/make/core/build-system.html 中有对应的说明,清理某一个模块。

<li><b>clean-$(LOCAL_MODULE)</b> and <b>clean-$(LOCAL_PACKAGE_NAME)</b> - 
Let you selectively clean one target.  For example, you can type
<code>make clean-libutils</code> and it will delete libutils.so and all of the
intermediate files, or you can type <code>make clean-Home</code> and it will
clean just the Home app.</li>

make dataclean

build/make/core/build-system.html 中有对应的说明,清理 data 目录。

<li><b>dataclean</b> - <code>make dataclean</code> deletes contents of the data 
directory inside the current combo directory.  This is especially useful on the
simulator and emulator, where the persistent data remains present between 
builds.</li>

对应 build/soong/ui/build/cleanbuild.go

func dataClean(ctx Context, config Config, what int) {
	removeGlobs(ctx, filepath.Join(config.ProductOut(), "data", "*"))
}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-05-18 17:46:02  更:2022-05-18 17:47:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 1:53:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码