Commit caab8270a5c038fe9412e6de4ab8f114be61993b

Patrick Steinhardt 2017-06-23T19:07:01

cmake: create object library target Currently, we're compiling our library code twice, once as part of the libgit2 library and once for the libgit2_clar executable. Since CMake 2.8.8, there exists a new library type OBJECT, which represents an intermediate target which can then subsequently be used when linking several targets against the same set of objects. Use an OBJECT library to create an internal library for linking. This new target is only used on CMake v2.8.8 or newer. As CMake 3.0 changed the way how generator expressions are evaluated when accessing properties, we need to enable CMake policy 0051 to keep `IDE_SPLIT_SOURCES` functioning.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index fb2f1ea..54809e1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,6 +14,9 @@
 PROJECT(libgit2 C)
 CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
 CMAKE_POLICY(SET CMP0015 NEW)
+IF (CMAKE_VERSION VERSION_GREATER 3.0)
+	CMAKE_POLICY(SET CMP0051 NEW)
+ENDIF()
 
 # Add find modules to the path
 SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
@@ -609,8 +612,24 @@ ELSE()
 	MESSAGE(FATAL_ERROR "Unsupported architecture (CMAKE_SIZEOF_VOID_P is unset)")
 ENDIF()
 
+SET(GIT2INTERNAL_OBJECTS ${SRC_H} ${SRC_GIT2} ${SRC_OS} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SSH} ${SRC_SHA1})
+
+IF (CMAKE_VERSION VERSION_GREATER 2.8.7)
+	ADD_LIBRARY(git2internal OBJECT ${GIT2INTERNAL_OBJECTS})
+	IDE_SPLIT_SOURCES(git2internal)
+	SET(GIT2INTERNAL_OBJECTS $<TARGET_OBJECTS:git2internal>)
+
+	IF (${CMAKE_VERSION} VERSION_LESS 2.8.12)
+		INCLUDE_DIRECTORIES(src include)
+	ELSE()
+		TARGET_INCLUDE_DIRECTORIES(git2internal PRIVATE src PUBLIC include)
+	ENDIF()
+ELSE()
+	INCLUDE_DIRECTORIES(src include)
+ENDIF()
+
 # Compile and link libgit2
-ADD_LIBRARY(git2 ${SRC_H} ${SRC_GIT2} ${SRC_OS} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SSH} ${SRC_SHA1} ${WIN_RC})
+ADD_LIBRARY(git2 ${WIN_RC} ${GIT2INTERNAL_OBJECTS})
 TARGET_LINK_LIBRARIES(git2 ${SECURITY_DIRS})
 TARGET_LINK_LIBRARIES(git2 ${COREFOUNDATION_DIRS})
 TARGET_LINK_LIBRARIES(git2 ${SSL_LIBRARIES})
@@ -619,12 +638,6 @@ TARGET_LINK_LIBRARIES(git2 ${GSSAPI_LIBRARIES})
 TARGET_LINK_LIBRARIES(git2 ${ICONV_LIBRARIES})
 TARGET_OS_LIBRARIES(git2)
 
-IF (${CMAKE_VERSION} VERSION_LESS 2.8.12)
-	INCLUDE_DIRECTORIES(src include)
-ELSE()
-	TARGET_INCLUDE_DIRECTORIES(git2 PRIVATE src PUBLIC include)
-ENDIF()
-
 # Workaround for Cmake bug #0011240 (see http://public.kitware.com/Bug/view.php?id=11240)
 # Win64+MSVC+static libs = linker error
 IF(MSVC AND GIT_ARCH_64 AND NOT BUILD_SHARED_LIBS)
@@ -692,7 +705,7 @@ IF (BUILD_CLAR)
 		${CLAR_PATH}/clar.c
 		PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clar.suite)
 
-	ADD_EXECUTABLE(libgit2_clar ${SRC_H} ${SRC_GIT2} ${SRC_OS} ${SRC_CLAR} ${SRC_TEST} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SSH} ${SRC_SHA1})
+	ADD_EXECUTABLE(libgit2_clar ${SRC_CLAR} ${SRC_TEST} $<TARGET_OBJECTS:git2internal>)
 
 	IF (${CMAKE_VERSION} VERSION_GREATER 2.8.11)
 		TARGET_INCLUDE_DIRECTORIES(libgit2_clar PRIVATE src PUBLIC include)