Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial find script #14

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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/[email protected])
- [Ryan Friedman](https://github.com/Ryanf55)
97 changes: 97 additions & 0 deletions cmake/FindASIO.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#[=======================================================================[.rst:
FindASIO
OlivierLDff marked this conversation as resolved.
Show resolved Hide resolved
-------

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 "")
OlivierLDff marked this conversation as resolved.
Show resolved Hide resolved
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
FOUND_VAR ASIO_FOUND
REQUIRED_VARS
ASIO_INCLUDE_DIR
ASIO_VERSION_MAJOR
ASIO_VERSION_MINOR
ASIO_VERSION_PATCH
ASIO_VERSION
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unclear - do we need to add ASIO_FOUND to the REQUIRED_VARS?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it supposed to do it by itself? Only a test can make sure of that.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, it would be nicer if the CMake docs would explain this point. I'll do a test.

VERSION_VAR ASIO_VERSION
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now, the version is required. Since this works since asio 0.3.8, I'd just recommend making it always part of the interface.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What work since asio 0.3.8?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parsing the asio/version.hpp for version info using the same regex.
Since 0.3.8, the version format has been the same and the regex is the same.

)
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
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to understand what to do with the asio macros:

https://think-async.com/Asio/asio-1.28.0/doc/asio/using.html#asio.using.macros

Should these all be exposed as CMake OPTIONs, then set here in target_compile_definitions and a call to target_compile_options?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard to answer here. It was easy when cmake when creating the asio target. I guess when asio is system installed this is the header only version no?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On ubuntu, I get the asio.cpp file but not the asio_ssl.cpp.

$ find /usr | grep asio | grep -v boost | grep cpp
/usr/include/asio/impl/src.cpp

From what I understand, which is used for the pre-compiled header, however 99% of asio is implemented in header files anyways. The find script here ideally should be able to support using asio in either mode. I have only gotten the header-only version working, pre-compiled has errors.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess action with matrix is the way to test everything

)
find_package(Threads REQUIRED)
target_link_libraries(asio INTERFACE Threads::Threads)
endif()