Commit a390a8464e720365271238d80586d2b6c6ac3780

Patrick Steinhardt 2017-07-01T13:06:00

cmake: move defines into "features.h" header In a future commit, we will split out the build instructions for our library directory and move them into a subdirectory. One of the benefits is fixing scoping issues, where e.g. defines do not leak to build targets where they do not belong to. But unfortunately, this does also pose the problem of how to propagate some defines which are required by both the library and the test suite. One way would be to create another variable keeping track of all added defines and declare it inside of the parent scope. While this is the most obvious and simplest way of going ahead, it is kind of unfortunate. The main reason to not use this is that these defines become implicit dependencies between the build targets. By simply observing a define inside of the CMakeLists.txt file, one cannot reason whether this define is only required by the current target or whether it is required by different targets, as well. Another approach would be to use an internal header file keeping track of all defines shared between targets. While configuring the library, we will set various variables and let CMake configure the file, adding or removing defines based on what has been configured. Like this, one can easily keep track of the current environment by simply inspecting the header file. Furthermore, these dependencies are becoming clear inside the CMakeLists.txt, as instead of simply adding a define, we now call e.g. `SET(GIT_THREADSAFE 1)`. Having this header file though requires us to make sure it is always included before any "#ifdef"-preprocessor checks are executed. As we have already refactored code to always include the "common.h" header file before any statement inside of a file, this becomes easy: just make sure "common.h" includes the new "features.h" header file first.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4695801..3f9ecd8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -51,7 +51,7 @@ OPTION( USE_EXT_HTTP_PARSER		"Use system HTTP_Parser if available" ON)
 OPTION( DEBUG_POOL			"Enable debug pool allocator"			OFF )
 
 IF(DEBUG_POOL)
-	ADD_DEFINITIONS(-DGIT_DEBUG_POOL)
+	SET(GIT_DEBUG_POOL 1)
 ENDIF()
 
 IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
@@ -237,12 +237,12 @@ IF (WIN32 AND EMBED_SSH_PATH)
 	FILE(GLOB SRC_SSH "${EMBED_SSH_PATH}/src/*.c")
 	INCLUDE_DIRECTORIES("${EMBED_SSH_PATH}/include")
 	FILE(WRITE "${EMBED_SSH_PATH}/src/libssh2_config.h" "#define HAVE_WINCNG\n#define LIBSSH2_WINCNG\n#include \"../win32/libssh2_config.h\"")
-	ADD_DEFINITIONS(-DGIT_SSH)
+	SET(GIT_SSH 1)
 ENDIF()
 
 IF (WIN32 AND WINHTTP)
-	ADD_DEFINITIONS(-DGIT_WINHTTP)
-	ADD_DEFINITIONS(-DGIT_HTTPS)
+	SET(GIT_WINHTTP 1)
+	SET(GIT_HTTPS 1)
 
 	# Since MinGW does not come with headers or an import library for winhttp,
 	# we have to include a private header and generate our own import library
@@ -289,7 +289,7 @@ ELSE ()
 	ENDIF ()
 
 	IF (CURL_FOUND)
-		ADD_DEFINITIONS(-DGIT_CURL)
+		SET(GIT_CURL 1)
 		INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIRS})
 		LINK_DIRECTORIES(${CURL_LIBRARY_DIRS})
 		LINK_LIBRARIES(${CURL_LIBRARIES})
@@ -299,18 +299,18 @@ ENDIF()
 
 # Specify sha1 implementation
 IF (USE_SHA1DC)
