From 5fcd8f7795dc92422d5a682ee1eb2fe14c5e5bf9 Mon Sep 17 00:00:00 2001 From: KTGH Date: Thu, 28 May 2020 17:09:20 -0400 Subject: [PATCH] Add automatic versioning to Cmake (#505) It pulls the version from the user-agent string in the header, so it will not need to be manually adjusted. This version file is installed so that you can check for a specific version with find_package(httplib) Also added HTTPLIB_INCLUDE_DIR (root path without header name), and HTTPLIB_LIBRARY (only if compiled). Added HTTPLIB_VERSION, and HTTPLIB_FOUND (although it's recommended to check if the target exists). Updated CMakeLists documentation for all this. --- CMakeLists.txt | 38 ++++++++++++++++++++++++++++++++++---- httplibConfig.cmake.in | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index acf893c..0786a5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,11 +32,15 @@ ------------------------------------------------------------------------------- - These three variables are available after you run find_package(httplib) - * HTTPLIB_HEADER_PATH - this is the full path to the installed header. + These variables are available after you run find_package(httplib) + * HTTPLIB_HEADER_PATH - this is the full path to the installed header (e.g. /usr/include/httplib.h). * HTTPLIB_IS_USING_OPENSSL - a bool for if OpenSSL support is enabled. * HTTPLIB_IS_USING_ZLIB - a bool for if ZLIB support is enabled. - * HTTPLIB_IS_COMPILED - a bool for if the library is header-only or compiled. + * HTTPLIB_IS_COMPILED - a bool for if the library is compiled, or otherwise header-only. + * HTTPLIB_INCLUDE_DIR - the root path to httplib's header (e.g. /usr/include). + * HTTPLIB_LIBRARY - the full path to the library if compiled (e.g. /usr/lib/libhttplib.so). + * HTTPLIB_VERSION - the project's version string. + * HTTPLIB_FOUND - a bool for if the target was found. Want to use precompiled headers (Cmake feature since v3.16)? It's as simple as doing the following (before linking): @@ -48,7 +52,15 @@ FindPython3 requires Cmake v3.12 ]] cmake_minimum_required(VERSION 3.12.0 FATAL_ERROR) -project(httplib LANGUAGES CXX) + +# Get the user agent and use it as a version +# This gets the string with the user agent from the header. +# This is so the maintainer doesn't actually need to update this manually. +file(STRINGS httplib.h _user_agent_match REGEX "User\-Agent.*cpp\-httplib/([0-9]+\.?)+") +# Need to pull out just the version for use +string(REGEX MATCH "([0-9]+\\.?)+" _httplib_version "${_user_agent_match}") + +project(httplib VERSION ${_httplib_version} LANGUAGES CXX) # Change as needed to set an OpenSSL minimum version. # This is used in the installed Cmake config file. @@ -205,6 +217,23 @@ configure_package_config_file("${PROJECT_NAME}Config.cmake.in" NO_CHECK_REQUIRED_COMPONENTS_MACRO ) +if(HTTPLIB_COMPILE) + write_basic_package_version_file("${PROJECT_NAME}ConfigVersion.cmake" + # Example: if you find_package(httplib 0.5.4) + # then anything >= 0.5 and <= 1.0 is accepted + COMPATIBILITY SameMajorVersion + ) +else() + write_basic_package_version_file("${PROJECT_NAME}ConfigVersion.cmake" + # Example: if you find_package(httplib 0.5.4) + # then anything >= 0.5 and <= 1.0 is accepted + COMPATIBILITY SameMajorVersion + # Tells Cmake that it's a header-only lib + # Mildly useful for end-users :) + ARCH_INDEPENDENT + ) +endif() + # Creates the export httplibTargets.cmake # This is strictly what holds compilation requirements # and linkage information (doesn't find deps though). @@ -218,6 +247,7 @@ install(FILES "${_httplib_build_includedir}/httplib.h" DESTINATION ${CMAKE_INSTA install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" DESTINATION ${_TARGET_INSTALL_CMAKEDIR} ) diff --git a/httplibConfig.cmake.in b/httplibConfig.cmake.in index 0f9ee1f..0e106cc 100644 --- a/httplibConfig.cmake.in +++ b/httplibConfig.cmake.in @@ -6,6 +6,7 @@ set(HTTPLIB_IS_USING_OPENSSL @HTTPLIB_IS_USING_OPENSSL@) set(HTTPLIB_IS_USING_ZLIB @HTTPLIB_IS_USING_ZLIB@) set(HTTPLIB_IS_COMPILED @HTTPLIB_COMPILE@) +set(HTTPLIB_VERSION @PROJECT_VERSION@) include(CMakeFindDependencyMacro) @@ -25,9 +26,41 @@ if(@HTTPLIB_IS_USING_ZLIB@) find_dependency(ZLIB REQUIRED) endif() -# Lets the end-user find the header path if needed +# Mildly useful for end-users +# Not really recommended to be used though +set_and_check(HTTPLIB_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@") +# Lets the end-user find the header path with the header appended # This is helpful if you're using Cmake's pre-compiled header feature set_and_check(HTTPLIB_HEADER_PATH "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@/httplib.h") # Brings in the target library include("${CMAKE_CURRENT_LIST_DIR}/httplibTargets.cmake") + +# Ouputs a "found httplib /usr/include/httplib.h" message when using find_package(httplib) +include(FindPackageMessage) +if(TARGET httplib::httplib) + set(HTTPLIB_FOUND TRUE) + + # Since the compiled version has a lib, show that in the message + if(@HTTPLIB_COMPILE@) + # The list of configurations is most likely just 1 unless they installed a debug & release + get_target_property(_httplib_configs httplib::httplib "IMPORTED_CONFIGURATIONS") + # Need to loop since the "IMPORTED_LOCATION" property isn't want we want. + # Instead, we need to find the IMPORTED_LOCATION_RELEASE or IMPORTED_LOCATION_DEBUG which has the lib path. + foreach(_httplib_conf "${_httplib_configs}") + # Grab the path to the lib and sets it to HTTPLIB_LIBRARY + get_target_property(HTTPLIB_LIBRARY httplib::httplib "IMPORTED_LOCATION_${_httplib_conf}") + # Check if we found it + if(HTTPLIB_LIBRARY) + break() + endif() + endforeach() + + unset(_httplib_configs) + unset(_httplib_conf) + + find_package_message(httplib "Found httplib: ${HTTPLIB_LIBRARY} (found version \"${HTTPLIB_VERSION}\")" "[${HTTPLIB_LIBRARY}][${HTTPLIB_HEADER_PATH}]") + else() + find_package_message(httplib "Found httplib: ${HTTPLIB_HEADER_PATH} (found version \"${HTTPLIB_VERSION}\")" "[${HTTPLIB_HEADER_PATH}]") + endif() +endif()