SoFunction
Updated on 2025-04-06

Methods to import Boost modules using C++20 Modules (problem record)

How to import Boost modules using C++20 Modules

My project case address: /yudaichen/coroutine_blog

introduction

The Modules feature introduced by C++20 has brought many benefits to C++ development, such as speeding up compilation speed and reducing duplicate inclusion of header files. Boost is a widely used collection of C++ libraries, which contains many powerful tools and libraries such as , , and . This article will explain in detail how to import these Boost modules using C++20 Modules.

Environmental preparation

Before you start, you need to make sure:

  • Compiler support: Use compilers that support C++20 Modules, such as GCC 10 and above, Clang 12 and above.
  • CMake Support: The CMake version needs to be 3.20 and above, because CMake 3.20 begins to have better support for C++20 Modules.
  • Boost library installation: Make sure that the Boost library is installed correctly and can be found by the compiler. You canBoost official websiteDownload the source code and compile and install it.

Project structure

First, we create a simple project structure as follows:

project/
├── 
├── 

Configuration

existIn the file, we need to make some configuration to support C++20 Modules and Boost libraries. Here is an example:

cmake_minimum_required(VERSION 3.20)
project(BoostModuleExample)
# Set the C++ standard to C++20set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Find Boost Libraryfind_package(Boost REQUIRED COMPONENTS asio beast redis json)
# Add executable fileadd_executable(BoostModuleExample )
# Link Boost Librarytarget_link_libraries(BoostModuleExample PRIVATE Boost::asio Boost::beast Boost::redis Boost::json)
# Set compiler options to support Modulesif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    target_compile_options(BoostModuleExample PRIVATE -fmodules-ts)
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    target_compile_options(BoostModuleExample PRIVATE -fmodules -fcxx-modules)
endif()

Code explanation:

  • find_package: Used to find Boost libraries and specify required components, includingasiobeastredisandjson
  • target_link_libraries: Link the Boost library to the executable file.
  • target_compile_options: Set the corresponding compilation options to support C++20 Modules according to different compilers.

Importing Boost modules using C++20 Modules

accomplish

// 
module; // Global module fragment/*#include <boost/>*/
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/thread_pool.hpp>
#include <boost/asio/static_thread_pool.hpp>
#include <boost/asio/as_tuple.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/asio/>
#include <boost/asio/>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/>
#include <boost/asio/ip/>
#include <boost/asio/>
#include <boost/asio/use_awaitable.hpp>
//Introduce header files#include <boost/beast/>
#include <boost/beast/>
#include <boost/beast/>
#include <boost/beast/>
#include <boost/beast/>
//Introduce header files#include <boost/>
#include <boost/mysql/>
#include <boost/mysql/handshake_params.hpp>
#include <boost/mysql/>
//Introduce header files#include <boost/>
#include <boost/redis/>
#include <boost/redis/>
#include <boost/redis/>
//Introduce header files#include <boost/json/>
#include <boost/json/>
#include <boost/json/>
#include <boost/json/>
export module boost;
// ===================================================export namespace asio {
// --- Core component export ---using boost::asio::any_completion_executor;
using boost::asio::any_io_executor;
using boost::asio::async_connect;
using boost::asio::awaitable;
using boost::asio::bad_executor;
using boost::asio::buffer;
using boost::asio::cancellation_signal;
using boost::asio::cancellation_slot;
using boost::asio::cancellation_state;
using boost::asio::cancellation_type;
using boost::asio::co_spawn;
using boost::asio::connect;
using boost::asio::coroutine;
using boost::asio::deferred;
using boost::asio::detached;
using boost::asio::detached_t;
using boost::asio::dynamic_buffer;
using boost::asio::execution_context;
using boost::asio::executor;
using boost::asio::executor_arg_t;
using boost::asio::invalid_service_owner;
using boost::asio::io_context;
using boost::asio::multiple_exceptions;
using boost::asio::post;
using boost::asio::service_already_exists;
using boost::asio::socket_base;
using boost::asio::static_thread_pool;
using boost::asio::steady_timer;
using boost::asio::system_context;
using boost::asio::system_executor;
using boost::asio::thread_pool;
using boost::asio::ip::address;
using boost::asio::append;
using boost::asio::as_tuple;
using boost::asio::async_compose;
using boost::asio::bind_cancellation_slot;
using boost::asio::cancel_after;
using boost::asio::consign;
using boost::asio::default_completion_token_t;
using boost::asio::detached;
using boost::asio::enable_terminal_cancellation;
using boost::asio::enable_total_cancellation;
using boost::asio::make_strand;
using boost::asio::signal_set;
// --- Error handling subnamespace ---namespace error {
using boost::asio::error::make_error_code;
}
// --- Coroutine related subnamespace ---namespace this_coro {
BOOST_ASIO_INLINE_VARIABLE constexpr boost::asio::this_coro::
    cancellation_state_t cancellation_state;
