Skip to content

Shouldn't -fmodules-embed-all-files be the default? #72383

@boris-kolpackov

Description

@boris-kolpackov

Consider these two translation units:

// hello.mxx

module;

#include <string>
#include <string_view>

export module hello;

export namespace hello
{
  std::string
  say_hello (const std::string_view& name)
  {
    return "Hello, " + std::string (name) + '!';
  }
}
// main.cxx

#include <string_view>

import hello;

void f (const std::string_view&) {}

int
main ()
{
  hello::say_hello ("World");
}

If I compile hello.mxx with Clang 16, then remove hello.mxx, and attempt to compile main.cxx, I get an error:

clang++-16 -std=c++2b -fmodule-output=hello.pcm -o hello.pcm.o -c -x c++-module hello.mxx
mv hello.mxx hello.mxx.bak
clang++-16 -std=c++2b -fmodule-file=hello=hello.pcm -o main.o -c -x c++ main.cxx
main.cxx:5:1: fatal error: malformed or corrupted AST file: 'could not find file '/tmp/hello-simple/hello.mxx' referenced by AST file 'hello.pcm''

This can be fixed by adding -Xclang -fmodules-embed-all-files when compiling hello.mxx.

However, -fmodules-embed-all-files appears to no longer be necessary for this example if using Clang 17 or later:

clang++-17 -std=c++2b -fmodule-output=hello.pcm -o hello.pcm.o -c -x c++-module hello.mxx
mv hello.mxx hello.mxx.bak
clang++-17 -std=c++2b -fmodule-file=hello=hello.pcm -o hello.o -c -x c++ main.cxx
# no error

But a minor change in main.cxx can bring its requirement back if compiling via -frewrite-includes:

// main.cxx

#include <string_view>

import hello;

void f (const std::string_view&) {}

int
main ()
{
  f (hello::say_hello ("World"));  // <-- NOW CALLING f().
}
clang++-17 -std=c++2b -fmodule-output=hello.pcm -o hello.pcm.o -c -x c++-module hello.mxx
mv hello.mxx hello.mxx.bak
clang++-17 -std=c++2b -fmodule-file=hello=hello.pcm -o hello.o -c -x c++ main.cxx
# no error

But:

clang++-17 -std=c++2b -x c++-module -E -frewrite-includes -o hello.ii hello.mxx
clang++-17 -std=c++2b -fmodule-output=hello.pcm -o hello.pcm.o -c -x c++-module hello.ii
rm hello.ii
clang++-17 -std=c++2b -fmodule-file=hello=hello.pcm -o hello.o -c -x c++ main.cxx
fatal error: cannot open file '/tmp/hello-simple1/hello.ii': No such file or directory

And if I add -Xclang -fmodules-embed-all-files to the second command, then everything again compiles fine. I get exactly the same behavior with Clang 18.

I have two questions about this:

  1. Is -fmodules-embed-all-files the default starting from Clang 17? If the answer is yes, then there seems to be a bug in the -fdirectives-only interaction.

  2. If -fmodules-embed-all-files is not the default, then should it not be made so? A BMI that still has references to source files is quite brittle since it can be moved around. AFAIK, neither GCC nor MSVC have this restriction for their BMIs.

@iains @ChuanqiXu9 @dwblaikie

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:modulesC++20 modules and Clang Header Modules

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions