* Generation of Make Dependencies for C++ Modules
@ 2025-12-22 18:11 joergboe
2025-12-23 16:23 ` Ben Boeckel
2025-12-27 5:50 ` vspefs
0 siblings, 2 replies; 18+ messages in thread
From: joergboe @ 2025-12-22 18:11 UTC (permalink / raw)
To: gcc
Background
For the translation of programs with C++ modules, the use of special
build systems is necessary.
The dependency information for modules that gcc currently generates in
the make format
(options -M -MD..) have led to some open error messages (109718, 105467,
120103)
and do not seem to be a satisfactory solution.
For build systems, module dependencies in JSON format have been introduced.
The following proposal describes the generation of module dependencies
in make format.
This makes it possible to translate C++ projects with modules using GNU
Make scripts alone,
similar to classic dependency analysis with make and gcc option -M etc
Proposal
1. (gcc) The current available header dependency information are used as is.
2. (gcc) Add the dependencies on imported modules in form of a variable.
(CXX_MOD_<module name>_CMI)
3. (gcc) Add information about which source file exports which module in
form of a list. (CXX_SRC_MOD_IF_LIST)
4. (gcc) A new format in option -fdeps-format activates the module
dependency information.
With this information provided from gcc the make scrip is able to obtain
all necessary dependency information.
5. (make script) Add rules for the generation of the dependency files.
6. (make script) Import the generation dependency files.
7. (make script) Walk through the source module list and emit variables
with the module to CMI file link.
8. (make script) Walk through the source module list and generate the
rules for the translation of the units with modules
as grouped target rules with the object file and the CMI file as target.
9. (make script) Generate the rules for the remaining non-module sources
as usual.
10. (make script) Enable secondary expansion for the prerequisites of
the dependency rules.
You can find a longer description here:
https://github.com/joergboe/MakeItSimple/discussions/8 (Chapter: The
Build Process with C++ Modules)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-22 18:11 Generation of Make Dependencies for C++ Modules joergboe
@ 2025-12-23 16:23 ` Ben Boeckel
2025-12-25 18:28 ` joergboe
2025-12-27 5:50 ` vspefs
1 sibling, 1 reply; 18+ messages in thread
From: Ben Boeckel @ 2025-12-23 16:23 UTC (permalink / raw)
To: joergboe; +Cc: gcc
On Mon, Dec 22, 2025 at 19:11:13 +0100, joergboe via Gcc wrote:
> Background
Hi,
Full disclosure: I authored P1689 (the JSON format), its GCC support,
and C++ modules support in CMake. I've also worked closely with Clang
and MSVC on their support of P1689 and keep tabs on build system
progress for modules ecosystem-wide.
> For the translation of programs with C++ modules, the use of special
> build systems is necessary.
Yes, I agree. I should clarify that my terminology is:
- build tool: a build graph executor (e.g., make, ninja)
- build system: a set of concepts around compilation artifacts (objects,
libraries, binaries) (e.g., cmake, gn, automake)
Some tools are both (e.g., bazel, tup). Either way, I do not believe
that build tools can build modules (sensibly; they can, of course, do
the commands) because there's a layer of understanding missing from them
(as they exist today). I do not believe the compiler possesses the
required information either. I do believe that there is space for a
"gcc+gmake modules compilations" solution, but I do not believe it is
suitable for "real projects" meant to be compiled by more than a handful
of people (see below).
The fundamental issue is to detect and error when something like this
happens:
liba: a.cpp # provides module `a`
libb: b.cpp liba.a # provides module `b` and links to `liba`
when `a.cpp` tries to `import b`. The compilations *can* be ordered to
make this work (absent other ordering constraints), but I see it as a
layering violation. You need to have some build *system* layer that
understands "libb depends on liba" and therefore "liba's sources may not
import libb's provided modules". The compiler definitely does not have
this information (today).
> The dependency information for modules that gcc currently generates in
> the make format
> (options -M -MD..) have led to some open error messages (109718, 105467,
> 120103)
> and do not seem to be a satisfactory solution.
I agree with this.
> For build systems, module dependencies in JSON format have been introduced.
> The following proposal describes the generation of module dependencies
> in make format.
> This makes it possible to translate C++ projects with modules using GNU
> Make scripts alone,
If your goal is to make it easy for CS1 and CS2 classes to compile
homework (and other similar things like Godbolt or small demonstration
snippets), sure. For actual deployment ("real projects"), I would
*highly* suggest considering using an actual build system (cmake, meson,
etc.). Note that modules support does vary between them, but *any*
suitable system would be recommended in my book.
> similar to classic dependency analysis with make and gcc option -M etc
>
> Proposal
>
> 1. (gcc) The current available header dependency information are used as is.
> 2. (gcc) Add the dependencies on imported modules in form of a variable.
> (CXX_MOD_<module name>_CMI)
> 3. (gcc) Add information about which source file exports which module in
> form of a list. (CXX_SRC_MOD_IF_LIST)
> 4. (gcc) A new format in option -fdeps-format activates the module
> dependency information.
> With this information provided from gcc the make scrip is able to obtain
> all necessary dependency information.
*Dependency* information yes, but it lacks *permission* information.
Just because a module *exists* does not mean it is *allowed* to be
imported by any given rule.
You may also have multiple rules generate the same module name (e.g.,
`module testing;` each in its own testing executable). This case is
highly unlikely to be solvable without some understanding of "these
sources belong to artifact A and there is a separate artifact dependency
graph" somewhere to understand that there is, in fact, no collision.
> 5. (make script) Add rules for the generation of the dependency files.
> 6. (make script) Import the generation dependency files.
> 7. (make script) Walk through the source module list and emit variables
> with the module to CMI file link.
> 8. (make script) Walk through the source module list and generate the
> rules for the translation of the units with modules
> as grouped target rules with the object file and the CMI file as target.
> 9. (make script) Generate the rules for the remaining non-module sources
> as usual.
What is the plan (if any) for rules to build tools that use modules
themselves as well as in code they generate? This looks like a "we do
one pass for module dependencies and then do everything after that"
which doesn't consider one-shot builds which generate sources that
use/generate modules during the build and do not exist during this one
pass.
> 10. (make script) Enable secondary expansion for the prerequisites of
> the dependency rules.
>
> You can find a longer description here:
> https://github.com/joergboe/MakeItSimple/discussions/8 (Chapter: The
> Build Process with C++ Modules)
Are there plans for supporting modules coming from external libraries
(e.g., `import boost;` or even `import std;` for that matter)? All
you're going to get are a list of module sources provided by the
library (CPS can provide more, but those, mostly, just turn into flags
rather than rules); CMI files are not going to be shipped (and even if
so, their window of reusability is so narrow as to be "useless" in
practice right now).
I see that at this link that header unit support is "CMI files must
be available before the dependency file can be generated", but this is:
- wasteful if headers are not imported;
- does not describe who/what will generate said CMI files;
- even if that happens, states nothing of how to make compatible CMI
files.
I'd encourage you to read this document:
https://gitlab.kitware.com/ben.boeckel/cmake/-/blob/cxxmodules-docs/Help/manual/cmake-cxxmodules.7.rst
(under review for integration at
https://gitlab.kitware.com/cmake/cmake/-/merge_requests/11507)
describing CMake's support to get some more background on the problem
space. It goes over CMake's support and rationale. You may certainly
decide to carve out a different space, but I would highly encourage
consideration of the use cases not supported under different support
spaces.
Thanks,
--Ben
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-23 16:23 ` Ben Boeckel
@ 2025-12-25 18:28 ` joergboe
2025-12-26 3:16 ` Ben Boeckel
0 siblings, 1 reply; 18+ messages in thread
From: joergboe @ 2025-12-25 18:28 UTC (permalink / raw)
To: Ben Boeckel; +Cc: gcc
Am 23.12.25 um 5:23 PM schrieb Ben Boeckel via Gcc:
> On Mon, Dec 22, 2025 at 19:11:13 +0100, joergboe via Gcc wrote:
>> Background
> Hi,
>
> Full disclosure: I authored P1689 (the JSON format), its GCC support,
> and C++ modules support in CMake. I've also worked closely with Clang
> and MSVC on their support of P1689 and keep tabs on build system
> progress for modules ecosystem-wide.
Hi,
thanks for the quick response.
>> For the translation of programs with C++ modules, the use of special
>> build systems is necessary.
> Yes, I agree. I should clarify that my terminology is:
>
> - build tool: a build graph executor (e.g., make, ninja)
> - build system: a set of concepts around compilation artifacts (objects,
> libraries, binaries) (e.g., cmake, gn, automake)
>
> Some tools are both (e.g., bazel, tup). Either way, I do not believe
> that build tools can build modules (sensibly; they can, of course, do
> the commands) because there's a layer of understanding missing from them
> (as they exist today). I do not believe the compiler possesses the
> required information either. I do believe that there is space for a
> "gcc+gmake modules compilations" solution, but I do not believe it is
> suitable for "real projects" meant to be compiled by more than a handful
> of people (see below).
>
> The fundamental issue is to detect and error when something like this
> happens:
>
> liba: a.cpp # provides module `a`
> libb: b.cpp liba.a # provides module `b` and links to `liba`
>
> when `a.cpp` tries to `import b`. The compilations *can* be ordered to
> make this work (absent other ordering constraints), but I see it as a
> layering violation. You need to have some build *system* layer that
> understands "libb depends on liba" and therefore "liba's sources may not
> import libb's provided modules". The compiler definitely does not have
> this information (today).
The dependency tree is refreshed in every build run. The a dependency files
are targets in Make rules, thus they will be re-created when outdated.
>> The dependency information for modules that gcc currently generates in
>> the make format
>> (options -M -MD..) have led to some open error messages (109718, 105467,
>> 120103)
>> and do not seem to be a satisfactory solution.
> I agree with this.
My goal ist to make this approach working for simple projects.
>
>> For build systems, module dependencies in JSON format have been introduced.
>> The following proposal describes the generation of module dependencies
>> in make format.
>> This makes it possible to translate C++ projects with modules using GNU
>> Make scripts alone,
> If your goal is to make it easy for CS1 and CS2 classes to compile
> homework (and other similar things like Godbolt or small demonstration
> snippets), sure. For actual deployment ("real projects"), I would
> *highly* suggest considering using an actual build system (cmake, meson,
> etc.). Note that modules support does vary between them, but *any*
> suitable system would be recommended in my book.
>
The goal is to make it easy for simple C++ projects with modules to build a
single executable or library with gcc and make only without the need of
dealing with JSON encoded files. I am aware that for complex build systems
the approach using JSON files is appropriate.
>> similar to classic dependency analysis with make and gcc option -M etc
>>
>> Proposal
>>
>> 1. (gcc) The current available header dependency information are used as is.
>> 2. (gcc) Add the dependencies on imported modules in form of a variable.
>> (CXX_MOD_<module name>_CMI)
>> 3. (gcc) Add information about which source file exports which module in
>> form of a list. (CXX_SRC_MOD_IF_LIST)
>> 4. (gcc) A new format in option -fdeps-format activates the module
>> dependency information.
>> With this information provided from gcc the make scrip is able to obtain
>> all necessary dependency information.
> *Dependency* information yes, but it lacks *permission* information.
> Just because a module *exists* does not mean it is *allowed* to be
> imported by any given rule.
>
> You may also have multiple rules generate the same module name (e.g.,
> `module testing;` each in its own testing executable). This case is
> highly unlikely to be solvable without some understanding of "these
> sources belong to artifact A and there is a separate artifact dependency
> graph" somewhere to understand that there is, in fact, no collision.
One build script is limited to build a single binary. This proposal is
not intended to
replace a 'build system'.
>> 5. (make script) Add rules for the generation of the dependency files.
>> 6. (make script) Import the generation dependency files.
>> 7. (make script) Walk through the source module list and emit variables
>> with the module to CMI file link.
>> 8. (make script) Walk through the source module list and generate the
>> rules for the translation of the units with modules
>> as grouped target rules with the object file and the CMI file as target.
>> 9. (make script) Generate the rules for the remaining non-module sources
>> as usual.
> What is the plan (if any) for rules to build tools that use modules
> themselves as well as in code they generate? This looks like a "we do
> one pass for module dependencies and then do everything after that"
> which doesn't consider one-shot builds which generate sources that
> use/generate modules during the build and do not exist during this one
> pass.
In such a case, the tools that Make offers can be used; write a rule
with the source file as the target.
>> 10. (make script) Enable secondary expansion for the prerequisites of
>> the dependency rules.
>>
>> You can find a longer description here:
>> https://github.com/joergboe/MakeItSimple/discussions/8 (Chapter: The
>> Build Process with C++ Modules)
> Are there plans for supporting modules coming from external libraries
> (e.g., `import boost;` or even `import std;` for that matter)? All
> you're going to get are a list of module sources provided by the
> library (CPS can provide more, but those, mostly, just turn into flags
> rather than rules); CMI files are not going to be shipped (and even if
> so, their window of reusability is so narrow as to be "useless" in
> practice right now).
Header units must be translates into CMI files beforehand with the same
compiler
version and settings.
> I see that at this link that header unit support is "CMI files must
> be available before the dependency file can be generated", but this is:
This statement reflects the current state how the dependency scanning with
gcc (-M) currently works.
> - wasteful if headers are not imported;
> - does not describe who/what will generate said CMI files;
> - even if that happens, states nothing of how to make compatible CMI
> files.
> I'd encourage you to read this document:
>
> https://gitlab.kitware.com/ben.boeckel/cmake/-/blob/cxxmodules-docs/Help/manual/cmake-cxxmodules.7.rst
>
> (under review for integration at
> https://gitlab.kitware.com/cmake/cmake/-/merge_requests/11507)
>
> describing CMake's support to get some more background on the problem
> space. It goes over CMake's support and rationale. You may certainly
> decide to carve out a different space, but I would highly encourage
> consideration of the use cases not supported under different support
> spaces.
>
> Thanks,
>
> --Ben
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-25 18:28 ` joergboe
@ 2025-12-26 3:16 ` Ben Boeckel
0 siblings, 0 replies; 18+ messages in thread
From: Ben Boeckel @ 2025-12-26 3:16 UTC (permalink / raw)
To: joergboe; +Cc: gcc
On Thu, Dec 25, 2025 at 19:28:43 +0100, joergboe wrote:
> The goal is to make it easy for simple C++ projects with modules to build a
> single executable or library with gcc and make only without the need of
> dealing with JSON encoded files. I am aware that for complex build systems
> the approach using JSON files is appropriate.
And that's a fine goal to have :) . I just want to make sure goals align
with strategy.
Thanks,
--Ben
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-22 18:11 Generation of Make Dependencies for C++ Modules joergboe
2025-12-23 16:23 ` Ben Boeckel
@ 2025-12-27 5:50 ` vspefs
2025-12-27 11:24 ` Jose E. Marchesi
1 sibling, 1 reply; 18+ messages in thread
From: vspefs @ 2025-12-27 5:50 UTC (permalink / raw)
To: joergboe; +Cc: gcc
Hi!
I also looked into this problem some time earlier this year. You can find my
result and the discussion with the community at a thread named "RFC: A redesign
of `-Mmodules` output" in the February and March mailing list. I had an
analysis of why things are what they are right now (related standard proposals,
GCC's motivation and limitation of current behavior), which haven't changed, so
at least that bit would be useful.
The CMake documentation Ben sent provides a robust and complete design from a
high point of view. It sums up pretty much everything you need to care about on
C++20 modules as a build system developer.
Also, I have 2 articles that might be of your interest:
https://vspefs-scons-cxxmodule-1.pages.dev and
https://vspefs-scons-cxxmodule-2.pages.dev. Yes, it has "SCons" in their titles,
but only the last bit in the 2nd article is about SCons. I tried to provide the
fullest picture of the reality, useful facilities, and challenges of building
C++20 modules. Also, I proposed 3 major ways of implementing it, which kind of
overlaps with the CMake documentation and Ben's reply in this thread, but is
still worth a read if you ask me.
And if you can, do read the thread and the Reddit post it mentioned. Much of
the discussion is beneficial for looking at C++20 from a fuller picture.
> For the translation of programs with C++ modules, the use of special
> build systems is necessary.
Yes. That's why we have to consider the users of the `-M` output. That is
either a direct Makefile user or a build system. For a direct Makefile user,
they might want to use implicit rules for convenience, whose usage is disabled
by grouped targets. And for a build system, many of the heavy lifting can be
moved to the build system at configuration or generation stage. Less script
in Makefile, faster the build process.
And Ben is right, C++20 modules is not for Make. So I think our main target
here is Autotools or any other build system that depends on Makefile recursion.
If we also support standalone Makefile rule generation that could be the cherry
on top, but first and foremost I think we need to make modules work with
Autotools (which would definitely involve modifying Autoconf or Automake source
as well).
Also, there are many problems that are "distribution" problems instead of
"building" problems.
> 2. (gcc) Add the dependencies on imported modules in form of a variable.
> (CXX_MOD_<module name>_CMI)
This is the tricky part. We can't assume there's only 1 CMI for every module
because CMIs are terribly incompatible. There are reasons to have more than 1
CMI for a module in a single build. Other challenges are mentioned in Ben's
reply, but they are more of a "higher point of view" stuff, and this is a
lower, DAG-level problem.
> You can find a longer description here:
> https://github.com/joergboe/MakeItSimple/discussions/8 (Chapter: The
> Build Process with C++ Modules)
What's your idea of libcody and GCC's built-in module mapper by the way?
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-27 5:50 ` vspefs
@ 2025-12-27 11:24 ` Jose E. Marchesi
2025-12-27 12:01 ` Arsen Arsenović
2025-12-28 4:31 ` vspefs
0 siblings, 2 replies; 18+ messages in thread
From: Jose E. Marchesi @ 2025-12-27 11:24 UTC (permalink / raw)
To: vspefs via Gcc; +Cc: joergboe, vspefs
> Hi!
>
> I also looked into this problem some time earlier this year. You can find my
> result and the discussion with the community at a thread named "RFC: A redesign
> of `-Mmodules` output" in the February and March mailing list. I had an
> analysis of why things are what they are right now (related standard proposals,
> GCC's motivation and limitation of current behavior), which haven't changed, so
> at least that bit would be useful.
>
> The CMake documentation Ben sent provides a robust and complete design from a
> high point of view. It sums up pretty much everything you need to care about on
> C++20 modules as a build system developer.
>
> Also, I have 2 articles that might be of your interest:
> https://vspefs-scons-cxxmodule-1.pages.dev and
> https://vspefs-scons-cxxmodule-2.pages.dev. Yes, it has "SCons" in their titles,
> but only the last bit in the 2nd article is about SCons. I tried to provide the
> fullest picture of the reality, useful facilities, and challenges of building
> C++20 modules. Also, I proposed 3 major ways of implementing it, which kind of
> overlaps with the CMake documentation and Ben's reply in this thread, but is
> still worth a read if you ask me.
>
> And if you can, do read the thread and the Reddit post it mentioned. Much of
> the discussion is beneficial for looking at C++20 from a fuller picture.
>
>> For the translation of programs with C++ modules, the use of special
>> build systems is necessary.
>
> Yes. That's why we have to consider the users of the `-M` output. That is
> either a direct Makefile user or a build system. For a direct Makefile user,
> they might want to use implicit rules for convenience, whose usage is disabled
> by grouped targets. And for a build system, many of the heavy lifting can be
> moved to the build system at configuration or generation stage. Less script
> in Makefile, faster the build process.
>
> And Ben is right, C++20 modules is not for Make. So I think our main target
> here is Autotools or any other build system that depends on Makefile recursion.
> If we also support standalone Makefile rule generation that could be the cherry
> on top, but first and foremost I think we need to make modules work with
> Autotools (which would definitely involve modifying Autoconf or Automake source
> as well).
Not sure how relevant this is for C++, but soon we will be sending a
proposal to Automake for supporting non-optional dependencies and thus
having native support for Algol 68, Fortran and Go modules/packages.
> Also, there are many problems that are "distribution" problems instead of
> "building" problems.
>
>> 2. (gcc) Add the dependencies on imported modules in form of a variable.
>> (CXX_MOD_<module name>_CMI)
>
> This is the tricky part. We can't assume there's only 1 CMI for every module
> because CMIs are terribly incompatible. There are reasons to have more than 1
> CMI for a module in a single build. Other challenges are mentioned in Ben's
> reply, but they are more of a "higher point of view" stuff, and this is a
> lower, DAG-level problem.
>
>> You can find a longer description here:
>> https://github.com/joergboe/MakeItSimple/discussions/8 (Chapter: The
>> Build Process with C++ Modules)
>
> What's your idea of libcody and GCC's built-in module mapper by the way?
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-27 11:24 ` Jose E. Marchesi
@ 2025-12-27 12:01 ` Arsen Arsenović
2025-12-28 4:31 ` vspefs
1 sibling, 0 replies; 18+ messages in thread
From: Arsen Arsenović @ 2025-12-27 12:01 UTC (permalink / raw)
To: Jose E. Marchesi; +Cc: Gcc, joergboe, vspefs
[-- Attachment #1: Type: text/plain, Size: 424 bytes --]
"Jose E. Marchesi" <jose.marchesi@oracle.com> writes:
> Not sure how relevant this is for C++, but soon we will be sending a
> proposal to Automake for supporting non-optional dependencies and thus
> having native support for Algol 68, Fortran and Go modules/packages.
C++ modules are in may ways similar to Fortran ones (but not entirely),
so it would be interesting to hear how that goes.
--
Arsen Arsenović
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 418 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-27 11:24 ` Jose E. Marchesi
2025-12-27 12:01 ` Arsen Arsenović
@ 2025-12-28 4:31 ` vspefs
2025-12-28 14:30 ` Jose E. Marchesi
1 sibling, 1 reply; 18+ messages in thread
From: vspefs @ 2025-12-28 4:31 UTC (permalink / raw)
To: Jose E. Marchesi; +Cc: vspefs via Gcc, joergboe
> Not sure how relevant this is for C++, but soon we will be sending a
> proposal to Automake for supporting non-optional dependencies and thus
> having native support for Algol 68, Fortran and Go modules/packages.
Highly relevant. Actually it would also concern Ada, Haskell, etc. because all
“compiles into an intermediate binary representation” module systems are alike.
It’s just that people expect more from C++ and C++ indeed has a far more
complex context.
For example, Fortran modules’ intermediate representation also has the
incompatibility problem, but far as I know Fortran users just manually manage
them. A Fortran user told me he just makes a directory to place the
intermediate files for every set of compilation flags he needs. Whereas in C++,
people expect package managers/build systems to automatically solve this
problem.
This could be interesting! I’m not familiar with Automake’s evolution process.
Where would you be sending the proposal, Automake mailing list?
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-28 4:31 ` vspefs
@ 2025-12-28 14:30 ` Jose E. Marchesi
2025-12-28 21:50 ` Nathaniel Shead
2025-12-29 2:50 ` Ben Boeckel
0 siblings, 2 replies; 18+ messages in thread
From: Jose E. Marchesi @ 2025-12-28 14:30 UTC (permalink / raw)
To: vspefs; +Cc: vspefs via Gcc, joergboe
>> Not sure how relevant this is for C++, but soon we will be sending a
>> proposal to Automake for supporting non-optional dependencies and thus
>> having native support for Algol 68, Fortran and Go modules/packages.
>
> Highly relevant. Actually it would also concern Ada, Haskell, etc. because all
> “compiles into an intermediate binary representation” module systems are alike.
> It’s just that people expect more from C++ and C++ indeed has a far more
> complex context.
We basically borrowed the Go model for Algol 68 modules. In this model,
the "exports" data that conforms the interface of a module gets
generated in a section .a68_exports, or .go_exports for Go. Of course
the Go exports and Algol 68 exports are very different, in both encoding
and actual contents, but the overall model is more or less the same.
In a nutshell, when you compile an Algol 68 compilation unit that
contains a module named Foo:
$ ga68 -c foo.a68
it results in a foo.o with the compiled object code, plus the exports
data in .a68_exports. If you then compile another file, bar.a68, that
uses the module defined in foo (via "access Foo"), you then do:
$ ga68 -c bar.a68
When the compiler sees the "access Foo" in bar.a68, it searches for
exports info for a module of that name. It does so by looking, in this
order:
- For a file foo.m68 that contains just exports info.
- For a file libfoo.so that might have an .a68_exports section.
- For a file libfoo.a whose objects might have .a68_exports sections.
- For a file foo.o which might have an .a68_exports section.
Both -I and -L paths are searched this way. The name mapping can be
altered by passing "module maps" to the compiler via -fmodules-map and
-fmodules-map-file options.
If the exports are found then they are searched for Foo's exports. If
these are not found an error is issued.
Exports data is concatenable, so linkers just DTRT when combining
several object files into archives or DSOs.
Using separated .m68 files should not be necessary in most cases. An
Algol 68 library distributed in the form of one or more DSOs will be
shipping all the necessary exports withing itself.
> For example, Fortran modules’ intermediate representation also has the
> incompatibility problem, but far as I know Fortran users just manually manage
> them. A Fortran user told me he just makes a directory to place the
> intermediate files for every set of compilation flags he needs. Whereas in C++,
> people expect package managers/build systems to automatically solve this
> problem.
>
I'm just finished with the implementation of the modules system itself
in ga68 (but for a few remaining nits) and I haven't had a chance yet to
reflect about (or even become aware of) most of these problems, so I
don't know how many of these will impact Algol 68, but it would be nice
to come with a solution/strategy/automake that would also work for the
other languages as well. It would be difficult to come with something
that works for Algol 68 but will wont for Go, and most likely Fortran as
well, but in the case of C++ I am not that sure, because AFAIK C++
modules are more like an intra-compiler optimization, i.e. are they
supposed to survive a final link and be distributed?. I obviously have
to get a clue, and I will start with the links provided in this thread.
The main limitation in Automake is that it currently supports automatic
dependency tracking, but only as an optimization for re-compilations,
i.e. given a list of sources foo.c, bar.c, baz.c, you should be able to
compile them in any order into foo.o, bar.o and baz.o (the header system
of C assures that.) If you have automatic dependency tracking enabled,
that compilation also extracts dependency info (via -M flags) that can
then be used in further re-compilations to optimize.
Our modules are different, of course.
Thinking quickly, the compiler would need to be invoked first with all
involved source files plus context (in -I or -L paths) to generate
_complete_ dependency info, taking into account the whole picture, but
no exports nor object code yet:
$ ga68 -MD foo.a68 bar.a68 ... -I.. -I.. -I..
This will also detect and report invalid configurations with circular
dependencies etc. The resulting dependency information, maybe in the
form of phony make rules with fill-able actions, would then be consumed
and used by Automake in order to arrange the rules for building each
object, then different primaries like executables, libraries, libtool
libraries, etc.
Both Autoconf and Automake already have Algol 68 support, but since the
later doesn't know about Algol 68 modules yet, we are forced to handle
dependencies by hand, which is a PITA. For example:
AM_A68FLAGS = -fcheck=nil -Whidden-declarations=prelude
bin_PROGRAMS = godcc
godcc_SOURCES = utils.a68 argp.a68 http.a68 json.a68 ce.a68 \
list.a68 compile.a68 format.a68 globals.a68 \
godcc.a68
# Dependencies.
# In the future will be generated by ga68.
utils.o: globals.o utils.a68
argp.o: utils.o argp.a68
http.o: utils.o http.a68
json.o: utils.o json.a68
ce.o: globals.o http.o json.o ce.a68
list.o: globals.o ce.o list.a68
compile.o: globals.o ce.o compile.a68
format.o: globals.o ce.o format.a68
godcc.o: compile.o list.o format.o godcc.a68
Things get worse with Algol 68 projects using libtool:
AM_A68FLAGS = -std=gnu68 -fcheck=nil \
-fmodules-map-file=$(srcdir)/Modules.map
lib_LTLIBRARIES = libgramp.la
libgramp_la_SOURCES = lg-error.a68 \
lg-symbol.a68 \
lg-word.a68 \
lg-alphabet.a68 \
lg-grammar.a68 \
lg-mgrammar.a68 \
lg-vwgrammar.a68 \
lg-language.a68 \
lg-automata.a68 \
lg-graml.a68 \
lg-gramvm.a68 \
libgramp.a68
libgramp_la_A68FLAGS = $(AM_A68FLAGS) -I../common
libgramp_la_LIBADD = ../common/libgrampcommon.la
Where for each .a68 file both PIC and non-pic files are built, with
names like:
libgramp_la-lg-word.o (non-PIC version)
.libs/libgramp_la-lg-word.o (PIC version)
where both objects contain exactly the same .a68_exports sections.
This is why we want to have built-in Automake support, sooner than
later. Handling these dependencies manually in Makefile.am is just
crazy.
> This could be interesting! I’m not familiar with Automake’s evolution process.
> Where would you be sending the proposal, Automake mailing list?
Automake changes are discussed in the Automake mailing list,
automake@gnu.org. CCing this list may make sense as well so everyone is
in the loop.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-28 14:30 ` Jose E. Marchesi
@ 2025-12-28 21:50 ` Nathaniel Shead
2025-12-29 0:03 ` vspefs
2025-12-29 2:50 ` Ben Boeckel
1 sibling, 1 reply; 18+ messages in thread
From: Nathaniel Shead @ 2025-12-28 21:50 UTC (permalink / raw)
To: Jose E. Marchesi; +Cc: vspefs, gcc, joergboe
On Sun, Dec 28, 2025 at 03:30:04PM +0100, Jose E. Marchesi via Gcc wrote:
>
> >> Not sure how relevant this is for C++, but soon we will be sending a
> >> proposal to Automake for supporting non-optional dependencies and thus
> >> having native support for Algol 68, Fortran and Go modules/packages.
> >
> > Highly relevant. Actually it would also concern Ada, Haskell, etc. because all
> > “compiles into an intermediate binary representation” module systems are alike.
> > It’s just that people expect more from C++ and C++ indeed has a far more
> > complex context.
>
> We basically borrowed the Go model for Algol 68 modules. In this model,
> the "exports" data that conforms the interface of a module gets
> generated in a section .a68_exports, or .go_exports for Go. Of course
> the Go exports and Algol 68 exports are very different, in both encoding
> and actual contents, but the overall model is more or less the same.
>
> In a nutshell, when you compile an Algol 68 compilation unit that
> contains a module named Foo:
>
> $ ga68 -c foo.a68
>
> it results in a foo.o with the compiled object code, plus the exports
> data in .a68_exports. If you then compile another file, bar.a68, that
> uses the module defined in foo (via "access Foo"), you then do:
>
> $ ga68 -c bar.a68
>
> When the compiler sees the "access Foo" in bar.a68, it searches for
> exports info for a module of that name. It does so by looking, in this
> order:
>
> - For a file foo.m68 that contains just exports info.
> - For a file libfoo.so that might have an .a68_exports section.
> - For a file libfoo.a whose objects might have .a68_exports sections.
> - For a file foo.o which might have an .a68_exports section.
>
> Both -I and -L paths are searched this way. The name mapping can be
> altered by passing "module maps" to the compiler via -fmodules-map and
> -fmodules-map-file options.
>
> If the exports are found then they are searched for Foo's exports. If
> these are not found an error is issued.
>
> Exports data is concatenable, so linkers just DTRT when combining
> several object files into archives or DSOs.
>
> Using separated .m68 files should not be necessary in most cases. An
> Algol 68 library distributed in the form of one or more DSOs will be
> shipping all the necessary exports withing itself.
>
> > For example, Fortran modules’ intermediate representation also has the
> > incompatibility problem, but far as I know Fortran users just manually manage
> > them. A Fortran user told me he just makes a directory to place the
> > intermediate files for every set of compilation flags he needs. Whereas in C++,
> > people expect package managers/build systems to automatically solve this
> > problem.
> >
>
> I'm just finished with the implementation of the modules system itself
> in ga68 (but for a few remaining nits) and I haven't had a chance yet to
> reflect about (or even become aware of) most of these problems, so I
> don't know how many of these will impact Algol 68, but it would be nice
> to come with a solution/strategy/automake that would also work for the
> other languages as well. It would be difficult to come with something
> that works for Algol 68 but will wont for Go, and most likely Fortran as
> well, but in the case of C++ I am not that sure, because AFAIK C++
> modules are more like an intra-compiler optimization, i.e. are they
> supposed to survive a final link and be distributed?. I obviously have
> to get a clue, and I will start with the links provided in this thread.
>
Some people seem to want that from C++ modules, but the way they
currently work is highly compiler specific (even to the point that
mismatching compiler flags can cause a compiled module interface to be
rejected). I don't see this changing anytime soon; my personal
expectation is that C++ build systems will still require distributing at
least the sources for any public module interfaces in addition to shared
libraries with the contents of any relevant implementation units.
> The main limitation in Automake is that it currently supports automatic
> dependency tracking, but only as an optimization for re-compilations,
> i.e. given a list of sources foo.c, bar.c, baz.c, you should be able to
> compile them in any order into foo.o, bar.o and baz.o (the header system
> of C assures that.) If you have automatic dependency tracking enabled,
> that compilation also extracts dependency info (via -M flags) that can
> then be used in further re-compilations to optimize.
>
> Our modules are different, of course.
>
> Thinking quickly, the compiler would need to be invoked first with all
> involved source files plus context (in -I or -L paths) to generate
> _complete_ dependency info, taking into account the whole picture, but
> no exports nor object code yet:
>
> $ ga68 -MD foo.a68 bar.a68 ... -I.. -I.. -I..
>
> This will also detect and report invalid configurations with circular
> dependencies etc. The resulting dependency information, maybe in the
> form of phony make rules with fill-able actions, would then be consumed
> and used by Automake in order to arrange the rules for building each
> object, then different primaries like executables, libraries, libtool
> libraries, etc.
>
> Both Autoconf and Automake already have Algol 68 support, but since the
> later doesn't know about Algol 68 modules yet, we are forced to handle
> dependencies by hand, which is a PITA. For example:
>
> AM_A68FLAGS = -fcheck=nil -Whidden-declarations=prelude
>
> bin_PROGRAMS = godcc
> godcc_SOURCES = utils.a68 argp.a68 http.a68 json.a68 ce.a68 \
> list.a68 compile.a68 format.a68 globals.a68 \
> godcc.a68
>
> # Dependencies.
> # In the future will be generated by ga68.
>
> utils.o: globals.o utils.a68
> argp.o: utils.o argp.a68
> http.o: utils.o http.a68
> json.o: utils.o json.a68
> ce.o: globals.o http.o json.o ce.a68
> list.o: globals.o ce.o list.a68
> compile.o: globals.o ce.o compile.a68
> format.o: globals.o ce.o format.a68
> godcc.o: compile.o list.o format.o godcc.a68
>
> Things get worse with Algol 68 projects using libtool:
>
> AM_A68FLAGS = -std=gnu68 -fcheck=nil \
> -fmodules-map-file=$(srcdir)/Modules.map
>
> lib_LTLIBRARIES = libgramp.la
> libgramp_la_SOURCES = lg-error.a68 \
> lg-symbol.a68 \
> lg-word.a68 \
> lg-alphabet.a68 \
> lg-grammar.a68 \
> lg-mgrammar.a68 \
> lg-vwgrammar.a68 \
> lg-language.a68 \
> lg-automata.a68 \
> lg-graml.a68 \
> lg-gramvm.a68 \
> libgramp.a68
> libgramp_la_A68FLAGS = $(AM_A68FLAGS) -I../common
> libgramp_la_LIBADD = ../common/libgrampcommon.la
>
> Where for each .a68 file both PIC and non-pic files are built, with
> names like:
>
> libgramp_la-lg-word.o (non-PIC version)
> .libs/libgramp_la-lg-word.o (PIC version)
>
> where both objects contain exactly the same .a68_exports sections.
>
> This is why we want to have built-in Automake support, sooner than
> later. Handling these dependencies manually in Makefile.am is just
> crazy.
>
> > This could be interesting! I’m not familiar with Automake’s evolution process.
> > Where would you be sending the proposal, Automake mailing list?
>
> Automake changes are discussed in the Automake mailing list,
> automake@gnu.org. CCing this list may make sense as well so everyone is
> in the loop.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-28 21:50 ` Nathaniel Shead
@ 2025-12-29 0:03 ` vspefs
2025-12-29 2:31 ` Ben Boeckel
0 siblings, 1 reply; 18+ messages in thread
From: vspefs @ 2025-12-29 0:03 UTC (permalink / raw)
To: Nathaniel Shead; +Cc: Jose E. Marchesi, gcc, joergboe
> Some people seem to want that from C++ modules, but the way they
> currently work is highly compiler specific (even to the point that
> mismatching compiler flags can cause a compiled module interface to be
> rejected). I don't see this changing anytime soon; my personal
> expectation is that C++ build systems will still require distributing at
> least the sources for any public module interfaces in addition to shared
> libraries with the contents of any relevant implementation units.
I haven’t really gone through Jose’s informative reply, but your concern here is valid. CMI is designed to be an extremely implementation-specific stuff and everything you said is right.
What I want to point out is there are some standard and community efforts to make it distributable, but to make it actually useful we’re practically at least designing a “standard C++ AST” which can be considered impractical. By “community efforts” I mean CMake does distribute CMI but that’s just one way of distributing module packages. The alternative, and from your (also my) point of view, the correct way, is to use CXX_MODULES file set to package module interface units in the final distribution. Meanwhile, Xmake and Bazel don’t really care about binary distribution.
There are naturally some distribution problems emerging here. CMake’s solution works perfectly if we stay in the CMake universe but it distributes CMake script along with the package. If we want module packages at least universal as pkg-config packages, we’ll need some consensus between build systems. It can be pessimistic or limiting. WG21 used to have a study group that could make it a standard effort but due to reasons they can’t. Now arguably the best place to discuss such things is the EcoStd organization.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-29 0:03 ` vspefs
@ 2025-12-29 2:31 ` Ben Boeckel
2025-12-29 6:12 ` vspefs
0 siblings, 1 reply; 18+ messages in thread
From: Ben Boeckel @ 2025-12-29 2:31 UTC (permalink / raw)
To: vspefs; +Cc: Nathaniel Shead, Jose E. Marchesi, gcc, joergboe
On Mon, Dec 29, 2025 at 00:03:44 +0000, vspefs via Gcc wrote:
> > Some people seem to want that from C++ modules, but the way they
> > currently work is highly compiler specific (even to the point that
> > mismatching compiler flags can cause a compiled module interface to be
> > rejected). I don't see this changing anytime soon; my personal
> > expectation is that C++ build systems will still require distributing at
> > least the sources for any public module interfaces in addition to shared
> > libraries with the contents of any relevant implementation units.
>
> I haven’t really gone through Jose’s informative reply, but your
> concern here is valid. CMI is designed to be an extremely
> implementation-specific stuff and everything you said is right.
I have a pending reply to Jose's post, but I'll reply here since it is
more focused.
> What I want to point out is there are some standard and community
> efforts to make it distributable, but to make it actually useful we’re
> practically at least designing a “standard C++ AST” which can be
> considered impractical. By “community efforts” I mean CMake does
> distribute CMI but that’s just one way of distributing module
> packages. The alternative, and from your (also my) point of view, the
> correct way, is to use CXX_MODULES file set to package module
> interface units in the final distribution. Meanwhile, Xmake and Bazel
CMake ships the CMI (though it uses the BMI TLA), but currently does not
consume it. The idea is that multiple CMI files could be shipped for
each module. If P2581 is ever implemented, CMake could look at what BMI
files are available for the module and use "copy file" as the "bmild the
module" implementation.
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2581r2.pdf
Will it ever exist? No idea.
I haven't dug into xmake's implementation, but Bazel (AFAIK) is much
stricter about flag sets across the build and can kind of wave it away
by convention.
> There are naturally some distribution problems emerging here. CMake’s
> solution works perfectly if we stay in the CMake universe but it
> distributes CMake script along with the package. If we want module
> packages at least universal as pkg-config packages, we’ll need some
> consensus between build systems. It can be pessimistic or limiting.
> WG21 used to have a study group that could make it a standard effort
> but due to reasons they can’t. Now arguably the best place to discuss
> such things is the EcoStd organization.
Please see CPS for shipping package information without using CMake
script. CPS export support is currently experimental in CMake, but it is
coming.
https://github.com/cps-org/cps
And yes, please consider joining EcoStd for discussion about such
things.
Thanks,
--Ben
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-28 14:30 ` Jose E. Marchesi
2025-12-28 21:50 ` Nathaniel Shead
@ 2025-12-29 2:50 ` Ben Boeckel
1 sibling, 0 replies; 18+ messages in thread
From: Ben Boeckel @ 2025-12-29 2:50 UTC (permalink / raw)
To: Jose E. Marchesi; +Cc: vspefs, vspefs via Gcc, joergboe
On Sun, Dec 28, 2025 at 15:30:04 +0100, Jose E. Marchesi via Gcc wrote:
>
> >> Not sure how relevant this is for C++, but soon we will be sending a
> >> proposal to Automake for supporting non-optional dependencies and thus
> >> having native support for Algol 68, Fortran and Go modules/packages.
> >
> > Highly relevant. Actually it would also concern Ada, Haskell, etc. because all
> > “compiles into an intermediate binary representation” module systems are alike.
> > It’s just that people expect more from C++ and C++ indeed has a far more
> > complex context.
>
> We basically borrowed the Go model for Algol 68 modules. In this model,
> the "exports" data that conforms the interface of a module gets
> generated in a section .a68_exports, or .go_exports for Go. Of course
> the Go exports and Algol 68 exports are very different, in both encoding
> and actual contents, but the overall model is more or less the same.
>
> In a nutshell, when you compile an Algol 68 compilation unit that
> contains a module named Foo:
>
> $ ga68 -c foo.a68
>
> it results in a foo.o with the compiled object code, plus the exports
> data in .a68_exports. If you then compile another file, bar.a68, that
> uses the module defined in foo (via "access Foo"), you then do:
>
> $ ga68 -c bar.a68
>
> When the compiler sees the "access Foo" in bar.a68, it searches for
> exports info for a module of that name. It does so by looking, in this
> order:
>
> - For a file foo.m68 that contains just exports info.
> - For a file libfoo.so that might have an .a68_exports section.
> - For a file libfoo.a whose objects might have .a68_exports sections.
> - For a file foo.o which might have an .a68_exports section.
>
> Both -I and -L paths are searched this way. The name mapping can be
> altered by passing "module maps" to the compiler via -fmodules-map and
> -fmodules-map-file options.
>
> If the exports are found then they are searched for Foo's exports. If
> these are not found an error is issued.
>
> Exports data is concatenable, so linkers just DTRT when combining
> several object files into archives or DSOs.
>
> Using separated .m68 files should not be necessary in most cases. An
> Algol 68 library distributed in the form of one or more DSOs will be
> shipping all the necessary exports withing itself.
Just from a glance, I think CMake would handle this exactly like it
handles C++ modules: try to bypass all search paths and make it
explicit. Basically, generate `-fmodules-map-file=` contents during the
build to answer all questions based on "scan" results (see below).
Not that CMake supports Algol68 (yet? ;) ).
> > For example, Fortran modules’ intermediate representation also has the
> > incompatibility problem, but far as I know Fortran users just manually manage
> > them. A Fortran user told me he just makes a directory to place the
> > intermediate files for every set of compilation flags he needs. Whereas in C++,
> > people expect package managers/build systems to automatically solve this
> > problem.
> >
>
> I'm just finished with the implementation of the modules system itself
> in ga68 (but for a few remaining nits) and I haven't had a chance yet to
> reflect about (or even become aware of) most of these problems, so I
> don't know how many of these will impact Algol 68, but it would be nice
> to come with a solution/strategy/automake that would also work for the
> other languages as well. It would be difficult to come with something
> that works for Algol 68 but will wont for Go, and most likely Fortran as
> well, but in the case of C++ I am not that sure, because AFAIK C++
> modules are more like an intra-compiler optimization, i.e. are they
> supposed to survive a final link and be distributed?. I obviously have
> to get a clue, and I will start with the links provided in this thread.
Discussed in the sibling reply.
> The main limitation in Automake is that it currently supports automatic
> dependency tracking, but only as an optimization for re-compilations,
> i.e. given a list of sources foo.c, bar.c, baz.c, you should be able to
> compile them in any order into foo.o, bar.o and baz.o (the header system
> of C assures that.) If you have automatic dependency tracking enabled,
> that compilation also extracts dependency info (via -M flags) that can
> then be used in further re-compilations to optimize.
There are, fundamentally, two different kinds of dependencies at play
here:
discovered dependencies
These are the typical dependencies reported via `-MF` and
friends. While they depend on contents, the files are generally
assumed to be extant at the point of compilation (i.e.,
generated headers are handled either as "written with the build
system" or "baked in the dependency graph by hand")
dynamic dependencies
These are modules (Fortran, C++, Algol, etc.) where the build
graph needs to first inspect for the dependency and *order work*
based on those contents so that derived information is available
as needed. This is *possible* in POSIX Make, but requires a
static 2-level recursion mechanism (AFAIK; GNU Make may have
features that allow it with a global graph).
P1689 used to have discovered dependencies listed as well, but it was
removed to make it easier for adoption.
> Our modules are different, of course.
>
> Thinking quickly, the compiler would need to be invoked first with all
> involved source files plus context (in -I or -L paths) to generate
> _complete_ dependency info, taking into account the whole picture, but
> no exports nor object code yet:
>
> $ ga68 -MD foo.a68 bar.a68 ... -I.. -I.. -I..
This could be replaced with a "scan" step which generates information
about the dynamic dependencies of the source. Build systems could then
use that to integrate with their generated build graph (e.g., to place
outputs somewhere and hook them up across directories). If you do go
this route, please consider using P1689 as the reporting format for such
dependencies. Some of the "that's weird for C++" comes from the
consideration for future Fortran support (CMake uses it internally for
its Fortran scanning).
Note that you want the scan step itself to also report `-MF`-style
dependencies for the files it reads so that it can be rerun as
necessary.
Scanning can be per-source or batched; P1689 supports both styles of
reporting. CMake only implements per-source. Batched is something I'd
like to do eventually so that performance behaviors of each can be
quantified. My gut is that per-source is better for
incremental/developer builds while batched is better for CI (at least
where there isn't a caching tool for scanning involved).
> This will also detect and report invalid configurations with circular
> dependencies etc. The resulting dependency information, maybe in the
> form of phony make rules with fill-able actions, would then be consumed
> and used by Automake in order to arrange the rules for building each
> object, then different primaries like executables, libraries, libtool
> libraries, etc.
This corresponds to the "collate" step described in CMake's
documentation.
> Both Autoconf and Automake already have Algol 68 support, but since the
> later doesn't know about Algol 68 modules yet, we are forced to handle
> dependencies by hand, which is a PITA. For example:
>
> AM_A68FLAGS = -fcheck=nil -Whidden-declarations=prelude
>
> bin_PROGRAMS = godcc
> godcc_SOURCES = utils.a68 argp.a68 http.a68 json.a68 ce.a68 \
> list.a68 compile.a68 format.a68 globals.a68 \
> godcc.a68
>
> # Dependencies.
> # In the future will be generated by ga68.
>
> utils.o: globals.o utils.a68
> argp.o: utils.o argp.a68
> http.o: utils.o http.a68
> json.o: utils.o json.a68
> ce.o: globals.o http.o json.o ce.a68
> list.o: globals.o ce.o list.a68
> compile.o: globals.o ce.o compile.a68
> format.o: globals.o ce.o format.a68
> godcc.o: compile.o list.o format.o godcc.a68
Fun. At least it is better than Intel Fortran documenting the "rerun the
build until it succeeds" strategy for its module compilation :) .
> Things get worse with Algol 68 projects using libtool:
>
> AM_A68FLAGS = -std=gnu68 -fcheck=nil \
> -fmodules-map-file=$(srcdir)/Modules.map
>
> lib_LTLIBRARIES = libgramp.la
> libgramp_la_SOURCES = lg-error.a68 \
> lg-symbol.a68 \
> lg-word.a68 \
> lg-alphabet.a68 \
> lg-grammar.a68 \
> lg-mgrammar.a68 \
> lg-vwgrammar.a68 \
> lg-language.a68 \
> lg-automata.a68 \
> lg-graml.a68 \
> lg-gramvm.a68 \
> libgramp.a68
> libgramp_la_A68FLAGS = $(AM_A68FLAGS) -I../common
> libgramp_la_LIBADD = ../common/libgrampcommon.la
>
> Where for each .a68 file both PIC and non-pic files are built, with
> names like:
>
> libgramp_la-lg-word.o (non-PIC version)
> .libs/libgramp_la-lg-word.o (PIC version)
>
> where both objects contain exactly the same .a68_exports sections.
>
> This is why we want to have built-in Automake support, sooner than
> later. Handling these dependencies manually in Makefile.am is just
> crazy.
It looks like a scan/collate strategy would work here. I presented this
paper to ISO in 2019 describing the overall strategy CMake uses for
Fortran:
https://mathstuf.fedorapeople.org/fortran-modules/fortran-modules.html
The information is in the CMake docs linked earlier, but this has
pictures :) .
> > This could be interesting! I’m not familiar with Automake’s evolution process.
> > Where would you be sending the proposal, Automake mailing list?
>
> Automake changes are discussed in the Automake mailing list,
> automake@gnu.org. CCing this list may make sense as well so everyone is
> in the loop.
Hmm. I believe I am on autoconf@, not automake@. Time to go subscribe
there too…
Thanks,
--Ben
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-29 2:31 ` Ben Boeckel
@ 2025-12-29 6:12 ` vspefs
2025-12-29 16:13 ` Ben Boeckel
0 siblings, 1 reply; 18+ messages in thread
From: vspefs @ 2025-12-29 6:12 UTC (permalink / raw)
To: Ben Boeckel; +Cc: Nathaniel Shead, Jose E. Marchesi, gcc, joergboe
> I haven't dug into xmake's implementation, but Bazel (AFAIK) is much
> stricter about flag sets across the build and can kind of wave it away
> by convention.
I think about distribution mainly in 2 ways, source distribution and binary
distribution. The former ships the full project, both source files and build
scripts. Source packages typically need running the corresponding build system
to consume. The latter, on the contrary, distributes as final output artifacts
as possible, and uses minimal meta information, whose logic (if there's any)
is kept minimal as well. Xmake and Bazel both strongly tend towards source
distribution. CMake packages, if export targets and install exported targets
and do other stuff right, is "binary distribution + meta info in CMake
script".Of course, CMake also supports source distribution and other forms of
binary distribution (none of which support C++20 modules now though).
The crucial difference is source distribution makes use of the full power of
the build system. No semantic information within the scope of that certain
build system is lost. So does "binary distribution + build system script".
Binary distribution kinda has to be fixed, universal, and simple (or what's
the point?). So I think the problem is not "making modules work in source
packages", because that's totally a per-build-system business, and all it
requires from the build system is a working dependency scanner. Binary
distribution + universal meta info is where it's tricky.
And honestly, the position of compiler in this picture? We don't know exactly
until we are clear of what that "universal meta info" would look like. But if
it's for Autotools, then I think it might be acceptable for GCC to have a
dedicated `dep-format`. Of course, if Autotools figures things out from only
P1689R5 format output, that's even better.
> Please see CPS for shipping package information without using CMake
> script. CPS export support is currently experimental in CMake, but it is
> coming.
>
> https://github.com/cps-org/cps
>
> And yes, please consider joining EcoStd for discussion about such
> things.
I know CPS as a good attempt to unify binary distribution meta info. It doesn't
natively support C++20 modules far as I know. And I don't think adding an
"interface_units" field could fix this problem. I think there has to be a way
to inform users which compilation flags are compatible with this artifact and
which are not. SG15 used to have core options which could beautifully solve
this problem (and a few others). Seems like has to be another EcoStd stuff now.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-29 6:12 ` vspefs
@ 2025-12-29 16:13 ` Ben Boeckel
2025-12-30 13:47 ` vspefs
0 siblings, 1 reply; 18+ messages in thread
From: Ben Boeckel @ 2025-12-29 16:13 UTC (permalink / raw)
To: vspefs; +Cc: Nathaniel Shead, Jose E. Marchesi, gcc, joergboe
On Mon, Dec 29, 2025 at 06:12:59 +0000, vspefs wrote:
> > I haven't dug into xmake's implementation, but Bazel (AFAIK) is much
> > stricter about flag sets across the build and can kind of wave it away
> > by convention.
>
> I think about distribution mainly in 2 ways, source distribution and binary
> distribution. The former ships the full project, both source files and build
> scripts. Source packages typically need running the corresponding build system
> to consume. The latter, on the contrary, distributes as final output artifacts
> as possible, and uses minimal meta information, whose logic (if there's any)
> is kept minimal as well. Xmake and Bazel both strongly tend towards source
> distribution. CMake packages, if export targets and install exported targets
> and do other stuff right, is "binary distribution + meta info in CMake
> script".Of course, CMake also supports source distribution and other forms of
> binary distribution (none of which support C++20 modules now though).
CMake's C++ module support is kind of a hybrid. Projects ship libraries
and module interface units. The consuming side then rebuilds BMIs as
necessary. I expect this to be the norm until BMI compatibility
detection tooling is available (and even then the support must be there,
but a very opinionated build system *could* just say "fix your stuff to
be consistent" at that point).
> The crucial difference is source distribution makes use of the full power of
> the build system. No semantic information within the scope of that certain
> build system is lost. So does "binary distribution + build system script".
> Binary distribution kinda has to be fixed, universal, and simple (or what's
> the point?). So I think the problem is not "making modules work in source
> packages", because that's totally a per-build-system business, and all it
> requires from the build system is a working dependency scanner. Binary
> distribution + universal meta info is where it's tricky.
Agreed.
> And honestly, the position of compiler in this picture? We don't know exactly
> until we are clear of what that "universal meta info" would look like. But if
> it's for Autotools, then I think it might be acceptable for GCC to have a
> dedicated `dep-format`. Of course, if Autotools figures things out from only
> P1689R5 format output, that's even better.
Note that I'd like to avoid yet another format because I doubt autotools
wants its module support to be "GCC only". I know LLVM-as-frontend is
eating the lunch of proprietary compilers, and P1689R5 is already there,
so that seems like an easy win to me.
I guess the main hurdle is either porting some JSON parser to an
automake-compatible language or growing a dependency on something like
`jq`.
> I know CPS as a good attempt to unify binary distribution meta info. It doesn't
> natively support C++20 modules far as I know. And I don't think adding an
> "interface_units" field could fix this problem. I think there has to be a way
This was added recently:
https://github.com/cps-org/cps/pull/95
> to inform users which compilation flags are compatible with this artifact and
> which are not. SG15 used to have core options which could beautifully solve
> this problem (and a few others). Seems like has to be another EcoStd stuff now.
CPS has a similar concept to CMake's compile option usage requirements,
so projects requiring specific flags can be propagated that way.
Note that CMake because re-builds BMIs at the consuming side, compatible
flags is down to the same ABI concerns we've always had with header and
library artifact mismatches that have always existed.
Thanks,
--Ben
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-29 16:13 ` Ben Boeckel
@ 2025-12-30 13:47 ` vspefs
2025-12-30 16:19 ` Ben Boeckel
2025-12-30 16:54 ` Arsen Arsenović
0 siblings, 2 replies; 18+ messages in thread
From: vspefs @ 2025-12-30 13:47 UTC (permalink / raw)
To: Ben Boeckel; +Cc: Nathaniel Shead, Jose E. Marchesi, gcc, joergboe
> Note that I'd like to avoid yet another format because I doubt autotools
> wants its module support to be "GCC only". I know LLVM-as-frontend is
> eating the lunch of proprietary compilers, and P1689R5 is already there,
> so that seems like an easy win to me.
>
> I guess the main hurdle is either porting some JSON parser to an
> automake-compatible language or growing a dependency on something like
> `jq`.
True. But I mean GCC and Clang consume CMI in very different ways so I guess
even if the dependency scanning and collating logic can be shared, there has
to be some "special treatment". Or GCC augments its current built-in module
mapper to support `-fmodule-file` behavior so that "special treatment" is
really minimum. Though far as I remember CMake passes a `.modmap` file as the
module mapper flag value and it works?
By the way, Automake is written in Perl. Parsing JSON in Perl is like one of
the easiest things on Earth so I think everyone should be happy about it.
> This was added recently:
>
> https://github.com/cps-org/cps/pull/95
> CPS has a similar concept to CMake's compile option usage requirements,
> so projects requiring specific flags can be propagated that way.
>
> Note that CMake because re-builds BMIs at the consuming side, compatible
> flags is down to the same ABI concerns we've always had with header and
> library artifact mismatches that have always existed.
I do have some opinions but I’ll talk about it in the CPS community.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-30 13:47 ` vspefs
@ 2025-12-30 16:19 ` Ben Boeckel
2025-12-30 16:54 ` Arsen Arsenović
1 sibling, 0 replies; 18+ messages in thread
From: Ben Boeckel @ 2025-12-30 16:19 UTC (permalink / raw)
To: vspefs; +Cc: Nathaniel Shead, Jose E. Marchesi, gcc, joergboe
On Tue, Dec 30, 2025 at 13:47:32 +0000, vspefs wrote:
> > Note that I'd like to avoid yet another format because I doubt autotools
> > wants its module support to be "GCC only". I know LLVM-as-frontend is
> > eating the lunch of proprietary compilers, and P1689R5 is already there,
> > so that seems like an easy win to me.
> >
> > I guess the main hurdle is either porting some JSON parser to an
> > automake-compatible language or growing a dependency on something like
> > `jq`.
>
> True. But I mean GCC and Clang consume CMI in very different ways so I guess
> even if the dependency scanning and collating logic can be shared, there has
> to be some "special treatment". Or GCC augments its current built-in module
There already has to be something to transform "I will write module X's
BMI file" to "automake wants BMI files for this compilation to live in
directory D" to bridge between the scanning and the build tool.
> mapper to support `-fmodule-file` behavior so that "special treatment" is
> really minimum. Though far as I remember CMake passes a `.modmap` file as the
> module mapper flag value and it works?
Yes, it works :) . It is "just" a response file for Clang and MSVC, but
GCC takes it with `-fmodule-mapper=`.
> By the way, Automake is written in Perl. Parsing JSON in Perl is like one of
> the easiest things on Earth so I think everyone should be happy about it.
Ah, nice.
> > This was added recently:
> >
> > https://github.com/cps-org/cps/pull/95
>
> > CPS has a similar concept to CMake's compile option usage requirements,
> > so projects requiring specific flags can be propagated that way.
> >
> > Note that CMake because re-builds BMIs at the consuming side, compatible
> > flags is down to the same ABI concerns we've always had with header and
> > library artifact mismatches that have always existed.
>
> I do have some opinions but I’ll talk about it in the CPS community.
Looking forward to it!
Thanks,
--Ben
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Generation of Make Dependencies for C++ Modules
2025-12-30 13:47 ` vspefs
2025-12-30 16:19 ` Ben Boeckel
@ 2025-12-30 16:54 ` Arsen Arsenović
1 sibling, 0 replies; 18+ messages in thread
From: Arsen Arsenović @ 2025-12-30 16:54 UTC (permalink / raw)
To: vspefs; +Cc: Ben Boeckel, Gcc, Nathaniel Shead, Jose E. Marchesi, joergboe
[-- Attachment #1: Type: text/plain, Size: 431 bytes --]
vspefs <vspefs@protonmail.com> writes:
> By the way, Automake is written in Perl. Parsing JSON in Perl is like
> one of the easiest things on Earth so I think everyone should be happy
> about it.
Yes, but the build systems it generates aren't. So that's not relevant.
Automake does not require Automake to be installed when Automake-based
build systems are used. That's a key advantage of it.
--
Arsen Arsenović
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 418 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2025-12-30 16:54 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-22 18:11 Generation of Make Dependencies for C++ Modules joergboe
2025-12-23 16:23 ` Ben Boeckel
2025-12-25 18:28 ` joergboe
2025-12-26 3:16 ` Ben Boeckel
2025-12-27 5:50 ` vspefs
2025-12-27 11:24 ` Jose E. Marchesi
2025-12-27 12:01 ` Arsen Arsenović
2025-12-28 4:31 ` vspefs
2025-12-28 14:30 ` Jose E. Marchesi
2025-12-28 21:50 ` Nathaniel Shead
2025-12-29 0:03 ` vspefs
2025-12-29 2:31 ` Ben Boeckel
2025-12-29 6:12 ` vspefs
2025-12-29 16:13 ` Ben Boeckel
2025-12-30 13:47 ` vspefs
2025-12-30 16:19 ` Ben Boeckel
2025-12-30 16:54 ` Arsen Arsenović
2025-12-29 2:50 ` Ben Boeckel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).