# Initialize ######################################################################################

Include                     ( cotire        OPTIONAL RESULT_VARIABLE HAS_COTIRE )
Include                     ( pedantic      OPTIONAL RESULT_VARIABLE HAS_PEDANTIC )
Include                     ( strip_symbols OPTIONAL RESULT_VARIABLE HAS_STRIP_SYMBOLS )

Option                      ( LIBHELLOWORLD_INSTALL_HEADER
                              "Install headers of libhelloworld."
                              ON )
Option                      ( LIBHELLOWORLD_INSTALL_STATIC
                              "Install static library of libhelloworld."
                              ON )
Option                      ( LIBHELLOWORLD_INSTALL_SHARED
                              "Install shared library of libhelloworld."
                              ON )
Option                      ( LIBHELLOWORLD_INSTALL_DEBUG
                              "Install the stripped debug informations of libhelloworld."
                              OFF )
Option                      ( LIBHELLOWORLD_NO_STRIP
                              "Do not strip debug symbols from binary."
                              OFF )

# Object Library ##################################################################################

Set                         ( CMAKE_POSITION_INDEPENDENT_CODE ON )
Set                         ( LIBHELLOWORLD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include )
File                        ( GLOB_RECURSE LIBHELLOWORLD_HEADER_FILES ${LIBHELLOWORLD_INCLUDE_DIR}/*.h )
File                        ( GLOB_RECURSE LIBHELLOWORLD_INLINE_FILES ${LIBHELLOWORLD_INCLUDE_DIR}/*.inl )
File                        ( GLOB_RECURSE LIBHELLOWORLD_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp )
Add_Library                 ( libhelloworld-objects
                              OBJECT
                                ${LIBHELLOWORLD_HEADER_FILES}
                                ${LIBHELLOWORLD_INLINE_FILES}
                                ${LIBHELLOWORLD_SOURCE_FILES} )
Target_Include_Directories  ( libhelloworld-objects
                              PUBLIC
                                $<BUILD_INTERFACE:${LIBHELLOWORLD_INCLUDE_DIR}>
                                $<INSTALL_INTERFACE:${LIBHELLOWORLD_INSTALL_DIR_INCLUDE}> )

# Static Library ##################################################################################

Message                     ( WARNING "Please configure the output name of the static library target!" )
Add_Library                 ( libhelloworld-static STATIC $<TARGET_OBJECTS:libhelloworld-objects> )
Set_Target_Properties       ( libhelloworld-static
                              PROPERTIES
                                OUTPUT_NAME "helloworld"
                                VERSION ${LIBHELLOWORLD_VERSION} )
Target_Include_Directories  ( libhelloworld-static
                              PUBLIC
                                $<BUILD_INTERFACE:${LIBHELLOWORLD_INCLUDE_DIR}>
                                $<INSTALL_INTERFACE:${LIBHELLOWORLD_INSTALL_DIR_INCLUDE}> )

# Shared Library ##################################################################################

Message                     ( WARNING "Please configure the output name of the shared library target!" )
Add_Library                 ( libhelloworld-shared SHARED $<TARGET_OBJECTS:libhelloworld-objects> )
Set_Target_Properties       ( libhelloworld-shared
                              PROPERTIES
                                OUTPUT_NAME "helloworld"
                                VERSION ${LIBHELLOWORLD_VERSION}
                                SOVERSION ${LIBHELLOWORLD_VERSION_SHORT} )
Target_Include_Directories  ( libhelloworld-shared
                              PUBLIC
                                $<BUILD_INTERFACE:${LIBHELLOWORLD_INCLUDE_DIR}>
                                $<INSTALL_INTERFACE:${LIBHELLOWORLD_INSTALL_DIR_INCLUDE}> )

# Optimization ####################################################################################

# pedantic
If                          ( HAS_PEDANTIC )
    Pedantic_Apply_Flags_Target ( libhelloworld-objects ALL )
    Pedantic_Apply_Flags_Target ( libhelloworld-static ALL )
    Pedantic_Apply_Flags_Target ( libhelloworld-shared ALL )
EndIf                       ( )

# cotire
If                          ( HAS_COTIRE )
    Cotire                      ( libhelloworld-objects )
    Cotire                      ( libhelloworld-static )
    Cotire                      ( libhelloworld-shared )
EndIf                       ( )

# Install #########################################################################################

# Header
If                          ( LIBHELLOWORLD_INSTALL_HEADER )
    Install                     ( FILES ${LIBHELLOWORLD_INCLUDE_DIR}/libhelloworld.h
                                  DESTINATION ${LIBHELLOWORLD_INSTALL_DIR_INCLUDE} )
    Install                     ( DIRECTORY ${LIBHELLOWORLD_INCLUDE_DIR}/libhelloworld
                                  DESTINATION ${LIBHELLOWORLD_INSTALL_DIR_INCLUDE} )
EndIf                       ( )

# Static
If                          ( LIBHELLOWORLD_INSTALL_STATIC )
    Install                     ( TARGETS libhelloworld-static
                                  EXPORT libhelloworld
                                  DESTINATION ${LIBHELLOWORLD_INSTALL_DIR_LIB} )
EndIf                       ( )

# Shared
If                          ( LIBHELLOWORLD_INSTALL_SHARED )
    Install                     ( TARGETS libhelloworld-shared
                                  EXPORT libhelloworld
                                  DESTINATION ${LIBHELLOWORLD_INSTALL_DIR_LIB} )
EndIf                       ( )

# Debug
If                          ( HAS_STRIP_SYMBOLS AND NOT LIBHELLOWORLD_NO_STRIP )
    Strip_Symbols               ( libhelloworld-shared LIBHELLOWORLD_DBG_FILE )
    If                          ( LIBHELLOWORLD_INSTALL_DEBUG )
        Install                     ( FILES ${LIBHELLOWORLD_DBG_FILE}
                                      DESTINATION ${LIBHELLOWORLD_INSTALL_DIR_LIB} )
    EndIf                       ( )
EndIf                       ( )
