2017-06-18 6 views
1

Einreichung meiner eigenen Antwort für Google-Verkehr. Betrachten Sie das MakefileC++ Catch-Framework 'Multiple Definition' Linker-Fehler mit 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 

Ich kompiliere Komponententests für Catch v1.9.5. Vergleichen Sie die unten gegen die 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 ergibt:

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 

Bezug auf catch.o in run-tests Entfernen bewirkt, daß der Linker über undefinierte Referenzen zu beklagen. Was ist falsch mit catch.o und main.cxx, die die redundanten Definitionen verursacht?

Antwort

0

Die catch.o Make Ziel fehlt die -c Flagge, so GCC ging voran und führte den Linker Schritt zu früh. Der Versuch, erneut mit den tatsächlichen Testsuites zu verknüpfen, führte dazu, dass GCC die Definitionen von Catch ein zweites Mal erzeugte, was die oben genannten Fehler verursachte. Die Lösung besteht darin, einfach -c zu g++ main.cxx -o catch.o hinzuzufügen, so dass Catch kompiliert wird, aber gewartet wird, bis eine Verknüpfung besteht, bis tatsächlich Tests kompiliert werden.