为什么google测试会编译但无法查看我的项目源?

时间:2014-08-11 21:28:26

标签: c++ cmake googletest

为什么google测试会编译但无法查看我的项目源?

这是我得到的错误:

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

1 个答案:

答案 0 :(得分:4)

您的测试可执行文件无法找到&s; 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允许您为该特定目标指定搜索路径。如果您将这些指定为PUBLICINTERFACE,则链接到此目标的后续目标也会自动继承这些搜索路径。

与此类似,您可以查看使用target_compile_definitionstarget_compile_options


<击> set(PROJECT_NAME mars_rover CXX)
project(${PROJECT_NAME})
project(mars_rover)

project命令设置变量PROJECT_NAME,因此您的set命令在这里几乎没用。并且CMake将根据源文件后缀检测到这是一个C ++项目。


通过将所有源包含在两个单独的目标(主exe和测试exe)中,这些将全部编译两次。为了避免这种低效率,我会在&#34; / src&#34;中建立一个包含所有来源的库。除了&#34; main.cpp&#34;然后有一个只有 有main.cpp并且链接到这个库的exe文件。

此外,不鼓励使用file(GLOB ...)file(GLOB_RECURSE ...)作为收集源列表的方法。

<击> set(CMAKE_CXX_FLAGS "-g -Wall -Werror")
file(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是一个小助手,它提供了一个{{ 1}}函数调用所需的gtest函数来调用测试。我猜测你还有main&#34; test / test_main.cpp&#34;因为你现在包括所有的&#34; src /&#34;文件,我想你在&#34; src / main.cpp&#34;中也有一个main

通过将main目标拆分为lib和exe,您只需链接到lib并避免明确排除&#34; src / main.cpp&#34;从测试。我不知道你是否想要使用自己的&#34; test_main.cpp&#34;或者使用gtest的助手 - 我已经假设了后者:

<击> mars_rover
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
file(GLOB_RECURSE TEST_SOURCES ...)
add_executable(${PROJECT_NAME}_TEST ${TEST_SOURCES})

target_link_libraries(${PROJECT_NAME}_TEST gtest gtest_main)

最后,如果您使用以下语法,则无需指定测试exe的完整路径:

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)