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

编写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变量,后续链接会触发多重定义错误,需要提前修正:

  1. 在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_ */
  1. 在任意一个.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 04:43:44