【开发日常】【Makefile】编译时如何将警告(warning)视为错误(error)?

本文详细介绍了Linux内核编译时警告与错误的处理方式,特别是-Werror选项如何将警告转化为错误,导致编译终止。通过修改内核Makefile文件,可以全局设置-Werror,使得所有警告被视为错误。反之,要取消这一行为,可以添加-w选项或-Wno-xxx特定警告标志。此外,还讨论了如何仅针对部分警告进行处理,以及在不修改Makefile的情况下通过命令行参数避免警告成为错误。
摘要由CSDN通过智能技术生成

我们有时会遇到内核编译时警告(warning)被视为错误(error)等问题

在内核源码中,移植外部驱动模块,出现报错:
error: unused variable ‘xxx’ [-Werror=unused-variable]
...
error: defined but not used [-Werror=unused-variable]
...
error: 'ret' may be used uninitialized in this function [-Werror=maybe-uninitialized]
...

但是上述这些信息,在另一个内核中编译,只是报警告:

warning: unused variable 'core_id' [-Wunused-variable]
...
warning: defined but not used [-Werror=unused-variable]
...
warning: 'ret' may be used uninitialized in this function [-Werror=maybe-uninitialized]
...

为什么有的内核编译时警告被视为错误?

出现上述现象的原因和GCC编译选项有关:

选 项含 义
-pedantic允许发出ANSI C标准所列的全部警告信息
-pedantic-error允许发出ANSI C标准所列的全部错误信息
-w关闭所有告警
-Wall允许发出Gcc提供的所有有用的报警信息
-werror把所有的告警信息转化为错误信息,并在告警发生时终止编译过程

其中的-Werror选项,会把所有的告警信息转化为错误信息,并在告警发生时终止编译过程。


做一个简单的试验,验证-Werror选项的作用

参考链接中的内容,写一个最简单的KO模块:
【开发日常】【module】Linux写一个简单的ko模块
然后模拟做一个简单的warning(未使用的变量):

static int hello_init(void)
{
    int a=1;
    printk("Hello, World !\n");
    return 0;
}

执行Makefile编译KO,提示告警:

zhugeyifan@83-28:~/test/ko_module_demo$ make
make -C /lib/modules/4.15.0-126-generic/build M=/home1/zhugeyifan/test/ko_module_demo modules
make[1]: Entering directory '/usr/src/linux-headers-4.15.0-126-generic'
  CC [M]  /home1/zhugeyifan/test/ko_module_demo/hello_world.o
/home1/zhugeyifan/test/ko_module_demo/hello_world.c: In function ‘hello_init’:
/home1/zhugeyifan/test/ko_module_demo/hello_world.c:6:9: warning: unused variable ‘a’ [-Wunused-variable]
     int a=1;  
         ^
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home1/zhugeyifan/test/ko_module_demo/hello_world.mod.o
  LD [M]  /home1/zhugeyifan/test/ko_module_demo/hello_world.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-126-generic'

再尝试在Makefile中添加-Werror选项:

ccflags-y += -Werror

再次执行Makefile编译,看到报错:

zhugeyifan@83-28:~/test/ko_module_demo$ make
make -C /lib/modules/4.15.0-126-generic/build M=/home1/zhugeyifan/test/ko_module_demo modules
make[1]: Entering directory '/usr/src/linux-headers-4.15.0-126-generic'
  CC [M]  /home1/zhugeyifan/test/ko_module_demo/hello_world.o
/home1/zhugeyifan/test/ko_module_demo/hello_world.c: In function ‘hello_init’:
/home1/zhugeyifan/test/ko_module_demo/hello_world.c:6:9: error: unused variable ‘a’ [-Werror=unused-variable]
     int a=1;  
         ^
cc1: all warnings being treated as errors
scripts/Makefile.build:337: recipe for target '/home1/zhugeyifan/test/ko_module_demo/hello_world.o' failed
make[2]: *** [/home1/zhugeyifan/test/ko_module_demo/hello_world.o] Error 1
Makefile:1587: recipe for target '_module_/home1/zhugeyifan/test/ko_module_demo' failed
make[1]: *** [_module_/home1/zhugeyifan/test/ko_module_demo] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-126-generic'
Makefile:31: recipe for target 'all' failed
make: *** [all] Error 2

至此,可以得出一个结论:在Makefile中添加-Werror,可以将告警信息转化为错误信息,并在告警发生时终止编译过程。
那假如想要让整个内核都带上-Werror选项,需要怎么做?(如何让内核编译时所有告警信息转化为错误信息,并在告警发生时终止编译过程。)


如何让整个内核都带上-Werror选项?

修改根目录下的Makefile,找到如下语句:
KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
                   -fno-strict-aliasing -fno-common \
                   -Werror-implicit-function-declaration \
                   -Wno-format-security \
                   -std=gnu89

在里面添加上-Werror选项,然后再执行Makefile,可以观察到所有的warning都变成了error,并且直接退出编译。

Ps:这里有个注意事项,“KBUILD_CFLAGS:=”的意思是如果未定义,则执行后面的赋值操作。所以在这个之前最好不要操作KBUILD_CFLAGS参数,否则可能会导致一些其他错误。如果在这段话之后,使用“KBUILD_CFLAGS+=”操作,就不会有影响。

实际应用中,我们可能只是希望把一部分warning,变成error,是我们的代码更加的符合规范,那需要怎么做?


内核编译时,如何只让一部分warning编译报错?

可以让Wrerror加上具体的参数,例如:-Werror-xxx,使其只转换一部分的warning。

