diff --git a/CMakeLists.txt b/CMakeLists.txt index fc530773d..696d6a088 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,67 @@ PROJECT(libgit2 C) CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +# Build options +# +OPTION( BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON ) +OPTION( THREADSAFE "Build libgit2 as threadsafe" OFF ) +OPTION( BUILD_CLAR "Build Tests using the Clar suite" ON ) +OPTION( BUILD_EXAMPLES "Build library usage example apps" OFF ) +OPTION( TAGS "Generate tags" OFF ) +OPTION( PROFILE "Generate profiling information" OFF ) +IF(MSVC) + # This option is only availalbe when building with MSVC. By default, libgit2 is + # build using the stdcall calling convention, as that's what the CLR expects by + # default and how the Windows API is built. + # + # If you are writing a C or C++ program and want to link to libgit2, you have to + # either: + # - Add /Gz to the compiler options of _your_ program / library. + # - Turn this option off by invoking CMake with the "-DSTDCALL=Off" argument. + # + OPTION( STDCALL "Build libgit2 with the __stdcall convention" ON ) +ENDIF() + +# Installation paths +# +SET(BIN_INSTALL_DIR bin CACHE PATH "Where to install binaries to.") +SET(LIB_INSTALL_DIR lib CACHE PATH "Where to install libraries to.") +SET(INCLUDE_INSTALL_DIR include CACHE PATH "Where to install headers to.") + +FUNCTION(TARGET_OS_LIBRARIES target) + IF(WIN32) + TARGET_LINK_LIBRARIES(${target} ws2_32) + ELSEIF(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") + TARGET_LINK_LIBRARIES(${target} socket nsl) + ENDIF () + IF(THREADSAFE) + TARGET_LINK_LIBRARIES(${target} ${CMAKE_THREAD_LIBS_INIT}) + ENDIF() +ENDFUNCTION() + +# For the MSVC IDE, this function splits up the source files like windows explorer does. +# This is esp. useful with the libgit2_clar project, were usually 2 or more files share +# the same name. +# Sadly, this file grouping is a per-directory option in cmake and not per-target, resulting +# in empty virtual folders "tests-clar" for the git2.dll +FUNCTION(MSVC_SPLIT_SOURCES target) + IF(MSVC_IDE) + GET_TARGET_PROPERTY(sources ${target} SOURCES) + FOREACH(source ${sources}) + IF(source MATCHES ".*/") + STRING(REPLACE ${CMAKE_CURRENT_SOURCE_DIR}/ "" rel ${source}) + IF(rel) + STRING(REGEX REPLACE "/([^/]*)$" "" rel ${rel}) + IF(rel) + STRING(REPLACE "/" "\\\\" rel ${rel}) + SOURCE_GROUP(${rel} FILES ${source}) + ENDIF() + ENDIF() + ENDIF() + ENDFOREACH() + ENDIF() +ENDFUNCTION() + FILE(STRINGS "include/git2/version.h" GIT2_HEADER REGEX "^#define LIBGIT2_VERSION \"[^\"]*\"$") STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"([0-9]+).*$" "\\1" LIBGIT2_VERSION_MAJOR "${GIT2_HEADER}") @@ -27,13 +88,14 @@ IF (AMIGA) ENDIF() # Find required dependencies -INCLUDE_DIRECTORIES(src include deps/http-parser) +INCLUDE_DIRECTORIES(src include) IF (WIN32 AND NOT MINGW) ADD_DEFINITIONS(-DGIT_WINHTTP) ELSE () FIND_PACKAGE(OpenSSL) FILE(GLOB SRC_HTTP deps/http-parser/*.c) + INCLUDE_DIRECTORIES(deps/http-parser) ENDIF() # Specify sha1 implementation @@ -49,44 +111,29 @@ ELSE() FILE(GLOB SRC_SHA1 src/hash/hash_generic.c) ENDIF() -IF (NOT WIN32) - FIND_PACKAGE(ZLIB) - IF (CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") - INCLUDE_DIRECTORIES(deps/regex) - SET(SRC_REGEX deps/regex/regex.c) - ENDIF() -ELSE() - # Windows doesn't understand POSIX regex on its own +# Include POSIX regex when it is required +IF(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") INCLUDE_DIRECTORIES(deps/regex) SET(SRC_REGEX deps/regex/regex.c) ENDIF() +# Optional external dependency: zlib +IF(NOT ZLIB_LIBRARY) + # It's optional, but FIND_PACKAGE gives a warning that looks more like an error. + FIND_PACKAGE(ZLIB QUIET) +ENDIF() IF (ZLIB_FOUND) INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIRS}) LINK_LIBRARIES(${ZLIB_LIBRARIES}) -ELSE (ZLIB_FOUND) +ELSE() + MESSAGE( "zlib was not found; using bundled 3rd-party sources." ) INCLUDE_DIRECTORIES(deps/zlib) ADD_DEFINITIONS(-DNO_VIZ -DSTDC -DNO_GZIP) FILE(GLOB SRC_ZLIB deps/zlib/*.c) ENDIF() -# Installation paths -SET(BIN_INSTALL_DIR bin CACHE PATH "Where to install binaries to.") -SET(LIB_INSTALL_DIR lib CACHE PATH "Where to install libraries to.") -SET(INCLUDE_INSTALL_DIR include CACHE PATH "Where to install headers to.") - -# Build options -OPTION (BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON) -OPTION (THREADSAFE "Build libgit2 as threadsafe" OFF) -OPTION (BUILD_CLAR "Build Tests using the Clar suite" ON) -OPTION (BUILD_EXAMPLES "Build library usage example apps" OFF) -OPTION (TAGS "Generate tags" OFF) -OPTION (PROFILE "Generate profiling information" OFF) - # Platform specific compilation flags IF (MSVC) - # Default to stdcall, as that's what the CLR expects and how the Windows API is built - OPTION (STDCALL "Buildl libgit2 with the __stdcall convention" ON) STRING(REPLACE "/Zm1000" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") @@ -148,26 +195,22 @@ FILE(GLOB SRC_H include/git2/*.h) # On Windows use specific platform sources IF (WIN32 AND NOT CYGWIN) ADD_DEFINITIONS(-DWIN32 -D_DEBUG -D_WIN32_WINNT=0x0501) - FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/win32/*.c src/compat/*.c) -ELSEIF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/unix/*.c src/compat/*.c) + FILE(GLOB SRC_OS src/win32/*.c) ELSEIF (AMIGA) ADD_DEFINITIONS(-DNO_ADDRINFO -DNO_READDIR_R) - FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/amiga/*.c src/compat/*.c) + FILE(GLOB SRC_OS src/amiga/*.c) ELSE() - FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/unix/*.c) -ENDIF () + FILE(GLOB SRC_OS src/unix/*.c) +ENDIF() +FILE(GLOB SRC_GIT2 src/*.c src/transports/*.c src/xdiff/*.c) # Compile and link libgit2 -ADD_LIBRARY(git2 ${SRC} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SHA1} ${WIN_RC}) +ADD_LIBRARY(git2 ${SRC_GIT2} ${SRC_OS} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SHA1} ${WIN_RC}) +TARGET_LINK_LIBRARIES(git2 ${SSL_LIBRARIES}) +TARGET_OS_LIBRARIES(git2) -IF (WIN32) - TARGET_LINK_LIBRARIES(git2 ws2_32) -ELSEIF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - TARGET_LINK_LIBRARIES(git2 socket nsl) -ENDIF () +MSVC_SPLIT_SOURCES(git2) -TARGET_LINK_LIBRARIES(git2 ${CMAKE_THREAD_LIBS_INIT} ${SSL_LIBRARIES}) SET_TARGET_PROPERTIES(git2 PROPERTIES VERSION ${LIBGIT2_VERSION_STRING}) SET_TARGET_PROPERTIES(git2 PROPERTIES SOVERSION ${LIBGIT2_VERSION_MAJOR}) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libgit2.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libgit2.pc @ONLY) @@ -208,20 +251,16 @@ IF (BUILD_CLAR) DEPENDS ${CLAR_PATH}/clar ${SRC_TEST} WORKING_DIRECTORY ${CLAR_PATH} ) - ADD_EXECUTABLE(libgit2_clar ${SRC} ${CLAR_PATH}/clar_main.c ${SRC_TEST} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SHA1}) - TARGET_LINK_LIBRARIES(libgit2_clar ${CMAKE_THREAD_LIBS_INIT} ${SSL_LIBRARIES}) + ADD_EXECUTABLE(libgit2_clar ${SRC_GIT2} ${SRC_OS} ${CLAR_PATH}/clar_main.c ${SRC_TEST} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SHA1}) + TARGET_LINK_LIBRARIES(libgit2_clar ${SSL_LIBRARIES}) + TARGET_OS_LIBRARIES(libgit2_clar) + MSVC_SPLIT_SOURCES(libgit2_clar) IF (MSVC_IDE) # Precompiled headers SET_TARGET_PROPERTIES(libgit2_clar PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") ENDIF () - IF (WIN32) - TARGET_LINK_LIBRARIES(libgit2_clar ws2_32) - ELSEIF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - TARGET_LINK_LIBRARIES(libgit2_clar socket nsl) - ENDIF () - ENABLE_TESTING() ADD_TEST(libgit2_clar libgit2_clar -iall) ENDIF ()