-	ADD_DEFINITIONS(-DGIT_SHA1_COLLISIONDETECT)
+	SET(GIT_SHA1_COLLISIONDETECT 1)
 	ADD_DEFINITIONS(-DSHA1DC_NO_STANDARD_INCLUDES=1)
 	ADD_DEFINITIONS(-DSHA1DC_CUSTOM_INCLUDE_SHA1_C=\"common.h\")
 	ADD_DEFINITIONS(-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"common.h\")
 	FILE(GLOB SRC_SHA1 src/hash/hash_collisiondetect.c src/hash/sha1dc/*)
 ELSEIF (WIN32 AND NOT MINGW)
-	ADD_DEFINITIONS(-DGIT_SHA1_WIN32)
+	SET(GIT_SHA1_WIN32 1)
 	FILE(GLOB SRC_SHA1 src/hash/hash_win32.c)
 ELSEIF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
-	ADD_DEFINITIONS(-DGIT_SHA1_COMMON_CRYPTO)
+	SET(GIT_SHA1_COMMON_CRYPTO 1)
 ELSEIF (OPENSSL_FOUND)
-	ADD_DEFINITIONS(-DGIT_SHA1_OPENSSL)
+	SET(GIT_SHA1_OPENSSL 1)
 	IF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
 		LIST(APPEND LIBGIT2_PC_LIBS "-lssl")
 	ELSE()
@@ -322,7 +322,7 @@ ENDIF()
 
 # Enable tracing
 IF (ENABLE_TRACE STREQUAL "ON")
-	ADD_DEFINITIONS(-DGIT_TRACE)
+	SET(GIT_TRACE 1)
 ENDIF()
 
 # Include POSIX regex when it is required
@@ -365,7 +365,7 @@ IF (USE_SSH)
 	PKG_CHECK_MODULES(LIBSSH2 libssh2)
 ENDIF()
 IF (LIBSSH2_FOUND)
-	ADD_DEFINITIONS(-DGIT_SSH)
+	SET(GIT_SSH 1)
 	INCLUDE_DIRECTORIES(${LIBSSH2_INCLUDE_DIRS})
 	LINK_DIRECTORIES(${LIBSSH2_LIBRARY_DIRS})
 	LIST(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS})
@@ -374,7 +374,7 @@ IF (LIBSSH2_FOUND)
 
 	CHECK_LIBRARY_EXISTS("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS)
 	IF (HAVE_LIBSSH2_MEMORY_CREDENTIALS)
-		ADD_DEFINITIONS(-DGIT_SSH_MEMORY_CREDENTIALS)
+		SET(GIT_SSH_MEMORY_CREDENTIALS 1)
 	ENDIF()
 ELSE()
 	MESSAGE(STATUS "LIBSSH2 not found. Set CMAKE_PREFIX_PATH if it is installed outside of the default search path.")
@@ -385,7 +385,7 @@ IF (USE_GSSAPI)
 	FIND_PACKAGE(GSSAPI)
 ENDIF()
 IF (GSSAPI_FOUND)
-	ADD_DEFINITIONS(-DGIT_GSSAPI)
+	SET(GIT_GSSAPI 1)
 ENDIF()
 
 # Optional external dependency: iconv
@@ -393,7 +393,7 @@ IF (USE_ICONV)
 	FIND_PACKAGE(Iconv)
 ENDIF()
 IF (ICONV_FOUND)
-	ADD_DEFINITIONS(-DGIT_USE_ICONV)
+	SET(GIT_USE_ICONV 1)
 	INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR})
 	LIST(APPEND LIBGIT2_PC_LIBS ${ICONV_LIBRARIES})
 ENDIF()
@@ -421,7 +421,8 @@ IF (MSVC)
 	ENDIF()
 
 	IF (MSVC_CRTDBG)
-		SET(CRT_FLAG_DEBUG "${CRT_FLAG_DEBUG} /DGIT_MSVC_CRTDBG")
+		SET(GIT_MSVC_CRTDBG 1)
+		SET(CRT_FLAG_DEBUG "${CRT_FLAG_DEBUG}")
 		SET(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES}" "Dbghelp.lib")
 	ENDIF()
 
@@ -548,16 +549,16 @@ ELSE()
 ENDIF()
 
 IF (SECURITY_FOUND)
-  ADD_DEFINITIONS(-DGIT_SECURE_TRANSPORT)
-  ADD_DEFINITIONS(-DGIT_HTTPS)
-  INCLUDE_DIRECTORIES(${SECURITY_INCLUDE_DIR})
+	SET(GIT_SECURE_TRANSPORT 1)
+	SET(GIT_HTTPS 1)
+	INCLUDE_DIRECTORIES(${SECURITY_INCLUDE_DIR})
 ENDIF ()
 
 IF (OPENSSL_FOUND)
-  ADD_DEFINITIONS(-DGIT_OPENSSL)
-  ADD_DEFINITIONS(-DGIT_HTTPS)
-  INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
-  SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES})
+	SET(GIT_OPENSSL 1)
+	SET(GIT_HTTPS 1)
+	INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
+	SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES})
 ENDIF()
 
 
@@ -567,19 +568,19 @@ IF (THREADSAFE)
 		FIND_PACKAGE(Threads REQUIRED)
 	ENDIF()
 
-	ADD_DEFINITIONS(-DGIT_THREADS)
+	SET(GIT_THREADS 1)
 ENDIF()
 
 IF (USE_NSEC)
-	ADD_DEFINITIONS(-DGIT_USE_NSEC)
+	SET(GIT_USE_NSEC 1)
 ENDIF()
 
 IF (HAVE_STRUCT_STAT_ST_MTIM)
-	ADD_DEFINITIONS(-DGIT_USE_STAT_MTIM)
+	SET(GIT_USE_STAT_MTIM 1)
 ELSEIF (HAVE_STRUCT_STAT_ST_MTIMESPEC)
-	ADD_DEFINITIONS(-DGIT_USE_STAT_MTIMESPEC)
+	SET(GIT_USE_STAT_MTIMESPEC 1)
 ELSEIF (HAVE_STRUCT_STAT_ST_MTIME_NSEC)
-	ADD_DEFINITIONS(-DGIT_USE_STAT_MTIME_NSEC)
+	SET(GIT_USE_STAT_MTIME_NSEC 1)
 ENDIF()
 
 ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
@@ -603,15 +604,18 @@ FILE(GLOB SRC_GIT2 src/*.c src/*.h src/transports/*.c src/transports/*.h src/xdi
 
 # Determine architecture of the machine
 IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
-	ADD_DEFINITIONS(-DGIT_ARCH_64)
+	SET(GIT_ARCH_64 1)
 ELSEIF (CMAKE_SIZEOF_VOID_P EQUAL 4)
-	ADD_DEFINITIONS(-DGIT_ARCH_32)
+	SET(GIT_ARCH_32 1)
 ELSEIF (CMAKE_SIZEOF_VOID_P)
 	MESSAGE(FATAL_ERROR "Unsupported architecture (pointer size is ${CMAKE_SIZEOF_VOID_P} bytes)")
 ELSE()
 	MESSAGE(FATAL_ERROR "Unsupported architecture (CMAKE_SIZEOF_VOID_P is unset)")
 ENDIF()
 
+CONFIGURE_FILE(src/features.h.in git2/sys/features.h)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
 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)
diff --git a/src/common.h b/src/common.h
index 7a93d99..17b9c14 100644
--- a/src/common.h
+++ b/src/common.h
@@ -7,6 +7,7 @@
 #ifndef INCLUDE_common_h__
 #define INCLUDE_common_h__
 
+#include "git2/sys/features.h"
 #include "git2/common.h"
 #include "cc-compat.h"
 
diff --git a/src/features.h.in b/src/features.h.in
new file mode 100644
index 0000000..c3fcc51
--- /dev/null
+++ b/src/features.h.in
@@ -0,0 +1,34 @@
+#ifndef INCLUDE_features_h__
+#define INCLUDE_features_h__
+
+#cmakedefine GIT_DEBUG_POOL 1
+#cmakedefine GIT_TRACE 1
+#cmakedefine GIT_THREADS 1
+#cmakedefine GIT_MSVC_CRTDBG 1
+
+#cmakedefine GIT_ARCH_64 1
+#cmakedefine GIT_ARCH_32 1
+
+#cmakedefine GIT_USE_ICONV 1
+#cmakedefine GIT_USE_NSEC 1
+#cmakedefine GIT_USE_STAT_MTIM 1
+#cmakedefine GIT_USE_STAT_MTIMESPEC 1
+#cmakedefine GIT_USE_STAT_MTIME_NSEC 1
+
+#cmakedefine GIT_SSH 1
+#cmakedefine GIT_SSH_MEMORY_CREDENTIALS 1
+
+#cmakedefine GIT_GSSAPI 1
+#cmakedefine GIT_WINHTTP 1
+#cmakedefine GIT_CURL 1
+
+#cmakedefine GIT_HTTPS 1
+#cmakedefine GIT_OPENSSL 1
+#cmakedefine GIT_SECURE_TRANSPORT 1
+
+#cmakedefine GIT_SHA1_COLLISIONDETECT 1
+#cmakedefine GIT_SHA1_WIN32 1
+#cmakedefine GIT_SHA1_COMMON_CRYPTO 1
+#cmakedefine GIT_SHA1_OPENSSL 1
+
+#endif
diff --git a/src/unix/posix.h b/src/unix/posix.h
index 52985fd..5483419 100644
--- a/src/unix/posix.h
+++ b/src/unix/posix.h
@@ -7,6 +7,7 @@
 #ifndef INCLUDE_posix__unix_h__
 #define INCLUDE_posix__unix_h__
 
+#include "git2/sys/features.h"
 #include <stdio.h>
 #include <dirent.h>
 #include <sys/param.h>
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 31144c6..6566f53 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -10,7 +10,7 @@ SET(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
 ADD_DEFINITIONS(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\")
 ADD_DEFINITIONS(-DCLAR_TMPDIR=\"libgit2_tests\")
 
-INCLUDE_DIRECTORIES(${CLAR_PATH})
+INCLUDE_DIRECTORIES(${CLAR_PATH} ${CMAKE_BINARY_DIR}/src)
 FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/*/*.h)
 SET(SRC_CLAR "main.c" "clar_libgit2.c" "clar_libgit2_trace.c" "clar_libgit2_timer.c" "clar.c")