Skip to content

Confusing "module file out of date" errors with C++20 modules #70569

Closed as not planned
@rnikander

Description

@rnikander

I will attach a zipped up project, with some source code and a Makefile. At the top of the Makefile, there are some variables that point to my build of clang. Those need to be changed, but then I hope you can reproduce this.

files.tgz

The commands in the Makefile are my attempt to follow the docs here.

Steps to demonstrate the issue

  1. Change this top part of the Makefile to fit your build of clang. I'm building on a Mac so I need that macos_sdk setting.
CXX = /Users/rob/Dev/llvm-project/build_phase1/bin/clang++
macos_sdk = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk
flags = -isysroot $(macos_sdk) -std=c++2b
  1. Run make, and you should see this output.
% make
Precompiling interface_part1.ccm -> interface_part1.pcm
Precompiling interface_part2.ccm -> interface_part2.pcm
Precompiling foo.ccm -> foo.pcm
Compiling main.cc -> main.o
Compiling foo.pcm -> foo.o
Compiling interface_part1.pcm -> interface_part1.o
Compiling interface_part2.pcm -> interface_part2.o
Linking program
  1. You can run the program to confirm that it compiled.
% ./program 
Starting main()
hello from foo:interface_part1
hello from foo:interface_part2
  1. Now, change the variable name in the other() function in interface_part1.ccm. For example change int a to int aa.
void other() {
    int aa = 1;
}
  1. Run make again. I see this:
% make     
Precompiling interface_part1.ccm -> interface_part1.pcm
Precompiling foo.ccm -> foo.pcm
foo.ccm:5:8: fatal error: module file 'interface_part1.pcm' is out of date and needs to be rebuilt: module file out of date
    5 | export import :interface_part2;
      |        ^
foo.ccm:5:8: note: imported by module 'foo:interface_part2' in 'interface_part2.pcm'

This seems like a problem to me, for a couple reasons:

  1. The error is misleading. It says interface_part1.pcm is out of date and "needs to be rebuilt", but I just rebuilt it.
  2. If interface_part2.pcm needs to be rebuilt, because it depends on part1, that seems like these modules are worse than headers at hiding implementation details. I changed a private non-exported function other(), and I changed an implementation detail - the name of the local variable. The exposed interface of interface_part1 should not change in this case. And I don't think it should trigger the need to recompile things that depend on it.

It's interesting that if I only change the value of int a in other(), say int a = 1 to int a = 2, then then make rebuilds things as expected without a problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:modulesC++20 modules and Clang Header ModulesduplicateResolved as duplicate

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions