diff --git a/Readme.md b/Readme.md index ce1e8ca..9c12a51 100644 --- a/Readme.md +++ b/Readme.md @@ -2,10 +2,30 @@ [![👷 compilation](https://github.com/OlivierLDff/asio.cmake/actions/workflows/main.yml/badge.svg)](https://github.com/OlivierLDff/asio.cmake/actions/workflows/main.yml) -CMake wrapper to add [asio](https://github.com/chriskohlhoff/asio) with a simple FetchContent as a static library. +CMake wrapper to add [asio](https://github.com/chriskohlhoff/asio) with a simple FetchContent as a static library or as a CMake find module. ## 🚀 How to use +### [CMake Find Module](https://cmake.org/cmake/help/latest/manual/cmake-developer.7.html#find-modules) + +Use `CMake Find Module` mode if you have installed asio on your system. +Compared to `FetchContent`, this allows your system's package manager to verify version compatability. +Addtionally, this method allows multiple applications to be guaranteed the same version. + +TODO: How should users add `/path/to/asio.cmake/cmake` to `CMAKE_MODULE_PATH`? + +To find whatever version in currently installed, regardless of the version: +```cmake +find_package(ASIO MODULE REQUIRED) +target_link_libraries(myapp PRIVATE asio::asio) +``` + +To specify the exact version required: +```cmake +find_package(ASIO 1.18.1 EXACT MODULE REQUIRED) +target_link_libraries(myapp PRIVATE asio::asio) +``` + ### [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) Use `FetchContent` to add this repository in your cmake script. @@ -126,3 +146,4 @@ Asio is released under the [Boost Software License](http://www.boost.org/LICENSE ## 👥 Authors - [Olivier LDff](https://github.com/OlivierLDff/NetTcpJson/blob/main/olivier.ldff@gmail.com) +- [Ryan Friedman](https://github.com/Ryanf55) diff --git a/cmake/FindASIO.cmake b/cmake/FindASIO.cmake new file mode 100644 index 0000000..6dc88fb --- /dev/null +++ b/cmake/FindASIO.cmake @@ -0,0 +1,93 @@ +#[=======================================================================[.rst: +FindASIO +------- + +Finds the Asio library. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module provides the following imported targets, if found: + +``asio::asio`` + The Asio library + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``ASIO_FOUND`` + True if the system has the Asio library. +``ASIO_VERSION`` + The version of the Asio library which was found. +``ASIO_INCLUDE_DIRS`` + Include directories needed to use Asio. +``ASIO_LIBRARIES`` + Libraries needed to link to Asio. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``ASIO_INCLUDE_DIR`` + The directory containing ``asio.hpp``. + +#]=======================================================================] + +find_path(ASIO_INCLUDE_DIR NAMES asio.hpp NO_CMAKE_FIND_ROOT_PATH REQUIRED) +set(ASIO_HEADER_LOC ${ASIO_INCLUDE_DIR}/asio/version.hpp) +if(NOT EXISTS ${ASIO_HEADER_LOC}) + message(FATAL_ERROR "Could not find asio version file at ${ASIO_HEADER_LOC}") +endif() + +# Read version info from asio header +file(READ ${ASIO_HEADER_LOC} ver_file) +# The line in the file to match: "#define ASIO_VERSION 101801 // 1.18.1" +# This should work as early as asio 0.3.8 +string(REGEX MATCH "#define ASIO_VERSION ([0-9]*)" res ${ver_file}) + +if(res STREQUAL "" OR CMAKE_MATCH_1 STREQUAL "") + message(FATAL_ERROR + "Failed to detect version information in ${ASIO_HEADER_LOC}" + ) +endif() + +math(EXPR + ASIO_VERSION_PATCH + "${CMAKE_MATCH_1} % 100" + OUTPUT_FORMAT DECIMAL +) +math(EXPR + ASIO_VERSION_MINOR + "${CMAKE_MATCH_1} / 100 % 1000" + OUTPUT_FORMAT DECIMAL +) +math(EXPR + ASIO_VERSION_MAJOR + "${CMAKE_MATCH_1} / 100000" + OUTPUT_FORMAT DECIMAL +) +set(ASIO_VERSION + ${ASIO_VERSION_MAJOR}.${ASIO_VERSION_MINOR}.${ASIO_VERSION_PATCH} +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ASIO + REQUIRED_VARS + ASIO_INCLUDE_DIR + VERSION_VAR ASIO_VERSION +) + +if("${ASIO_FOUND}" AND NOT TARGET asio::asio) + add_library(asio IMPORTED INTERFACE) + add_library(asio::asio ALIAS asio) + target_include_directories(asio INTERFACE ${ASIO_INCLUDE_DIR}) + target_compile_definitions(asio + INTERFACE + ASIO_STANDALONE + ) + find_package(Threads REQUIRED) + target_link_libraries(asio INTERFACE Threads::Threads) +endif()