【已解决】编译Linux内核报错multiple definition of yylloc

问题描述

在学习正点原子的驱动开发指南过程中,在编译Linux内核时出现以下报错,内核文件为:linux-imx-rel_imx_4.1.15_2.1.0_ga。

./mx6ull_alientek_emmc.sh文件内容如下

#!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16

 报错信息如下:

In file included from include/linux/kernel.h:11,
                 from include/asm-generic/bug.h:13,
                 from ./arch/arm/include/asm/bug.h:61,
                 from include/linux/bug.h:4,
                 from include/linux/page-flags.h:9,
                 from kernel/bounds.c:9:
include/linux/log2.h:22:1: warning: ignoring attribute ‘noreturn’ because it conflicts with attribute ‘const’ [-Wattributes]
   22 | int ____ilog2_NaN(void);
      | ^~~
  CHK     include/generated/bounds.h
  UPD     include/generated/bounds.h
  CC      arch/arm/kernel/asm-offsets.s
In file included from include/linux/kernel.h:11,
                 from include/linux/sched.h:17,
                 from arch/arm/kernel/asm-offsets.c:14:
include/linux/log2.h:22:1: warning: ignoring attribute ‘noreturn’ because it conflicts with attribute ‘const’ [-Wattributes]
   22 | int ____ilog2_NaN(void);
      | ^~~
  CHK     include/generated/asm-offsets.h
  UPD     include/generated/asm-offsets.h
  CALL    scripts/checksyscalls.sh
  HOSTLD  scripts/dtc/dtc
/usr/bin/ld: scripts/dtc/dtc-parser.tab.o:(.bss+0x50): multiple definition of yylloc'; scripts/dtc/dtc-lexer.lex.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [scripts/Makefile.host:100:scripts/dtc/dtc] 错误 1
make[1]: *** [scripts/Makefile.build:403:scripts/dtc] 错误 2
make[1]: *** 正在等待未完成的任务....
  HOSTLD  scripts/genksyms/genksyms
  HOSTLD  scripts/mod/modpost
make: *** [Makefile:556:scripts] 错误 2
make: *** 正在等待未完成的任务....
txj@txj-virtual-machine:~/IMX6ULL/linux_core/linux-imx-rel_imx_4.1.15_2.1.0_ga$

解决方案

需要gcc设置为gcc-9的版本,笔者原先是gcc-12版本无法正常编译。

安装gcc指令

sudo apt install gcc-9

 更新 update-alternatives 配置

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 30

 选择默认版本

sudo update-alternatives --config gcc

如果还不行请尝试以下方法:

重新下载了arm-linux-gnueabihf-gcc

gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar 

通过百度网盘分享的文件:gcc-linaro-4.9.4-2017.01-x86_64_arm...
链接:https://pan.baidu.com/s/1tdF7qalld4E86S3kc9-dAQ?pwd=us5v 
提取码:us5v 
--来自百度网盘超级会员V5的分享

步骤如下:

将文件拷贝到Ubuntu根目录下的tools文件中
sudo mkdir /usr/local/arm
sudo cp gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz /usr/local/arm/ -f
sudo tar -vxf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz
sudo vi /etc/profile
export PATH=$PATH:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin
sudo apt-get install lsb-core lib32stdc++6
sudo reboot
arm-linux-gnueabihf-gcc -v

 gcc版本为下图,为安装成功。

 这个时候再运行一次./mx6ull_alientek_emmc.sh 应该就能够正常编译了。

如果gcc版本还是原来的,需要先删除先前的arm-linux-gnueabihf-gcc再重新进行上面的步骤。

which arm-linux-gnueabihf-gcc-<version>,找到文件的路径,备份一下,然后删除它即可。

