libcpp: add .c++-header-unit target

The dependency output for header unit modules is based on the absolute
pathname of the header file, but that's not something that a makefile can
portably refer to.  This patch adds a .c++-header-unit target based on the
header name relative to an element of the include path.

libcpp/ChangeLog:

	* internal.h (_cpp_get_file_dir): Declare.
	* files.cc (_cpp_get_file_dir): New fn.
	* mkdeps.cc (make_write): Use it.

gcc/testsuite/ChangeLog:

	* g++.dg/modules/dep-4.H: New test.
This commit is contained in:
Jason Merrill 2024-06-04 21:15:02 -04:00
parent 0dc389f21b
commit 7b8b96a327
4 changed files with 31 additions and 0 deletions

View File

@ -0,0 +1,7 @@
// { dg-do preprocess }
// { dg-additional-options "-fmodules -M" }
inline void f() { }
// { dg-final { scan-file dep-4.i {dep-4\.H\.c\+\+-header-unit:} } }
// { dg-final { scan-file-not dep-4.i {inline} } }

View File

@ -2336,6 +2336,13 @@ _cpp_get_file_stat (_cpp_file *file)
return &file->st;
}
/* Return the directory where FILE was found. */
struct cpp_dir *
_cpp_get_file_dir (_cpp_file *file)
{
return file->dir;
}
/* Set the include chain for "" to QUOTE, for <> to BRACKET. If
QUOTE_IGNORES_SOURCE_DIR, then "" includes do not look in the
directory of the including file.

View File

@ -786,6 +786,7 @@ extern bool _cpp_save_file_entries (cpp_reader *pfile, FILE *f);
extern bool _cpp_read_file_entries (cpp_reader *, FILE *);
extern const char *_cpp_get_file_name (_cpp_file *);
extern struct stat *_cpp_get_file_stat (_cpp_file *);
extern struct cpp_dir *_cpp_get_file_dir (_cpp_file *);
extern bool _cpp_has_header (cpp_reader *, const char *, int,
enum include_type);

View File

@ -463,6 +463,19 @@ make_write (const cpp_reader *pfile, FILE *fp, unsigned int colmax)
/* module-name : cmi-name */
column = make_write_name (d->module_name, fp, 0, colmax,
true, ".c++-module");
const char *module_basename = nullptr;
if (d->is_header_unit)
{
/* Also emit a target for the include name, so for #include
<iostream> you'd make iostream.c++-header-unit, regardless of
what actual directory iostream lives in. We reconstruct the
include name by skipping the directory where we found it. */
auto *dir = _cpp_get_file_dir (pfile->main_file);
gcc_assert (!strncmp (d->module_name, dir->name, dir->len));
module_basename = (d->module_name + dir->len + 1);
column = make_write_name (module_basename, fp, column, colmax,
true, ".c++-header-unit");
}
fputs (":", fp);
column++;
column = make_write_name (d->cmi_name, fp, column, colmax);
@ -471,6 +484,9 @@ make_write (const cpp_reader *pfile, FILE *fp, unsigned int colmax)
column = fprintf (fp, ".PHONY:");
column = make_write_name (d->module_name, fp, column, colmax,
true, ".c++-module");
if (module_basename)
column = make_write_name (module_basename, fp, column, colmax,
true, ".c++-header-unit");
fputs ("\n", fp);
}