FindGTest.cmake 9.49 KB
Newer Older
1 2 3 4
#.rst:
# FindGTest
# ---------
#
5 6
# Locate the Google C++ Testing Framework.
#
7 8
# Imported targets
# ^^^^^^^^^^^^^^^^
9
#
10
# This module defines the following :prop_tgt:`IMPORTED` targets:
11
#
12 13 14 15 16
# ``GTest::GTest``
#   The Google Test ``gtest`` library, if found; adds Thread::Thread
#   automatically
# ``GTest::Main``
#   The Google Test ``gtest_main`` library, if found
17 18
#
#
19 20
# Result variables
# ^^^^^^^^^^^^^^^^
21
#
22
# This module will set the following variables in your project:
23
#
24 25 26 27
# ``GTEST_FOUND``
#   Found the Google Testing framework
# ``GTEST_INCLUDE_DIRS``
#   the directory containing the Google Test headers
28
#
29 30
# The library variables below are set as normal variables.  These
# contain debug/optimized keywords when a debugging library is found.
31
#
32 33 34 35 36 37 38
# ``GTEST_LIBRARIES``
#   The Google Test ``gtest`` library; note it also requires linking
#   with an appropriate thread library
# ``GTEST_MAIN_LIBRARIES``
#   The Google Test ``gtest_main`` library
# ``GTEST_BOTH_LIBRARIES``
#   Both ``gtest`` and ``gtest_main``
39
#
40 41
# Cache variables
# ^^^^^^^^^^^^^^^
42
#
43
# The following cache variables may also be set:
44
#
45 46 47 48 49 50
# ``GTEST_ROOT``
#   The root directory of the Google Test installation (may also be
#   set as an environment variable)
# ``GTEST_MSVC_SEARCH``
#   If compiling with MSVC, this variable can be set to ``MD`` or
#   ``MT`` (the default) to enable searching a GTest build tree
51 52
#
#
53 54
# Example usage
# ^^^^^^^^^^^^^
55
#
56 57 58 59
# ::
#
#     enable_testing()
#     find_package(GTest REQUIRED)
60
#
61
#     add_executable(foo foo.cc)
62
#     target_link_libraries(foo GTest::GTest GTest::Main)
63 64 65 66
#
#     add_test(AllTestsInFoo foo)
#
#
67 68
# Deeper integration with CTest
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
69 70
#
# If you would like each Google test to show up in CTest as a test you
71
# may use the following macro::
72
#
73
#     GTEST_ADD_TESTS(executable extra_args files...)
74
#
75 76 77 78 79 80 81 82
# ``executable``
#   the path to the test executable
# ``extra_args``
#   a list of extra arguments to be passed to executable enclosed in
#   quotes (or ``""`` for none)
# ``files...``
#   a list of source files to search for tests and test fixtures.  Or
#   ``AUTO`` to find them from executable target
83
#
84 85 86
# However, note that this macro will slow down your tests by running
# an executable for each test and test fixture.  You will also have to
# re-run CMake after adding or removing tests or test fixtures.
87
#
88
# Example usage::
89 90 91
#
#      set(FooTestArgs --foo 1 --bar 2)
#      add_executable(FooTest FooUnitTest.cc)
92
#      GTEST_ADD_TESTS(FooTest "${FooTestArgs}" AUTO)
93

94 95 96
#=============================================================================
# Copyright 2009 Kitware, Inc.
# Copyright 2009 Philip Lowman <philip@yhbt.com>
97
# Copyright 2009 Daniel Blezek <blezek@gmail.com>
98
#
99 100 101 102 103 104 105
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
106
# (To distribute this file outside of CMake, substitute the full
107
#  License text for the above reference.)
108 109
#
# Thanks to Daniel Blezek <blezek@gmail.com> for the GTEST_ADD_TESTS code
110