<think>我们面对的是在编译Linux内核或U-Boot时出现的'multiple definition of `yylloc''错误。根据引用内容,这个问题通常发生在scripts/dtc目录下的文件中,涉及yylloc变量的重复定义。 引用[1]和[3]指出,yylloc变量在dtc-lexer.lex.c_shipped和dtc-parser.tab.c_shipped两个文件中都有定义,导致编译时重复。解决方案是确保只有一个地方定义该变量,其他地方使用extern声明。 具体步骤: 1. 进入内核或U-Boot源码目录下的scripts/dtc子目录。 2. 修改dtc-lexer.lex.c_shipped文件:在其中将yylloc作为实际变量定义(通常这个文件中的定义是有效的,保留)。 3. 修改dtc-parser.tab.c_shipped文件:找到yylloc的定义(可能是`YYLTYPE yylloc;`),将其改为`extern YYLTYPE yylloc;`,这样它就只是一个声明而不是定义。 4. 注意:引用[3]特别提醒不要修改dtc-parser.tab.c,因为它会在编译过程中被重新生成(从_shipped文件生成),所以修改_shipped文件才是根本。 另外,引用[2]提到的问题和解决方法类似,同样适用于U-Boot编译。 因此,解决步骤总结如下: 步骤1:打开文件 使用文本编辑器(如vim或vscode)打开以下两个文件(假设在内核源码根目录下): - `scripts/dtc/dtc-lexer.lex.c_shipped` - `scripts/dtc/dtc-parser.tab.c_shipped` 步骤2:修改lexer文件(保留定义) 在`dtc-lexer.lex.c_shipped`中,搜索`yylloc`,应该会看到类似这样的定义: YYLTYPE yylloc; 我们保留这个定义不变。 步骤3:修改parser文件(改为extern声明) 在`dtc-parser.tab.c_shipped`中,搜索`yylloc`,找到类似这样的行: YYLTYPE yylloc; 将其修改为: extern YYLTYPE yylloc; 步骤4:保存文件并重新编译。 注意:如果还有其他文件包含yylloc的定义,同样需要将其改为extern声明。但根据引用内容,主要就是这两个文件。 这个错误的原因是yylloc在多个编译单元中被定义(即多个.o文件都包含该变量的定义),而C语言要求全局变量只能定义一次(可以在多个地方声明)。通过将除一个定义外的其他定义改为声明,即可解决重复定义问题。 引用[1]还提到“其他组合方式可能无效”,所以按照上述步骤操作。 如果问题依旧,可以尝试清理编译中间文件(如执行`make clean`或`make distclean`)再重新编译。 根据引用[4]的编译脚本,通常编译内核的步骤是: make distclean make defconfig make menuconfig # 可选 make -jN # N为并行编译数 在修改了上述文件后,重新执行编译命令。 注意:如果使用的是U-Boot,步骤类似,但可能路径和编译命令稍有不同。 总结:修改两个_shipped文件,保留lexer中的定义,将parser中的定义改为extern声明,然后重新编译。 </think> ### 解决 `multiple definition of 'yylloc'` 编译错误 该错误通常发生在编译 Linux 内核或 U-Boot 时,由 `scripts/dtc` 目录下的文件变量重复定义引起。以下是已验证的解决方案: #### 解决步骤 1. **定位关键文件** 打开内核/U-Boot 源码目录中的以下文件: - `scripts/dtc/dtc-lexer.lex.c_shipped` - `scripts/dtc/dtc-parser.tab.c_shipped` 2. **修改变量声明** - 在 `dtc-lexer.lex.c_shipped` 中保留 `yylloc` 的原始定义(通常为 `YYLTYPE yylloc;`) - 在 `dtc-parser.tab.c_shipped` 中搜索 `yylloc`,将其定义修改为外部引用: ```c extern YYLTYPE yylloc; // 原内容 "YYLTYPE yylloc;" 替换为此 ``` *注:直接修改 `.c` 文件无效,因编译时会从 `_shipped` 文件重新生成[^3]* 3. **清理并重新编译** ```bash make distclean # 彻底清理 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_defconfig # 示例配置 make -j$(nproc) # 重新编译 ``` #### 原因说明 错误源于 `yylloc` 变量在多个目标文件中被重复定义: - `dtc-lexer.lex.o` 首先定义了 `yylloc` - `dtc-parser.tab.o` 尝试重复定义导致冲突 通过 `extern` 声明使后者引用前者的定义,消除重复[^1][^3]。 #### 注意事项 - 确保修改的是 `*_shipped` 源文件而非中间生成文件 - ARM 架构需指定交叉编译链(如 `CROSS_COMPILE=arm-linux-gnueabihf-`) - 此方案适用于 Linux 内核和 U-Boot 的同类错误[^2][^4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值