Cygwin环境下Make编译出现多重定义错误求助
Cygwin环境下编译msb项目时遇到多重定义链接错误
我是Makefile新手,在Cygwin环境编译msb项目时碰到了链接错误,具体信息和相关文件内容如下:
项目根目录Makefile内容
CC=gcc default: msb doc lib: libmsb-* cd libmsb-*/ && make -f Makefile.in msb: lib msb.c $(CC) msb.c -o msb -I libmsb-*/ -L libmsb-*/ -l msb install: msb install -s msb -t $(DESTDIR)/bin/ doc: msb.1 groff -Tlatin1 -man msb.1 | col -b > msb.1.txt cleanup: rm -f libmsb-*/*.o libmsb-*/*.a clean: cleanup rm -f msb rm -f msb.1.txt
运行make后的错误输出
cd libmsb-*/ && make -f Makefile.in make[1]: Entering directory 'C:/Users/****/Desktop/msb-0.1/libmsb-0.2' make[1]: 'libmsb.a' is up to date. make[1]: Leaving directory 'C:/Users/****/Desktop/msb-0.1/libmsb-0.2' gcc msb.c -o msb -I libmsb-*/ -L libmsb-*/ -l msb msb.c: In function ‘main’: msb.c:94:19: warning: ‘optarg’ redeclared without dllimport attribute: previous dllimport ignored [-Wattributes] 94 | extern char * optarg; | ^~~~~~ msb.c:95:16: warning: ‘optind’ redeclared without dllimport attribute: previous dllimport ignored [-Wattributes] 95 | extern int optind, optopt; | ^~~~~~ msb.c:95:24: warning: ‘optopt’ redeclared without dllimport attribute: previous dllimport ignored [-Wattributes] 95 | extern int optind, optopt; | ^~~~~~ /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: libmsb-0.2//libmsb.a(msb_std.o):msb_std.c:(.bss+0x0): multiple definition of `msb_parities'; /tmp/cch7E9uN.o:msb.c:(.bss+0x0): first defined here /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: libmsb-0.2//libmsb.a(msb_std.o):msb_std.c:(.bss+0x4): multiple definition of `msb_lrc_flags'; /tmp/cch7E9uN.o:msb.c:(.bss+0x4): first defined here /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: libmsb-0.2//libmsb.a(msb_std.o):msb_std.c:(.bss+0x8): multiple definition of `msb_std_track_map'; /tmp/cch7E9uN.o:msb.c:(.bss+0x8): first defined here /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: libmsb-0.2//libmsb.a(msb_encode.o):msb_encode.c:(.bss+0x0): multiple definition of `msb_parities'; /tmp/cch7E9uN.o:msb.c:(.bss+0x0): first defined here /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: libmsb-0.2//libmsb.a(msb_encode.o):msb_encode.c:(.bss+0x4): multiple definition of `msb_lrc_flags'; /tmp/cch7E9uN.o:msb.c:(.bss+0x4): first defined here /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: libmsb-0.2//libmsb.a(msb_encode.o):msb_encode.c:(.bss+0x8): multiple definition of `msb_std_track_map'; /tmp/cch7E9uN.o:msb.c:(.bss+0x8): first defined here /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: libmsb-0.2//libmsb.a(msb_decode.o):msb_decode.c:(.bss+0x0): multiple definition of `msb_parities'; /tmp/cch7E9uN.o:msb.c:(.bss+0x0): first defined here /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: libmsb-0.2//libmsb.a(msb_decode.o):msb_decode.c:(.bss+0x4): multiple definition of `msb_lrc_flags'; /tmp/cch7E9uN.o:msb.c:(.bss+0x4): first defined here /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: libmsb-0.2//libmsb.a(msb_decode.o):msb_decode.c:(.bss+0x8): multiple definition of `msb_std_track_map'; /tmp/cch7E9uN.o:msb.c:(.bss+0x8): first defined here /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: libmsb-0.2//libmsb.a(msb_7811.o):msb_7811.c:(.bss+0x0): multiple definition of `msb_parities'; /tmp/cch7E9uN.o:msb.c:(.bss+0x0): first defined here /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: libmsb-0.2//libmsb.a(msb_7811.o):msb_7811.c:(.bss+0x4): multiple definition of `msb_lrc_flags'; /tmp/cch7E9uN.o:msb.c:(.bss+0x4): first defined here /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: libmsb-0.2//libmsb.a(msb_7811.o):msb_7811.c:(.bss+0x8): multiple definition of `msb_std_track_map'; /tmp/cch7E9uN.o:msb.c:(.bss+0x8): first defined here collect2: error: ld returned 1 exit status make: *** [Makefile:6: msb] Error 1
libmsb子目录Makefile.in内容
libmsb.a: msb_common.h msb_std.h msb_encode.h msb_decode.h msb_7811.h\ msb_std.c msb_encode.c msb_decode.c msb_7811.c $(CC) -c msb_std.c -o msb_std.o $(CC) -c msb_encode.c -o msb_encode.o $(CC) -c msb_decode.c -o msb_decode.o $(CC) -c msb_7811.c -o msb_7811.o ar crs libmsb.a msb_std.o msb_encode.o msb_decode.o msb_7811.o
问题分析与解决办法
核心问题
链接器报错的multiple definition是因为全局变量msb_parities、msb_lrc_flags、msb_std_track_map在msb.c和库文件libmsb.a的多个目标文件中都被定义了。这是C语言中典型的全局变量重复定义问题——当多个编译单元(.o文件)都定义了同名全局变量,链接时就会冲突。
具体修复步骤
修改msb.c中的全局变量定义
打开msb.c,找到这三个全局变量的定义(类似int msb_parities;的代码),将它们改为外部声明:extern int msb_parities; extern int msb_lrc_flags; extern int msb_std_track_map[];这样
msb.c就不会再定义这些变量,而是引用库中已经定义的版本。确保库中的变量定义唯一
检查libmsb-0.2目录下的头文件(如msb_std.h),如果这些变量在头文件中被定义(而非声明),需要修改为带extern的声明,然后在对应的.c文件(如msb_std.c)中保留唯一的定义。
示例:- 头文件中改为:
extern int msb_parities; extern int msb_lrc_flags; extern int msb_std_track_map[]; - 在
msb_std.c中保留:int msb_parities; int msb_lrc_flags; int msb_std_track_map[...]; // 填写原代码中的数组长度
- 头文件中改为:
处理optarg相关警告
报错中的optarg、optind、optopt重复声明警告,是因为msb.c手动声明了这些变量,但它们已经在<unistd.h>中定义。解决办法:- 删除
msb.c第94、95行的手动声明 - 在
msb.c开头添加头文件包含:#include <unistd.h>
- 删除
重新编译
先执行make clean清理旧的目标文件和库,再运行make重新编译。
额外优化建议
- 避免在Makefile中使用
libmsb-*/通配符,直接写具体目录名(如libmsb-0.2),防止目录结构变化导致编译出错。 - 编译库时添加
-fPIC参数($(CC) -c -fPIC msb_std.c -o msb_std.o),生成位置无关代码,提升兼容性。
内容的提问来源于stack exchange,提问作者O'Neil Lawrence
相关产品推荐
相关产品推荐

