Skip to content

Feature/module#5

Open
ClausKlein wants to merge 48 commits intodevelopfrom
feature/module
Open

Feature/module#5
ClausKlein wants to merge 48 commits intodevelopfrom
feature/module

Conversation

@ClausKlein
Copy link
Owner

@ClausKlein ClausKlein commented Mar 1, 2026

e049443 Feat: Modernize CMakeLists.txt to build and install CXX_MODULE asio the Daniela's way

  • Use import std; where toolchain supports it
  • Change Windows CI Workflow to use import std; too
  • CI workflow with gcc-15, gcc-16
  • CI workflow with clang-21, clang-22
  • CI workflow with MSVC 2025
  • Add more examples
  • Add tests?

DanielaE and others added 26 commits December 6, 2025 11:26
Changes:
- Change 'static const' to 'inline const' for ssl_category and stream_category
- Add optional SSL support via ASIO_ENABLE_SSL CMake option (default: OFF)
- Resolves 'cannot export symbol with internal linkage' compilation error

The inline specifier ensures external linkage while maintaining semantics.
- Fix typo in asio-gmf.h: 'openssl / conf.h' -> 'openssl/conf.h'
- Add SYSTEM keyword for OpenSSL include directories
- Change ASIO_ENABLE_SSL default to ON
- Add detailed logging for OpenSSL paths
@ClausKlein ClausKlein self-assigned this Mar 1, 2026
@ClausKlein ClausKlein requested a review from ecoezen March 3, 2026 07:30
@DanielaE
Copy link

DanielaE commented Mar 3, 2026

Great! 🎉
I will check later this day if the additional change sets on top of mine still work here.

ecoezen
ecoezen previously requested changes Mar 3, 2026
Copy link
Collaborator

@ecoezen ecoezen left a comment

Choose a reason for hiding this comment

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

hey! import std in asio.ixx must be moved after asio module declaration, but remaining comments are not critical that requires changes, an left for general discussion, and potential quality improvements.

@anarthal
Copy link
Collaborator

anarthal commented Mar 3, 2026

Does

import std;
import asio;

work under any of the compilers? without ifdef-ing includes out, I got the impression it probably doesn't as of today. Are you running the test suite importing instead of including?

@DanielaE
Copy link

DanielaE commented Mar 3, 2026

At least it did in 2022 (see my plenary talk at CppCon 2022 and some of my later talks), and it still does today.

I've tested with msvc and clang back then, but not with gcc (for obvious reasons).

@DanielaE
Copy link

DanielaE commented Mar 3, 2026

I've done a quick check with VS2026, building Asio with the additional changeset both as a named module and a header unit. The build of a small in-house application of ours together with the modularized standard library and a couple of other modules is fine, and the application works a expected.

@ClausKlein
Copy link
Owner Author

ClausKlein commented Mar 3, 2026

Does

import std;
import asio;

work under any of the compilers?

yes, not all compilers(Not appleclang), but with MSVC, clang-19+, gcc-15+ it works

Only the current Windows CI has to be modernised
It has only Cmake v3.31.6, for import std we need v4.2+

without ifdef-ing includes out, I got the impression it probably doesn't as of today. Are you running the test suite importing instead of including?

NOT yet, I need to write CMakeLists.txt for the tests, I dit is years ago, It should be possible again.

@anarthal
Copy link
Collaborator

anarthal commented Mar 3, 2026

I've done a little playing and this fails to compile under clang-22/libc++/Ubuntu 24.04:

import std;
import asio;
#include <iterator>

Interestingly, this builds fine:

import asio;
#include <iterator>

I recalled that the problems with mixing include and import std happened transitively, but it looks like this is not the case anymore.

@anarthal
Copy link
Collaborator

anarthal commented Mar 3, 2026

FYI, in my Boost modularization prototype I'm using the notion of "compatibility headers", which will include the standard header or not depending on a config macro (like your ASIO_HAS_IMPORT_STD). This way you don't need to add so many ifdefs, you only need to replace the include:

https://github.com/anarthal/config/blob/feature/cxx20-modules/include/boost/config/std/algorithm.hpp

@ecoezen
Copy link
Collaborator

ecoezen commented Mar 4, 2026

FYI, in my Boost modularization prototype I'm using the notion of "compatibility headers", which will include the standard header or not depending on a config macro (like your ASIO_HAS_IMPORT_STD). This way you don't need to add so many ifdefs, you only need to replace the include:

https://github.com/anarthal/config/blob/feature/cxx20-modules/include/boost/config/std/algorithm.hpp

yes, actually i personally adopted compat headers way as well. it is far more cleaner than preprocessor clutter. i am working on it now.

introduce per-header wrappers (include/asio/detail/std/) and a cmake
script (module/module_compat.cmake) to manage them atomically.

core invariant: std headers are never reachable in module purview.
- without import std: headers included in gmf only
- with import std: only macro-providing headers in gmf (types come
  from import std; macros cannot)
- purview: always blocked for std headers

asio-gmf.h now owns the ASIO_IN_GMF define lifecycle. all
asio includes rewritten via the cmake script.

ran module_compat.cmake to generate headers and update existing header
files to use generated wrapper headers for std includes.
@ecoezen ecoezen self-requested a review March 4, 2026 20:22
@ecoezen
Copy link
Collaborator

ecoezen commented Mar 4, 2026

i'll look at CI stuff soon. fyi @ClausKlein

@ecoezen ecoezen dismissed their stale review March 4, 2026 20:29

