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

Reply via email to