BOOST_ASIO_INLINE_VARIABLE constexpr boost::asio::this_coro::executor_t
    executor;
// using boost::asio::this_coro::cancellation_state;
// using boost::asio::this_coro::executor;
using boost::asio::this_coro::reset_cancellation_state;
using boost::asio::this_coro::throw_if_cancelled;
} // namespace this_coro
// ======================== Encapsulation use_awaitable ================================#if defined(GENERATING_DOCUMENTATION)
BOOST_ASIO_INLINE_VARIABLE constexpr boost::asio::use_awaitable_t<>
    use_awaitable;
#else
BOOST_ASIO_INLINE_VARIABLE constexpr boost::asio::use_awaitable_t<>
    use_awaitable(0, 0, 0);
#endif
// =========================== Network support ========================namespace net {
namespace ip {
address make_address(const std::string &str) {
  return boost::asio::ip::make_address(str);
}
} // namespace ip
// --- TCP protocol implementation ---namespace tcp {
using boost::asio::ip::tcp::socket::shutdown_send;
// Use the tcp classusing protocol = boost::asio::ip::tcp;
// Core socket typetemplate <typename Protocol = protocol>
using basic_socket = boost::asio::basic_socket<Protocol>;
template <typename Protocol = protocol>
using basic_socket_acceptor = boost::asio::basic_socket_acceptor<Protocol>;
template <typename Protocol = protocol>
using basic_stream_socket = boost::asio::basic_stream_socket<Protocol>;
template <typename Protocol = protocol>
using basic_resolver = boost::asio::ip::basic_resolver<Protocol>;
// Predefined instanceusing socket = basic_stream_socket<protocol>;
using acceptor = basic_socket_acceptor<protocol>;
using endpoint = boost::asio::ip::basic_endpoint<protocol>;
using resolver = basic_resolver<protocol>;
using resolver_query = boost::asio::ip::basic_resolver_query<protocol>;
using resolver_results = boost::asio::ip::basic_resolver_results<protocol>;
// Factory functioninline socket make_socket(io_context &ctx) { return socket(ctx); }
inline acceptor make_acceptor(io_context &ctx, const endpoint &ep) {
  acceptor a(ctx);
  (());
  a.set_option(socket_base::reuse_address(true));
  (ep);
  ();
  return a;
}
// Enhanced operation functionstemplate <typename Protocol, typename... Args>
auto async_connect(basic_stream_socket<Protocol> &sock, Args &&...args) {
  return boost::asio::async_connect(sock, std::forward<Args>(args)...);
}
// Encapsulation async_read_untiltemplate <typename AsyncReadStream, typename DynamicBuffer,
          typename CompletionToken>
auto async_read_until(AsyncReadStream &stream, DynamicBuffer &&buffer,
                      const std::string &delim, CompletionToken &&token) {
  return boost::asio::async_read_until(
      stream, std::forward<DynamicBuffer>(buffer), delim,
      std::forward<CompletionToken>(token));
}
// Encapsulation async_writetemplate <typename AsyncWriteStream, typename ConstBufferSequence,
          typename CompletionToken>