mostly resolved by last commits

@ClausKlein
Copy link
Owner Author

@ecoezen we should add a Windows CI build on windows-2025-vs2026 too!

ecoezen added 3 commits March 6, 2026 23:33
- add CMakePresets.json with initial configurations for MSVC, GCC, and Clang [WIP]
- extract experimental 'import std' logic into cmake/enable_import_std.cmake
- clean up root CMakeLists.txt by moving fragile, hardcoded compiler flags into presets
- adapts CMakeLists.txt to changes accordingly
@ecoezen
Copy link
Collaborator

ecoezen commented Mar 6, 2026

hey @ClausKlein. I clean up cmake a bit, introduce an initial cmake presets configuration and updated actions accordingly. i noticed we werent tested import std properly in previous workflows. current failures are import std failures with both clang and gcc. msvc works fine on both modes. feel free to tweak workflows, run conditions etc as i may have changed your initial configurations.

notes/todos:

  • hard coded public flags on targets were problematic as modules are extremely sensitive for flag differences (e.g. not setting /EHsc for import std, but using it on asio module). moved all into the preset. we can create individual toolchain files, if desired.
  • mingw disabled for now to save ci time. we should first resolve problems with clang and gcc on linux imo.
  • we should also bring vs2026, but i believe it will just work flawlessly (which it is locally for me) so we should focus on import std on linux.

current failure:

  • clang with import std: clang++ reports wrong path for libc++.modules.json and cmake not helpful even when setting CMAKE_CXX_STDLIB_MODULES_JSON manually. i'm looking at it. i think i saw your bug report on cmake, which is the reason for the failure.

  • gcc with import std: seems we need some workarounds for macro provided std headers. i think we can reduce some of them by adding complaining macro providing std headers to 'MACRO_STD_HEADERS' in module_compat.cmake and regenerate headers. currently investigating.

=> last 2 commits are still WIP in nature. if you don't like the direction, please feel free to revert it and direct me accordingly. @ClausKlein

@anarthal
Copy link
Collaborator

anarthal commented Mar 7, 2026

Note that for gcc, include and then import works for std, but the other way around doesn't. This applies even if the included file is located in a TU that becomes reachable through an import.

@ecoezen
Copy link
Collaborator

ecoezen commented Mar 7, 2026

Note that for gcc, include and then import works for std, but the other way around doesn't. This applies even if the included file is located in a TU that becomes reachable through an import.

by the commit b12e96c, there is no longer any std includes in module purview. all std includes strictly restricted in global module fragment, with the help of compability headers that guard std header inclusions with ASIO_IN_GMF preprocessor definition. thus, the aforementioned error has been already resolved for the standard library usage in asio. fyi.

logic is as following:

  1. import std supported: only some macro providing std headers included in gmf, rest is provided by import std. no purview inclusion of std headers.
  2. no import std: all std headers included in gmf. no purview inclusions of std headers.

ecoezen added 3 commits March 8, 2026 00:36
…ON path resolution when building with libc++
… to fix module link errors

msvc 19.50 incorrectly drops definitions of unexported inline variables.
@ecoezen
Copy link
Collaborator

ecoezen commented Mar 7, 2026

hey @ClausKlein, I pushed a few updates to the PR. when you have a chance, could you take a look and let me know what you think? happy to iterate further if needed.

Comment on lines +116 to +118
extern "C++"{
inline const winsock_init<>& winsock_init_instance = winsock_init<>(false);
}
Copy link

Choose a reason for hiding this comment

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

You understand that enclosing a declaration with an extern "C++" linkage specification [dcl.link] doesn't affect the linkage of inline variable 'winsock_init_instance' at all, right? It has module linkage, "C++" language linkage like before. The only change is in attachment.

That variable will get initialized as soon as module 'asio' is nominated for import for the first time in transitive appearance order of the module interface dependency tree.

Copy link
Collaborator

Choose a reason for hiding this comment

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

you are right, my wording was poor. the intent is indeed to detach the declaration from the named module so it is no longer attached to asio. i still sometimes (incorrectly) use terms like external/global linkage when i really mean module attachment tweaks, so thanks for the correction.

with msvc 19.50 we observed that an unexported inline definition attached to the module can be discarded if it is not referenced within the module unit itself. when consumers import asio and instantiate templates that reference winsock_init_instance, the linker then fails to find the definition.

placing it inside a linkage-specification detaches the declaration, which makes msvc emit the definition normally and resolves the linker errors. i also considered __declspec(selectany) as an alternative, but this approach seemed preferable since it avoids compiler-specific attributes.

Copy link

Choose a reason for hiding this comment

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

I don't see that in my own current tests using cl.exe 19.50.35725, but did some time in the past:

Miscompiled dynamic initializers

Anyway, do whatever you prefer, it doesn't really matter.

Copy link
Collaborator

Choose a reason for hiding this comment

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

interesting. you can observe the related failure at 4d3168d CI

i have the same error with msvc 19.50 on a different project.

Copy link

Choose a reason for hiding this comment

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

This is a different problem: you see a missing linker symbol. I never did.

The problem that I've reported back to the compiler team was the fact that the code for initializing the variable (i.e. the call to the initializer) wasn't even generated in the first place. 💥at the first instance where an initialized WinSock is required. This is what I am testing for.

Copy link
Collaborator

Choose a reason for hiding this comment

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

yes! that's why i got a bit confused because the error i was facing was a simple codegen bug that boom during linking. i hope this fix survives your initialization tests without any 💥!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants