CMAKE_MINIMUM_REQUIRED (VERSION 2.8.12)

IF ((CMAKE_VERSION VERSION_GREATER 3.1) OR
    (CMAKE_VERSION VERSION_EQUAL 3.1))
    CMAKE_POLICY(SET CMP0054 NEW)
ENDIF ()

OPTION (MSGPACK_BUILD_TESTS "Build msgpack tests." ON)
OPTION (MSGPACK_GEN_COVERAGE "Enable running gcov to get a test coverage report." OFF)

if(MSGPACK_BUILD_TESTS)
    PROJECT (msgpack-c)
else()
    PROJECT (msgpack-c C)
endif()

FILE (READ ${CMAKE_CURRENT_SOURCE_DIR}/include/msgpack/version_master.h contents)
STRING (REGEX MATCH "#define MSGPACK_VERSION_MAJOR *([0-9a-zA-Z_]*)" NULL_OUT ${contents})
SET (VERSION_MAJOR ${CMAKE_MATCH_1})
STRING (REGEX MATCH "#define MSGPACK_VERSION_MINOR *([0-9a-zA-Z_]*)" NULL_OUT ${contents})
SET (VERSION_MINOR ${CMAKE_MATCH_1})
STRING (REGEX MATCH "#define MSGPACK_VERSION_REVISION *([0-9a-zA-Z_]*)" NULL_OUT ${contents})
SET (VERSION_REVISION ${CMAKE_MATCH_1})
SET (VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION})

