犯错误:多个定义...尽管包括警卫
Posted
技术标签:
【中文标题】犯错误:多个定义...尽管包括警卫【英文标题】:make error: multiple definitions of... despite include guard 【发布时间】:2015-06-29 12:10:52 【问题描述】:我的编译器给了我一些关于函数的多个定义(或者更确切地说是特定 .c 文件中的所有函数)的非常奇怪的错误。
我正在使用包含保护来防止多个声明
我的头文件不包含任何定义,只有声明。文件中没有定义变量,只有函数。
我仔细检查了:只有 .h 文件包含在其他文件中。 .c 文件不包含在任何地方。
我使用相同的方法来包含我的其余代码,我没有任何问题。因此,我不能给出我的问题的最小示例,因为我看不出正在工作的文件和导致编译器问题的文件之间没有(相关的)差异。
在 git 中合并两个分支后首先开始出现错误。两个分支中的每一个都在合并之前顺利编译。
目前,我很高兴有任何关于此问题可能来自何处的提示。
如果有人需要,我也会提供我的代码和/或错误日志。代码比较长,如果有需要请随时咨询
make 的错误信息是
错误信息
src/rhs.o: In function `calculate_rhs':
/home/user/Desktop/WS5/src/rhs.c:15: multiple definition of `calculate_rhs'
src/rhs.o:/home/user/Desktop/WS5/src/rhs.c:15: first defined here
src/rhs.o: In function `evaluate_rhs1':
/home/user/Desktop/WS5/src/rhs.c:103: multiple definition of `evaluate_rhs1'
src/rhs.o:/home/user/Desktop/WS5/src/rhs.c:103: first defined here
src/rhs.o: In function `evaluate_rhs2':
/home/user/Desktop/WS5/src/rhs.c:140: multiple definition of `evaluate_rhs2'
src/rhs.o:/home/user/Desktop/WS5/src/rhs.c:140: first defined here
collect2: error: ld returned 1 exit status
make: [exec] Error 1 (ignored)
rhs.o
的编译器命令是
/usr/lib/petscdir/3.6.0/arch-linux2-c-debug/bin/mpicc -o src/rhs.o -c -fPIC -Wall -Wwrite-strings -Wno-strict-aliasing -Wno-unknown-pragmas -g3 -O0 -std=c99 -I/usr/lib/petscdir/3.6.0/include -I/usr/lib/petscdir/3.6.0/arch-linux2-c-debug/include `pwd`/src/rhs.c
.h 文件在这里:http://pastebin.com/Za37iWr7
.c 文件在这里:http://pastebin.com/2mSzdZvT
.h 文件仅包含在上述 .c 文件和主函数中
所有其他包含(由 rhs.c)文件的标题是:
gauss.h:http://pastebin.com/QSaTMRhk global.h:http://pastebin.com/sMEkehWM eval.h:http://pastebin.com/QjJAGSdf indices.h:http://pastebin.com/jHvtnvQh生成文件: http://pastebin.com/LDj1e7xB
提前感谢:)
【问题讨论】:
不,请构造一个minimal test-case,并发布准确的错误消息。现在,我们没有什么可做的。 (另外,请先尝试清理,然后尝试重新构建。) 另一个注意事项:如果我正确解释了 git diff,那么合并引入的所有更改都与导致问题的文件无关.....我是在这里没有想法,非常感谢您的帮助。 @amdixon:对不起,它在私人服务器上的 gitlab repo 上。反正我可以在这里上传文件吗? @OliverCharlesworth:如上所述,我不能发布最小测试用例,因为最小测试用例确实有效。我不知道是什么导致了这个问题,现在主要是在寻找任何提示。 让我们从发布确切的错误消息开始,以及哪个编译步骤失败(即 makefile 行)。有多少个文件? 【参考方案1】:很可能您的 makefile 或构建脚本在合并中搞砸了,它链接同一个文件 (rhs.o
) 两次。
【讨论】:
我在上面发布了我的makefile。我在那里找不到错误,但您似乎是对的。 耶稣一个人能有多瞎??? rhs 在 makefile 中出现两次。我一遍又一遍地查看该列表,根本没有看到它。感谢您的提示。现在一切正常。也感谢其他试图提供帮助的人。结果证明这是一个非常愚蠢的错误,但如果没有你的帮助,我可能需要几个小时才能发现它。【参考方案2】:问题出在 make 文件中。
注意:'all' 应该是第一个目标,而不是第二个
注意:每个未创建具有目标名称的文件的目标都应包含在 .PHONY: 目标中
注意:宏应该使用 ':=' 而不是 '=' 来定义,因为 '=' 将导致宏在每次调用时都被重新计算,而 ':=' 将导致宏只被评估一次。
注意:把依赖文件的include写成这样:
(扩展 'ifneq' 以包括 'clean_all' 和 'cleaning' 和 'clean_doc'
# wrap with ifneg... so will not rebuild *.d files when goal is 'clean_all', etc
#
ifneq "$(MAKECMDGOALS)" "clean_all"
-include $(OBJ:.o=.d)
-include $(TEST_OBJ:.o=.d)
endif
这是问题的根源:
OBJ = $(SRC)/main.o\
$(SRC)/helper.o\
$(SRC)/init.o\
$(SRC)/basis.o\
$(SRC)/gauss.o\
$(SRC)/indices.o\
$(SRC)/eval.o\
$(SRC)/rhs.o\ <-- first instance of rhs.o
$(SRC)/visual.o\
$(SRC)/matrix.o\
$(SRC)/rhs.o <-- second instance of rhs.o
还有这条规则:
exec: $(OBJ) chkopts
-$(CLINKER) -o sim $(OBJ) $(PETSC_KSP_LIB)
包含 $(OBJ) 的扩展,其中 $(OBJ) 包含上述错误
【讨论】:
感谢您的反馈。如上所述,我已经发现了问题。但我肯定也会看看你的其他建议。顺便说一句:由于某种原因,petsc
库(包含在 makefile 中)无论如何都会更改很多 make 的设置(例如,默认更改为我不知道是什么)。这就是为什么我不再关心目标的顺序。感谢您关于ifneq
的提示,我实际上正在寻找类似的东西。以上是关于犯错误:多个定义...尽管包括警卫的主要内容,如果未能解决你的问题,请参考以下文章