Merge pull request #1682 from dakotahawkins/improve-exported-targets

Improve CMake exported targets
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f8a97fa..db1b289 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,22 +1,16 @@
-cmake_minimum_required(VERSION 2.6.4)
+cmake_minimum_required(VERSION 2.8.8)
 
 if (POLICY CMP0048)
   cmake_policy(SET CMP0048 NEW)
 endif (POLICY CMP0048)
 
-project( googletest-distribution )
+project(googletest-distribution)
+set(GOOGLETEST_VERSION 1.9.0)
 
 enable_testing()
 
 include(CMakeDependentOption)
-if (CMAKE_VERSION VERSION_LESS 2.8.5)
-  set(CMAKE_INSTALL_BINDIR "bin" CACHE STRING "User executables (bin)")
-  set(CMAKE_INSTALL_LIBDIR "lib${LIB_SUFFIX}" CACHE STRING "Object code libraries (lib)")
-  set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE STRING "C header files (include)")
-  mark_as_advanced(CMAKE_INSTALL_BINDIR CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_INCLUDEDIR)
-else()
-  include(GNUInstallDirs)
-endif()
+include(GNUInstallDirs)
 
 option(BUILD_GTEST "Builds the googletest subproject" OFF)
 
@@ -26,8 +20,31 @@
 cmake_dependent_option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" ON "BUILD_GTEST OR BUILD_GMOCK" OFF)
 cmake_dependent_option(INSTALL_GMOCK "Enable installation of googlemock. (Projects embedding googlemock may want to turn this OFF.)" ON "BUILD_GMOCK" OFF)
 
+if(WIN32)
+  set(INSTALL_CMAKE_DIR "cmake" CACHE PATH "CMake exported targets")
+else()
+  set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/gtest" CACHE PATH "CMake exported targets")
+endif()
+
+set(googletest_install_targets)
 if(BUILD_GMOCK)
   add_subdirectory( googlemock )
 elseif(BUILD_GTEST)
   add_subdirectory( googletest )
 endif()
