ADD_LIBRARY(${LIBNAME}
    msrproto/DataConverter.cpp
    msrproto/DirNode.cpp
    msrproto/PeriodicSubscriptions.cpp
    msrproto/ProtocolHandler.cpp
    msrproto/Subscription.cpp
    msrproto/Variable.cpp
    Debug.cpp
    MessageManagerBase.cpp
    IOLayer.cpp
    Process.cpp
    Sasl.cpp
    Selector.cpp
    SpyLayer.cpp
    StreambufLayer.cpp
    Subscription.cpp
    Variable.cpp
)

IF(VERSION_HASH)
    # Hash was given as option, so write it directly
    # useful for OBS packaging
    FILE(WRITE "${CMAKE_CURRENT_BINARY_DIR}/git_revision_hash.h"
        "#define GIT_REV \"${VERSION_HASH}\"
")
ELSE()
    # recompute hash on every `make` invocation
    # Note: CMake variable definitions (-D) must be before the -P option!
    ADD_CUSTOM_TARGET(GitRevision
        BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/git_revision_hash.h"
        COMMAND ${CMAKE_COMMAND}
            -DSOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}/.."
            -DHASH_MACRO_NAME="GIT_REV"
            -DTARGET_FILE="${CMAKE_CURRENT_BINARY_DIR}/git_revision_hash.h"
            -P ${CMAKE_CURRENT_SOURCE_DIR}/git_revision.cmake
    )
    ADD_DEPENDENCIES(${LIBNAME} GitRevision)
ENDIF()

if (USE_SYMBOL_VERSIONING)
    math(EXPR VERSCRIPT_ARCH "8 * ${CMAKE_SIZEOF_VOID_P}")
    string(FIND "${CMAKE_CXX_FLAGS}" "-flto" LTO_POS)
    set(LTO_ARCH "")
    if (NOT LTO_POS EQUAL "-1")
        set(LTO_ARCH "-lto")
    endif()
    add_custom_command(OUTPUT pdcom.map
        COMMAND "${PYTHON_EXECUTABLE}"
        ARGS "${CMAKE_CURRENT_SOURCE_DIR}/../symbol-versioning/symbol_version_tool.py"
                -i "${CMAKE_CURRENT_SOURCE_DIR}/pdcom.map.yaml"
                -o "${CMAKE_CURRENT_BINARY_DIR}/pdcom.map"
                --arch "generic${VERSCRIPT_ARCH}${LTO_ARCH}"
                GenerateLinkerVersionScript
        MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/pdcom.map.yaml"
        DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/../symbol-versioning/symbol_version_tool.py"
    )
    # to force relinking upon changing the map file,
    # we add an OBJECT_DEPENDS
    set(PROCESS_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pdcom.map")
    set_source_files_properties(Process.cpp PROPERTIES OBJECT_DEPENDS "${PROCESS_DEPENDS}")
    # inform linker about version script
    set_target_properties(${LIBNAME} PROPERTIES LINK_FLAGS " -Wl,-version-script=${CMAKE_CURRENT_BINARY_DIR}/pdcom.map")

    if (CHECK_SYMBOL_VERSIONING)
        add_custom_target(CheckPdComVersionScript ALL
            "${PYTHON_EXECUTABLE}"
            "${CMAKE_CURRENT_SOURCE_DIR}/../symbol-versioning/symbol_version_tool.py"
            -i "${CMAKE_CURRENT_SOURCE_DIR}/pdcom.map.yaml"
            --arch "generic${VERSCRIPT_ARCH}${LTO_ARCH}"
            --library $<TARGET_FILE:${LIBNAME}>
            CheckGeneratedLibraries
            COMMENT "Checking whether all symbols are versioned correctly..."
        )
    endif()
endif()

GENERATE_EXPORT_HEADER(${LIBNAME}
    EXPORT_MACRO_NAME PDCOM5_PUBLIC
    NO_EXPORT_MACRO_NAME PDCOM5_LOCAL
)

IF(NOT WIN32)
    TARGET_SOURCES(${LIBNAME} PRIVATE PosixProcess.cpp)
ENDIF()

TARGET_LINK_LIBRARIES(${LIBNAME} PRIVATE ${EXPAT_LIBRARIES})
TARGET_INCLUDE_DIRECTORIES(${LIBNAME} PUBLIC
    "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>"
    "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/..>"
    "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>"
    "$<INSTALL_INTERFACE:include>"
)
TARGET_INCLUDE_DIRECTORIES(${LIBNAME} PRIVATE
    ${EXPAT_INCLUDE_DIR}
)

SET_TARGET_PROPERTIES ( ${LIBNAME} PROPERTIES
    POSITION_INDEPENDENT_CODE ${BUILD_POSITION_INDEPENDENT}
    SOVERSION "${SOVERSION}"
    CLEAN_DIRECT_OUTPUT 1
    PUBLIC_HEADER "${LIBHEADERS}"
    VERSION "${SOVERSION}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
)

TARGET_COMPILE_FEATURES(${LIBNAME} PUBLIC cxx_std_11)
IF (HAVE_XML_SetReparseDeferralEnabled)
    TARGET_COMPILE_DEFINITIONS(${LIBNAME} PRIVATE HAVE_XML_SetReparseDeferralEnabled)
ENDIF()

IF (BUILD_SHARED_LIBS)
    SET_TARGET_PROPERTIES ( ${LIBNAME} PROPERTIES
        CXX_VISIBILITY_PRESET "hidden"
        VISIBILITY_INLINES_HIDDEN 1
    )
ELSE()
    TARGET_COMPILE_DEFINITIONS(${LIBNAME} PUBLIC PDCOM5_STATIC_DEFINE)
ENDIF()

IF (CMAKE_COMPILER_IS_GNUCXX OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
    TARGET_COMPILE_OPTIONS(${LIBNAME} PRIVATE -Wall -Wextra)
ELSEIF(MSVC)
    # disable msvc langange extensions and enable conforming exception handling
    TARGET_COMPILE_OPTIONS(${LIBNAME} PRIVATE /Za /EHsc)
ENDIF()


## install target and headers

INSTALL (TARGETS ${LIBNAME}
    EXPORT ${LIBNAME}Targets
    ARCHIVE DESTINATION  "${CMAKE_INSTALL_LIBDIR}"
    LIBRARY DESTINATION  "${CMAKE_INSTALL_LIBDIR}"
    RUNTIME DESTINATION  "${CMAKE_INSTALL_BINDIR}"
)

INSTALL (FILES "${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME}_export.h"
    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")

## cmake target export stuff

SET(ConfigPackageLocation "${CMAKE_INSTALL_LIBDIR}/cmake/${LIBNAME}")
CONFIGURE_PACKAGE_CONFIG_FILE(../Config.cmake.in
        "${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME}/${LIBNAME}-config.cmake"
    INSTALL_DESTINATION ${ConfigPackageLocation}
)
WRITE_BASIC_PACKAGE_VERSION_FILE(
        "${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME}/${LIBNAME}-configVersion.cmake"
    COMPATIBILITY SameMajorVersion
)
INSTALL(EXPORT ${LIBNAME}Targets
    NAMESPACE EtherLab::
    FILE ${LIBNAME}Targets.cmake
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${LIBNAME}
)
INSTALL(FILES
        ${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME}/${LIBNAME}-config.cmake
        ${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME}/${LIBNAME}-configVersion.cmake
    DESTINATION ${ConfigPackageLocation}
)
EXPORT(EXPORT ${LIBNAME}Targets
    FILE "${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME}/${LIBNAME}Targets.cmake"
    NAMESPACE EtherLab::
)
