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.

Reply via email to