为什么谷歌测试可以编译但看不到我的项目源代码?
这是我收到的错误:
$ cmake . && make && make test
-- Configuring done
-- Generating done
-- Build files have been written to: mars_rover
Scanning dependencies of target mars_rover
[ 8%] Building CXX object CMakeFiles/mars_rover.dir/src/rover.cpp.o
Linking CXX executable build/bin/mars_rover
[ 33%] Built target mars_rover
[ 41%] Built target gtest
[ 50%] Built target gtest_main
Scanning dependencies of target mars_rover_TEST
[ 58%] Building CXX object CMakeFiles/mars_rover_TEST.dir/test/test_mars_rover.cpp.o
mars_rover/test/test_mars_rover.cpp:2:10: fatal error: 'src/directions.h' file not found
#include "src/directions.h"
^
1 error generated.
make[2]: *** [CMakeFiles/mars_rover_TEST.dir/test/test_mars_rover.cpp.o] Error 1
make[1]: *** [CMakeFiles/mars_rover_TEST.dir/all] Error 2
make: *** [all] Error 2
以下是我的项目布局:
$ tree {src,test,lib} -L 1
src
├── directions.cpp
├── directions.h
├── main.cpp
├── plateau.cpp
├── plateau.h
├── point.h
├── rover.cpp
└── rover.h
test
├── input1
├── output1
├── test_main.cpp
└── test_mars_rover.cpp
lib
├── CMakeLists.txt
└── gtest-1.7.0
这是我的 CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
# Options. Turn on with 'cmake -Dtest=ON'.
option(test "Build all tests." ON)
set(PROJECT_NAME mars_rover CXX)
project(${PROJECT_NAME})
set(CMAKE_CXX_FLAGS "-g -Wall -Werror")
file(GLOB_RECURSE PROJECT_SOURCES ${CMAKE_SOURCE_DIR}/src/*.cpp)
add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/build/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/build/lib)
if (test)
add_subdirectory(lib/gtest-1.7.0)
enable_testing()
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
# finding test sources
file(GLOB_RECURSE TEST_SOURCES ${CMAKE_SOURCE_DIR}/test/*.cpp ${CMAKE_SOURCE_DIR}/src/*.cpp)
add_executable(${PROJECT_NAME}_TEST ${TEST_SOURCES})
# link to gtest
target_link_libraries(${PROJECT_NAME}_TEST gtest gtest_main)
add_test(CardinalDirectionTests ${EXECUTABLE_OUTPUT_PATH}/${PROJECT_NAME}_TEST --gtest_filter=MarsRoverTest.CardinalDirectionTests)
add_test(RelativeDirectionTests ${EXECUTABLE_OUTPUT_PATH}/${PROJECT_NAME}_TEST --gtest_filter=MarsRoverTest.RelativeDirectionTests)
endif()
最佳答案
您的测试可执行文件找不到“src/directions.h”,因为其父级 (${CMAKE_SOURCE_DIR}
) 尚未添加到 include_directories
调用中。只需添加它就可以了。
但是,我可以在您的设置中看到其他一些小点。运行您的 CMakeLists.txt,以下是我要做的更改:
cmake_minimum_required(VERSION 2.8.12)
如果您可以指定 2.8.12 作为最小值,您就可以访问更有用的 target_include_directories
命令。 include_directories
是一种有点错误的方法,而 target_include_directories
允许您仅为该特定目标指定搜索路径。如果您将这些指定为 PUBLIC
或 INTERFACE
,则链接到该目标的后续目标也将自动继承这些搜索路径。
以类似的方式,您可以考虑使用 target_compile_definitions
和 target_compile_options
.
设置(PROJECT_NAME mars_rover CXX)
项目(${PROJECT_NAME})
项目(mars_rover)
project
命令设置变量PROJECT_NAME
,因此您的set
命令在这里几乎没有用处。 CMake 会根据源文件后缀检测到这是一个 C++ 项目。
通过将所有源代码包含在两个单独的目标(主 exe 和测试 exe)中,这些都将被编译两次。为了避免这种低效率,我会在“/src”中创建一个包含除“main.cpp”之外的所有源代码的库,然后创建一个仅具有 main.cpp 并链接到该库的 exe。
此外,不鼓励使用 file(GLOB ...)
或 file(GLOB_RECURSE ...)
作为收集源列表的方法。
set(CMAKE_CXX_FLAGS "-g -Wall -Werror")
文件(GLOB_RECURSE PROJECT_SOURCES ${CMAKE_SOURCE_DIR}/src/*.cpp)
add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
# No need to include .h files, but they show up in IDEs like Xcode if you do.
set(libSources
src/directions.cpp src/directions.h
src/plateau.cpp src/plateau.h
src/point.h
src/rover.cpp src/rover.h
)
add_library(${PROJECT_NAME}_LIB ${libSources})
# Anything linking to this will automatically have ${PROJECT_SOURCE_DIR}
# added to the compiler's search paths since it is PUBLIC. Prefer
# ${PROJECT_SOURCE_DIR} to ${CMAKE_SOURCE_DIR} in case this project is not
# the top-level one.
target_include_directories(${PROJECT_NAME}_LIB PUBLIC ${PROJECT_SOURCE_DIR})
# Use generator expressions to conditionally apply the flags to Unix and Debug
# builds. Anything linking to this will automatically have these flags also
# applied since they are PUBLIC.
target_compile_options(${PROJECT_NAME}_LIB PUBLIC
$<$<BOOL:${UNIX}>:-Werror -Wall $<$<CONFIG:Debug>:-g>>)
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}_LIB)
对于测试,看起来您有 2 个或 3 个 main
函数 - 这将是一个问题:-) gtest_main
是一个小助手,它提供了main
函数调用所需的 gtest 函数来调用测试。我猜您在“test/test_main.cpp”中也有 main
,并且由于您当前包含所有“src/”文件,我想您也有一个 main
在“src/main.cpp”中。
通过将 mars_rover
目标拆分为 lib 和 exe,您可以仅链接到该 lib,并避免从测试中显式排除“src/main.cpp”。我无法判断您是否想使用自己的“test_main.cpp”或使用 gtest 的助手 - 我假设是后者:
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
文件(GLOB_RECURSE TEST_SOURCES ...)
add_executable(${PROJECT_NAME}_TEST ${TEST_SOURCES})
target_link_libraries(${PROJECT_NAME}_TEST gtest gtest_main)
add_executable(${PROJECT_NAME}_TEST test/test_mars_rover.cpp)
# Only bring gtest's include path into scope - its src dir is not designed to
# be public
target_include_directories(${PROJECT_NAME}_TEST PRIVATE
${gtest_SOURCE_DIR}/include)
target_link_libraries(${PROJECT_NAME}_TEST ${PROJECT_NAME}_LIB gtest gtest_main)
最后,如果使用以下语法,则无需指定测试 exe 的完整路径:
add_test(NAME CardinalDirectionTests
COMMAND ${PROJECT_NAME}_TEST
--gtest_filter=MarsRoverTest.CardinalDirectionTests)
add_test(NAME RelativeDirectionTests
COMMAND ${PROJECT_NAME}_TEST
--gtest_filter=MarsRoverTest.RelativeDirectionTests)
关于c++ - 为什么谷歌测试可以编译但看不到我的项目源代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25252723/