111 112 113 114
function(GTEST_ADD_TESTS executable extra_args)
    if(NOT ARGN)
        message(FATAL_ERROR "Missing ARGN: Read the documentation for GTEST_ADD_TESTS")
    endif()
115 116 117 118
    if(ARGN STREQUAL "AUTO")
        # obtain sources used for building that executable
        get_property(ARGN TARGET ${executable} PROPERTY SOURCES)
    endif()
119
    set(gtest_case_name_regex ".*\\( *([A-Za-z_0-9]+) *, *([A-Za-z_0-9]+) *\\).*")
120
    set(gtest_test_type_regex "(TYPED_TEST|TEST_?[FP]?)")
121 122
    foreach(source ${ARGN})
        file(READ "${source}" contents)
123
        string(REGEX MATCHALL "${gtest_test_type_regex} *\\(([A-Za-z_0-9 ,]+)\\)" found_tests ${contents})
124
        foreach(hit ${found_tests})
125
          string(REGEX MATCH "${gtest_test_type_regex}" test_type ${hit})
126

127
          # Parameterized tests have a different signature for the filter
128
          if("x${test_type}" STREQUAL "xTEST_P")
129
            string(REGEX REPLACE ${gtest_case_name_regex}  "*/\\1.\\2/*" test_name ${hit})
130
          elseif("x${test_type}" STREQUAL "xTEST_F" OR "x${test_type}" STREQUAL "xTEST")
131
            string(REGEX REPLACE ${gtest_case_name_regex} "\\1.\\2" test_name ${hit})
132
          elseif("x${test_type}" STREQUAL "xTYPED_TEST")
133 134 135 136 137
            string(REGEX REPLACE ${gtest_case_name_regex} "\\1/*.\\2" test_name ${hit})
          else()
            message(WARNING "Could not parse GTest ${hit} for adding to CTest.")
            continue()
          endif()
138
          add_test(NAME ${test_name} COMMAND ${executable} --gtest_filter=${test_name} ${extra_args})
139 140 141
        endforeach()
    endforeach()
endfunction()
142

143 144 145 146 147 148 149
function(_gtest_append_debugs _endvar _library)
    if(${_library} AND ${_library}_DEBUG)
        set(_output optimized ${${_library}} debug ${${_library}_DEBUG})
    else()
        set(_output ${${_library}})
    endif()
    set(${_endvar} ${_output} PARENT_SCOPE)
150 151
endfunction()

152 153 154 155
function(_gtest_find_library _name)
    find_library(${_name}
        NAMES ${ARGN}
        HINTS
156
            ENV GTEST_ROOT
157 158 159 160 161
            ${GTEST_ROOT}
        PATH_SUFFIXES ${_gtest_libpath_suffixes}
    )
    mark_as_advanced(${_name})
endfunction()
162

163
#
164

165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
if(NOT DEFINED GTEST_MSVC_SEARCH)
    set(GTEST_MSVC_SEARCH MD)
endif()

set(_gtest_libpath_suffixes lib)
if(MSVC)
    if(GTEST_MSVC_SEARCH STREQUAL "MD")
        list(APPEND _gtest_libpath_suffixes
            msvc/gtest-md/Debug
            msvc/gtest-md/Release)
    elseif(GTEST_MSVC_SEARCH STREQUAL "MT")
        list(APPEND _gtest_libpath_suffixes
            msvc/gtest/Debug
            msvc/gtest/Release)
    endif()
endif()
181 182


183 184 185 186 187 188
find_path(GTEST_INCLUDE_DIR gtest/gtest.h
    HINTS
        $ENV{GTEST_ROOT}/include
        ${GTEST_ROOT}/include
)
mark_as_advanced(GTEST_INCLUDE_DIR)
189

190 191 192 193 194 195 196
if(MSVC AND GTEST_MSVC_SEARCH STREQUAL "MD")
    # The provided /MD project files for Google Test add -md suffixes to the
    # library names.
    _gtest_find_library(GTEST_LIBRARY            gtest-md  gtest)
    _gtest_find_library(GTEST_LIBRARY_DEBUG      gtest-mdd gtestd)
    _gtest_find_library(GTEST_MAIN_LIBRARY       gtest_main-md  gtest_main)
    _gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_main-mdd gtest_maind)
