# How to Integrate Asio with CMake: A Complete Guide for Standalone Header-Only Networking

> Seamlessly integrate standalone Asio with CMake. This guide shows you how to expose header-only Asio, define ASIO_STANDALONE, and build robust networking applications.

- Repository: [chriskohlhoff/asio](https://github.com/chriskohlhoff/asio)
- Tags: how-to-guide
- Published: 2026-07-16

---

**Standalone Asio is header-only, so CMake integration requires only exposing the `include/` directory to your compiler and defining the `ASIO_STANDALONE` macro to use the built-in implementation instead of Boost.**

The `chriskohlhoff/asio` repository provides a standalone C++ networking library that operates independently of Boost.Asio. Because the repository does not ship a native CMake package, you must manually configure include paths and compile definitions to integrate Asio with CMake.

## Understanding the Asio Header-Only Structure

According to the `chriskohlhoff/asio` source code, Asio is a header-only library. The public API resides entirely in the `include/` directory, with [`include/asio.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio.hpp) serving as the umbrella header that pulls in all components. Individual features like `io_context`, `steady_timer`, and SSL support live in [`include/asio/io_context.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/io_context.hpp), [`include/asio/steady_timer.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/steady_timer.hpp), and `include/asio/ssl/` respectively. No compilation of `.cpp` files is required unless you explicitly opt for separate compilation mode using [`src/asio.cpp`](https://github.com/chriskohlhoff/asio/blob/main/src/asio.cpp).

## Fetching Asio with CMake FetchContent

The most maintainable way to consume Asio is through CMake’s `FetchContent` module, which downloads the source at configure time.

```cmake
cmake_minimum_required(VERSION 3.14)
project(MyAsioApp LANGUAGES CXX)

include(FetchContent)
FetchContent_Declare(
  asio
  GIT_REPOSITORY https://github.com/chriskohlhoff/asio.git
  GIT_TAG        master   # or a specific release tag

)
FetchContent_MakeAvailable(asio)

```

This populates the variable `${asio_SOURCE_DIR}`, which points to the root of the cloned repository.

## Creating an Interface Library Target

Because Asio is header-only, you should create an `INTERFACE` library that propagates include paths and definitions to consuming targets.

```cmake
add_library(asio INTERFACE)
target_include_directories(asio INTERFACE
  ${asio_SOURCE_DIR}/include
)
target_compile_definitions(asio INTERFACE ASIO_STANDALONE)

```

The `ASIO_STANDALONE` macro tells the headers in `include/asio/` to use the built-in implementation rather than searching for Boost components.

## Linking to Your Application

Link the interface library to your executable or library target to automatically apply the include directories and compile definitions.

```cmake
add_executable(my_app src/main.cpp)
target_link_libraries(my_app PRIVATE asio)

```

## Configuring SSL and Threading Dependencies

While the core library is header-only, certain features require system libraries.

### OpenSSL for SSL Support

If you use `asio::ssl` components (defined in [`include/asio/ssl.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/ssl.hpp)), link against OpenSSL:

```cmake
find_package(OpenSSL REQUIRED)
target_link_libraries(my_app PRIVATE OpenSSL::SSL OpenSSL::Crypto)

```

### POSIX Threading on Unix

On Linux and other POSIX platforms, Asio requires the pthread library for `io_context` threading and timers:

```cmake
if(UNIX AND NOT APPLE)
  target_link_libraries(my_app PRIVATE pthread)
endif()

```

## Complete Working Example

The following [`CMakeLists.txt`](https://github.com/chriskohlhoff/asio/blob/main/CMakeLists.txt) demonstrates a minimal, production-ready setup:

```cmake
cmake_minimum_required(VERSION 3.14)
project(MyAsioApp LANGUAGES CXX)

include(FetchContent)
FetchContent_Declare(
  asio
  GIT_REPOSITORY https://github.com/chriskohlhoff/asio.git
  GIT_TAG        master
)
FetchContent_MakeAvailable(asio)

add_library(asio INTERFACE)
target_include_directories(asio INTERFACE ${asio_SOURCE_DIR}/include)
target_compile_definitions(asio INTERFACE ASIO_STANDALONE)

add_executable(my_app src/main.cpp)
target_link_libraries(my_app PRIVATE asio)

find_package(OpenSSL REQUIRED)
target_link_libraries(my_app PRIVATE OpenSSL::SSL OpenSSL::Crypto)

if(UNIX AND NOT APPLE)
  target_link_libraries(my_app PRIVATE pthread)
endif()

```

A corresponding [`src/main.cpp`](https://github.com/chriskohlhoff/asio/blob/main/src/main.cpp) that compiles with this configuration:

```cpp
#include <asio.hpp>
#include <iostream>

int main() {
  asio::io_context ctx;
  asio::steady_timer timer(ctx, std::chrono::seconds(1));
  
  timer.async_wait([](const asio::error_code& ec) {
    if (!ec) std::cout << "Timer expired!\n";
  });
  
  ctx.run();
  return 0;
}

```

## Alternative: Git Submodule Integration

If you prefer not to use `FetchContent`, add Asio as a git submodule:

```bash
git submodule add https://github.com/chriskohlhoff/asio.git external/asio

```

Then modify the include directory path in your [`CMakeLists.txt`](https://github.com/chriskohlhoff/asio/blob/main/CMakeLists.txt):

```cmake
target_include_directories(asio INTERFACE
  ${CMAKE_CURRENT_SOURCE_DIR}/external/asio/include
)

```

## Summary

- **Standalone Asio** from `chriskohlhoff/asio` is header-only; all APIs are in [`include/asio.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio.hpp) and the `include/asio/` directory.
- **CMake integration** requires adding `${asio_SOURCE_DIR}/include` to your target’s include path.
- **Define `ASIO_STANDALONE`** to disable Boost dependencies and enable built-in implementations.
- **Link OpenSSL** when using SSL features, and link `pthread` on POSIX systems for threading support.
- **No source compilation** is required unless you explicitly enable separate compilation mode using [`src/asio.cpp`](https://github.com/chriskohlhoff/asio/blob/main/src/asio.cpp).

## Frequently Asked Questions

### Does Asio ship with a CMake config file?

No, the `chriskohlhoff/asio` repository does not provide a ready-made `asio-config.cmake`. You must manually create an interface library or use `target_include_directories` directly to expose the `include/` directory.

### What is the purpose of the `ASIO_STANDALONE` macro?

This macro disables code paths that depend on Boost libraries and enables Asio’s standalone implementations for smart pointers, error codes, and other utilities. Define it as a compile definition via `target_compile_definitions` to ensure all translation units that include `<asio.hpp>` see the standalone configuration.

### Can I mix standalone Asio with Boost.Asio in the same project?

Technically yes, but you must avoid defining `ASIO_STANDALONE` and instead define `BOOST_ASIO_SEPARATE_COMPILATION` if you want to mix the libraries. However, this is uncommon and generally discouraged because the two libraries share symbol names and can cause One Definition Rule violations.

### Do I need to compile any source files from the `src/` directory?

Only if you use **separate compilation** mode to reduce compile times. In that case, you compile [`src/asio.cpp`](https://github.com/chriskohlhoff/asio/blob/main/src/asio.cpp) and remove the `ASIO_STANDALONE` definition (or use `BOOST_ASIO_SEPARATE_COMPILATION`). For standard header-only usage, you do not need to build any `.cpp` files from the repository.