From 3e33bb316651981916d623488caf2f8ee1b79b50 Mon Sep 17 00:00:00 2001
From: "Azamat H. Hackimov" <azamat.hackimov@gmail.com>
Date: Thu, 9 Aug 2018 15:11:50 +0300
Subject: [PATCH] Improvements to CMake buildsystem (#563)

* Move enable_testing() into proper place

* Added CMake's checks for C++11 standards

Raised minimal version of CMake to 3.1, since on old systems there no
decent compilers that supports c++11.

Closes #377.

* Externalize googletest project

Externalize gtest to avoid installation, fixes #539.

* Remove defined cmake_policies

CMP0012 - OLD marked as deprecated for >=cmake-3.1 and will be removed
CMP0015 - does not affect to build process
CMP0042 - already NEW for >=cmake-3.1

Fixes #505

* Fix compiling in Windows MSVC
---
 CMakeLists.txt      | 26 +++++-------------
 test/CMakeLists.txt | 67 +++++++++++++++++++++++++++++----------------
 util/CMakeLists.txt |  4 +--
 3 files changed, 51 insertions(+), 46 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 715c846..154230a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,26 +1,11 @@
 ###
 ### CMake settings
 ###
-## Due to Mac OSX we need to keep compatibility with CMake 2.6
 # see http://www.cmake.org/Wiki/CMake_Policies
-cmake_minimum_required(VERSION 2.6)
-# see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#policy:CMP0012
-if(POLICY CMP0012)
-	cmake_policy(SET CMP0012 OLD)
-endif()
-# see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#policy:CMP0015
-if(POLICY CMP0015)
-	cmake_policy(SET CMP0015 OLD)
-endif()
-# see https://cmake.org/cmake/help/latest/policy/CMP0042.html
-if(POLICY CMP0042)
-	# Enable MACOSX_RPATH by default.
-	cmake_policy(SET CMP0042 NEW)
-endif()
+cmake_minimum_required(VERSION 3.1)
 
 include(CheckCXXCompilerFlag)
 
-
 ###
 ### Project settings
 ###
@@ -31,8 +16,6 @@ set(YAML_CPP_VERSION_MINOR "6")
 set(YAML_CPP_VERSION_PATCH "2")
 set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}")
 
-enable_testing()
-
 
 ###
 ### Project options
@@ -48,6 +31,10 @@ option(YAML_CPP_BUILD_CONTRIB "Enable contrib stuff in library" ON)
 #     http://www.cmake.org/cmake/help/cmake2.6docs.html#command:add_library
 option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
 
+# Set minimum C++ to 2011 standards
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
 # --> Apple
 option(APPLE_UNIVERSAL_BIN "Apple: Build universal binary" OFF)
 
@@ -188,7 +175,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR
 		set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} ${FLAG_TESTED}")
 	endif()
 	#
-	set(yaml_cxx_flags "-Wall ${GCC_EXTRA_OPTIONS} -pedantic -Wno-long-long -std=c++11 ${yaml_cxx_flags}")
+	set(yaml_cxx_flags "-Wall ${GCC_EXTRA_OPTIONS} -pedantic -Wno-long-long ${yaml_cxx_flags}")
 
 	### Make specific
 	if(${CMAKE_BUILD_TOOL} MATCHES make OR ${CMAKE_BUILD_TOOL} MATCHES gmake)
@@ -360,6 +347,7 @@ endif()
 ### Extras
 ###
 if(YAML_CPP_BUILD_TESTS)
+	enable_testing()
 	add_subdirectory(test)
 endif()
 if(YAML_CPP_BUILD_TOOLS)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index ad61a3c..a83d9dd 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,26 +1,39 @@
