编译含mksquashfs的项目时遇multiple definition链接错误求解决
编译mksquashfs时的"multiple definition"链接错误解决方法
错误现象
编译包含mksquashfs的项目时出现链接错误,具体报错如下:
/usr/bin/ld: read_fs.o:(.bss+0x0): multiple definition of `fwriter_buffer'; mksquashfs.o:(.bss+0x400c90): first defined here /usr/bin/ld: read_fs.o:(.bss+0x8): multiple definition of `bwriter_buffer'; mksquashfs.o:(.bss+0x400c98): first defined here /usr/bin/ld: action.o:(.bss+0x0): multiple definition of `fwriter_buffer'; mksquashfs.o:(.bss+0x400c90): first defined here /usr/bin/ld: action.o:(.bss+0x8): multiple definition of `bwriter_buffer'; mksquashfs.o:(.bss+0x400c98): first defined here /usr/bin/ld: sort.o:(.bss+0x100000): multiple definition of `fwriter_buffer'; mksquashfs.o:(.bss+0x400c90): first defined here /usr/bin/ld: sort.o:(.bss+0x100008): multiple definition of `bwriter_buffer'; mksquashfs.o:(.bss+0x400c98): first defined here /usr/bin/ld: info.o:(.bss+0x10): multiple definition of `bwriter_buffer'; mksquashfs.o:(.bss+0x400c98): first defined here /usr/bin/ld: info.o:(.bss+0x8): multiple definition of `fwriter_buffer'; mksquashfs.o:(.bss+0x400c90): first defined here /usr/bin/ld: restore.o:(.bss+0x0): multiple definition of `fwriter_buffer'; mksquashfs.o:(.bss+0x400c90): first defined here /usr/bin/ld: restore.o:(.bss+0x8): multiple definition of `bwriter_buffer'; mksquashfs.o:(.bss+0x400c98): first defined here /usr/bin/ld: process_fragments.o:(.bss+0x0): multiple definition of `fwriter_buffer'; mksquashfs.o:(.bss+0x400c90): first defined here /usr/bin/ld: process_fragments.o:(.bss+0x8): multiple definition of `bwriter_buffer'; mksquashfs.o:(.bss+0x400c98): first defined here /usr/bin/ld: xattr.o:(.bss+0x8): multiple definition of `fwriter_buffer'; mksquashfs.o:(.bss+0x400c90): first defined here /usr/bin/ld: xattr.o:(.bss+0x10): multiple definition of `bwriter_buffer'; mksquashfs.o:(.bss+0x400c98): first defined here collect2: error: ld returned 1 exit status make[3]: *** [Makefile:284: mksquashfs] Error 1 make[3]: *** Waiting for unfinished jobs....
经排查,fwriter_buffer和bwriter_buffer变量在多个目标文件(mksquashfs.o、read_fs.o、action.o等)中被重复定义。
编译环境:Linux系统,使用riscv64-unknown-linux-gnu-gcc 13.2.0,构建工具为make。
解决步骤
1. 定位变量定义位置
先找到这两个变量的定义文件,大概率是某个头文件中直接定义了变量(如char fwriter_buffer[...];),多个.c文件包含该头文件后,每个编译单元都生成了一份变量定义,最终导致链接冲突。
2. 修改变量作用域或声明方式
- 方法一:用
static限制作用域
如果变量不需要跨编译单元共享,直接在定义前添加static关键字,让变量仅在当前编译单元可见:
static char fwriter_buffer[BUFFER_SIZE]; static char bwriter_buffer[BUFFER_SIZE];
每个.c文件中的变量会成为独立副本,不会引发链接冲突。
- 方法二:头文件声明+单文件定义
如果变量需要跨编译单元共享:
- 在头文件中用
extern声明变量(不分配内存),同时添加头文件保护防止重复包含:
#ifndef BUFFER_HEADERS_H #define BUFFER_HEADERS_H extern char fwriter_buffer[]; extern char bwriter_buffer[]; #endif // BUFFER_HEADERS_H
- 在单个.c文件(如mksquashfs.c)中实际定义变量:
char fwriter_buffer[BUFFER_SIZE]; char bwriter_buffer[BUFFER_SIZE];
3. 调整编译选项(妥协方案)
若以上方法无效,可检查是否启用了-fcommon编译选项(GCC旧版本默认启用,新版本默认关闭)。若项目依赖该选项,可在Makefile中添加:
CFLAGS += -fcommon
此方法仅作临时修复,建议优先从代码层面规范变量定义。
避免此类冲突的最佳实践
- 变量定义与声明分离:头文件仅做
extern声明,变量实际定义放在单个.c文件中,配合头文件保护防止重复包含。 - 用
static约束非共享变量:仅在当前编译单元使用的变量,一律添加static,避免污染全局作用域。 - 禁止在头文件中定义变量:头文件只存放类型定义、宏、函数声明和
extern变量声明,绝不直接定义变量。 - 启用编译警告:添加
-Wall、-Wextra等警告选项,提前发现潜在的重复定义问题。 - 使用封装减少全局变量:大型项目可通过静态结构体、命名前缀等方式,降低全局变量名冲突概率。
内容的提问来源于stack exchange,提问作者Alphin Thomas
相关产品推荐
相关产品推荐

