Search code examples
c++testingcmakeg++googletest

Cmake: undefined reference to included methods


I am learning to use cmake and I am trying to compile a simple set of tests using gtest for a very small project that I wrote.

my CMakeLists.txt looks like

cmake_minimum_required(VERSION 2.6)

project(circuit_sim)

include(FetchContent)
FetchContent_Declare(
  googletest
  # Specify the commit you depend on and update it regularly.
  URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

add_executable(test Connector.cpp test.cpp)
target_link_libraries(test gtest_main)

I got most of it from the googletest docs. I am trying to compile an executable that has a main() in test.cpp and relies on a Connector class in Connector.cpp and Connector.h. All files are in the same directory

when I run cmake . and then make I get the following error:

/usr/bin/ld: CMakeFiles/test.dir/test.cpp.o: in function `AllTests_CircuitTest_Test::TestBody()':
test.cpp:(.text+0x33): undefined reference to `Connector::Connector()'
/usr/bin/ld: test.cpp:(.text+0x4c): undefined reference to `Connector::Connector()'
/usr/bin/ld: test.cpp:(.text+0x6d): undefined reference to `Connector::Connector(Connector*)'       
/usr/bin/ld: test.cpp:(.text+0x7d): undefined reference to `Connector::connect(Connector*)'
/usr/bin/ld: test.cpp:(.text+0x93): undefined reference to `Connector::in(unsigned long, unsigned long)'
/usr/bin/ld: test.cpp:(.text+0xb8): undefined reference to `Connector::out()'
/usr/bin/ld: test.cpp:(.text+0xc4): undefined reference to `Connector::get_out_conn()'
/usr/bin/ld: test.cpp:(.text+0xd6): undefined reference to `Connector::get_v()'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/test.dir/build.make:86: test] Error 1
make[1]: *** [CMakeFiles/Makefile2:139: CMakeFiles/test.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

It seems that cmake did not know to include Connector.cpp in the compilation even though I specified it in the CMakeLists.txt. What am I doing wrong?

Code for Connector.cpp, currently it doesn't do very much lol but it's a wip

#include "Connector.h"
#include "circuit_utils.h"

Connector::Connector(){
    this->v = 0;
    this->c = 0;
    this->out_conn = nullptr;
}

Connector::Connector(Connector* out_conn){
    this->v = 0;
    this->c = 0;
    this->out_conn = out_conn;
}

Connector* Connector::connect(Connector* out_conn){
    this->out_conn = out_conn;
    return this;
}

Connector* Connector::in(uint64_t v, uint64_t c){
    this->v = v;
    this->c = c;
    //this->out();
    return this;
}

Connector* Connector::out(){
    if(out_conn != nullptr)
        out_conn->in(v, c);
    return this;
}

uint64_t Connector::get_v() { return v; }
uint64_t Connector::get_c() { return c; }
Connector* Connector::get_out_conn() { return out_conn; }

std::string Connector::to_string() {
    std::string to_return = "";
    to_return += "-------------\n";
    to_return += "voltage: " + std::to_string(FROM_MICROS(((double)v))) + " volts\n";
    to_return += "current: " + std::to_string(FROM_MICROS(((double)c))) + " amps\n";
    to_return += "-------------\n";
    return to_return;
}

Code for test.cpp

#include <iostream> 
#include <unistd.h>

#include "gtest/gtest.h"

#include "Connector.h"
#include "circuit_utils.h"

using namespace std;

TEST (AllTests, CircuitTest) {
    Connector* power = new Connector();
    Connector* ground = new Connector(); 
    power->connect(new Connector(ground));
    power->in(TO_MICROS(3.3), TO_MICROS(3.3));

    Connector *cur_conn = power;
    while(cur_conn != nullptr){
        sleep(5);
        cur_conn->out();
        cur_conn = cur_conn->get_out_conn();
    }
    ASSERT_EQ(3.3, ground->get_v());
}

Solution

  • Since you need external class, you should put that class "library" in target_link_libraries(), so that the last line of your CMakeLists.txt will become

    target_link_libraries(test connector gtest_main)
    

    Also, in another CMakeLists.txt which is in the same directory as Connector.cpp, your should declare them as one library:

    set(SOURCES Connector.cpp)
    add_library(connector STATIC ${SOURCES})