public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
From: Ben Boeckel <ben.boeckel@kitware.com>
To: Jason Merrill <jason@redhat.com>
Cc: gcc-patches@gcc.gnu.org, nathan@acm.org, fortran@gcc.gnu.org,
	gcc@gcc.gnu.org, brad.king@kitware.com
Subject: Re: [PATCH v5 3/5] p1689r5: initial support
Date: Sun, 25 Jun 2023 13:08:19 -0400	[thread overview]
Message-ID: <20230625170819.GE270821@farprobe> (raw)
In-Reply-To: <e9dc7075-2eae-5dcb-c134-0a7d906d4181@redhat.com>

On Fri, Jun 23, 2023 at 14:31:17 -0400, Jason Merrill wrote:
> On 6/20/23 15:46, Ben Boeckel wrote:
> > On Tue, Feb 14, 2023 at 16:50:27 -0500, Jason Merrill wrote:
> >> On 1/25/23 13:06, Ben Boeckel wrote:
> 
> >>> Header units (including the standard library headers) are 100%
> >>> unsupported right now because the `-E` mechanism wants to import their
> >>> BMIs. A new mode (i.e., something more workable than existing `-E`
> >>> behavior) that mocks up header units as if they were imported purely
> >>> from their path and content would be required.
> >> >> I notice that the cpp dependency generation tries (in open_file_failed)
> >> to continue after encountering a missing file, is that not sufficient 
> >> for header units?  Or adjustable to be sufficient?
> > 
> > No. Header units can introduce macros which can be used to modify the
> > set of modules that are imported. Included headers are "discovered"
> > dependencies and don't modify the build graph (just add more files that
> > trigger a rebuild) and can be collected during compilation. Module
> > dependencies are needed to get the build correct in the first place in
> > order to:
> > 
> > - order module compilations in the build graph so that imported modules
> >   are ready before anything using them; and
> > - computing the set of flags needed for telling the compiler where
> >   imported modules' CMI files should be located.
> 
> So if the header unit CMI isn't available during dependency generation, 
> would it be better to just #include the header?

It's not so simple: the preprocessor state needs to isolate out
`LOCAL_ONLY` from this case:

```
#define LOCAL_ONLY 1
import <some/header.h>; // The preprocessing of this should *not* see
                        // `LOCAL_ONLY`.
```

> > Hmm. But `stdout` is probably fine to use for both though. Basically:
> > 
> >      if (fdeps_stream == out_stream && fdeps_stream != stdout)
> >        make_diagnostic_noise ();
> 
> (fdeps_stream == deps_stream, but sure, that's reasonable.

Done.

> >> So, I take it this is the common use case you have in mind, generating
> >> Make dependencies for the p1689 file?  When are you thinking the Make
> >> dependencies for the .o are generated?  At build time?
> > 
> > Yes. If an included file changes, the scanning should be performed
> > again. The compilation will have its own `-MF` as well (which should
> > point to the same files plus the CMI files it ends up reading).
> > 
> >> I'm a bit surprised you're using .json rather than an extension that
> >> indicates what the information is.
> > 
> > I can change that; the filename doesn't *really* matter (e.g., CMake
> > uses `.ddi` for "dynamic dependency information").
> 
> That works.

Done.

> >>> `-M` is about discovered dependencies: those that you find out while
> >>> doing work. `-fdep-*` is about ordering dependencies: extracting
> >>> information from file content in order to even order future work around.
> >>
> >> I'm not sure I see the distinction; Makefiles also express ordering
> >> dependencies.  In both cases, you want to find out from the files what
> >> order you will want to process them in when building the project.
> > 
> > Makefiles can express ordering dependencies, but not the `-M` snippets;
> > these are for files that, if changed, should trigger a rebuild. This is > fundamentally different than module dependencies which instead indicate
> > which *compiles* (or CMI generation if using a 2-phase setup) need to
> > complete before compilation (or CMI generation) of the scanned TU can be
> > performed. Generally generated headers will be ordered manually in the
> > build system description. However, maintaining that same level for
> > in-source dependency information on a per-source level is a *far* higher
> > burden.
> 
> The main difference I see is that the CMI might not exist yet.  As you 
> say, we don't want to require people to write all the dependencies by 
> hand, but that just means we need to be able to generate the 
> dependencies automatically.  In the Make-only model I'm thinking of, one 
> would collect dependencies on an initial failing build, and then start 
> over from the beginning again with the dependencies we discovered.  It's 
> the same two-phase scan and build, but one that uses the same compile 
> commands for both phases.

It's a potentially unbounded set of phases:

- 2 phases per tool that is built that generates other module-using
  code for other tools:

    - scan files for toolA
    - build files for toolA
    - scan files written by toolA (for toolB)
    - build files written by toolA (for toolB)
    - …

- if a referenced module does not exist, knowing when one is "done" is
  difficult (an import cycle would appear like this because while module
  X does exist, it depends on Y which itself claims a dependency on X).

*Something* needs to interpret the information being provided in the
`-fdeps-file=` and communicate back to the build tool what is going on.
This requires:

