CMake - 未定义的参考

时间:2017-05-14 13:54:10

标签: c++ cmake googletest undefined-reference

我正在尝试将gtest包含在我的项目中。

问题是我在GTest中得到一个未定义的引用错误。

我正在尝试在Gtest中测试Node类。在Node的构造函数内部,我正在使用Class Logger。虽然我已经将库记录器添加到gtest-target中,但仍然存在关于Logger的未定义的引用错误....

我的猜测CMake没有查找Node内部使用的嵌套类。 只有Node本身。

Temperoy修复 如果我在gtest-node.cpp中使用Logger它可以工作 gtest.cpp

/* Pseudo Code */
TEST Node
{ 
     Logger::log("Temp Fix")
     Node * n = Node(0,0,0)
}

这样,Logger直接在gtest中使用,这样logger-library将通过cmake添加到目标。

我的设置(伪代码因为我的项目比这个大) (https://github.com/ronsalm/LearningLunch

├── CMakeLists.txt
├── main.cpp
├── logger
│   ├── CMakeLists.txt
│   ├── logger.cpp
│   └── logger.h
├── Node
│   ├── CMakeLists.txt
│   ├── node.cpp
│   └── node.h
└── Gtest
    ├── CMakeLists.txt
    ├── gtest-node.cpp
    └── node.h

的main.cpp

/* Pseudo Code */
int main()
{ 
     Node * n = Node(0,0,0)
}

logger.h

/* Pseudo Code */
class Logger
{ 
     log(string)
}

logger.cpp

/* Pseudo Code */
Logger::log(string s)
{
//write to string to file
}

node.h

/* Pseudo Code */
class Node
{ 
     Node(int,int,int)
}

node.cpp

/* Pseudo Code */
Node::node(int x, int y , int z)
{
     Logger::log("Create Node")
}

gtest.cpp

/* Pseudo Code */
TEST Node
{ 
     Node * n = Node(0,0,0)
}

CMakeLists.txt(Root)

project(applic)
include_directories(
      "${CMAKE_SOURE_DIR/node"
      "${CMAKE_SOURE_DIR/logger")

add_library(node node.cpp)
add_executable(applic main.cpp)
target_link_libraries(applic logger node)

CMakeLists.txt(记录器)

add_library(logger logger.cpp)

CMakeLists.txt(节点)

add_library(node node.cpp)

CMakeLists.txt(Gtest)

add_executable(gtest-node gtest-node.cpp)
set_target_properties(gtest-node PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
target_link_libraries(gtest-logger gtest phtread logger node)
add_test(NAME node COMMAND $<TARGET_FILE:gtest-node>

enable_testing()

原始错误:

../../../../lib/libdatabase.a(sql.cpp.o): In function `SQL::Open()':
/home/rsalm/test/src/database/sql/sql.cpp:19: undefined reference to `Logger::TagDebug'
/home/rsalm/test/src/database/sql/sql.cpp:19: undefined reference to `Logger::instance(std::string const&)                                               '
../../../../lib/libdatabase.a(sql.cpp.o): In function `SQL::Close()':
/home/rsalm/test/src/database/sql/sql.cpp:27: undefined reference to `Logger::TagDebug'
/home/rsalm/test/src/database/sql/sql.cpp:27: undefined reference to `Logger::instance(std::string const&)                                               '
../../../../lib/libdatabase.a(sql.cpp.o): In function `Logger& operator<< <char [25]>(Logger&, char const (&) [25])                                               ':
/home/rsalm/test/inc/logger.h:33: undefined reference to `Logger::pInstance'
../../../../lib/libdatabase.a(sql.cpp.o): In function `Logger& operator<< <char [21]>(Logger&, char const (&) [21])                                               ':
/home/rsalm/test/inc/logger.h:33: undefined reference to `Logger::pInstance'
../../../../lib/libdatabase.a(sql.cpp.o): In function `Logger& operator<< <char [26]>(Logger&, char const (&) [26])                                               ':
/home/rsalm/test/inc/logger.h:33: undefined reference to `Logger::pInstance'
../../../../lib/libdatabase.a(sql.cpp.o): In function `Logger& operator<< <char [24]>(Logger&, char const (&) [24])                                               ':
/home/rsalm/test/inc/logger.h:33: undefined reference to `Logger::pInstance'
collect2: error: ld returned 1 exit status
src/layout/gtest/CMakeFiles/gtest-layout-factory.dir/build.make:98: recipe for target '../bin/gtest-layout-factory'                                                failed
make[2]: *** [../bin/gtest-layout-factory] Error 1
CMakeFiles/Makefile2:1824: recipe for target 'src/layout/gtest/CMakeFiles/gtest-layout-factory.dir/all' failed

1 个答案:

答案 0 :(得分:1)

您的node库使用logger库,但您尚未指定该链接关系。您需要添加以下内容:

target_link_library(node PRIVATE logger)

然后,只要您链接到node,如果将logger构建为静态库,CMake会将node附加到链接库。

几乎躲过了你在那里明确添加gtest-logger库的logger目标的链接所做的事情,假设你实际意味着{{1}在gtest-node的调用中,而不是gtest-logger。如果您在target_link_library()之后列出logger,我原本期望构建工作(假设目标名称拼写错误),但这不是正确的方法。如果node中的某些内容直接引用logger类中的某些内容,则您只需要明确地将gtest-logger列为gtest.cpp的链接依赖项。