问题
I have the following CMakeLists.txt
:
cmake_minimum_required(VERSION 3.15)
set(CMAKE_CXX_STANDARD 17)
# adding library
set(ST_SRC simple_tree.cpp)
add_library(st ${ST_SRC})
target_include_directories(st PUBLIC ${PROJECT_SOURCE_DIR}/include/data_structures/simple_tree/)
# adding googletest
set(GOOGLETEST_PATH ~/local/googletest)
set(GTEST_INCLUDE_DIR ~/local/include/)
set(GTEST_LIBRARY ~/local/lib/)
set(GTEST_MAIN_LIBRARY ~/local/lib/)
find_package(GTest REQUIRED)
# adding tests
set(TEST_TARGET test_simple_tree)
add_executable(${TEST_TARGET} test_simple_tree.cpp)
target_include_directories(${TEST_TARGET}
PUBLIC
${PROJECT_SOURCE_DIR}/include/data_structures/simple_tree
${GOOGLETEST_PATH}
${GTEST_INCLUDE_DIR})
target_link_libraries(${TEST_TARGET} PUBLIC st)
target_link_libraries(${TEST_TARGET} PUBLIC gtest gtest_main)
Basically, I've installed googletest
into my home directory rather than system-wide.
The find_package()
command apparently succeeds. However, trying to build test_simple_tree
fails with:
/usr/bin/ld: cannot find -lgtest
/usr/bin/ld: cannot find -lgtest_main
Inside this CMakeLists.txt
, how else can I tell the linker to look elsewhere
for the gtest
?
EDIT: After reading the docs, I've fixed the Gtest
issue as described below. However, the following issue cropped up: CMake imported target includes non-existent path
回答1:
If find_package()
was successful in finding the GTest includes/libraries, it should populate targets for you, per the CMake FindGTest documentation:
This module defines the following
IMPORTED
targets:
GTest::GTest
: The Google Testgtest
library, if found; adds Thread::Thread automatically
GTest::Main
: The Google Testgtest_main
library, if found
You should use these in your target_link_libraries()
command instead. Also, CMake will populate GTEST_INCLUDE_DIRS
, but the GTest include directories should be pulled in from the imported targets mentioned above.
Another important note: I'm not sure if you posted all of your CMake code, but I don't see a project()
call in your code. As a result, the ${PROJECT_SOURCE_DIR}
variable may not be what you expect. In general, it is good practice to declare your project with project()
at the top of your CMake.
Your CMake file with these modifications could look something like this:
cmake_minimum_required(VERSION 3.15)
project(simple_tree_example)
set(CMAKE_CXX_STANDARD 17)
# adding library
set(ST_SRC simple_tree.cpp)
add_library(st ${ST_SRC})
target_include_directories(st PUBLIC
${PROJECT_SOURCE_DIR}/include/data_structures/simple_tree/)
# adding googletest
set(GOOGLETEST_PATH ~/local/googletest)
set(GTEST_INCLUDE_DIR ~/local/include/)
set(GTEST_LIBRARY ~/local/lib/)
set(GTEST_MAIN_LIBRARY ~/local/lib/)
find_package(GTest REQUIRED)
# adding tests
set(TEST_TARGET test_simple_tree)
add_executable(${TEST_TARGET} test_simple_tree.cpp)
target_include_directories(${TEST_TARGET}
PUBLIC
${PROJECT_SOURCE_DIR}/include/data_structures/simple_tree
${GOOGLETEST_PATH})
target_link_libraries(${TEST_TARGET} PUBLIC st GTest::GTest GTest::Main)
回答2:
Targets gtest
and gtest_main
are created only when GTest is used via add_subdirectory()
approach.
When use GTest via find_package()
, one need to use either IMPORTED targets GTest::GTest
and GTest::Main
, or variables GTEST_LIBRARIES
and GTEST_MAIN_LIBRARIES
correspondingly. This is described in the documentation:
find_package(GTest REQUIRED)
...
target_link_libraries(test_simple_tree PUBLIC GTest::GTest gtest_main)
or
find_package(GTest REQUIRED)
...
# That case we need to add include directories
target_include_directories(test_simple_tree ${GTEST_INCLUDE_DIRS})
target_link_libraries(test_simple_tree PUBLIC ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES})
来源:https://stackoverflow.com/questions/59009607/linking-against-gtest-fails