installation.cmake 6.88 KB
set( INSTALLATION_CURRENT_CMAKE_DIR ${CMAKE_CURRENT_LIST_DIR} )

# Layout
set(USR_LOCAL_DIR "/usr/local" CACHE STRING "" FORCE)
set(LD_SO_CONF_D_DIR "/etc/ld.so.conf.d" CACHE STRING "" FORCE)
set(SYSTEMD_CONFIG_DIR "/etc/systemd/system" CACHE STRING "" FORCE)
set(VAR_LOG_DIR "/var/log" CACHE STRING "" FORCE)
set(VAR_RUN_DIR "/var/run" CACHE STRING "" FORCE)
set(PROJCOMP_LOG_INSTALL_DIR "${VAR_LOG_DIR}/${PROJECT_NAME}")
set(PROJCOMP_RUN_INSTALL_DIR "${VAR_RUN_DIR}/${PROJECT_NAME}")
set(PROJCOMP_BIN_INSTALL_DIR "${PROJECT_NAME}/bin")
set(PROJCOMP_LIB_INSTALL_DIR "lib")
set(PROJCOMP_INCLUDE_INSTALL_DIR "${PROJECT_NAME}/include")
set(PROJCOMP_ETC_INSTALL_DIR "${PROJECT_NAME}/etc")
set(PROJCOMP_CMAKE_INSTALL_DIR "${PROJECT_NAME}/cmake")
set(PROJCOMP_COMPONENT_NAME "${REPOSITORY_PACKAGE_NAME}-${PROJECT_NAME}")
set(PROJCOMP_COMPONENT_NAME_DEVEL "${PROJCOMP_COMPONENT_NAME}-devel")

# @brief Installs a library component and performs related actions.
function(install_component)