197
else()
198 199 200 201
    _gtest_find_library(GTEST_LIBRARY            gtest)
    _gtest_find_library(GTEST_LIBRARY_DEBUG      gtestd)
    _gtest_find_library(GTEST_MAIN_LIBRARY       gtest_main)
    _gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_maind)
202 203
endif()

204
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
205 206 207 208 209 210 211
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTest DEFAULT_MSG GTEST_LIBRARY GTEST_INCLUDE_DIR GTEST_MAIN_LIBRARY)

if(GTEST_FOUND)
    set(GTEST_INCLUDE_DIRS ${GTEST_INCLUDE_DIR})
    _gtest_append_debugs(GTEST_LIBRARIES      GTEST_LIBRARY)
    _gtest_append_debugs(GTEST_MAIN_LIBRARIES GTEST_MAIN_LIBRARY)
    set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES})
212

213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
    include(CMakeFindDependencyMacro)
    find_dependency(Threads)

    if(NOT TARGET GTest::GTest)
        add_library(GTest::GTest UNKNOWN IMPORTED)
        set_target_properties(GTest::GTest PROPERTIES
            INTERFACE_LINK_LIBRARIES "Threads::Threads")
        if(GTEST_INCLUDE_DIRS)
            set_target_properties(GTest::GTest PROPERTIES
                INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIRS}")
        endif()
        if(EXISTS "${GTEST_LIBRARY}")
            set_target_properties(GTest::GTest PROPERTIES
                IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
                IMPORTED_LOCATION "${GTEST_LIBRARY}")
        endif()
        if(EXISTS "${GTEST_LIBRARY_DEBUG}")
            set_property(TARGET GTest::GTest APPEND PROPERTY
                IMPORTED_CONFIGURATIONS DEBUG)
            set_target_properties(GTest::GTest PROPERTIES
                IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
                IMPORTED_LOCATION_DEBUG "${GTEST_LIBRARY_DEBUG}")
        endif()
        if(EXISTS "${GTEST_LIBRARY_RELEASE}")
            set_property(TARGET GTest::GTest APPEND PROPERTY
                IMPORTED_CONFIGURATIONS RELEASE)
            set_target_properties(GTest::GTest PROPERTIES
                IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
                IMPORTED_LOCATION_RELEASE "${GTEST_LIBRARY_RELEASE}")
        endif()
      endif()
      if(NOT TARGET GTest::Main)
          add_library(GTest::Main UNKNOWN IMPORTED)
          set_target_properties(GTest::Main PROPERTIES
              INTERFACE_LINK_LIBRARIES "GTest::GTest")
          if(EXISTS "${GTEST_MAIN_LIBRARY}")
              set_target_properties(GTest::Main PROPERTIES
                  IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
                  IMPORTED_LOCATION "${GTEST_MAIN_LIBRARY}")
          endif()
          if(EXISTS "${GTEST_MAIN_LIBRARY_DEBUG}")
            set_property(TARGET GTest::Main APPEND PROPERTY
                IMPORTED_CONFIGURATIONS DEBUG)
            set_target_properties(GTest::Main PROPERTIES
                IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
                IMPORTED_LOCATION_DEBUG "${GTEST_MAIN_LIBRARY_DEBUG}")
          endif()
          if(EXISTS "${GTEST_MAIN_LIBRARY_RELEASE}")
            set_property(TARGET GTest::Main APPEND PROPERTY
                IMPORTED_CONFIGURATIONS RELEASE)
            set_target_properties(GTest::Main PROPERTIES
                IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
                IMPORTED_LOCATION_RELEASE "${GTEST_MAIN_LIBRARY_RELEASE}")
          endif()
    endif()
endif()