LIST (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/")
SET (prefix ${CMAKE_INSTALL_PREFIX})
SET (exec_prefix "\${prefix}")
SET (libdir "\${exec_prefix}/lib")
SET (includedir "\${prefix}/include")

OPTION (MSGPACK_32BIT "32bit compile" OFF)

INCLUDE(TestBigEndian)
TEST_BIG_ENDIAN(BIGENDIAN)
IF (BIGENDIAN)
    SET(MSGPACK_ENDIAN_BIG_BYTE 1)
    SET(MSGPACK_ENDIAN_LITTLE_BYTE 0)
ELSE ()
    SET(MSGPACK_ENDIAN_BIG_BYTE 0)
        SET(MSGPACK_ENDIAN_LITTLE_BYTE 1)
ENDIF ()

CONFIGURE_FILE (
    cmake/sysdep.h.in
    include/msgpack/sysdep.h
    @ONLY
)

CONFIGURE_FILE (
    cmake/pack_template.h.in
    include/msgpack/pack_template.h
    @ONLY
)

IF (APPLE)
    SET(CMAKE_MACOSX_RPATH ON)
    SET(CMAKE_SKIP_BUILD_RPATH FALSE)
    SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
    SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
    SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
    LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
    IF ("${isSystemDir}" STREQUAL "-1")
        SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
    ENDIF ()
ENDIF ()

IF (MSGPACK_32BIT)
   IF ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
      SET (CMAKE_C_FLAGS "-m32 ${CMAKE_C_FLAGS}")
      SET (CMAKE_EXE_LINKER_FLAGS "-m32 ${CMAKE_EXE_LINKER_FLAGS}")
   ELSEIF ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
      SET (CMAKE_C_FLAGS "-m32 ${CMAKE_C_FLAGS}")
      SET (CMAKE_EXE_LINKER_FLAGS "-m32 ${CMAKE_EXE_LINKER_FLAGS}")
   ENDIF ()
ENDIF ()

OPTION (MSGPACK_BUILD_EXAMPLES "Build msgpack examples." ON)

IF (MSGPACK_CHAR_SIGN)
   SET (CMAKE_C_FLAGS "-f${MSGPACK_CHAR_SIGN}-char ${CMAKE_C_FLAGS}")
ENDIF ()

IF (DEFINED BUILD_SHARED_LIBS)
    IF (BUILD_SHARED_LIBS)
        IF (DEFINED MSGPACK_ENABLE_SHARED AND NOT MSGPACK_ENABLE_SHARED)
            MESSAGE(WARNING "MSGPACK_ENABLE_SHARED is overridden to ON by BUILD_SHARED_LIBS")
        ENDIF ()
        SET (MSGPACK_ENABLE_SHARED ON)
        IF (DEFINED MSGPACK_ENABLE_STATIC AND MSGPACK_ENABLE_STATIC)
            MESSAGE(WARNING "MSGPACK_ENABLE_STATIC is overridden to OFF by BUILD_SHARED_LIBS")
        ENDIF ()
        SET (MSGPACK_ENABLE_STATIC OFF)
    ELSE ()
        IF (DEFINED MSGPACK_ENABLE_SHARED AND MSGPACK_ENABLE_SHARED)
            MESSAGE(WARNING "MSGPACK_ENABLE_SHARED is overridden to OFF by BUILD_SHARED_LIBS")
        ENDIF ()
        SET (MSGPACK_ENABLE_SHARED OFF)
        IF (DEFINED MSGPACK_ENABLE_STATIC AND NOT MSGPACK_ENABLE_STATIC)
            MESSAGE(WARNING "MSGPACK_ENABLE_STATIC is overridden to ON by BUILD_SHARED_LIBS")
        ENDIF ()
        SET (MSGPACK_ENABLE_STATIC ON)
    ENDIF ()
ELSE ()
    IF (NOT DEFINED MSGPACK_ENABLE_SHARED)
        SET (MSGPACK_ENABLE_SHARED ON)
    ENDIF ()
    IF (NOT DEFINED MSGPACK_ENABLE_STATIC)
        SET (MSGPACK_ENABLE_STATIC ON)
    ENDIF ()
    SET (BUILD_SHARED_LIBS ${MSGPACK_ENABLE_SHARED})
ENDIF ()

INCLUDE (Files.cmake)

CONFIGURE_FILE (
    msgpack-c.pc.in
    msgpack-c.pc
    @ONLY
)

IF (MSGPACK_ENABLE_SHARED OR MSGPACK_ENABLE_STATIC)
    ADD_LIBRARY (msgpack-c
        ${msgpack-c_SOURCES}
        ${msgpack-c_HEADERS}
    )

    SET_TARGET_PROPERTIES (msgpack-c PROPERTIES SOVERSION 2 VERSION 2.0.0)

    TARGET_INCLUDE_DIRECTORIES (msgpack-c
        PUBLIC
            $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
            $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
            $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include/msgpack>
            $<INSTALL_INTERFACE:include>
        PRIVATE
            ${CMAKE_CURRENT_SOURCE_DIR}
    )
ENDIF ()


IF (MSGPACK_ENABLE_SHARED AND MSGPACK_ENABLE_STATIC)
    ADD_LIBRARY (msgpack-c-static STATIC
        ${msgpack-c_SOURCES}
        ${msgpack-c_HEADERS}
    )

    TARGET_INCLUDE_DIRECTORIES (msgpack-c-static
        PUBLIC
            $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
            $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
            $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include/msgpack>
            $<INSTALL_INTERFACE:include>
        PRIVATE
            ${CMAKE_CURRENT_SOURCE_DIR}
    )

    SET_TARGET_PROPERTIES (msgpack-c-static PROPERTIES OUTPUT_NAME "msgpack-c")

    IF (MSGPACK_ENABLE_SHARED)
        IF (MSVC)
            SET_TARGET_PROPERTIES (msgpack-c PROPERTIES IMPORT_SUFFIX "_import.lib")
        ELSEIF (MINGW)
            SET_TARGET_PROPERTIES (msgpack-c PROPERTIES IMPORT_SUFFIX ".dll.a")
        ENDIF ()
    ENDIF ()
ENDIF ()

IF (MSGPACK_GEN_COVERAGE)
    IF (NOT MSGPACK_BUILD_TESTS)
        MESSAGE(FATAL_ERROR "Coverage requires -DMSGPACK_BUILD_TESTS=ON")
    ENDIF ()
    STRING(TOUPPER "${CMAKE_BUILD_TYPE}" UPPER_CMAKE_BUILD_TYPE)
    IF (NOT "${UPPER_CMAKE_BUILD_TYPE}" STREQUAL "DEBUG")
        MESSAGE(FATAL_ERROR "Coverage requires -DCMAKE_BUILD_TYPE=Debug")
    ENDIF ()

    INCLUDE(CodeCoverage)
    SET (CMAKE_C_FLAGS   "${CMAKE_C_FLAGS} ${COVERAGE_FLAGS}")

    SETUP_TARGET_FOR_COVERAGE(coverage make coverage test)
ENDIF ()

IF (MSGPACK_BUILD_TESTS)
    ENABLE_TESTING ()
    list(APPEND CMAKE_CTEST_ARGUMENTS "--output-on-failure")
    # MEMORYCHECK_COMMAND_OPTIONS needs to place prior to CTEST_MEMORYCHECK_COMMAND
    SET (MEMORYCHECK_COMMAND_OPTIONS "--leak-check=full --show-leak-kinds=definite,possible --error-exitcode=1")
    FIND_PROGRAM(CTEST_MEMORYCHECK_COMMAND NAMES valgrind)
    INCLUDE(Dart)
    ADD_SUBDIRECTORY (test)
ENDIF ()

IF ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
    IF (MSGPACK_ENABLE_SHARED OR MSGPACK_ENABLE_STATIC)
        SET_PROPERTY (TARGET msgpack-c APPEND_STRING PROPERTY COMPILE_FLAGS " -Wall -Wextra -DPIC")
    ENDIF ()
    IF (MSGPACK_ENABLE_SHARED AND MSGPACK_ENABLE_STATIC)
       SET_PROPERTY (TARGET msgpack-c-static APPEND_STRING PROPERTY COMPILE_FLAGS " -Wall -Wextra" )
    ENDIF ()
ENDIF ()

IF ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
    IF (MSGPACK_ENABLE_SHARED OR MSGPACK_ENABLE_STATIC)
        SET_PROPERTY (TARGET msgpack-c APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-mismatched-tags")
    ENDIF ()
    IF (MSGPACK_ENABLE_SHARED AND MSGPACK_ENABLE_STATIC)
        SET_PROPERTY (TARGET msgpack-c-static APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-mismatched-tags")
    ENDIF ()
ENDIF ()

IF ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
    IF (CMAKE_C_FLAGS MATCHES "/W[0-4]")
        STRING(REGEX REPLACE "/W[0-4]" "/W3 /WX" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
    ELSE ()
        SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3 /WX")
    ENDIF ()
ENDIF ()

IF ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
    IF (CMAKE_C_FLAGS MATCHES "/W[0-4]")
        STRING(REGEX REPLACE "/W[0-4]" "/W3 /WX" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
    ELSE ()
        SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3 /WX")
    ENDIF ()
ENDIF ()

IF ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC90" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC10")
    SET_SOURCE_FILES_PROPERTIES(${msgpack-c_SOURCES} PROPERTIES LANGUAGE C)
ENDIF ()

IF ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "sparc")
    SET (CMAKE_C_FLAGS   "-DMSGPACK_ZONE_ALIGN=8 ${CMAKE_C_FLAGS}")
ENDIF ()

IF (NOT DEFINED CMAKE_INSTALL_BINDIR)
    SET(CMAKE_INSTALL_BINDIR bin)
ENDIF ()

IF (NOT DEFINED CMAKE_INSTALL_LIBDIR)
    SET(CMAKE_INSTALL_LIBDIR lib)
ENDIF ()

IF (MSGPACK_BUILD_EXAMPLES)
    ADD_SUBDIRECTORY (example)
ENDIF ()

IF (MSGPACK_ENABLE_SHARED OR MSGPACK_ENABLE_STATIC)
    SET (MSGPACK_INSTALLTARGETS msgpack-c)
ENDIF ()

IF (MSGPACK_ENABLE_SHARED AND MSGPACK_ENABLE_STATIC)
    LIST (APPEND MSGPACK_INSTALLTARGETS msgpack-c-static)
ENDIF ()

INSTALL (TARGETS ${MSGPACK_INSTALLTARGETS} EXPORT msgpack-c-targets
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
FOREACH (file ${msgpack-c_common_HEADERS})
    GET_FILENAME_COMPONENT (dir ${file} PATH)
    INSTALL (FILES ${file} DESTINATION ${CMAKE_INSTALL_PREFIX}/${dir})
ENDFOREACH ()
FOREACH (file ${msgpack-c_configured_HEADERS})
    GET_FILENAME_COMPONENT (dir ${file} PATH)
    INSTALL (FILES ${CMAKE_CURRENT_BINARY_DIR}/${file} DESTINATION ${CMAKE_INSTALL_PREFIX}/${dir})
ENDFOREACH ()
IF (NOT MSVC)
    INSTALL (FILES ${CMAKE_CURRENT_BINARY_DIR}/msgpack-c.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
ENDIF ()

# Doxygen
FIND_PACKAGE (Doxygen)
IF (DOXYGEN_FOUND)
    LIST (APPEND Doxyfile_c_CONTENT
        COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
        COMMAND ${CMAKE_COMMAND} -E echo "FILE_PATTERNS      = *.h" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
        COMMAND ${CMAKE_COMMAND} -E echo "OUTPUT_DIRECTORY   = doc_c" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
        COMMAND ${CMAKE_COMMAND} -E echo "INPUT              = ${CMAKE_CURRENT_SOURCE_DIR}/include" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
        COMMAND ${CMAKE_COMMAND} -E echo "EXTRACT_ALL        = YES" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
        COMMAND ${CMAKE_COMMAND} -E echo "PROJECT_NAME       = \"MessagePack for C\"" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
        COMMAND ${CMAKE_COMMAND} -E echo "STRIP_FROM_PATH    = ${CMAKE_CURRENT_SOURCE_DIR}/include" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
    )
    IF (DOXYGEN_DOT_FOUND)
        LIST (APPEND Doxyfile_c_CONTENT
            COMMAND ${CMAKE_COMMAND} -E echo "HAVE_DOT       = YES" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
        )
    ENDIF ()
    ADD_CUSTOM_TARGET (
        doxygen
        ${Doxyfile_c_CONTENT}
        COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
        VERBATIM
    )
ENDIF ()

INCLUDE (CMakePackageConfigHelpers)

SET (CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/msgpack-c")

WRITE_BASIC_PACKAGE_VERSION_FILE (
    msgpack-c-config-version.cmake
    VERSION ${VERSION}
    COMPATIBILITY SameMajorVersion
)

IF (NOT CMAKE_VERSION VERSION_LESS 3.0)
    EXPORT (EXPORT msgpack-c-targets
        FILE "${CMAKE_CURRENT_BINARY_DIR}/msgpack-c-targets.cmake"
    )
ENDIF ()

CONFIGURE_PACKAGE_CONFIG_FILE (msgpack-c-config.cmake.in
    msgpack-c-config.cmake
    INSTALL_DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
)

INSTALL (EXPORT msgpack-c-targets
    FILE
        msgpack-c-targets.cmake
    DESTINATION
        "${CMAKE_INSTALL_CMAKEDIR}"
)

INSTALL (
    FILES
        "${CMAKE_CURRENT_BINARY_DIR}/msgpack-c-config.cmake"
        "${CMAKE_CURRENT_BINARY_DIR}/msgpack-c-config-version.cmake"
    DESTINATION
        "${CMAKE_INSTALL_CMAKEDIR}"
)