KBUILD_CFLAGS   += -Werror-implicit-function-declaration
KBUILD_CFLAGS   += -Werror=unknown-warning-option
KBUILD_CFLAGS   += -Werror-implicit-int
KBUILD_CFLAGS   += -Werror-strict-prototypes
KBUILD_CFLAGS   += -Werror-date-time
KBUILD_CFLAGS   += -Werror-incompatible-pointer-types
KBUILD_CFLAGS   += -Werror-designated-init
...

如何使内核编译时不将warning视为error?

其实就是上述问题的反向操作。
有多种方式:

1.在Makefile中去除-Werror选项。

第一种方式适用于比较简单的Makefile。就像上面的例子,把Makefile里添加的-Werror去掉就行了!
但是内核代码里,全局搜索Werror会找到很多,一个一个去除太麻烦了!
这时候使用“-w”选项更适合


2.在Makefile中添加-w选项

-w选项是关闭所有告警,这个同样是在内核的根目录下的Makefile中做:

KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
                   -fno-strict-aliasing -fno-common \
                   -Werror-implicit-function-declaration \
                   -Wno-format-security \
                   -std=gnu89

在KBUILD_CFLAGS中添加"-w"参数,再次执行Makefile。
当然,有时候我们是希望只去除一部分的warning转error操作。


3.只去除一部分的warning转error操作

这时候可以通过下面的参数:
KBUILD_CFLAGS   += -Wno-unused-variable
KBUILD_CFLAGS   += -Wno-sign-compare
KBUILD_CFLAGS   += -Wno-pointer-sign
KBUILD_CFLAGS   += -Wno-unused-function
KBUILD_CFLAGS   += -Wno-unused-parameter
KBUILD_CFLAGS   += -Wno-unused-variable
KBUILD_CFLAGS   += -Wno-implicit-function-declaration
KBUILD_CFLAGS   += -Wno-unused-result

/*通过Andriod.mk进行编译*/
如果通过Android.mk进行编译,则修改
LOCAL_CFLAGS += -Wno-unused-variable
LOCAL_CFLAGS += -Wno-unused-parameter 
LOCAL_CFLAGS += -Wno-missing-field-initializers 
LOCAL_CFLAGS += -Wno-implicit-function-declaration
LOCAL_CFLAGS += -Wno-pointer-sign
LOCAL_CFLAGS += -Wno-sign-compare
LOCAL_CFLAGS += -Wno-ignored-attributes
LOCAL_CFLAGS += -Wno-format-invalid-specifier
LOCAL_CFLAGS += -Wno-error

比如上面第一个例子,报错信息是

/home1/zhugeyifan/test/ko_module_demo/hello_world.c:6:9: error: unused variable ‘a’ [-Werror=unused-variable]

那就添加标志如下:
KBUILD_CFLAGS   += -Wno-unused-variable

这个标志的意思是:-W,去除unused-variable报错(no-unused-variable)


有没有什么办法不修改Makefile,同样实现不将警告视为错误?

可以在执行makefile时,从外部传参:
make KBUILD_CFLAGS+=-w

这样也能实现。不过就是有个隐患,它好像会将Makefile中的KBUILD_CFLAGS其他参数覆盖掉,如同我上面提到的:

KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
                   -fno-strict-aliasing -fno-common \
                   -Werror-implicit-function-declaration \
                   -Wno-format-security \
                   -std=gnu89

Ps:这里有个注意事项,“KBUILD_CFLAGS:=”的意思是如果未定义,则执行后面的赋值操作。所以在这个之前最好不要操作KBUILD_CFLAGS参数,否则可能会导致一些其他错误。如果在这段话之后,使用“KBUILD_CFLAGS+=”操作,就不会有影响。


引用中的错误提示`make: *** [scripts/kconfig/lxdialog/checklist.o] Error 1 Makefile:417: recipe for target 'menuconfig' failed make: *** [menuconfig] Error 2`表示在执行`make menuconfig`命令,出现了错误。该错误是由于`scripts/kconfig/lxdialog/checklist.c`文件的编译失败导致的。可能的原因是缺少必要的依赖文件,或者编译环境配置不正确。 引用中的错误提示`drivers/video/console/vgacon.o:987:warning:comparison is always true due to limited range of data type make:***[drivers/video/console/vgacon.o] error 1 make:***[drivers/video/console2] error 2 make:***[drivers/video1] error 2 make:***[drivers] error 2`表明在编译`drivers/video/console/vgacon.c`文件出现了错误。其中包含了一些警告错误信息,这可能是由于代码中的类型比较问题导致的。 引用中的错误提示`make zImage和make xipImageKernel configured for XIP (CONFIG_XIP_KERNEL=y) Only the xipImage target is available in this case make: *** [arch/arm/boot/zImage] Error 1 make: *** [zImage] Error 2`表示在编译内核,出现了一些错误。这可能与配置的选项有关,例如使用了XIP内核(可执行内核映像)的选项,但当前环境下只能使用xipImage目标进行编译。 针对以上错误提示,可以考虑以下解决方法: 1. 确保编译环境配置正确,并安装了必要的依赖文件。 2. 检查相关源代码文件的完整性,并确保没有错误的代码。 3. 如果出现警告信息,可以尝试根据警告信息进行代码调整。 4. 如果使用了特定的内核配置选项,可以尝试禁用或更改这些选项,以便使用正确的编译目标。 注意:由于缺少具体编译环境和相关代码的信息,以上只是一些可能的解决方法。建议进一步检查详细的错误日志和相关配置文件,以便更准确地解决问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [make menuconfig出错的解决方案](https://blog.csdn.net/lwz15071387627/article/details/88823617)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [内核编译错误的一些解决办法](https://blog.csdn.net/xiyangfan/article/details/5467811)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Evan_ZGYF丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值