在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 ARCHarm CROSS_COMPILEaarch64-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.y3.2 具体修改步骤打开dtc-lexer.l找到以下行YYLTYPE yylloc;将其注释掉或删除。打开dtc-parser.y确保只有一处YYLTYPE yylloc;声明。清理并重新编译make distclean make your_defconfig make ARCHarm CROSS_COMPILEaarch64-linux-gnu-注意这种方法需要一定的代码熟悉度但能彻底解决问题适合长期维护的项目。4. 解决方案三升级或打补丁如果你使用的U-Boot版本较旧可以考虑以下方法4.1 升级U-Boot版本较新的U-Boot版本已经修复了这个问题。查看以下提交U-Boot官方修复018921ee (Remove redundant YYLOC global declaration)Linux内核中的类似修复torvalds/linuxe33a8144.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选项会略微增加内存占用但对嵌入式开发影响微乎其微源码修改是最干净的解决方案没有任何运行时开销在实际项目中我通常会先使用方案一快速验证构建是否能够通过然后根据项目周期决定采用方案二还是方案三。对于长期维护的项目源码级别的修复是最推荐的做法。