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

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 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, 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.

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_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.

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.

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), link against OpenSSL:

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:

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

Complete Working Example

The following CMakeLists.txt demonstrates a minimal, production-ready setup:

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 that compiles with this configuration:

#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:

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

Then modify the include directory path in your CMakeLists.txt:

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 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.

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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →