提交我自己的Google流量答案。考虑一下Makefile
SHELL := /bin/bash
run-tests: catch.o
for x in *.cpp; do g++ $$x -o $$x.o catch.o && ./$$x.o; done
catch.o: catch.hpp
g++ main.cxx -o catch.o
我正在为Catch v1.9.5编译单元测试。将下面的内容与example given by their docs:
进行比较// main.cxx
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
// meta.cpp
#include "catch.hpp"
int foo(int a) {
return -a;
}
TEST_CASE("foo", "[example]") {
REQUIRE(foo(0) == 0);
REQUIRE(foo(2) == -2);
REQUIRE(foo(-2) == 2);
}
make
收益:
catch.o:(.rodata+0x0): multiple definition of `_IO_stdin_used'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crt1.o:(.rodata.cst4+0x0): first defined here
catch.o:(.rodata+0x8): multiple definition of `__dso_handle'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/crtbegin.o:(.rodata+0x0): first defined here
catch.o: In function `_fini':
(.fini+0x0): multiple definition of `_fini'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crti.o:(.fini+0x0): first defined here
catch.o: In function `_start':
(.text+0x0): multiple definition of `_start'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crt1.o:(.text+0x0): first defined here
catch.o: In function `_init':
(.init+0x0): multiple definition of `_init'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crti.o:(.init+0x0): first defined here
catch.o: In function `data_start':
(.data+0x0): multiple definition of `__data_start'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crt1.o:(.data+0x0): first defined here
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/crtend.o:(.tm_clone_table+0x0): multiple definition of `__TMC_END__'
catch.o:(.data+0x98): first defined here
/usr/bin/ld: error in catch.o(.eh_frame); no .eh_frame_hdr table will be created.
collect2: error: ld returned 1 exit status
Makefile:5: recipe for target 'run-tests' failed
make: *** [run-tests] Error 1
删除catch.o
中对run-tests
的引用会导致链接器抱怨未定义的引用。导致冗余定义的catch.o
和main.cxx
出了什么问题?
答案 0 :(得分:1)
catch.o
Make目标缺少-c
标志,因此GCC继续并过早地运行链接器步骤。尝试再次与实际测试套件链接导致GCC第二次从Catch生成定义,导致上述错误。解决方法是简单地将-c
添加到g++ main.cxx -o catch.o
,以便它编译Catch,但等待链接直到它实际上有要编译的测试。