C++ Logo

sg15

Advanced search

Re: [Tooling] [isocpp-modules] Path to modules with old bad build systems

From: Ben Boeckel <ben.boeckel_at_[hidden]>
Date: Fri, 8 Mar 2019 09:53:42 -0500
On Fri, Mar 08, 2019 at 01:10:09 -0500, Tom Honermann wrote:
> Thank you for this write up, Ben.? This all strongly matches what I've
> been thinking.
>
> The listed constraints suggest some requirements:
> 1. Means to determine if a header file is a modular header unit.

Is this for the purposes of transforming `#include` into `import`? If
so, I'd rather that either be implicit compiler magic or the compiler
reports on it as if it was `import`. If a header unit shows up, it shows
up just like any other provides/requires entry.

> 2. Means to map modules IDs to module interface unit source file names.

That isn't part of this spec since we have the source and want the
module name(s). It can be inferred from the output, but that might also
be incomplete.

> 3. That pre-built packages provide:
> 3.1. The above information for their modular headers and module
> interface units (packaged software can't require consumers to perform a
> scanning step).

How this gets specified in pkg-config or CMake's usage requirements is
separate from this. For strawman CMake syntax:

    https://gitlab.kitware.com/ben.boeckel/cxx-modules-sandbox/blob/master/header-units/external/CMakeLists.txt

Though I suspect a scan step will still be required since you need to
discover compile dependent modules for things like `export import`.
Header units can probably get away with it…but they can also do
`import`, so probably not.

How that information gets encoded in a `.pc` file can be bikeshedded
once we figure out what information needs to be provided.

> 3.2. The source files for module interface units (packaged software
> can't require consumers to consume BMIs).

How to extract an MIU from a source file is also something I want. But
that's a much harder problem than getting a build. Also, out-of-scope
here.

> Clang modules has already solved these problems in a way that I believe
> 1) has proven deployable, 2) that programmers have shown willingness to
> use.? The following is heavily based on how Clang modules works today.

Clang modules as deployed widely is all implicit (AFAIK). This format is
for explicit modules (though can probably be used to some extent by
implicit modules).

> Elaborating on #1 above.? P1103R2 states in 2.3.4p2:
>
> "When a *#include* appears within non-modular code, if the named
> header file is known to correspond to a legacy header unit, the
> implementation treats the *#include* as an import of the
> corresponding legacy header unit. The mechanism for discovering this
> correspondence is left implementation-defined; there are multiple
> viable strategies here (such as explicitly building legacy header
> modules and providing them as input to downstream compilations, or
> introducing accompanying files describing the legacy header
> structure) and we wish to encourage exploration of this space. An
> implementation is also permitted to not provide any mapping
> mechanism, and process each legacy header unit independently."
>
> For the purposes of the TR, we'll need to define a mechanism for
> nominating a header file as a header unit.? Clang modules accomplishes

For the TR, probably. For this format, no. I'm leaning towards CMake
just saying "if you want to import a header, say `import`". But passing
extra flags to give a list of headers which are importable and having
the scan step report as if it did `import` in the dependency
information.

> this via a module.modulemap file that must be co-located with the header
> file.? When processing a #include directive, Clang searches include
> paths normally for a matching header file and, if a module.modulemap
> file is present, scans it to see if the header file is associated with a
> defined module.? If it is, then the header is treated as a header unit,
> otherwise (or if module support is disabled), it is treated as a
> traditional header.? I like this approach for several reasons:
> 1. It doesn't require any new search paths.? Existing include paths suffice.
> 2. Having the module map file co-located with the header files it
> governs avoids complicated path matching needs.
>
> If such a module map file is also used to map module IDs to module
> interface unit source files, then we can also avoid requiring separate
> search paths for module interface units.? An obvious consequence of this
> is that module interface unit source files would need to be present in
> an include path.

The module map file consumed by the compiler for the name -> bmi mapping
format is not that much work for *me*. If compilers agree on a format,
I'm 100% OK with that. I encourage you to start a new thread discussing
module map details because I, at least, view it as out-of-scope for this
format specification.

--Ben

Received on 2019-03-08 15:53:45