+
+if(googletest_install_targets)
+  include(CMakePackageConfigHelpers)
+  configure_package_config_file(
+    "${CMAKE_CURRENT_LIST_DIR}/cmake/googletestConfig.cmake.in"
+    "${CMAKE_CURRENT_BINARY_DIR}/googletestConfig.cmake"
+    INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}")
+  write_basic_package_version_file(
+    ${CMAKE_CURRENT_BINARY_DIR}/googletestConfigVersion.cmake
+    VERSION "${GOOGLETEST_VERSION}"
+    COMPATIBILITY SameMajorVersion)
+  install(FILES
+    ${CMAKE_CURRENT_BINARY_DIR}/googletestConfig.cmake
+    ${CMAKE_CURRENT_BINARY_DIR}/googletestConfigVersion.cmake
+    DESTINATION "${INSTALL_CMAKE_DIR}")
+endif()
diff --git a/cmake/googletestConfig.cmake.in b/cmake/googletestConfig.cmake.in
new file mode 100644
index 0000000..3a5957f
--- /dev/null
+++ b/cmake/googletestConfig.cmake.in
@@ -0,0 +1,35 @@
+@PACKAGE_INIT@
+
+set(googletest_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
+
+set(googletest_NAMESPACE_TARGETS)
+set(googletest_ALL_INCLUDE_DIRS)
+
+foreach(target @googletest_install_targets@)
+  include(${CMAKE_CURRENT_LIST_DIR}/${target}ConfigInternal.cmake)
+
+  add_library(googletest::${target} INTERFACE IMPORTED)
+  set_target_properties(googletest::${target}
+    PROPERTIES
+      INTERFACE_LINK_LIBRARIES googletest_${target}
+      IMPORTED_GLOBAL ON)
+  if(googletest_BUILD_SHARED_LIBS)
+    set_target_properties(googletest::${target}
+      PROPERTIES
+        INTERFACE_COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
+  endif()
+  add_library(${target} ALIAS googletest::${target})
+
+  get_target_property(${target}_INCLUDE_DIRS googletest_${target} INTERFACE_INCLUDE_DIRECTORIES)
+
+  list(APPEND googletest_ALL_INCLUDE_DIRS ${${target}_INCLUDE_DIRS})
+  list(APPEND googletest_NAMESPACE_TARGETS googletest::${target})
+endforeach()
+
+list(REMOVE_DUPLICATES googletest_ALL_INCLUDE_DIRS)
+set(GOOGLETEST_INCLUDE_DIRS ${googletest_ALL_INCLUDE_DIRS})
+
+list(REMOVE_DUPLICATES googletest_NAMESPACE_TARGETS)
+set(GOOGLETEST_LIBRARIES ${googletest_NAMESPACE_TARGETS})
+
+set(GOOGLETEST_VERSION "@GOOGLETEST_VERSION@")
diff --git a/googlemock/CMakeLists.txt b/googlemock/CMakeLists.txt
index 07b6ad2..1db14a2 100644
--- a/googlemock/CMakeLists.txt
+++ b/googlemock/CMakeLists.txt
@@ -37,7 +37,7 @@
   project(gmock CXX C)
 else()
   cmake_policy(SET CMP0048 NEW)
-  project(gmock VERSION 1.9.0 LANGUAGES CXX C)
+  project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
 endif()
 cmake_minimum_required(VERSION 2.6.4)
 
@@ -120,18 +120,45 @@
 # to the targets for when we are part of a parent build (ie being pulled
 # in via add_subdirectory() rather than being a standalone build).
 if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
-  target_include_directories(gmock      SYSTEM INTERFACE "${gmock_SOURCE_DIR}/include")
-  target_include_directories(gmock_main SYSTEM INTERFACE "${gmock_SOURCE_DIR}/include")
+  target_include_directories(gmock SYSTEM
+    INTERFACE
+      $<BUILD_INTERFACE:${gmock_SOURCE_DIR}/include>
+      $<BUILD_INTERFACE:${gmock_SOURCE_DIR}>
+      $<BUILD_INTERFACE:${gtest_SOURCE_DIR}/include>
+      $<BUILD_INTERFACE:${gtest_SOURCE_DIR}>
+      $<INSTALL_INTERFACE:include>)
+  target_include_directories(gmock_main SYSTEM
+    INTERFACE
+      $<BUILD_INTERFACE:${gmock_SOURCE_DIR}/include>
+      $<BUILD_INTERFACE:${gmock_SOURCE_DIR}>
+      $<BUILD_INTERFACE:${gtest_SOURCE_DIR}/include>
+      $<BUILD_INTERFACE:${gtest_SOURCE_DIR}>
+      $<INSTALL_INTERFACE:include>)
 endif()
 
 ########################################################################
 #
 # Install rules
 if(INSTALL_GMOCK)
-  install(TARGETS gmock gmock_main
+  install(TARGETS gmock
+    EXPORT gmockConfigInternal
     RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
-    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
-    ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
+    ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
+  install(EXPORT gmockConfigInternal
+    DESTINATION "${INSTALL_CMAKE_DIR}"
+    NAMESPACE googletest_)
+  install(TARGETS gmock_main
+    EXPORT gmock_mainConfigInternal
+    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+    ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
+  install(EXPORT gmock_mainConfigInternal
+    DESTINATION "${INSTALL_CMAKE_DIR}"
+    NAMESPACE googletest_)
+  set(googletest_install_targets
+    ${googletest_install_targets} gmock gmock_main PARENT_SCOPE)
+
   install(DIRECTORY "${gmock_SOURCE_DIR}/include/gmock"
     DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
 
diff --git a/googletest/CMakeLists.txt b/googletest/CMakeLists.txt
index 2c735f6..3ab964f 100644
--- a/googletest/CMakeLists.txt
+++ b/googletest/CMakeLists.txt
@@ -44,7 +44,7 @@
   project(gtest CXX C)
 else()
   cmake_policy(SET CMP0048 NEW)
-  project(gtest VERSION 1.9.0 LANGUAGES CXX C)
+  project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
 endif()
 cmake_minimum_required(VERSION 2.6.4)
 
@@ -118,18 +118,41 @@
 # to the targets for when we are part of a parent build (ie being pulled
 # in via add_subdirectory() rather than being a standalone build).
 if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
-  target_include_directories(gtest      SYSTEM INTERFACE "${gtest_SOURCE_DIR}/include")
-  target_include_directories(gtest_main SYSTEM INTERFACE "${gtest_SOURCE_DIR}/include")
+  target_include_directories(gtest SYSTEM
+    INTERFACE
+      $<BUILD_INTERFACE:${gtest_SOURCE_DIR}/include>
+      $<BUILD_INTERFACE:${gtest_SOURCE_DIR}>
+      $<INSTALL_INTERFACE:include>)
+  target_include_directories(gtest_main SYSTEM
+    INTERFACE
+      $<BUILD_INTERFACE:${gtest_SOURCE_DIR}/include>
+      $<BUILD_INTERFACE:${gtest_SOURCE_DIR}>
+      $<INSTALL_INTERFACE:include>)
 endif()
 
 ########################################################################
 #
 # Install rules
 if(INSTALL_GTEST)
-  install(TARGETS gtest gtest_main
+  install(TARGETS gtest
+    EXPORT gtestConfigInternal
     RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
     ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
     LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
+  install(EXPORT gtestConfigInternal
+    DESTINATION "${INSTALL_CMAKE_DIR}"
+    NAMESPACE googletest_)
+  install(TARGETS gtest_main
+    EXPORT gtest_mainConfigInternal
+    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+    ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
+  install(EXPORT gtest_mainConfigInternal
+    DESTINATION "${INSTALL_CMAKE_DIR}"
+    NAMESPACE googletest_)
+  set(googletest_install_targets
+    ${googletest_install_targets} gtest gtest_main PARENT_SCOPE)
+
   install(DIRECTORY "${gtest_SOURCE_DIR}/include/gtest"
     DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")