GTest linking error: undefined reference to 'foo::function'
GTest linking error: undefined reference to 'foo::function'
我想使用 GTest 并让示例运行。现在我想测试我自己的代码,但是我遇到了一个 linking 问题。
我在 Whosebug 上搜索过,发现了一个类似的问题,但答案并没有帮助我解决问题。
我的文件是:
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)
tests.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
我几乎可以肯定它与 include 或 link 问题有关,但我找不到正确的语法。
你的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
,您应该传递文件模式,而不是文件路径。无论如何,从 doc:
We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.
改为考虑 set
:
set(files
Datahandler.h
Datahandler.cpp
)
下一个:
include_directories(${GTEST_INCLUDE_DIRS})
#...
target_link_libraries(runTests ${GTEST_LIBRARIES} pthread)
你可以考虑 imported targets:
而不是老式的 ${GTEST_LIBRARIES}
target_link_libraries(runTests GTest::Main)
GTest::Main
将通过导入的目标处理包含目录,因此您无需调用 include_directories
。此外,它会添加对线程库的依赖,所以我很确定你可以删除 pthread
(待测试)。最后,GTest::Main
包含了 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));
}
我想使用 GTest 并让示例运行。现在我想测试我自己的代码,但是我遇到了一个 linking 问题。
我在 Whosebug 上搜索过,发现了一个类似的问题,但答案并没有帮助我解决问题。
我的文件是:
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)
tests.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
我几乎可以肯定它与 include 或 link 问题有关,但我找不到正确的语法。
你的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
,您应该传递文件模式,而不是文件路径。无论如何,从 doc:
We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.
改为考虑 set
:
set(files
Datahandler.h
Datahandler.cpp
)
下一个:
include_directories(${GTEST_INCLUDE_DIRS})
#...
target_link_libraries(runTests ${GTEST_LIBRARIES} pthread)
你可以考虑 imported targets:
而不是老式的${GTEST_LIBRARIES}
target_link_libraries(runTests GTest::Main)
GTest::Main
将通过导入的目标处理包含目录,因此您无需调用 include_directories
。此外,它会添加对线程库的依赖,所以我很确定你可以删除 pthread
(待测试)。最后,GTest::Main
包含了 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));
}