1.问题
在进行内核模块编译的时候突然提示如下错误:
/work/kernel/module.c:136:86: error: macro "__TIME__" might prevent reproducible builds [-Werror=date-time]
MODULE_DESCRIPTION("compiled by GCC " __VERSION__ " build on " __TIME__ " " __DATE__);
/work/dte/src/kernel/module.c:136:86: error: macro "__DATE__" might prevent reproducible builds [-Werror=date-time]
1.1开发环境
开发环境如下图所示
2.定位
首先看到错误日志就能确认在内核模块中引用了如下代码“MODULE_DESCRIPTION("compiled by GCC " __VERSION__ " build on " __TIME__ " " __DATE__);”
在4.9(含)的gcc版本中添加了-Wdate-time告警,如果在内核模块代码中使用了__DATE__, __TIME__, or __TIMESTAMP__这几个宏,会产生这几种错误;
点击打开链接
[PATCH 7/7] Makefile: Build with -Werror=date-time if the compilersupports it
From:
Josh Triplett
Date:
Mon Dec 23 2013 - 16:56:19 EST
- Next message: Josh Triplett: "[PATCH 3/7] staging: rtl8188eu: Drop print of build date/time"
- Previous message: Josh Triplett: "[PATCH 6/7] x86: math-emu: Drop already-disabled print of build date"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
GCC 4.9 and newer have a new warning -Wdate-time, which warns on any use
of __DATE__, __TIME__, or __TIMESTAMP__, which would make the build
non-deterministic. Now that the kernel does not use any of those
macros, turn on -Werror=date-time if available, to keep it that way.
The kernel already (optionally) records this information at build time
in a single place; other kernel code should not duplicate that.
Signed-off-by: Josh Triplett
---
Makefile | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Makefile b/Makefile
index 14d592c..188eea7 100644
--- a/Makefile
+++ b/Makefile
@@ -668,6 +668,9 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=implicit-int)
# require functions to have arguments in prototypes, not empty 'int foo()'
KBUILD_CFLAGS += $(call cc-option,-Werror=strict-prototypes)
+# Prohibit date/time macros, which would make the build non-deterministic
+KBUILD_CFLAGS += $(call cc-option,-Werror=date-time)
+
# use the deterministic mode of AR if available
KBUILD_ARFLAGS := $(call ar-option,D)
--
1.8.5.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
3.解决方法
解决方法有如下几种,可根据需求进行选择
第一种解决方法 在makefile中添加如下选项
EXTRA_CFLAGS += -Wno-error=date-time
EXTRA_CFLAGS +=-Wno-date-time
注意:在第二段定位中已经说到只有在4.9以及之后的gcc版本中才有这两个选项,如果你在gcc版本小于4.9的系统上编译,比如在centos7.2系统中,centos中默认的gcc版本是4.8.5,编译时就会报"cc1: 错误:-Werror=date-time:没有选项 -Wdate-time"错误,所以这种解决方法如果只是使用4.9以上的gcc版本是没有问题的;
第二种解决方法
修改/lib/modules/'uname -r'/build/Makefile文件,我的是/lib/modules/4.4.0-116-generic/build/Makefile
将KBUILD_CFLAGS += $(call cc-option,-Werror=date-time)这一行注释掉
注意:这种方法虽然解决了这个问题,但是修改了系统本身的属性,不太推荐
第三种解决方法
这一种方法也是我比较推荐的方法,修改内核模块的makefile文件,添加一行
ccflags-y+=$(shell if [ $(call cc-version) -ge 0490 ] ; then echo "-Wno-error=date-time -Wno-date-time"; fi ;)
在linux内核的最顶层目录也就是根目录下面的Makefile文件中,有一个变量"KBUILD_CFLAGS",这个$(KBUILD_CFLAGS)中存放的是传递给gcc编译器的编译选项,如果被编译的文件在被gcc编译时,没有特殊的要求的话就会使用$(KBUILD_CFLAGS)中的编译选项。
但是如果被gcc编译的文件有特殊的编译选项要求的话,使用如下的方式来指定编译选项:
ccflags-y,是指定给$(CC)的编译选项;
asflags-y,是指定给$(AS)的编译选项;
ldflags-y,是指定给$(LD)的编译选项;