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

多main函数引发Makefile编译错误:如何生成两个独立可执行文件?

解决Makefile中"multiple definition of `main'"错误并生成独立可执行文件

你的问题核心在于当前Makefile让每个可执行文件都链接了所有的目标文件——因为你的两个源文件都包含main函数,链接时把所有.o文件打包到一起,自然就会出现重复定义的错误。下面我会帮你修正Makefile,同时满足将可执行文件输出到./bld目录的需求。

问题分析

看你当前的Makefile规则:

$(TARGET): $(OBJECTS)
	$(CC) $(CFLAGS) $^ -o $@

这里$(TARGET)是两个可执行文件(比如bld/prog1和bld/prog2),而$(OBJECTS)是所有.c文件编译出的.o文件。这意味着每个可执行文件都会尝试链接所有目标文件,包括两个包含main的.o,所以链接器报错。

修正后的Makefile

假设你的两个主程序源文件是prog1.c、prog2.c,共享的函数定义文件是common.c(你可以根据实际文件名修改),修正后的Makefile如下:

CC := gcc
CFLAGS := -g -Wall -Werror
RM := rm
MKDIR := mkdir -p
OUT_DIR := bld
OBJ_DIR := $(OUT_DIR)/obj

# 1. 明确指定包含main的主程序源文件
MAIN_SRCS := prog1.c prog2.c
# 2. 指定共享的源文件(不包含main)
COMMON_SRCS := common.c

# 生成对应的目标文件路径
MAIN_OBJS := $(addprefix $(OBJ_DIR)/, $(MAIN_SRCS:.c=.o))
COMMON_OBJS := $(addprefix $(OBJ_DIR)/, $(COMMON_SRCS:.c=.o))

# 最终的可执行文件路径
TARGETS := $(addprefix $(OUT_DIR)/, $(MAIN_SRCS:.c=))

.PHONY: all clean
all: $(TARGETS)

clean:
	$(RM) -rf $(OUT_DIR)

# 3. 每个可执行文件只链接自己的main目标文件 + 共享目标文件
$(OUT_DIR)/%: $(OBJ_DIR)/%.o $(COMMON_OBJS)
	@$(MKDIR) $(dir $@)
	$(CC) $(CFLAGS) $^ -o $@

$(OBJ_DIR)/%.o: %.c
	@$(MKDIR) $(dir $@)
	$(CC) $(CFLAGS) -c $< -o $@

关键修改说明

  • 拆分源文件:把带main的入口文件和共享代码文件分开定义,避免混淆。如果你的主程序文件有命名规律(比如以_main.c结尾),也可以用自动匹配:
    MAIN_SRCS := $(filter %_main.c, $(wildcard *.c))
    COMMON_SRCS := $(filter-out $(MAIN_SRCS), $(wildcard *.c))
    
    但手动指定MAIN_SRCS更可靠,防止误把其他文件当成入口。
  • 调整依赖规则:新的$(OUT_DIR)/%规则让每个可执行文件只依赖自己对应的.o文件加上共享的.o文件,这样每个可执行文件只会包含一个main函数,解决重复定义问题。
  • 保留目录结构:依然会自动创建bld和bld/obj目录,所有目标文件存在bld/obj,可执行文件输出到bld根目录,符合你的需求。

验证

运行make后,你会在./bld目录下看到两个独立的可执行文件,分别对应你的两个main函数源文件,链接时不会再出现重复定义错误。

内容的提问来源于stack exchange,提问作者RErik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:28:27