ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Ubuntu高版本编译Linux 4.1.x内核报 multiple definition of yylloc 解决方法

Ubuntu高版本编译Linux 4.1.x内核报 multiple definition of yylloc 解决方法 Ubuntu 高版本编译 Linux 4.1.x时提示 multiple definition of yylloc 解决方法1. 问题背景在编译 NXP i.MX6ULL 平台 BSP 时使用厂家提供的老版本 Linux 内核linux-imx-rel_imx_4.1.15_2.1.0_ga执行make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- -j16编译过程中出现错误/usr/bin/x86_64-linux-gnu-ld.bfd: scripts/dtc/dtc-parser.tab.o:(.bss0x50): multiple definition of yylloc; scripts/dtc/dtc-lexer.lex.o:(.bss0x0): first defined here collect2: error: ld returned 1 exit status make[2]: *** [scripts/Makefile.host:100: scripts/dtc/dtc] Error 12. 问题定位从错误可以看到scripts/dtc/dtc-parser.tab.o scripts/dtc/dtc-lexer.lex.o出错位置是scripts/dtc而不是 ARM 内核代码。说明失败的是编译运行在主机上的设备树编译器 dtcLinux 编译过程中会先编译一些 host 工具scripts/ | -- kconfig | -- dtc | -- modpost这些工具运行在 PC 上而不是运行在目标 ARM 板子上。3. 根本原因yylloc来自scripts/dtc/ | -- dtc-lexer.lex.c | -- dtc-parser.tab.c这两个文件分别由flexbison生成。里面都有类似YYLTYPE yylloc;的全局变量定义。老 GCC 行为以前 GCC 默认-fcommon多个同名未初始化全局变量int a;会合并处理。例如a.cint yylloc;b.cint yylloc;链接时正常通过新 GCC 行为GCC 10 开始默认-fno-common同名全局变量会被认为是重复定义multiple definition所以老版本 LinuxLinux 4.1 U-Boot 2016在新 UbuntuUbuntu 20.04 GCC 10环境下容易出现该问题。4. 解决方法方法一增加 -fcommon推荐修改 Linux 顶层 Makefile找到HOSTCC gcc HOSTCXX g HOSTCFLAGS -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -stdgnu89 HOSTCXXFLAGS -O2修改HOSTCC gcc HOSTCXX g HOSTCFLAGS -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -stdgnu89 HOSTCFLAGS -fcommon HOSTCXXFLAGS -O2作用让 host 工具编译时恢复 GCC 老版本行为。方法二编译时临时指定不修改源码make ARCHarm \ CROSS_COMPILEarm-linux-gnueabihf- \ HOSTCFLAGS-fcommon \ -j16如果编译通过再永久修改 Makefile。5. 为什么不是修改 dtc 源码也可以修改scripts/dtc/dtc-lexer.lex.c把YYLTYPE yylloc;改成extern YYLTYPE yylloc;但是不推荐。原因这些文件是自动生成的dtc-lexer.l | flex | v dtc-lexer.lex.c重新编译可能会被覆盖。6. 总结编译老版本 BSP 时例如i.MX6ULLi.MX6Linux 4.xU-Boot 2016如果遇到multiple definition of xxx特别是yylloc通常原因GCC 10 修改了默认全局变量处理规则。解决HOSTCFLAGS -fcommon即可。这个问题本质不是代码错误而是老版本嵌入式 Linux BSP 与新开发环境之间的兼容性问题。
返回列表