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

编译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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:10:16