Cmake:对包含方法的未定义引用

Posted

技术标签:

【中文标题】Cmake:对包含方法的未定义引用【英文标题】:Cmake: undefined reference to included methods 【发布时间】:2021-04-27 02:41:50 【问题描述】:

我正在学习使用 cmake,我正在尝试使用 gtest 为我编写的一个非常小的项目编译一组简单的测试。

我的 CMakeLists.txt 看起来像

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)

我从 googletest 文档中获得了大部分内容。我正在尝试编译在 test.cpp 中具有 main() 并依赖于 Connector.cpp 和 Connector.h 中的 Connector 类的可执行文件。所有文件都在同一个目录中

当我运行 cmake 时。然后让我得到以下错误:

/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

即使我在 CMakeLists.txt 中指定了,cmake 似乎也不知道在编译中包含 Connector.cpp。我做错了什么?

Connector.cpp 的代码,目前它做的不是很多,哈哈,但它是一个 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;

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());

【问题讨论】:

cmake_minimum_required(VERSION 2.6) 似乎很奇怪。我这么说是因为 2.6 已经很老了。它于 2008 年发布。 我用谷歌搜索了 FetchContent,它告诉我它在 3.11 中首次出现在 CMake 中,所以这可能是一个很好的起点。 可能你Conntector.cpp 没有定义给定的方法。请出示代码(C++一,最好是minimal reproducible example)。 这是我的猜测,从外部看来,这似乎不是 CMake 问题。 您是否尝试在不同的目录或新目录中设置项目?也许 make 项目存在问题,没有意识到某些依赖项已过时... 【参考方案1】:

既然你需要外部类,你应该把那个类“库”放在target_link_libraries(),这样你的CMakeLists.txt的最后一行就会变成

target_link_libraries(test connector gtest_main)

另外,在与 Connector.cpp 位于同一目录的另一个 CMakeLists.txt 中,您应该将它们声明为一个库:

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

【讨论】:

以上是关于Cmake:对包含方法的未定义引用的主要内容,如果未能解决你的问题,请参考以下文章

即使在链接库时,也会获得对 OpenCV 元素的未定义引用。使用 CMake

使用 Qt 对 vtable 的未定义引用

Android Native:CMake链接错误:GL函数的未定义引用 - 即使包含和链接了EGL和GLESv3

libVLC|make:对“libvlc_new”的未定义引用

对结构方法的未定义引用[重复]

CMake“uuid”链接失败