编写Makefile编译双源文件程序时遇未定义引用错误求助
编译时出现"func未定义引用"的错误原因及修复方案
一、直接错误原因:Makefile编译规则缺少-c参数
从编译输出能看到,执行的命令是gcc -Wall -std=c99 main.c——这是直接把main.c编译并链接成可执行文件,但此时func.c还未被编译,链接器找不到func函数的实现,因此抛出"未定义引用"错误。
问题出在Makefile的.c.o规则:
.c.o: $(CC) $(CFLAGS) $<
gcc默认只传入源文件时,会直接执行编译+链接流程生成可执行文件,而非目标文件(.o)。必须添加-c参数,明确告诉gcc只编译不链接,生成对应的目标文件。
二、修复后的Makefile
将.c.o规则修改为:
.c.o: $(CC) $(CFLAGS) -c $<
修改后,make会分别编译main.c和func.c生成main.o、func.o,最后链接阶段将两个目标文件合并成app_test,就能找到func的定义。
三、潜在问题:全局结构体的重复定义
当前data.h直接定义了test_cfg结构体变量:
struct { int a1; int b1; int c1; } test_cfg;
当main.c和func.c都包含data.h时,每个源文件都会生成独立的test_cfg变量,后续链接会触发多重定义错误,需要提前修正:
- 在
data.h中用extern声明变量:
#ifndef _DATA_H_ #define _DATA_H_ struct cfg_struct { int a1; int b1; int c1; }; extern struct cfg_struct test_cfg; int func(void); #endif /* end of _DATA_H_ */
- 在任意一个.c文件(比如
func.c)中定义变量:
#include <stdio.h> #include <stdlib.h> #include "data.h" // 定义全局变量 struct cfg_struct test_cfg; int func(void) { test_cfg.b1 = 12; printf("test_cfg.b1 = %d\n", test_cfg.b1); return 0; }
这样两个源文件会共享同一个test_cfg变量,避免重复定义问题。
四、验证修复效果
修改后执行make,会依次完成编译、链接流程,运行生成的app_test会输出:
test_cfg.a1 = 1 test_cfg.b1 = 12
内容的提问来源于stack exchange,提问作者Cprogrammer
相关产品推荐
相关产品推荐

