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, > [email protected]. CCing this list may make sense as well so everyone is > in the loop.
