Use partitions on Poco module to simplify module API#5268
Use partitions on Poco module to simplify module API#5268mikomikotaishi wants to merge 6 commits intopocoproject:mainfrom
Poco module to simplify module API#5268Conversation
|
Thanks for the PR! I like the goal of simplifying the module API, but I have a concern about how this interacts with Poco's optional component architecture. The problem: C++20 module partitions ( The previous design — separate modules ( Could you share more about the use case driving this? If the main goal is removing the Recommended: Generate Keep separate modules but have CMake generate the umbrella file, emitting only the set(POCO_MODULE_IMPORTS "")
if(ENABLE_FOUNDATION)
string(APPEND POCO_MODULE_IMPORTS "export import Poco.Foundation;\n")
endif()
if(ENABLE_CRYPTO)
string(APPEND POCO_MODULE_IMPORTS "export import Poco.Crypto;\n")
endif()
# ... etc
configure_file(Poco.cppm.in Poco.cppm @ONLY)This eliminates the preprocessor guards while preserving optional components. Other alternatives:
|
I think it only adds the empty partitions, but does not link anything (for example, if After all, the CI tests do succeed, which does suggest nothing is breaking between this change - it only makes all the module pieces into partitions which may or may not have exported contents. So, again, even though the partition |
But what is the point of having empty partitions?
C++ modules are built only in one CI job, not all. I am trying to understand the goal of these changes. I am probably missing something. |
I recalled at some point finding a paper that was adopted which prohibited |
|
Is this the article that you had in mind? https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1857r3.html |
Counter-Proposal: Per-Component Module Targets with
|
| Aspect | Current | This PR | Proposed |
|---|---|---|---|
#ifdef guards in .cppm |
Yes, everywhere | Removed (but empty partitions compiled) | Not needed — CMake controls what's built |
Minimal builds (ENABLE_CRYPTO=OFF) |
Works (conditional file list) | Compiles empty partition anyway | Works (.cppm never compiled) |
| Inter-component dependencies | Not expressed in modules | Lost (everything is one module) | Explicit import + target_link_libraries |
Separate Modules target |
Yes | Yes | Eliminated |
| Per-component CMake changes | None | None | One POCO_MODULE() call each |
| Module feature opt-in | Always built if sources present | Always built | ENABLE_POCO_MODULES=ON/OFF |
References
- CMake C++20 Modules Documentation —
FILE_SET CXX_MODULES, dependency scanning, installation - Kitware: import CMake; the Experiment is Over! — recommended patterns for multi-target module projects
- P1857R3: Modules Dependency Discovery — the actual restrictions on preprocessor + modules
- C++20 Modules, CMake, and Shared Libraries — practical guide for shared library projects
|
Ah, that was the paper, but indeed it does not restrict conditional That being said, we should continue with changing them to partitions. It would be a potential point of confusion for users to see both So, I'll return the CMake to the original form, but leave the files as partitions rather than full modules. |
|
@matejk Any thoughts on this iteration? |
| #endif | ||
|
|
||
| export module Poco.Dynamic; | ||
| export module Poco:Dynamic; |
There was a problem hiding this comment.
Poco Dynamic is a part of Foundation. Not sure how to declare that in C++ modules syntax.
There was a problem hiding this comment.
We could move all that code into Poco:Foundation. That would actually be a benefit for compile times as fewer, larger translation units are faster to build than multiple small translation units.
In fact, since ENABLE_FOUNDATION is always forced to be on when building the library, should we just remove all of the macro checks for that here?
There was a problem hiding this comment.
It is a part of Foundation already, not a separate library.
Macro checks could be removed for Foundation, true.
There was a problem hiding this comment.
I've gone ahead and moved the stuff originally in Poco:Dynamic just into Poco:Foundation, deleted the Dynamic.cppm file since it's no longer needed, and removed #ifdef guards on Foundation stuff.
Poco modulePoco module to simplify module API
|
@matejk any chance you could re-visit this and let me know your thoughts on my change |
|
I am sorry for not answering so long. The changes are now minimal and I don't have any objections on them. However I am wondering if we need a separate library for C++ modules? IMO modules could be seamlessly integrated with the existing Poco modules as proposed above. What do you think? |
|
I'm confused what you mean by a separate library. Do you mean a separate CMake target? As it is the modules feature is still opt-in, but keeping it bundled is to my knowledge the simplest way to make it accessible to those who request it. Considering how much the module itself depends on what parts of the library are built, it seems easier to me to just leave it directly integrated in the same target, but if you have a concern left unaddressed or know something I don't please let me know. |
Yes, I mean separate CMake target that creates a library (.so or .dll) for C++ modules. As I wrote, I am not sure what is the common practice for other products or what the standard recommends for this. |
|
I'm actually not sure what to do. I'm afraid my experience with whether people prefer to call it directly from the same target or to have it in a separate DLL is a beyond me here. A separate target was the first iteration I made back in #4999, but I think we ended up deciding just to integrate everything into the actual target. |
|
Does this article provide any help: https://mropert.github.io/2026/04/13/modules_in_2026/ |
|
I unfortunately don't see any mention of advice on what to do about shared objects/DLLs. The post was a very interesting read, though. After looking a bit more into it making them separate targets makes sense if users want to both |
This pull request makes the
Pocomodule only consist of partitions. This removes allPoco.*modules and turns them toPoco:*, so that only one module is created rather than several. This should simplify the API and make it far simpler to users (so there is no need to decide betweenimport Poco;orimport Poco.Foundation;, etc.)