别急着换Ubuntu!在Fedora上搞定U-Boot交叉编译的‘multiple definition of yylloc‘报错
在Fedora上根治U-Boot交叉编译的'yylloc'多重定义错误
当你在Fedora 35或更高版本上交叉编译较旧版本的U-Boot时,可能会遇到一个令人头疼的错误:"multiple definition of `yylloc'"。这个错误通常出现在编译dtc(设备树编译器)组件时,导致整个构建过程中断。本文将深入分析问题根源,并提供多种在Fedora环境下彻底解决此问题的方法,让你无需切换到其他发行版就能继续工作。
1. 问题根源剖析
这个错误的本质在于符号重复定义。具体来说,yylloc变量在以下两个文件中被多次定义:
scripts/dtc/dtc-parser.tab.oscripts/dtc/dtc-lexer.lex.o
在Fedora 35+上,这个问题变得尤为突出,主要原因有三:
- GCC默认行为变化:从GCC 10开始,默认编译选项从
-fcommon变为-fno-common,这改变了未初始化全局变量的处理方式。 - dtc工具链更新:Fedora自带的dtc版本较新,与旧版U-Boot中的dtc源码存在兼容性问题。
- 历史遗留代码:旧版U-Boot中的dtc实现存在冗余的全局变量声明。
提示:这个问题不仅出现在U-Boot中,Linux内核早期版本在Fedora上编译时也可能遇到类似的'yylloc'冲突。
2. 解决方案一:修改编译器标志
最快捷的解决方法是恢复GCC的旧有行为,通过添加编译选项来解决问题。
2.1 临时解决方案
在编译命令中添加-fcommon标志:
make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- HOSTCFLAGS="-fcommon"这个方法简单直接,但有两个缺点:
- 需要每次编译都手动添加该选项
- 不能解决代码本身的潜在问题
2.2 永久解决方案
修改U-Boot顶层Makefile,添加以下内容:
HOSTCFLAGS += -fcommon或者更精确地,只对dtc目录应用此修改:
scripts/dtc/HOSTCFLAGS += -fcommon优缺点对比:
| 方法 | 优点 | 缺点 |
|---|---|---|
| 临时方案 | 快速验证 | 每次需手动添加 |
| 顶层Makefile修改 | 一劳永逸 | 影响所有主机工具编译 |
| dtc目录特定修改 | 精准定位 | 需要了解Makefile结构 |
3. 解决方案二:修改源代码
对于希望从根本上解决问题的开发者,可以直接修改U-Boot源码。
3.1 定位问题文件
需要修改以下两个文件:
scripts/dtc/dtc-lexer.lscripts/dtc/dtc-parser.y
3.2 具体修改步骤
打开
dtc-lexer.l,找到以下行:YYLTYPE yylloc;将其注释掉或删除。
打开
dtc-parser.y,确保只有一处YYLTYPE yylloc;声明。清理并重新编译:
make distclean make your_defconfig make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu-
注意:这种方法需要一定的代码熟悉度,但能彻底解决问题,适合长期维护的项目。
4. 解决方案三:升级或打补丁
如果你使用的U-Boot版本较旧,可以考虑以下方法:
4.1 升级U-Boot版本
较新的U-Boot版本已经修复了这个问题。查看以下提交:
- U-Boot官方修复:018921ee ("Remove redundant YYLOC global declaration")
- Linux内核中的类似修复:torvalds/linux@e33a814
4.2 手动应用补丁
如果无法升级整个U-Boot,可以单独应用相关补丁。创建一个patch文件:
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l index abc1234..def5678 100644 --- a/scripts/dtc/dtc-lexer.l +++ b/scripts/dtc/dtc-lexer.l @@ -20,7 +20,6 @@ #include "dtc-parser.tab.h" extern bool treesource_error; -YYLTYPE yylloc;然后应用补丁:
patch -p1 < yylloc_fix.patch5. 解决方案对比与选择建议
不同的解决方案适合不同的场景:
- 快速验证/临时使用:方案一(编译器标志)
- 长期维护项目:方案二(源码修改)或方案三(升级/打补丁)
- 系统管理员:考虑在Fedora中安装兼容性包
性能影响评估:
-fcommon选项会略微增加内存占用,但对嵌入式开发影响微乎其微- 源码修改是最干净的解决方案,没有任何运行时开销
在实际项目中,我通常会先使用方案一快速验证构建是否能够通过,然后根据项目周期决定采用方案二还是方案三。对于长期维护的项目,源码级别的修复是最推荐的做法。
