Makefile链接阶段出现全局变量重定义错误的解决求助
问题描述
编译生成目标文件时一切正常,但链接Test.c生成可执行文件Test的阶段,出现全局变量重定义错误,示例错误如下:
D:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: ./lib/AUretim.o:AUretim.c:(.bss+0x0): multiple definition of `URETIM'; ./lib/Uretim.o:Uretim.c:(.bss+0x0): first defined here
相关代码如下:
Makefile代码
ALL: Compile Execute Compile: gcc -I ./include/ -o ./lib/Uretim.o -c ./src/Uretim.c gcc -I ./include/ -o ./lib/AUretim.o -c ./src/AUretim.c gcc -I ./include/ -o ./lib/BUretim.o -c ./src/BUretim.c gcc -I ./include/ -o ./lib/Taktik.o -c ./src/Taktik.c gcc -I ./include/ -o ./lib/Ataktik.o -c ./src/Ataktik.c gcc -I ./include/ -o ./lib/Btaktik.o -c ./src/Btaktik.c gcc -I ./include/ -o ./lib/Koloni.o -c ./src/Koloni.c gcc -I ./include/ -o ./lib/Oyun.o -c ./src/Oyun.c @echo :"denem" gcc -I ./include/ -o ./bin/Test ./lib/Uretim.o ./lib/AUretim.o ./lib/BUretim.o ./lib/Taktik.o ./lib/Ataktik.o ./lib/Btaktik.o ./lib/Koloni.o ./lib/Oyun.o ./src/Test.c @echo :"denem" Execute: ./bin/Test
Uretim.h代码
#ifndef URETIM_H #define URETIM_H struct URETIM { int deger; void (*degerdegistirU)(struct URETIM *,int ); int (*Uret)(struct URETIM *); void (*yoketU)(struct URETIM *); int (*degerdondurU)(); }URETIM; typedef struct URETIM *Uretim; #endif
AUretim.h代码
#ifndef AURETIM_H #define AURETIM_H #include "Uretim.h" struct AURETIM { struct URETIM * super; int (*degerDondurUA)(struct AURETIM *); void (*AyoketU)(struct AURETIM *); }AURETIM; typedef struct AURETIM *Auretim; #endif
Koloni.h代码
#ifndef KOLONI_H #define KOLONI_H #include "ATaktik.h" #include "BTaktik.h" #include "AUretim.h" #include "BUretim.h" struct KOLONI { ATaktik atak; BTaktik batak; Auretim auret; Buretim BUret; int (* stokgetir)(struct KOLONI *); int ( * populasyongetir)(struct KOLONI *); char (*sembolgetir)(struct KOLONI *); void (*Uretimyap)(struct KOLONI *); int (*Savasyap)(struct KOLONI *,struct KOLONI *); void (*Populasyonduzenle)(struct KOLONI *,int); void (*stokDuzenle)(struct KOLONI *,int); }KOLONI; typedef struct KOLONI *Koloni; #endif
Oyun.h代码
#ifndef OYUN_H #define OYUN_H #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #include<time.h> #include "Koloni.h" struct OYUN { void (*kolonisavasi)(struct KOLONI *,struct KOLONI *); }OYUN; typedef struct OYUN *Oyun; // typedef struct KOLONI *Koloni; Oyun oyunolustur(); #endif
问题原因
- 头文件中直接定义了全局变量(如
URETIM、AURETIM、KOLONI、OYUN这些结构体实例),而头文件会被多个源文件(.c)包含。 - 每个包含该头文件的.c文件在编译时,都会生成一个该变量的独立副本。链接阶段,链接器发现多个同名全局变量,因此抛出「multiple definition」错误。
修复方案
核心原则:头文件仅做变量声明,变量定义放到对应的.c文件中
1. 修改所有存在问题的头文件
在头文件中用extern关键字声明变量,而非直接定义:
修改后的Uretim.h
#ifndef URETIM_H #define URETIM_H struct URETIM { int deger; void (*degerdegistirU)(struct URETIM *,int ); int (*Uret)(struct URETIM *); void (*yoketU)(struct URETIM *); int (*degerdondurU)(); }; typedef struct URETIM *Uretim; extern struct URETIM URETIM; // 仅声明,不定义 #endif
修改后的AUretim.h
#ifndef AURETIM_H #define AURETIM_H #include "Uretim.h" struct AURETIM { struct URETIM * super; int (*degerDondurUA)(struct AURETIM *); void (*AyoketU)(struct AURETIM *); }; typedef struct AURETIM *Auretim; extern struct AURETIM AURETIM; // 仅声明,不定义 #endif
修改后的Koloni.h
#ifndef KOLONI_H #define KOLONI_H #include "ATaktik.h" #include "BTaktik.h" #include "AUretim.h" #include "BUretim.h" struct KOLONI { ATaktik atak; BTaktik batak; Auretim auret; Buretim BUret; int (* stokgetir)(struct KOLONI *); int ( * populasyongetir)(struct KOLONI *); char (*sembolgetir)(struct KOLONI *); void (*Uretimyap)(struct KOLONI *); int (*Savasyap)(struct KOLONI *,struct KOLONI *); void (*Populasyonduzenle)(struct KOLONI *,int); void (*stokDuzenle)(struct KOLONI *,int); }; typedef struct KOLONI *Koloni; extern struct KOLONI KOLONI; // 仅声明,不定义 #endif
修改后的Oyun.h
#ifndef OYUN_H #define OYUN_H #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #include<time.h> #include "Koloni.h" struct OYUN { void (*kolonisavasi)(struct KOLONI *,struct KOLONI *); }; typedef struct OYUN *Oyun; extern struct OYUN OYUN; // 仅声明,不定义 Oyun oyunolustur(); #endif
2. 在对应的.c文件中添加变量定义
把原来头文件里的变量定义移到各自的.c文件末尾:
- 在
Uretim.c中添加:struct URETIM URETIM; - 在
AUretim.c中添加:struct AURETIM AURETIM; - 在
Koloni.c中添加:struct KOLONI KOLONI; - 在
Oyun.c中添加:struct OYUN OYUN;
3. 验证修复
重新执行Makefile,链接阶段将不再出现重定义错误。
内容的提问来源于stack exchange,提问作者goOdyaga
相关产品推荐
相关产品推荐

