改了某个文件,应该remake哪个模块?

本文介绍了一种在make目录中寻找特定字符串的方法。该方法适用于在模块级别的目录内进行精确匹配,帮助开发者快速定位到含有指定字符串的文件。

在make目录下查找这个文件名的字符串.字符串所在的文件就在这个模块目录下。(make目录下每个目录代表一个模块,再下一层当然就不是了)

Description: This script for build qcom/mtk platform android system goals OPTIONS: -b, --build_action support build: new、remake、clean、update-api、ssi(qssi/mssi)、vnd、merge -K(大写), --keep build android. Keep going when some targets cant be made -k(小写), --key-number mtkr image sign key number -f, --filepath mtkr image path for sign -t, --type Build type(user/userdebug/eng) (Default: userdebug) -j, --jobs Specifies the number of jobs to run simultaneously (Default: 20) -m, --module module/outfile/target/image to be build with make -n, --ninja_module module/outfile/target/image to be build with ninja -a, --accurate filepath/changes.txt/changes gerrit url/filepath to precise build -p, --project, -P, --Project builds and installs all of the modules in the supplied directories, and their dependencies. Use OPLUS_CI_USER_MM="true" only builds and installs current directory, and their dependencies. eg: -p frameworks/base. -d, --pathdir build the corresponding target according to the modified content. -N, --ninja module/pathfile/target/image to be build with ninja -M, --make module/pathfile/target/image to be build with make -v, --vendor_target set MTK LD2.0 vendor target (hal/krn/vext) == (mgvi/mgk/vext) == (out_hal/out_krn/out). default is all. -c, --copy_target copy target to oplus_ci_out component dir -h, --help Display this help message -l, --list list targets in directory path Usage: 整体编译: 1 ./mk_android.sh -t userdebug -b new 清除out后,全编译${WHAT_COMPONENT} tree. 2 ./mk_android.sh -t userdebug -b remake 不清楚out,增量编译${WHAT_COMPONENT} tree. 模块编译: \033[33m如果模块属于vnd,且是MTK LD2.0编译架构,请记得添加-v [mgvi/mgk/vext], 默认是all.\033[0m 1 ./mk_android.sh -t userdebug -m \$target 通过make的方式编译某个target,target可以是编译目标和目标文件 eg: kernel、bootimage、systemimage、recoveryimage eg: out/target/product/xxx/\$file 2 ./mk_android.sh -t userdebug -n \$target 通过ninja的方式编译某个target. ninja的编译方式会比make方式快很多,在没有编译依赖的情况下,建议采用该方式编译. eg: kernel、bootimage、systemimage、recoveryimage eg: out/target/product/xxx/\$file 3 ./mk_android.sh -t userdebug -p \$pathDir pathDir为Android.mk/Android.bp所在目录, 如应用、jar、so等. eg: ./mk_android.sh -t userdebug -p packages/apps/Bluetooth/ 没有修Android.mk或Android.bp的情况下,可以通过ninja的方式快速编译. eg: ./mk_android.sh -t userdebug -p packages/apps/Bluetooth/ -N 4 ./mk_android.sh -t userdebug -p \$pathDir:\$target 如果\$pathDir下的Android.mk/Android.bp有太多的编译目标时,可以指定特定的目标. eg: ./mk_android.sh -t userdebug -p packages/apps/Bluetooth/:libbluetooth_jni 5 ./mk_android.sh -t userdebug -d \$pathDir 编译\$pathDir目录下的所有目标 eg: ./mk_android.sh -t userdebug -d vendor/qcom/proprietary/chi-cdk 没有修Android.mk或Android.bp的情况下,可以通过ninja的方式快速编译. eg: ./mk_android.sh -t userdebug -d vendor/qcom/proprietary/chi-cdk -N 6 ./mk_android.sh -t userdebug -e chnages.txt 精准编译changes.txt记录文件内容. changes.txt记录内容: frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp eg: ./mk_android.sh -t userdebug -e changes.txt 则精准编译AudioPolicyService.cpp相关模块。 其他编译选项: 1 ./mk_android.sh -t userdebug -b android -K #K(大写) 编译android时保持keep going,直到编译完成后退出,如果有报错之后一起列出。 可用于基线升级时验证android代码编译问题。 eg: ./mk_android.sh -t userdebug -m \$target -K 表示编译\$target 是keep going 2 ./mk_android.sh -f \$filepath -k \$keynumber #k(小写) 对MTK R平台image文件进行单独签名. filepath为image路径,keynumber通常是项目号。如: 对18073项目的lk.img签名。 eg: ./mk_android.sh -f out/target/product/xxx/lk.img -k 18073
08-30
<think> 我们正在讨论如何调试Kbuild生成的Makefile规则。根据引用[2]和[3],Kbuild系统在编译过程中会两次扫描Makefile:首先读取顶层Makefile,然后根据顶层Makefile的指示读取各个子目录中的Kbuild Makefile(或Makefile)。这些Makefile是动态生成的,因此调试它们需要特殊的方法。 调试Kbuild生成的Makefile规则的方法: 1. **查看生成的Makefile文件**: 在编译内核时,Kbuild会生成许多中间文件,包括展开后的Makefile。这些文件通常位于内核构建目录(通常是源码目录,但如果是外部模块则可能是单独的构建目录)中。我们可以通过查看这些文件来了解实际的规则。 例如,在编译模块时,可以通过以下命令查看某个目录下最终生成的Makefile: ```bash make -C /path/to/kernel/source M=$PWD modules V=1 ``` 其中`V=1`表示详细输出,它会显示实际执行的命令。同时,在构建目录中会生成一些中间文件,比如在模块的构建目录中,可能会有一个`Makefile`文件,它是由Kbuild系统根据`Kbuild`文件(或`Makefile`)生成的。 2. **使用Kbuild的调试选项**: Kbuild提供了一些调试选项,可以打印出额外的信息: - `make V=1`:显示详细的命令执行过程。 - `make V=2`:显示更详细的输出,包括为什么需要重新构建某个目标。 此外,还可以使用`make -n`(干运行)来查看将要执行的命令而不实际执行它们。 3. **查看构建日志**: 构建日志(通常通过重定向`make`的输出到文件)包含了构建过程中执行的命令和规则。通过分析日志,可以了解哪些规则被触发以及为什么。 4. **使用Kbuild的调试目标**: 在内核的顶层Makefile中,提供了一些调试目标,例如: - `make help`:显示帮助信息,其中包含一些调试目标。 - `make -p`:打印数据库(规则和变量)。这个命令会输出make读取的所有规则和变量,包括内置的和由Kbuild生成的。但是,由于输出非常庞大,通常需要结合grep进行过滤。 例如,要查看某个目标(比如`vmlinux`)的构建规则,可以运行: ```bash make -p | grep -A20 '^vmlinux:' ``` 5. **追踪变量和函数展开**: Kbuild的Makefile中使用了大量的变量和函数。我们可以使用`make`的调试功能来查看变量的值和函数的展开过程。 - 使用`make -n --debug=basic`:可以显示基本的调试信息,包括规则的目标和依赖,以及变量赋值。 - 使用`make -n --debug=v`:显示更详细的调试信息,包括变量的定义和使用。 另外,可以在Makefile中临时添加调试语句,例如: ```makefile $(warning VAR=$(VAR)) ``` 这样,在执行时会在控制台打印出变量`VAR`的值。注意,这种方法需要修Makefile,但Kbuild的Makefile通常是自动生成的,所以我们可以修我们自己的Kbuild文件(比如在驱动目录下的Makefile)来添加调试信息。 6. **使用Kbuild的扩展调试支持**: 在Linux内核的Kbuild系统中,可以设置环境变量`KBUILD_VERBOSE`来增加输出,例如: ```bash KBUILD_VERBOSE=1 make ``` 相当于`make V=1`。 另外,还可以使用`KBUILD_EXTRA_WARN`来开启额外的警告信息。 7. **分析依赖关系图**: 通过生成依赖关系图,可以了解目标之间的依赖关系。可以使用`make -d`(输出调试信息)并重定向到文件,然后分析依赖关系。不过这个输出非常详细,需要耐心分析。 8. **使用专门的Makefile调试工具**: 有一些工具可以帮助调试Makefile,例如`remake`(GNU Make的增强版,带有调试器)和`make --trace`(跟踪规则执行)。 9. **查看Kbuild的文档**: 内核文档中有关于Kbuild的详细说明,位于`Documentation/kbuild`目录下。特别是`makefiles.txt`和`modules.txt`文件。 10. **调试实际的编译命令**: 当编译出错时,Kbuild会打印出失败的命令。我们可以复制这个命令,手动执行并添加调试选项(比如gcc的`-v`选项)来查看详细过程。 示例:调试一个模块的编译过程 假设我们有一个内核模块的Makefile如下: ```makefile obj-m := mymodule.o ``` 在编译时,我们可以这样获取详细信息: ```bash make -C /lib/modules/$(uname -r)/build M=$(pwd) V=1 ``` 这会显示编译每个文件时使用的具体命令。 如果我们想查看Kbuild为这个模块生成的完整Makefile,可以在编译时使用`-n`和`-d`选项,并将输出重定向到文件: ```bash make -C /lib/modules/$(uname -r)/build M=$(pwd) -n -d > log.txt 2>&1 ``` 然后搜索生成的规则。 注意:由于Kbuild的Makefile是动态生成的,所以直接查看源码目录下的Makefile可能不是最终使用的规则。因此,上述方法都是针对实际构建过程中生成的规则。 总结:调试Kbuild生成的Makefile规则需要结合多种方法,包括查看详细输出、分析构建日志、使用make的调试选项以及临时添加调试语句等。同时,由于Kbuild的复杂性,需要一定的经验来快速定位问题。 [^1]: Kbuild 是 Linux 内核构建系统的重要组成部分,它使得内核构建过程更加模块化、可维护和灵活。 [^2]: 从Linux内核2.6开始,Linux内核的编译采用Kbuild系统,这和过去的编译系统有很大的不同,尤其对于Linux内核模块的编译。在新的系统下,Linux编译系统会两次扫描Linux的Makefile:首先编译系统会读取Linux内核顶层的Makefile,然后根据读到的内容第二次读取Kbuild的Makefile来编译Linux内核。 [^3]: 从Linux内核2.6开始,Linux内核的编译采用Kbuild系统,这同过去的编译系统有很大的不同,尤其对于Linux内核模块的编译。在新的系统下,Linux编译系统会两次扫描Linux的Makefile:首先编译系统会读取Linux内核顶层的 Makefile,然后根据读到的内容第二次读取Kbuild的Makefile来编译Linux内核。 [^4]: Linux内核模块开发入门:GCC、Makefile和Kbuild -- 搞定编译三剑客。这篇文章将手把手带你入门 Linux 内核模块的开发,重点介绍内核模块编译中使用的三个核心工具:GCC、Makefile 和 Kbuild。 [^5]: 基于Linux的PCIe设备驱动开发入门到精通-- 8.1 编写健壮的Kbuild Makefile。这一切的核心,就是一个健壮、灵活、可维护的 Makefile。它不仅是将源代码编译成 .ko 模块的工具,更是整个驱动开发流程的基石。 §§相关问题§§ 1. 如何在内核编译过程中获取更详细的调试输出? 2. 如何修Kbuild文件以添加自定义的调试信息? 3. 如何分析Kbuild构建过程中出现的依赖关系问题? </think> ### 调试Kbuild生成的Makefile规则的方法 在内核开发中调试Kbuild生成的Makefile规则,可通过以下方法实现: #### 1. **启用详细构建输出** ```bash # V=1显示基本命令,V=2显示完整命令和变量 make V=2 ``` - 显示所有执行的命令和变量展开过程 - 可定位规则执行顺序和参数传递问题[^2][^3] - 示例输出: ```makefile gcc -Wp,-MD,drivers/usb/.usb_driver.o.d ... -c -o drivers/usb/usb_driver.o drivers/usb/usb_driver.c ``` #### 2. **使用`-n`干运行模式** ```bash make -n drivers/usb/ ``` - 仅打印将要执行的命令而不实际运行 - 验证规则链是否正确生成[^3] - 适合检查条件编译逻辑(如`obj-$(CONFIG_USB)`的展开结果) #### 3. **检查生成的中间文件** 关键文件位置: ```bash # 1. 自动生成的依赖文件(.d文件) ls drivers/usb/.usb_driver.o.d # 2. Kbuild解析后的中间Makefile cat scripts/Makefile.build ``` - `.d`文件包含头文件依赖关系 - `Makefile.build`是Kbuild处理后的实际执行规则[^3] #### 4. **添加自定义调试语句** 在Makefile中插入调试命令: ```makefile # 在Kbuild文件中添加 $(warning DEBUG: obj-y contents=$(obj-y)) # 或添加规则打印变量 print-var: @echo "CONFIG_USB = $(CONFIG_USB)" ``` - 执行`make print-var`查看变量值 - `$(warning)`在解析阶段实时输出信息[^5] #### 5. **使用`make -p`分析规则数据库** ```bash make -p | grep -A10 "usb_driver.o" ``` - 打印make的完整内部规则数据库 - 显示Kbuild生成的目标/依赖关系和变量值[^3] #### 6. **检查配置文件映射** ```bash # 验证配置选项是否正确定义 grep CONFIG_USB .config # 查看配置到Makefile的映射 cat include/generated/autoconf.h | grep USB ``` - 确认`.config`选项正确传递到C代码和Makefile[^1] #### 7. **分阶段调试构建过程** ```bash # 只执行预处理阶段 make drivers/usb/usb_driver.i # 查看预处理后的代码 vi drivers/usb/usb_driver.i ``` - 隔离编译阶段以定位问题源头[^4] #### 8. **使用Kbuild追踪工具** ```bash # 开启Kbuild调试(需内核4.19+) make KBUILD_VERBOSE=3 ``` - 显示Kbuild解析过程的详细日志 - 输出包括: - 目录递归过程 - 条件规则评估 - 变量替换逻辑[^2] > **调试流程建议**: > 1. 用`make -n`验证规则结构 > 2. 用`V=2`检查命令执行细节 > 3. 用`$(warning)`定位变量异常 > 4. 用`.d`文件确认依赖关系 > 5. 用`make -p`分析完整规则链 [^1]: Kbuild 是 Linux 内核构建系统的重要组成部分,它使得内核构建过程更加模块化、可维护和灵活。 [^2]: 从Linux内核2.6开始,Linux内核的编译采用Kbuild系统,这和过去的编译系统有很大的不同,尤其对于Linux内核模块的编译。在新的系统下,Linux编译系统会两次扫描Linux的Makefile。 [^3]: Makefile由五个部分组成: 顶层Makefile是所有Makefile文件的核心,从总体上控制着内核的编译,链接.config是配置文件。 [^4]: 你将学会如何创建、编译、加载和卸载一个简单的内核模块,并深入理解它们在内核模块编译中的作用。 [^5]: 编写健壮的Kbuild Makefile是驱动开发流程的基石,糟糕的Makefile会导致构建失败、难以调试。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值