set(GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")

# Configuration
string(TOLOWER ${PROJECT_NAME} MODULE_NAME_LOWER)
set(PROJECT_CONFIG "${GENERATED_DIR}/${MODULE_NAME_LOWER}-config.cmake")

# Generate the cmake config file
include(CMakePackageConfigHelpers)
configure_package_config_file(
    "${INSTALLATION_CURRENT_CMAKE_DIR}/config.cmake.in"
    "${PROJECT_CONFIG}"
    INSTALL_DESTINATION "${PROJCOMP_CMAKE_INSTALL_DIR}"
    PATH_VARS PROJCOMP_INCLUDE_INSTALL_DIR PROJCOMP_LIB_INSTALL_DIR PROJCOMP_CMAKE_INSTALL_DIR
)

# Install license file
if (EXISTS "${INSTALLATION_CURRENT_CMAKE_DIR}/COPYING.OSDEV")
    install(
        FILES "${INSTALLATION_CURRENT_CMAKE_DIR}/COPYING.OSDEV"
        DESTINATION ${PROJCOMP_LIB_INSTALL_DIR}
        COMPONENT "${PROJCOMP_COMPONENT_NAME}"
    )
endif()

# Install targets
install(
    TARGETS ${PROJECT_NAME}
    DESTINATION ${PROJCOMP_LIB_INSTALL_DIR}
    COMPONENT "${PROJCOMP_COMPONENT_NAME}"
)

# Configure and install dynamic linker runtime bindings (ld.so.conf.d file)
configure_file(
    "${INSTALLATION_CURRENT_CMAKE_DIR}/ld.so.conf.d.cmake.in"
    "${GENERATED_DIR}/${PROJECT_NAME}.conf"
)
install(
    FILES "${GENERATED_DIR}/${PROJECT_NAME}.conf"
    DESTINATION ${LD_SO_CONF_D_DIR}
    COMPONENT "${PROJCOMP_COMPONENT_NAME}"
)

# Configure and set cpack post install script
configure_file(
    "${INSTALLATION_CURRENT_CMAKE_DIR}/library.post_install.inc.cmake.in"
    "${GENERATED_DIR}/library.post_install.inc"
)
# Set the per-component post install script file.
set(CPACK_RPM_${PROJCOMP_COMPONENT_NAME}_POST_INSTALL_SCRIPT_FILE "${GENERATED_DIR}/library.post_install.inc" CACHE STRING "${PROJECT_NAME} post_install script" FORCE)

# Headers
# At the moment, we anticipate the headers to be located according to either 1) or 2).

# 1) Apply glob style pattern for those projects that have the header files in the root folder of the repository (such as opcua_model).
file (GLOB PACKAGE_HEADERS "${CMAKE_CURRENT_LIST_DIR}/*.h*")
install(
    FILES ${PACKAGE_HEADERS}
    DESTINATION ${PROJCOMP_INCLUDE_INSTALL_DIR}
    COMPONENT "${PROJCOMP_COMPONENT_NAME_DEVEL}"
)
# 2) Copy the include dir for those projects that have the header files in include/mlogic (such as opc_utils).
if (EXISTS ${CMAKE_CURRENT_LIST_DIR}/include/mlogic)
    install(
        DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/mlogic
        DESTINATION ${PROJCOMP_INCLUDE_INSTALL_DIR}
        COMPONENT "${PROJCOMP_COMPONENT_NAME_DEVEL}"
    )
endif()

# Install cmake project config
install(
    FILES ${PROJECT_CONFIG}
    DESTINATION ${PROJCOMP_CMAKE_INSTALL_DIR}
    COMPONENT "${PROJCOMP_COMPONENT_NAME_DEVEL}"
)

# The -devel package depends on the runtime package
set(CPACK_RPM_${PROJCOMP_COMPONENT_NAME_DEVEL}_PACKAGE_REQUIRES "${PROJCOMP_COMPONENT_NAME} = ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}-${CURRENT_PROJECT_VERSION_RELEASENR}" CACHE STRING "${PROJCOMP_COMPONENT_NAME_DEVEL} dependency" FORCE )
# Clear the dependencies for the runtime package, as cpack erroneously added unexpected dependencies (hints towards the previously built package)
set(CPACK_RPM_${PROJCOMP_COMPONENT_NAME}_PACKAGE_REQUIRES "" CACHE STRING "${PROJCOMP_COMPONENT_NAME} dependencies" FORCE )

endfunction()

# @brief Installs the executable binary and related items
# (such as systemd service files, log folder, post [un]install scripts)
# @param INSTALL_SYSTEMD_SERVICE [optional] Boolean to indicate whether the systemd unit files must be installed. Optional. The default is ON.
function(install_application)

set ( optional_macro_args ${ARGN} )
list ( LENGTH optional_macro_args num_optional_args )
if ( ${num_optional_args} GREATER 0 )
    list ( GET optional_macro_args 0 INSTALL_SYSTEMD_SERVICE )
endif()

if(NOT DEFINED INSTALL_SYSTEMD_SERVICE)
    set(INSTALL_SYSTEMD_SERVICE "ON")
endif()

message(STATUS "INSTALL_SYSTEMD_SERVICE: ${INSTALL_SYSTEMD_SERVICE}")

set(GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")

# Install license file
if (EXISTS "${INSTALLATION_CURRENT_CMAKE_DIR}/COPYING.OSDEV")
    install(
        FILES "${INSTALLATION_CURRENT_CMAKE_DIR}/COPYING.OSDEV"
        DESTINATION ${PROJCOMP_BIN_INSTALL_DIR}
        COMPONENT "${PROJCOMP_COMPONENT_NAME}"
    )
endif()

# Install binary file
install(
    TARGETS ${PROJECT_NAME}
    DESTINATION ${PROJCOMP_BIN_INSTALL_DIR}
    COMPONENT "${PROJCOMP_COMPONENT_NAME}"
)

# Install configuration
if (EXISTS ${CMAKE_CURRENT_LIST_DIR}/config/)
    install(
        DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/config/
        DESTINATION ${PROJCOMP_ETC_INSTALL_DIR}
        COMPONENT "${PROJCOMP_COMPONENT_NAME}"
    )
endif()

if (INSTALL_SYSTEMD_SERVICE STREQUAL "ON")
    # Configure and install systemd unit file
    configure_file(
        "${INSTALLATION_CURRENT_CMAKE_DIR}/service.cmake.in"
        "${GENERATED_DIR}/${PROJECT_NAME}.service"
    )
    install(
        FILES "${GENERATED_DIR}/${PROJECT_NAME}.service"
        DESTINATION ${SYSTEMD_CONFIG_DIR}
        COMPONENT "${PROJCOMP_COMPONENT_NAME}"
    )
endif()

# Install log folder
install(
    DIRECTORY
    DESTINATION ${PROJCOMP_LOG_INSTALL_DIR}
    DIRECTORY_PERMISSIONS
        OWNER_WRITE OWNER_READ OWNER_EXECUTE
        GROUP_WRITE GROUP_READ GROUP_EXECUTE SETGID
        # No permissions for WORLD
    COMPONENT "${PROJCOMP_COMPONENT_NAME}"
)

# Install run folder
install(
    DIRECTORY
    DESTINATION ${PROJCOMP_RUN_INSTALL_DIR}
    DIRECTORY_PERMISSIONS
        OWNER_WRITE OWNER_READ OWNER_EXECUTE
        GROUP_WRITE GROUP_READ GROUP_EXECUTE
        # No permissions for WORLD
    COMPONENT "${PROJCOMP_COMPONENT_NAME}"
)

# Configure and set cpack post install script
configure_file(
    "${INSTALLATION_CURRENT_CMAKE_DIR}/application.post_install.inc.cmake.in"
    "${GENERATED_DIR}/application.post_install.inc"
)
# Set the per-component post install script file.
set(CPACK_RPM_${PROJCOMP_COMPONENT_NAME}_POST_INSTALL_SCRIPT_FILE "${GENERATED_DIR}/application.post_install.inc" CACHE STRING "${PROJECT_NAME} post_install script" FORCE)

endfunction()