From 4fe2256bffd752e7f9c75fa14d921e6ccd0aa1af Mon Sep 17 00:00:00 2001 From: KOLANICH Date: Tue, 20 Jul 2021 13:53:38 +0300 Subject: [PATCH] Implemented packaging using CPack and generation of the pkg-config file. --- .travis.yml | 8 +- CMakeLists.txt | 91 +++++++++++++++++++++-- README.md | 2 +- cmake/GenPkgConfig.cmake | 154 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 244 insertions(+), 11 deletions(-) create mode 100644 cmake/GenPkgConfig.cmake diff --git a/.travis.yml b/.travis.yml index ae171f1..ba5d1db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ matrix: include: - name: "function-loader, example, tests -- linux, debug, cppcheck, coverage, g++, 64-bit" os: linux - dist: xenial + dist: focal language: cpp env: BUILD_TYPE="Debug" compiler: g++ @@ -13,13 +13,13 @@ matrix: addons: apt: sources: - - ubuntu-toolchain-r-test + - ubuntu-toolchain-r/test packages: - - g++-6 + - g++-10 - cppcheck before_install: - pip install --user cpp-coveralls - install: export CXX="g++-6" + install: export CXX="g++-10" script: - set -e diff --git a/CMakeLists.txt b/CMakeLists.txt index d199af8..7446982 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,36 @@ cmake_minimum_required(VERSION 3.8 FATAL_ERROR) -project(function-loader VERSION 1.2.6 LANGUAGES CXX) +include(CMakePackageConfigHelpers) +include(GNUInstallDirs) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +include(GenPkgConfig) + +set(CPACK_PACKAGE_VERSION_MAJOR "1") +set(CPACK_PACKAGE_VERSION_MINOR "2") +set(CPACK_PACKAGE_VERSION_PATCH "7") +set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") + +project(function-loader VERSION ${CPACK_PACKAGE_VERSION} LANGUAGES CXX) + +set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") +set("PROJECT_DESCRIPTION" "Header-only library that can execute functions in a shared library and provides wrappers around these") +set("PROJECT_HOMEPAGE_URL" "https://github.com/karel-burda/function-loader") +set(CPACK_PACKAGE_VENDOR "Karel Burda") +set(CPACK_PACKAGE_DESCRIPTION "${PROJECT_DESCRIPTION}") +set(CPACK_PACKAGE_HOMEPAGE_URL "${PROJECT_HOMEPAGE_URL}") +set(CPACK_PACKAGE_MAINTAINER "${CPACK_PACKAGE_VENDOR}") +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_PACKAGE_MAINTAINER}") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") +set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") +set(CPACK_PACKAGE_MAINTAINER "${CPACK_PACKAGE_VENDOR}") + add_library(${PROJECT_NAME} INTERFACE) target_sources(${PROJECT_NAME} INTERFACE + $: ${CMAKE_CURRENT_LIST_DIR}/include/function_loader/detail/library_loader_platform_specific_windows.hpp> $<$: - ${CMAKE_CURRENT_LIST_DIR}/include/function_loader/detail/library_loader_platform_specific_unix.hpp>) + ${CMAKE_CURRENT_LIST_DIR}/include/function_loader/detail/library_loader_platform_specific_unix.hpp> + >) target_include_directories(${PROJECT_NAME} INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/include) + $) if (CMAKE_DL_LIBS) message(STATUS "Will add ${CMAKE_DL_LIBS}") @@ -40,12 +66,65 @@ target_compile_features(${PROJECT_NAME} cxx_std_11) install(TARGETS ${PROJECT_NAME} - EXPORT _targets) + EXPORT _targets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + +set(CONFIG_FILE_NAME_WITHOUT_EXT "${PROJECT_NAME}-config") + +install(EXPORT _targets + FILE ${CONFIG_FILE_NAME_WITHOUT_EXT}.cmake + NAMESPACE "burda::" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") export(EXPORT _targets NAMESPACE burda:: FILE "${PROJECT_NAME}-config.cmake") include(CMakePackageConfigHelpers) -write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake - COMPATIBILITY ExactVersion) + +set(CMAKE_CONFIG_FILE_BASENAME "${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_FILE_NAME_WITHOUT_EXT}") +set(CMAKE_CONFIG_VERSION_FILE_NAME "${CMAKE_CONFIG_FILE_BASENAME}-version.cmake") +set(CMAKE_CONFIG_FILE_NAME "${CMAKE_CONFIG_FILE_BASENAME}.cmake") + +if(${CMAKE_VERSION} VERSION_GREATER "3.14") + set(OPTIONAL_ARCH_INDEPENDENT "ARCH_INDEPENDENT") +endif() + +write_basic_package_version_file("${CMAKE_CONFIG_VERSION_FILE_NAME}" + COMPATIBILITY ExactVersion + ${OPTIONAL_ARCH_INDEPENDENT}) + +install(FILES "${CMAKE_CONFIG_VERSION_FILE_NAME}" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") + + +set(PackagingTemplatesDir "${CMAKE_CURRENT_SOURCE_DIR}/packaging") + +string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UPPER) +set(PKG_CONFIG_NAME "${PROJECT_NAME}") + +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/function_loader" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + +configure_pkg_config_file("${PROJECT_NAME}" + NAME "${PROJECT_NAME}" + VERSION "${PROJECT_VERSION}" + DESCRIPTION "${PROJECT_DESCRIPTION}" + URL "${PROJECT_HOMEPAGE_URL}" + INSTALL_LIB_DIR "${CMAKE_INSTALL_LIBDIR}" + INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}") + +set("CPACK_DEBIAN_PACKAGE_NAME" "lib${PROJECT_NAME}-dev") +set("CPACK_DEBIAN_PACKAGE_DEPENDS" "libc6-dev") +set("CPACK_DEBIAN_PACKAGE_SUGGESTS" "cmake, pkg-config, pkg-conf") + +set("CPACK_RPM_PACKAGE_NAME" "lib${PROJECT_NAME}-devel") +set("CPACK_RPM_PACKAGE_SUGGESTS" "${CPACK_DEBIAN_PACKAGE_SUGGESTS}") + +set(CPACK_DEB_COMPONENT_INSTALL ON) +set(CPACK_RPM_COMPONENT_INSTALL ON) +set(CPACK_NSIS_COMPONENT_INSTALL ON) +set(CPACK_DEBIAN_COMPRESSION_TYPE "xz") + +include(CPack) diff --git a/README.md b/README.md index 6d9298c..ee2f168 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Version](https://img.shields.io/badge/version-1.2.6-blue.svg) +![Version](https://img.shields.io/badge/version-1.2.7-blue.svg) [![License](https://img.shields.io/badge/license-MIT_License-blue.svg?style=flat)](LICENSE) [![Build Status](https://travis-ci.org/karel-burda/function-loader.svg?branch=develop)](https://travis-ci.org/karel-burda/function-loader) [![Codecov Status](https://codecov.io/gh/karel-burda/function-loader/branch/develop/graph/badge.svg)](https://codecov.io/gh/karel-burda/function-loader/branch/develop) diff --git a/cmake/GenPkgConfig.cmake b/cmake/GenPkgConfig.cmake new file mode 100644 index 0000000..b310f7d --- /dev/null +++ b/cmake/GenPkgConfig.cmake @@ -0,0 +1,154 @@ +#[=======================================================================[.rst: + +GenPkgConfig +------------ + +This is the library helping you to generate and install pkg-config files. + +The latest version can be here: https://github.com/KOLANICH-libs/Boilerplate.cmake/blob/master/GenPkgConfig.cmake + +Unlicense +^^^^^^^^^ + +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +For more information, please refer to + +Functions +^^^^^^^^^ +.. command:: configure_pkg_config_file + + Generates a pkg-config file for + + :: + + configure_pkg_config_file( + NAME + VERSION + DESCRIPTION + URL + COMPONENT + INSTALL_LIB_DIR + INSTALL_INCLUDE_DIR + REQUIRES ... ... + REQUIRES ... ... + ) + + The arguments are optional and usually are not needed to be set if global (not component-specific) CPACK vars have been set before. + + Generation is done in build time using packaging expressions. + +#]=======================================================================] + + +function(configure_pkg_config_file TARGET) + cmake_parse_arguments("" + "" # options + "NAME;VERSION;DESCRIPTION;URL;COMPONENT;INSTALL_LIB_DIR;INSTALL_INCLUDE_DIR" # one_value_keywords + "REQUIRES;CONFLICTS" # multi_value_keywords + ${ARGN} + ) + + configure_pkg_config_file_vars("${TARGET}" "${_NAME}" "${_INSTALL_LIB_DIR}" "${_INSTALL_INCLUDE_DIR}" "${_COMPONENT}" "${_DESCRIPTION}" "${_URL}" "${_VERSION}" "${_REQUIRES}" "${_CONFLICTS}") +endfunction() + +function(configure_pkg_config_file_vars TARGET _NAME _INSTALL_LIB_DIR _INSTALL_INCLUDE_DIR _COMPONENT _DESCRIPTION _URL _VERSION _REQUIRES _CONFLICTS) + #$ + #INTERFACE_LINK_DIRECTORIES + #INTERFACE_LINK_LIBRARIES + #INTERFACE_LINK_OPTIONS + + if(_NAME) + else() + set(_NAME "$") + endif() + + if(_DESCRIPTION) + else() + set(_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION}") + endif() + + if(_VERSION) + else() + set(_VERSION "${CPACK_PACKAGE_VERSION}") + endif() + + if(_URL) + else() + set(_URL "${CPACK_PACKAGE_HOMEPAGE_URL}") + endif() + + if(INSTALL_INCLUDE_DIR) + else() + set(INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}") + endif() + + if(INSTALL_LIB_DIR) + else() + set(INSTALL_LIB_DIR "${CMAKE_INSTALL_LIBDIR}") + endif() + + set(PKG_CONFIG_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/${_NAME}.pc") + + set(PUBLIC_INCLUDES "$") + set(PUBLIC_LIBS "$") + set(PUBLIC_COMPILE_FLAGS "$") + + set("NEEDS_LIBS" "$,INTERFACE_LIBRARY>>") + string(REPLACE "," "$" NEEDS_LIBS_ESCAPED "${NEEDS_LIBS}") + string(REPLACE ">" "$" NEEDS_LIBS_ESCAPED "${NEEDS_LIBS_ESCAPED}") + + list(APPEND header "prefix=${CMAKE_INSTALL_PREFIX}") + list(APPEND header "$,${NEEDS_LIBS}>,libdir=\${prefix}/${INSTALL_LIB_DIR},>") + list(APPEND header "$,includedir=\${prefix}/${INSTALL_INCLUDE_DIR},>") + + + list(APPEND libSpecific "Name: ${_NAME}") + if(_DESCRIPTION) + list(APPEND libSpecific "Description: ${_DESCRIPTION}") + endif() + if(_URL) + list(APPEND libSpecific "URL: ${_URL}") + endif() + if(_VERSION) + list(APPEND libSpecific "Version: ${_VERSION}") + endif() + if(_REQUIRES) + list(APPEND libSpecific "Requires: ${_REQUIRES}") + endif() + if(_CONFLICTS) + list(APPEND libSpecific "Conflicts: ${_CONFLICTS}") + endif() + + set(OTHER_INCLUDE_FLAGS "-I$, -I>") # Not needed, we can only get build interface flags here. Insert them after -I\${includedir} if you find a way to fix/workaround it + + # Here is a workaround to inability to use TARGET_LINKER_FILE_NAME for targets not involving library generation. + # Strangely $<") # A hack because there is no escape for `$` or `<` or `$<`. So we just disrupt $< into pieces + set(CURRENT_LIB_ESCAPED_BINARY_NAME "${ESCAPED_GENEXPR_BEGINNING}TARGET_LINKER_FILE_NAME:${TARGET}$") + set(LINK_CURRENT_LIB_FLAG "$>") + + list(APPEND libSpecific "$,${NEEDS_LIBS}>,Libs: -L\${libdir} ${LINK_CURRENT_LIB_FLAG} $,-l$, -l>,>,>\n$,$>,Cflags: -I\${includedir} $,>,>") + + + list(JOIN header "\n" header) + list(JOIN libSpecific "\n" libSpecific) + set(libSpecific "${header}\n\n${libSpecific}") + + #file(WRITE "${PKG_CONFIG_FILE_NAME}" ${libSpecific}) + file(GENERATE OUTPUT "${PKG_CONFIG_FILE_NAME}" + CONTENT "${libSpecific}" + #[CONDITION expression] + ) + + install(FILES "${PKG_CONFIG_FILE_NAME}" + DESTINATION "${_INSTALL_LIB_DIR}/pkgconfig" + COMPONENT "${_COMPONENT}" + ) +endfunction() +