Resolving the 'multiple definition of yylloc' Error 1 2 3 The multiple definition of 'yylloc' error occurs during the compilation process, typically when building the Linux kernel or related projects. This error indicates that the yylloc symbol is defined in multiple places, causing a conflict. Example /usr/bin/ld: scripts/dtc/dtc-parser.tab.o:(.bss+0x10): multiple definition of 'yylloc'; scripts/dtc/dtc-lexer.lex.o:(.bss+0x0): first defined here collect2: error: ld returned 1 exit status Solution 1: Modify Source Code One common solution is to modify the source code to declare yylloc as an external variable 1 . Steps: Open the file scripts/dtc/dtc-lexer.lex.c. Find the line YYLTYPE yylloc;. Change it to extern YYLTYPE yylloc;. Example: // Original line YYLTYPE yylloc; // Modified line extern YYLTYPE yylloc; Solution 2: Use an Older GCC Version The error can also be caused by using a newer version of GCC (e.g., GCC 10 or later). Downgrading to an older version like GCC 9 can resolve the issue 2 . Steps: Install GCC 9. Set it as the default compiler. Example: sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 9 Solution 3: Clean and Rebuild Sometimes, old object files can cause this issue. Cleaning the build directory and rebuilding can help 3 . Steps: Clean the build directory. Rebuild the project. Example: make clean make By following these steps, you can resolve the multiple definition of 'yylloc' error and successfully compile your project. Learn more 1 github.com 2 blog.csdn.net 3 github.com
时间: 2025-04-05 11:05:12 浏览: 92
<think>好的,我现在需要帮助用户解决编译时出现的“multiple definition of 'yylloc'”错误。用户之前已经询问过类似的问题,现在又提供了一个包含解决方案的模板,并希望得到进一步的解释或确认。
首先,我要回顾之前的对话。用户最初提供的错误信息显示在编译Linux内核或相关项目时,链接器发现了yylloc符号的重复定义。我之前的回答给出了三个解决方案:修改源代码声明为外部变量、使用-fcommon编译选项、更新dtc工具或清理重建。现在用户的新内容提到了三种方法:修改源代码、使用旧版GCC、清理重建,并列出了具体步骤。
接下来,我需要比较用户提供的解决方案和我之前的回答是否有差异。用户提到的第二种解决方案是降级GCC版本,而我在之前提到的是使用-fcommon选项。这可能是因为不同版本的GCC默认行为不同,比如GCC 10之后不再默认使用-fcommon,导致符号重复定义错误更容易出现。因此,用户可能从其他资料中找到了降级GCC的方法,这也是合理的。
现在,我需要整合这些信息,验证每个方法的正确性,并确保提供的步骤准确有效。同时,要注意用户可能的疑问点,比如如何正确修改源代码,或者降级GCC的具体步骤是否适用不同Linux发行版。
另外,用户提供的示例中修改dtc-lexer.lex.c文件中的yylloc声明为extern,这需要确认该文件是否由Flex生成,如果是,直接修改生成的文件可能不够持久,因为重新生成时会被覆盖。正确的方法应该是修改.l或.y源文件,然后重新生成.c文件,这在我的之前的回答中已经提到,但用户提供的解决方案可能没有说明这一点,需要指出以避免用户困惑。
用户提到的第三种方法是清理和重建,这通常是有效的,但有时候可能需要更彻底的清理,比如make mrproper,而不仅仅是make clean。这也需要补充说明。
最后,需要评估哪种方法最推荐。通常,修改源代码(正确的位置,即.l和.y文件)是最根本的解决方案,而使用旧版GCC可能只是临时规避问题。此外,GCC的-fcommon选项也是一个快速的解决方法,可能比降级编译器更方便。
在组织回答时,应该结构清晰,分点说明每个解决方案的步骤、原理和注意事项,并指出推荐的方法。同时,提醒用户如果问题仍然存在,需要提供更多环境信息以便进一步排查。</think>以下是针对编译过程中出现 **`multiple definition of 'yylloc'`** 错误的深度解析及解决方案:
---
### **错误本质**
- **`yylloc`** 是 Flex/Bison 工具链生成的**词法分析器与语法分析器共享的全局变量**,用于记录词法解析的位置信息(如行号、列号)。
- **错误触发原因**:Flex 生成的 `dtc-lexer.lex.c` 和 Bison 生成的 `dtc-parser.tab.c` 中重复定义了 `yylloc` 变量,导致链接器(`ld`)发现同一符号的多次定义。
---
### **解决方案详解**
#### **方法1:修改源码声明(根本性修复)**
**适用场景**:需长期解决符号冲突问题
**步骤**:
1. **修改词法分析器源文件(`.l` 文件)**:
在 `dtc-lexer.l` 的头部声明 `yylloc` 为外部变量(`extern`):
```c
%{
#include "dtc-parser.tab.h" // 包含语法分析器生成的头文件
extern YYLTYPE yylloc; // 声明 yylloc 为外部变量
%}
```
2. **修改语法分析器源文件(`.y` 文件)**:
在 `dtc-parser.y` 中通过 `%code requires` 声明 `yylloc`:
```c
%code requires {
YYLTYPE yylloc; // 显式定义 yylloc
}
```
3. **重新生成解析器代码**:
执行 `make clean` 后重新编译,确保 Flex/Bison 生成新的 `.lex.c` 和 `.tab.c` 文件。
**关键点**:
- 需确保词法分析器(Flex)**不重复定义** `yylloc`,而是引用语法分析器(Bison)中定义的变量。
- **不推荐直接修改生成的 `.lex.c` 或 `.tab.c` 文件**(重新生成时会被覆盖)。
---
#### **方法2:调整编译器行为(快速临时修复)**
**适用场景**:紧急绕过错误,不修改源码
**原理**:通过 `-fcommon` 选项允许 GCC 将重复符号视为公共符号(common symbol),避免链接冲突。
**步骤**:
在编译命令或 Makefile 中添加 `-fcommon` 选项:
```bash
# 示例:修改 dtc 的编译规则
CFLAGS += -fcommon
```
**注意**:此方法适用于 **GCC 10+**(默认启用 `-fno-common`),可能掩盖潜在代码问题。
---
#### **方法3:降级 GCC 版本(兼容性修复)**
**适用场景**:工具链版本冲突
**步骤**(以 Ubuntu 为例):
1. 安装 GCC 9:
```bash
sudo apt install gcc-9 g++-9
```
2. 切换默认编译器:
```bash
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 90
```
**注意**:降级 GCC 可能影响其他项目,建议仅在隔离环境中使用。
---
#### **方法4:清理并重建(排除缓存干扰)**
**适用场景**:旧对象文件残留导致冲突
**步骤**:
```bash
make clean # 清理常规生成文件
make mrproper # 深度清理内核编译环境(包括配置)
make scripts/dtc # 重新编译 dtc 工具
```
---
### **技术背景**
- **Flex/Bison 协作**:Flex 生成词法分析器,Bison 生成语法分析器,两者通过 `yylloc` 共享位置信息。
- **符号重复定义**:若双方均未声明 `extern`,则各自生成独立的 `yylloc` 定义,导致链接错误。
- **GCC 行为变化**:GCC 10 起默认使用 `-fno-common`,严格禁止重复符号,旧版代码更易暴露此问题。
---
### **推荐方案优先级**
1. **修改源码声明**(方法1) > 2. **添加 `-fcommon`**(方法2) > 3. **清理重建**(方法4) > 4. **降级 GCC**(方法3)
- **长期项目**:优先使用方法1,确保代码规范性。
- **快速修复**:使用方法2或方法4。
- **环境限制**:若无法修改代码且 GCC 版本不可调,考虑容器化编译环境。
---
若问题仍未解决,请提供以下信息进一步分析:
1. 操作系统及发行版(如 `Ubuntu 22.04`)
2. Flex/Bison 版本(`flex --version` / `bison --version`)
3. 完整的编译日志(`make V=1` 输出)
阅读全文
相关推荐