auto async_write(AsyncWriteStream &stream, const ConstBufferSequence &buffers,
                 CompletionToken &&token) {
  return boost::asio::async_write(stream, buffers,
                                  std::forward<CompletionToken>(token));
}
// Export no_delay option#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined no_delay;
#else
typedef boost::asio::detail::socket_option::boolean<
    BOOST_ASIO_OS_DEF(IPPROTO_TCP), BOOST_ASIO_OS_DEF(TCP_NODELAY)>
    no_delay;
#endif
} // namespace tcp
// --- UDP protocol implementation ---namespace udp {
using protocol = boost::asio::ip::udp;
template <typename Protocol = protocol>
using basic_socket = boost::asio::basic_socket<Protocol>;
template <typename Protocol = protocol>
using basic_endpoint = boost::asio::ip::basic_endpoint<Protocol>;
using socket = basic_socket<protocol>;
using endpoint = basic_endpoint<protocol>;
} // namespace udp
} // namespace net
// ======================== SSL/TLS Support ===========================namespace ssl {
using boost::asio::ssl::context;
using boost::asio::ssl::context_base;
using boost::asio::ssl::host_name_verification;
using boost::asio::ssl::stream;
using boost::asio::ssl::stream_base;
using boost::asio::ssl::verify_context;
// SSL over TCP specialization typetemplate <typename Protocol = net::tcp::protocol>
using ssl_socket = stream<net::tcp::basic_stream_socket<Protocol>>;
// SSL factory functiontemplate <typename Protocol>
ssl_socket<Protocol>
make_ssl_socket(net::tcp::basic_stream_socket<Protocol> &sock, context &ctx) {
  return ssl_socket<Protocol>(std::move(sock), ctx);
}
// SSL error handlingnamespace error {
using boost::asio::ssl::error::make_error_code;
using boost::asio::ssl::error::stream_errors;
} // namespace error
} // namespace ssl
} // namespace asio
// =============================================================export namespace beast {
// --- Core component export ---using boost::beast::error_code;
using boost::beast::file_mode;
using boost::beast::flat_buffer;
using boost::beast::role_type;
using boost::beast::string_view;
using boost::beast::tcp_stream;
using boost::beast::buffers_to_string;
using boost::beast::get_lowest_layer;
// --- HTTP support ---namespace http {
using boost::beast::http::dynamic_body;
using boost::beast::http::empty_body;
using boost::beast::http::field;
using boost::beast::http::file_body;
using boost::beast::http::request;
using boost::beast::http::response;
using boost::beast::http::status;
using boost::beast::http::string_body;
using boost::beast::http::verb;
using boost::beast::http::basic_fields;
using boost::beast::http::request_parser;
// HTTP factory functiontemplate <typename Body = string_body,
          typename Fields = boost::beast::http::fields>
