使用 Makefile 的 C++ Catch 框架 'multiple definition' 链接器错误

标签 c++ unit-testing linker linker-errors catch-unit-test

提交我自己的 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);
}

制作 产量:

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

run-tests 中删除对 catch.o 的引用会导致链接器提示 undefined reference 。导致冗余定义的 catch.omain.cxx 有什么问题?

最佳答案

catch.o Make 目标缺少 -c 标志,因此 GCC 过早地运行了链接器步骤。尝试再次与实际测试套件链接导致 GCC 第二次从 Catch 生成定义,从而导致上述错误。修复方法是简单地将 -c 添加到 g++ main.cxx -o catch.o 中,这样它就可以编译 Catch,但会等待链接,直到它确实有要编译的测试。

关于使用 Makefile 的 C++ Catch 框架 'multiple definition' 链接器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44618958/

相关文章:

java - 如何为 Java Stream 编写 Junit

c# - 针对特定异常的单元测试异步方法

c++ - 通过 C++ 接口(interface)访问 PostgreSQL(链接器错误)

android - 如何使用gles创建ios模糊效果

c++ - 静态 map 初始化函数错误

c++ - VS2008 内部编译错误

swift - 使用 Firebase 和 Google pod 时发生链接器错误

c++ - VS2015 中的智能感知永无止境

visual-studio - Visual Studio 2010 速成版中的 MSTest

linux - 如何在 debian 系统上调试(慢速)链接器