多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
相关产品推荐
相关产品推荐