auto make_request(verb method, std::string target, unsigned version = 11) {
  return request<Body, Fields>(method, target, version);
}
// HTTP asynchronous operationtemplate <typename Stream, typename Request, typename CompletionToken>
auto async_write(Stream &stream, Request &&req, CompletionToken &&token) {
  return boost::beast::http::async_write(stream, std::forward<Request>(req),
                                         std::forward<CompletionToken>(token));
}
template <typename Stream, typename Request>
auto async_write(Stream &stream, Request &&req) {
  return boost::beast::http::async_write(stream, std::forward<Request>(req),
                                         asio::use_awaitable);
}
template <typename Stream, typename Response, typename CompletionToken>
auto async_read(Stream &stream, flat_buffer &buffer, Response &res,
                CompletionToken &&token) {
  return boost::beast::http::async_read(stream, buffer, res,
                                        std::forward<CompletionToken>(token));
}
template <typename Stream, typename Response>
auto async_read(Stream &stream, flat_buffer &buffer, Response &res) {
  return boost::beast::http::async_read(stream, buffer, res,
                                        asio::use_awaitable);
}
} // namespace http
// --- WebSocket Support ---namespace websocket {
using boost::beast::role_type;
using boost::beast::websocket::close_code;
using boost::beast::websocket::is_upgrade;
using boost::beast::websocket::request_type;
using boost::beast::websocket::response_type;
using boost::beast::websocket::stream;
using boost::beast::websocket::stream_base;
// WebSocket factory functiontemplate <typename NextLayer>
auto make_websocket_stream(NextLayer &next_layer) {
  return stream<NextLayer>(next_layer);
}
} // namespace websocket
// --- SSL support ---namespace ssl {
using boost::beast::ssl_stream;
// SSL factory functiontemplate <typename Protocol>
auto make_ssl_stream(asio::net::tcp::basic_stream_socket<Protocol> &sock,
                     asio::ssl::context &ctx) {
  return ssl_stream<asio::net::tcp::basic_stream_socket<Protocol>>(
      std::move(sock), ctx);
}
} // namespace ssl
} // namespace beast
// =============================================================export namespace mysql {
using boost::mysql::connection;
using boost::mysql::connection_pool;
using boost::mysql::datetime;
using boost::mysql::diagnostics;
using boost::mysql::error_code;
using boost::mysql::handshake_params;
using boost::mysql::pool_params;
using boost::mysql::pooled_connection;
using boost::mysql::results;
using boost::mysql::row_view;
using boost::mysql::ssl_mode;
using boost::mysql::statement;
using boost::mysql::tcp_ssl_connection;
using boost::mysql::with_params;
// MySQL factory functionsinline auto
make_connection(connection<connection<boost::asio::ssl::stream<
                    boost::asio::basic_stream_socket<boost::asio::ip::tcp>>>>
                    ctx) {
  return connection<tcp_ssl_connection>(std::move(ctx));
}
// MySQL asynchronous operationtemplate <typename CompletionToken>
auto async_connect(connection<tcp_ssl_connection> &conn,
                   const std::string &host, const std::string &user,
                   const std::string &password, const std::string &database,
                   CompletionToken &&token) {
  return conn.async_connect(host, user, password, database,
                            std::forward<CompletionToken>(token));
}
template <typename CompletionToken>
auto async_execute(connection<tcp_ssl_connection> &conn,
                   const std::string &query, results &result,
                   CompletionToken &&token) {
  return conn.async_execute(query, result,
                            std::forward<CompletionToken>(token));
}
} // namespace mysql
// =============================================================export namespace redis {
using boost::redis::connection;
using boost::redis::request;
using boost::redis::response;
// Redis factory functioninline auto make_connection(asio::io_context &ctx) { return connection(ctx); }
// Redis asynchronous operationtemplate <typename CompletionToken>
auto async_execute(connection &conn, const request &req,
                   boost::redis::response<boost::redis::ignore_t> &res,
                   CompletionToken &&token) {
  return conn.async_exec(req, res, std::forward<CompletionToken>(token));
}
} // namespace redis
export namespace boost {
namespace json {
using boost::json::array;
using boost::json::object;
using boost::json::parse;
using boost::json::serialize;
using boost::json::value;
} // namespace json
} // namespace boost

Code explanation:

  • importStatement: UseimportStatements are imported into the Boost module, which can avoid some problems contained in traditional header files.
  • Using the Boost library:existmainIn the functions, we demonstrate how to use the \ and \ libraries.

Things to note

  • Module availability: Make sure that the version of Boost you installed supports C++20 Modules, and some older versions may not.
  • Compile options: Different compilers may support C++20 Modules, and the compilation options need to be adjusted according to actual conditions.

Summarize

By using C++20 Modules to import Boost modules, we can improve compilation efficiency and reduce the problems caused by duplicate inclusion of header files. At the same time, with the rich features of the Boost library, we can develop C++ applications more efficiently. I hope this article can help you import Boost modules smoothly using C++20 Modules.

The above is the detailed method of using C++20 Modules to import Boost modules. If you encounter any problems during the practice, please leave a message in the comment area to discuss.

My project case address: /yudaichen/coroutine_blog

This is the article about how to import Boost modules using C++20 Modules. For more related contents of C++ import Boost modules, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!