GTest 链接错误:未定义对“foo::function”的引用

GTest linking error: undefined reference to 'foo::function'

提问人:Yoeri Kroon 提问时间:10/25/2016 最后编辑:rocambilleYoeri Kroon 更新时间:10/25/2016 访问量:4723

问:

我想使用 GTest 并让示例工作。现在我想测试我自己的代码,但我遇到了一个链接问题。

我在stackoverflow上搜索过,发现了一个类似的问题,但答案并没有帮助我解决我的问题。

我的文件是:

CMakeLists.txt

cmake_minimum_required(VERSION 2.6)

SET(CMAKE_CXX_FLAGS "-std=gnu++11")

# Locate GTest
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
file(GLOB files
    Datahandler.h 
    Datahandler.cpp 
    )

# Link runTests with what we want to test and the GTest and pthread library
add_executable(runTests tests.cpp ${files} )
target_link_libraries(runTests ${GTEST_LIBRARIES} pthread)

测试.cpp

#include "DataHandler.h"
#include <gtest/gtest.h>

TEST(checkFilled, All){
    DataHandler handler("loc", "prot", 1);
    handler.filledElement[1] = 1;
    ASSERT_EQ(1, handler.checkFilled(1));
    ASSERT_EQ(0, handler.checkFilled(2));
    ASSERT_EQ(1, handler.checkFilled(8));
    ASSERT_EQ(0, handler.checkFilled(9));
}

int main(int argc, char **argv) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

我得到的错误是:

CMakeFiles/runTests.dir/tests.cpp.o: In function `checkFilled_All_Test::TestBody()':
tests.cpp:(.text+0x121): undefined reference to `DataHandler::DataHandler(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char)'
tests.cpp:(.text+0x172): undefined reference to `DataHandler::checkFilled(unsigned char)'
tests.cpp:(.text+0x271): undefined reference to `DataHandler::checkFilled(unsigned char)'
tests.cpp:(.text+0x382): undefined reference to `DataHandler::checkFilled(unsigned char)'
tests.cpp:(.text+0x48d): undefined reference to `DataHandler::checkFilled(unsigned char)'
collect2: error: ld returned 1 exit status
CMakeFiles/runTests.dir/build.make:95: recipe for target 'runTests' failed
make[2]: *** [runTests] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/runTests.dir/all' failed
make[1]: *** [CMakeFiles/runTests.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

我几乎可以肯定它与包含或链接问题有关,但我找不到正确的语法。

C++ C++11 cmake googletest undefined-reference

评论


答:

3赞 rocambille 10/25/2016 #1

CMake 项目中有几点:

SET(CMAKE_CXX_FLAGS "-std=gnu++11")

使用 时,最好不要删除以前的值:CMAKE_CXX_FLAGS

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")

默认情况下,该值为空,因此此处不应更改任何内容。无论如何,要需要 C++11,您可以考虑:CMAKE_CXX_STANDARD

SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)

下一个:

file(GLOB files
    Datahandler.h 
    Datahandler.cpp 
    )

如果使用 ,则应传递文件模式,而不是文件路径。无论如何,从文档中:GLOB

我们不建议使用 GLOB 从源代码树中收集源文件列表。如果在添加或删除源时没有 CMakeLists.txt 文件更改,则生成的生成系统无法知道何时要求 CMake 重新生成。

请考虑:set

set(files
    Datahandler.h 
    Datahandler.cpp 
    )

下一个:

include_directories(${GTEST_INCLUDE_DIRS})

#...

target_link_libraries(runTests ${GTEST_LIBRARIES} pthread)

您可以考虑导入的目标,而不是老式的 ,而不是 old-fashioned :${GTEST_LIBRARIES}

target_link_libraries(runTests GTest::Main)

GTest::Main将通过导入的目标处理包含目录,因此无需调用 .此外,它将向线程库添加依赖项,因此我很确定您可以删除(待测试)。最后,包括 main 函数的基本实现,该函数完全按照您的方式执行,因此您可以删除您的函数。include_directoriespthreadGTest::Main

请注意,您需要升级所需的最低 CMake 版本,以使导入的目标完全可用:

cmake_minimum_required(VERSION 2.8.11)

因此,2016 年的 CMake 项目应如下所示:

cmake_minimum_required(VERSION 2.8.11)

SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)

set(files
    Datahandler.h 
    Datahandler.cpp 
    )

# Locate GTest
find_package(GTest REQUIRED)

# Link runTests with what we want to test and the GTest library
add_executable(runTests tests.cpp ${files})

target_link_libraries(runTests GTest::Main)

和:test.cpp

#include "DataHandler.h"
#include <gtest/gtest.h>

TEST(checkFilled, All){
    DataHandler handler("loc", "prot", 1);
    handler.filledElement[1] = 1;
    ASSERT_EQ(1, handler.checkFilled(1));
    ASSERT_EQ(0, handler.checkFilled(2));
    ASSERT_EQ(1, handler.checkFilled(8));
    ASSERT_EQ(0, handler.checkFilled(9));
}

评论

0赞 Asalle 3/15/2018
有史以来最伟大的答案之一