环境
| 环境 | Ubuntu 18.04 (官方推荐) | Ubuntu 24.04(我的wsl) |
|---|---|---|
| GCC | 7.x | 13.3 |
| binutils | 2.30 | 2.42 |
| glibc | 2.27 | 2.39 |
| Linux-xlnx | 2020.2 | 2020.2 |
现象
bash
minglie@ming:/home/wpf/workspace/kernel-driver/linux-xlnx-xlnx_rebase_v5.4_2020.2$ make
HOSTLD scripts/dtc/dtc
/usr/bin/ld: scripts/dtc/dtc-parser.tab.o:
(.bss+0x20): multiple definition of yylloc';
scripts/dtc/dtc-lexer.lex.o:
(.bss+0x0): first defined here collect2:
error: ld returned 1 exit status make[1]:
*** [scripts/Makefile.host:116: scripts/dtc/dtc]
Error 1 make: *** [Makefile:1263: scripts_dtc] Error 2
旧版 Linux 内核(5.4 Xilinx 2020.2)和新版 Ubuntu/WSL 的 flex/bison 不兼容
yylloc 全局变量被定义了两次
dtc-parser.tab.o 定义了一次 yylloc
dtc-lexer.lex.o 又定义了一次 yylloc
GCC 10 有个编译选项-fcommon 和 -fno-common
| 对比项 | -fcommon(GCC 10 以前默认) |
-fno-common(GCC 10 以后默认) |
|---|---|---|
| 默认版本 | GCC < 10 | GCC ≥ 10 |
对未初始化全局变量 int x; 的处理 |
生成 Common Symbol | 生成真正的全局变量定义 |
多个源文件都有 int x; |
链接器自动合并 | 链接时报错 |
nm 查看符号 |
C(Common) |
B(BSS)或 D(Data) |
| 是否容易隐藏 Bug | 是 | 否 |
| 是否符合现代 C 工程规范 | 较宽松 | 更严格、更推荐 |
| Linux 新版本支持情况 | 已逐渐淘汰 | 官方推荐 |
gcc编译选项
bash
minglie@ming$ gcc -Q --help=common | grep common
-fcommon [disabled]
-fpredictive-commoning [disabled]
-funconstrained-commons [disabled]
修改scripts/dtc/dtc-lexer.l重新编译
bash
# scripts/dtc/dtc-lexer.l 的 26行
# YYLTYPE yylloc; 改为 extern YYLTYPE yylloc;
$ vim scripts/dtc/dtc-lexer.l
# 重新编译
make mrproper
make xilinx_zynq_defconfig
make -j$(nproc)
# 或者
# 删除 dtc 的生成文件
rm -f scripts/dtc/dtc
rm -f scripts/dtc/*.o
rm -f scripts/dtc/*.tab.*
rm -f scripts/dtc/*.lex.c
# 重新编译
make -j$(nproc)