This is an archive of the discontinued LLVM Phabricator instance.

[clang][deps] Canonicalize module map path
ClosedPublic

Authored by benlangmuir on Sep 29 2022, 4:35 PM.

Details

Summary

When dep-scanning, canonicalize the module map path as much as we can. This avoids unnecessarily needing to build multiple versions of a module due to symlinks or case-insensitive file paths.

Despite the name tryGetRealPathName, the previous implementation did not actually return the realpath most of the time, and indeed it would be incorrect to do so since the realpath could be outside the module directory, which would have broken finding headers relative to the module.

Instead, use a canonicalization that is specific to the needs of modulemap files (canonicalize the directory separately from the filename).

Diff Detail

Event Timeline

benlangmuir created this revision.Sep 29 2022, 4:35 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 29 2022, 4:35 PM
benlangmuir requested review of this revision.Sep 29 2022, 4:35 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 29 2022, 4:35 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript

IIUC this not only canonicalizes path to the main input file when compiling a PCM, but also -fmodule-map-file= arguments for dependencies, correct? Since that behavior is desirable, I think it would make sense to check for that in the test, WDYT?

clang/lib/Lex/ModuleMap.cpp
1307

Is that because the parser is looking for headers in ../Headers and ../PrivateHeaders? If so, would it make sense to make the parser smarter and canonicalize even framework paths here?

IIUC this not only canonicalizes path to the main input file when compiling a PCM, but also -fmodule-map-file= arguments for dependencies, correct? Since that behavior is desirable, I think it would make sense to check for that in the test, WDYT?

Yep, makes sense to me!

clang/lib/Lex/ModuleMap.cpp
1307

The failure I am aware of is that loadModuleMapFile will not detect the correct module Directory. I'm not sure if there are more failures after that. I didn't want to complicate this logic, because it seems like there are several possibilities:

  • Modules/module.modulemap
  • Versions/A/Modules/module.modulemap
  • Versions/Current/Modules/module.modulemap

Also, if we get one of the versioned paths, but Modules/module.modulemap does not point to that specific file then it would be incorrect to use it. I'm inclined to leave this alone, at least for the current change.

Test -fmodule-map-file paths as well.

jansvoboda11 accepted this revision.Sep 29 2022, 5:11 PM

Thanks, this LGTM with the test extension.

clang/test/ClangScanDeps/modules-symlink-dir.c
34

Nit: I assume {{.}} is here to prevent issues with path separators on Windows. I'd prefer putting / here for readability and injecting sed 's:\\\\\?:/:g' into the RUN line like we do in rest of scanner tests.

This revision is now accepted and ready to land.Sep 29 2022, 5:11 PM

Fix windows path separators using sed instead of regex "."

(You could also use the PREFIX variable you're passing to FileCheck to remove some .* regexes.)

Simplify modmap checks in test to use PREFIX

Canonicalize path separator(s) in between the (already canonicalized directory) and the filename. This could cause issues with redundant path separators (foo//bar) or non-native separators (foo/bar vs foo\bar on Windows). Hopefully this was the only issue on Windows.

Rebased after landing https://reviews.llvm.org/D135220, which should hopefully fix the Windows test failure (it fixed the path for me locally on Windows, but I had some python-related issues that prevented me from running the tests properly).

This revision was automatically updated to reflect the committed changes.