- some coordination of where each TU will store these files (e.g., CMake
  has a per-target directory for storing such things and the collator
  knows which TUs belong to which targets to tell everything about
  them); and
- some kind of coordination for the target-level dependency graph (i.e.,
  if libA depends-on only libB, a TU from libA using a module "from"
  libB is ok, but using one "from" libC is bad and the same if libB uses
  a module "from" libA).

Therefore any automation will need to have an idea of the overall build
graph and an understanding of "yes, module X exists, but this TU is not
allowed to use it because the graph doesn't allow that edge". I don't
think a "drop in" tool to any arbitrary `Makefile`-using project can
exist as there's just not enough structure in a `Makefile` to really
require such information. `automake` can provide one, however, because
(AFAIK) it *does* have an idea about these kinds of things (though it
may need to be more structured than it is today).

The `libcody` GNU Make support patch doesn't have this structured
information and (AFAIK) will happily let any TU import any module from
any other TU even if the linker is going to be unhappy later. Again, I
think we can give users (and they deserve) better error messages than
"<mangled module initializer symbol> not found".

> Anyway, this isn't an objection to this patch, just another model I also 
> want to support.

The old Intel Fortran "how to build with modules" docs used to have a
"run `make` until it works" instruction step. I think we can do better
these days (yes, it means that pure-`make` is far harder than it used to
be).

> >>> <snip JSON output diff>
> >>
> >> Is there a reason not to use the gcc/json.h interface for JSON output?
> > 
> > This is `libcpp`; is that not a dependency cycle?
> 
> Ah, indeed.  We could move it to libiberty, but it would need 
> significant adjustments to remove its dependencies on other stuff in 
> gcc/.  So maybe just add a TODO comment about that, along with adding 
> comments before the functions.

Done.

--Ben

  reply	other threads:[~2023-06-25 17:08 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-25 21:06 [PATCH v5 0/5] P1689R5 support Ben Boeckel
2023-01-25 21:06 ` [PATCH v5 1/5] libcpp: reject codepoints above 0x10FFFF Ben Boeckel
2023-02-13 15:53   ` Jason Merrill
2023-05-12 14:26     ` Ben Boeckel
2023-01-25 21:06 ` [PATCH v5 2/5] libcpp: add a function to determine UTF-8 validity of a C string Ben Boeckel
2023-10-23 15:16   ` David Malcolm
2023-10-23 15:24     ` Jason Merrill
2023-10-23 15:28       ` David Malcolm
2023-01-25 21:06 ` [PATCH v5 3/5] p1689r5: initial support Ben Boeckel
2023-02-14 21:50   ` Jason Merrill
2023-05-12 14:24     ` Ben Boeckel
2023-06-19 21:33       ` Jason Merrill
2023-06-20 16:51         ` Ben Boeckel
2023-06-20 19:46     ` Ben Boeckel
2023-06-23 18:31       ` Jason Merrill
2023-06-25 17:08         ` Ben Boeckel [this message]
2023-01-25 21:06 ` [PATCH v5 4/5] c++modules: report imported CMI files as dependencies Ben Boeckel
2023-02-13 18:33   ` Jason Merrill
2023-05-12 14:26     ` Ben Boeckel
2023-06-22 21:21   ` Jason Merrill
2023-06-23  2:45     ` Ben Boeckel
2023-06-23 12:12       ` Nathan Sidwell
2023-06-25 16:36         ` Ben Boeckel
2023-07-18 20:52           ` Jason Merrill
2023-07-18 21:12             ` Nathan Sidwell
2023-07-19  0:01             ` Ben Boeckel
2023-07-19 21:11               ` Nathan Sidwell
2023-07-20  0:47                 ` Ben Boeckel
2023-07-20 21:00                   ` Nathan Sidwell
2023-07-21 14:57                     ` Ben Boeckel
2023-07-21 20:23                       ` Nathan Sidwell
2023-07-24  0:26                         ` Ben Boeckel
2023-07-28  1:13                           ` Jason Merrill
2023-07-29 14:25                             ` Ben Boeckel
2023-01-25 21:06 ` [PATCH v5 5/5] c++modules: report module mapper files as a dependency Ben Boeckel
2023-06-23 14:44   ` Jason Merrill
2023-06-25 16:42     ` Ben Boeckel
2023-02-02 14:04 ` [PATCH v5 0/5] P1689R5 support Ben Boeckel
2023-02-02 20:24 ` Harald Anlauf
2023-02-03  4:00   ` Ben Boeckel
2023-02-03  4:07 ` Andrew Pinski
2023-02-03  8:58   ` Jonathan Wakely
2023-02-03  9:10     ` Jonathan Wakely
2023-02-03 14:52       ` Ben Boeckel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230625170819.GE270821@farprobe \
    --to=ben.boeckel@kitware.com \
    --cc=brad.king@kitware.com \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=gcc@gcc.gnu.org \
    --cc=jason@redhat.com \
    --cc=nathan@acm.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).