CMake - Undefined Reference

不问归期 提交于 2021-02-10 06:42:46

问题


I am trying to include gtest to my project.

The problem is that I get a undefined reference error in the GTest.

I am trying to test the Node class in Gtest. Inside the constructor of the Node I am using the Class Logger. Although I have added the library logger to the gtest-target I still the undefined reference error regarding to the Logger....

My guess CMake does no look for nested classes that are used inside Node. only Node itself.

Temperoy fix If I use the Logger in the gtest-node.cpp it works gtest.cpp

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

This way the the Logger is directly used in the gtest this way the logger-library will be add to the target by cmake.

My Setup (pseudo-code because my project is way bigger than this) (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 (Logger)

add_library(logger logger.cpp)

CMakeLists.txt (Node)

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

The original error:

../../../../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:


Your node library uses the logger library, but you haven't specified that link relationship. You need to add the following:

target_link_library(node PRIVATE logger)

Then, any time you link to node, CMake will append logger to the link libraries if node is built as a static library.

You almost get away with what you did with the linking of the gtest-logger target where you explicitly added the logger library there, assuming you actually meant gtest-node rather than gtest-logger in that call to target_link_library(). If you had listed logger after node, I would have expected the build to work (assuming the target name typo), but that would not be the correct way to do it. You should only need to explicitly list logger as a link dependency of gtest-logger if something in gtest.cpp directly referenced something from the Logger class.



来源:https://stackoverflow.com/questions/43964691/cmake-undefined-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!