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

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

Find_Package                        ( Sanitizers QUIET )

# 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 ##################################################################################

Add_Library                         ( libhelloworld-static STATIC $<TARGET_OBJECTS:libhelloworld-objects> )
Set_Target_Properties               ( libhelloworld-static
                                      PROPERTIES
                                        OUTPUT_NAME "${LIBHELLOWORLD_OUTPUTNAME}"
                                        VERSION ${LIBHELLOWORLD_VERSION} )
Target_Include_Directories          ( libhelloworld-static
                                      PUBLIC
                                        $<BUILD_INTERFACE:${LIBHELLOWORLD_INCLUDE_DIR}>
                                        $<INSTALL_INTERFACE:${LIBHELLOWORLD_INSTALL_DIR_INCLUDE}> )

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

Add_Library                         ( libhelloworld-shared SHARED $<TARGET_OBJECTS:libhelloworld-objects> )
Set_Target_Properties               ( libhelloworld-shared
                                      PROPERTIES
                                        OUTPUT_NAME "${LIBHELLOWORLD_OUTPUTNAME}"
                                        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 ####################################################################################

# sanitizers
If                                  ( Sanitizers_FOUND )
    Add_Sanitizers                      ( libhelloworld-objects )
EndIf                               ( )

# 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 #########################################################################################

Set                                 ( LIBHELLOWORLD_HAS_EXPORT False PARENT_SCOPE )

# 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 )
    Set                                 ( LIBHELLOWORLD_HAS_EXPORT True PARENT_SCOPE )
    Install                             ( TARGETS libhelloworld-static
                                          EXPORT libhelloworld
                                          DESTINATION ${LIBHELLOWORLD_INSTALL_DIR_LIB} )
EndIf                               ( )

# Shared
If                                  ( LIBHELLOWORLD_INSTALL_SHARED )
    Set                                 ( LIBHELLOWORLD_HAS_EXPORT True PARENT_SCOPE )
    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                               ( )
