编译C程序遇main()及argp相关多重定义错误求助
问题分析与解决
问题根源
编译出现的multiple definition错误,核心原因是Makefile的编译规则写错了:
你定义的$(OBJ): $(SRC)规则会让所有目标文件(obj/cshot.o和obj/screenshot.o)都使用第一个源文件(src/cshot.c)编译。这导致screenshot.o实际是cshot.c的编译产物,里面包含了main函数和argp相关全局变量,最终链接时和真正的cshot.o出现重复定义冲突。
修正后的Makefile
TARGET = cshot CC = gcc SRC_PATH = src/ OBJ_PATH = obj/ SRC = $(wildcard $(SRC_PATH)*.c) OBJ = $(patsubst $(SRC_PATH)%.c, $(OBJ_PATH)%.o, $(SRC)) FLAGS = -Wall -g -O3 LINK = -lX11 $(TARGET): $(OBJ) $(CC) $(FLAGS) $(LINK) $(OBJ) -o $(TARGET) # 模式规则:每个.o文件对应同名的.c源文件 $(OBJ_PATH)%.o: $(SRC_PATH)%.c # 编译阶段无需链接库,移除$(LINK)参数 $(CC) -c $(FLAGS) $< -o $@ clean: rm -f $(OBJ_PATH)*.o rm -f $(TARGET)
关键修改说明
- 替换原错误规则为模式规则
$(OBJ_PATH)%.o: $(SRC_PATH)%.c,确保每个目标文件对应正确的源文件 - 编译阶段(带
-c参数)不需要添加链接库参数$(LINK),链接库仅在最终生成可执行程序时使用 - 清理命令添加
-f参数,避免文件不存在时触发报错
原文件代码与错误信息
原代码文件
cshot.c
#include <stdio.h> #include <argp.h> #include "screenshot.h" int main(int argc, char **argv) { ... }
screenshot.h
#ifndef SCREENSHOT_H #define SCREENSHOT_H #include <X11/Xlib.h> extern char *err_log; int take_screenshot(char *path); #endif
screenshot.c
#include <X11/Xlib.h> #include "screenshot.h" int take_screenshot(char *path) { ... }
编译错误信息
obj/screenshot.o: in function `main': ... multiple definition of `main'; multiple definition of `argp_program_bug_address'; obj/cshot.o:/usr/include/argp.h:401: first defined here /usr/lib/gcc/x86_64-pc-linux-gnu/11.3.0/../../../../x86_64-pc-linux-gnu/bin/ld: obj/screenshot.o:/usr/include/argp.h:385: multiple definition of `argp_program_version'; obj/cshot.o:/usr/include/argp.h:385: first defined here
内容的提问来源于stack exchange,提问作者floatfoo
相关产品推荐
相关产品推荐

