You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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文件)都定义了同名全局变量,链接时就会冲突。

具体修复步骤

  1. 修改msb.c中的全局变量定义
    打开msb.c,找到这三个全局变量的定义(类似int msb_parities;的代码),将它们改为外部声明:

    extern int msb_parities;
    extern int msb_lrc_flags;
    extern int msb_std_track_map[];
    

    这样msb.c就不会再定义这些变量,而是引用库中已经定义的版本。

  2. 确保库中的变量定义唯一
    检查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[...]; // 填写原代码中的数组长度
      
  3. 处理optarg相关警告
    报错中的optarg、optind、optopt重复声明警告,是因为msb.c手动声明了这些变量,但它们已经在<unistd.h>中定义。解决办法:

    • 删除msb.c第94、95行的手动声明
    • 在msb.c开头添加头文件包含:#include <unistd.h>
  4. 重新编译
    先执行make clean清理旧的目标文件和库,再运行make重新编译。

额外优化建议

  • 避免在Makefile中使用libmsb-*/通配符,直接写具体目录名(如libmsb-0.2),防止目录结构变化导致编译出错。
  • 编译库时添加-fPIC参数($(CC) -c -fPIC msb_std.c -o msb_std.o),生成位置无关代码,提升兼容性。

内容的提问来源于stack exchange,提问作者O'Neil Lawrence

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 02:54:25