-set(gtest_force_shared_crt ${MSVC_SHARED_RT} CACHE BOOL
-  "Use shared (DLL) run-time lib even when Google Test built as a static lib.")
-add_subdirectory(gtest-1.8.0)
-include_directories(SYSTEM gtest-1.8.0/googlemock/include)
-include_directories(SYSTEM gtest-1.8.0/googletest/include)
-
-if(WIN32 AND BUILD_SHARED_LIBS)
-  add_definitions("-DGTEST_LINKED_AS_SHARED_LIBRARY")
+include(ExternalProject)
+
+if(MSVC)
+    # MS Visual Studio expects lib prefix on static libraries,
+    # but CMake compiles them without prefix
+    # See https://gitlab.kitware.com/cmake/cmake/issues/17338
+    set(CMAKE_STATIC_LIBRARY_PREFIX "")
 endif()
 
+ExternalProject_Add(
+	googletest_project
+	SOURCE_DIR "${CMAKE_SOURCE_DIR}/test/gtest-1.8.0"
+	INSTALL_DIR "${CMAKE_BINARY_DIR}/prefix"
+	CMAKE_ARGS
+		-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+		-DBUILD_GMOCK=ON
+		-Dgtest_force_shared_crt=ON
+)
+
+add_library(gmock UNKNOWN IMPORTED)
+set_target_properties(gmock PROPERTIES
+    IMPORTED_LOCATION
+    ${PROJECT_BINARY_DIR}/prefix/lib/${CMAKE_STATIC_LIBRARY_PREFIX}gmock${CMAKE_STATIC_LIBRARY_SUFFIX}
+)
+
+find_package(Threads)
+
+include_directories(SYSTEM "${PROJECT_BINARY_DIR}/prefix/include")
+
 if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR
-   CMAKE_CXX_COMPILER_ID MATCHES "Clang")
-  set(yaml_test_flags "-Wno-variadic-macros -Wno-sign-compare")
-
-  if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
-    set(yaml_test_flags "${yaml_test_flags} -Wno-c99-extensions")
-  endif()
-
-  if(CMAKE_COMPILER_IS_GNUCXX)
-    set(yaml_test_flags "${yaml_test_flags} -std=gnu++11")
-  else()
-    set(yaml_test_flags "${yaml_test_flags} -std=c++11")
-  endif()
+	CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+	set(yaml_test_flags "-Wno-variadic-macros -Wno-sign-compare")
+
+	if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+		set(yaml_test_flags "${yaml_test_flags} -Wno-c99-extensions")
+	endif()
 endif()
 
 file(GLOB test_headers [a-z_]*.h)
@@ -34,12 +47,18 @@ include_directories(${YAML_CPP_SOURCE_DIR}/src)
 include_directories(${YAML_CPP_SOURCE_DIR}/test)
 
 add_executable(run-tests
-	${test_sources}
-	${test_headers}
+    ${test_sources}
+    ${test_headers}
 )
+
+add_dependencies(run-tests googletest_project)
+
 set_target_properties(run-tests PROPERTIES
-  COMPILE_FLAGS "${yaml_c_flags} ${yaml_cxx_flags} ${yaml_test_flags}"
+    COMPILE_FLAGS "${yaml_c_flags} ${yaml_cxx_flags} ${yaml_test_flags}"
 )
-target_link_libraries(run-tests yaml-cpp gmock)
+target_link_libraries(run-tests
+    yaml-cpp
+    gmock
+    ${CMAKE_THREAD_LIBS_INIT})
 
 add_test(yaml-test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/run-tests)
diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt
index 931884f..8a803b0 100644
--- a/util/CMakeLists.txt
+++ b/util/CMakeLists.txt
@@ -3,14 +3,12 @@ cmake_minimum_required(VERSION 3.5)
 add_sources(parse.cpp)
 add_executable(parse parse.cpp)
 target_link_libraries(parse yaml-cpp)
-set_target_properties(parse PROPERTIES COMPILE_FLAGS "-std=c++11")
 
 add_sources(sandbox.cpp)
 add_executable(sandbox sandbox.cpp)
 target_link_libraries(sandbox yaml-cpp)
-set_target_properties(sandbox PROPERTIES COMPILE_FLAGS "-std=c++11")
 
 add_sources(read.cpp)
 add_executable(read read.cpp)
 target_link_libraries(read yaml-cpp)
-set_target_properties(read PROPERTIES COMPILE_FLAGS "-std=c++11")
+
-- 
GitLab