Skip to content

Commit 0c89427

Browse files
authored
Reland "[clang][modules] Print library module manifest path." (#82160)
This implements a way for the compiler to find the modules.json associated with the C++23 Standard library modules. This is based on a discussion in SG15. At the moment no Standard library installs this manifest. #75741 adds this feature in libc++. This reverts commit 82f424f. Disables the tests on non-X86 platforms as suggested.
1 parent 5f05839 commit 0c89427

File tree

4 files changed

+97
-0
lines changed

4 files changed

+97
-0
lines changed

clang/include/clang/Driver/Driver.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,16 @@ class Driver {
620620
// FIXME: This should be in CompilationInfo.
621621
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const;
622622

623+
/// Lookup the path to the Standard library module manifest.
624+
///
625+
/// \param C - The compilation.
626+
/// \param TC - The tool chain for additional information on
627+
/// directories to search.
628+
//
629+
// FIXME: This should be in CompilationInfo.
630+
std::string GetStdModuleManifestPath(const Compilation &C,
631+
const ToolChain &TC) const;
632+
623633
/// HandleAutocompletions - Handle --autocomplete by searching and printing
624634
/// possible flags, descriptions, and its arguments.
625635
void HandleAutocompletions(StringRef PassedFlags) const;

clang/include/clang/Driver/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5364,6 +5364,9 @@ def print_resource_dir : Flag<["-", "--"], "print-resource-dir">,
53645364
def print_search_dirs : Flag<["-", "--"], "print-search-dirs">,
53655365
HelpText<"Print the paths used for finding libraries and programs">,
53665366
Visibility<[ClangOption, CLOption]>;
5367+
def print_std_module_manifest_path : Flag<["-", "--"], "print-library-module-manifest-path">,
5368+
HelpText<"Print the path for the C++ Standard library module manifest">,
5369+
Visibility<[ClangOption, CLOption]>;
53675370
def print_targets : Flag<["-", "--"], "print-targets">,
53685371
HelpText<"Print the registered targets">,
53695372
Visibility<[ClangOption, CLOption]>;

clang/lib/Driver/Driver.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2197,6 +2197,12 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
21972197
return false;
21982198
}
21992199

2200+
if (C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2201+
llvm::outs() << GetStdModuleManifestPath(C, C.getDefaultToolChain())
2202+
<< '\n';
2203+
return false;
2204+
}
2205+
22002206
if (C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
22012207
if (std::optional<std::string> RuntimePath = TC.getRuntimePath())
22022208
llvm::outs() << *RuntimePath << '\n';
@@ -6169,6 +6175,44 @@ std::string Driver::GetProgramPath(StringRef Name, const ToolChain &TC) const {
61696175
return std::string(Name);
61706176
}
61716177

6178+
std::string Driver::GetStdModuleManifestPath(const Compilation &C,
6179+
const ToolChain &TC) const {
6180+
std::string error = "<NOT PRESENT>";
6181+
6182+
switch (TC.GetCXXStdlibType(C.getArgs())) {
6183+
case ToolChain::CST_Libcxx: {
6184+
std::string lib = GetFilePath("libc++.so", TC);
6185+
6186+
// Note when there are multiple flavours of libc++ the module json needs to
6187+
// look at the command-line arguments for the proper json.
6188+
// These flavours do not exist at the moment, but there are plans to
6189+
// provide a variant that is built with sanitizer instrumentation enabled.
6190+
6191+
// For example
6192+
// StringRef modules = [&] {
6193+
// const SanitizerArgs &Sanitize = TC.getSanitizerArgs(C.getArgs());
6194+
// if (Sanitize.needsAsanRt())
6195+
// return "modules-asan.json";
6196+
// return "modules.json";
6197+
// }();
6198+
6199+
SmallString<128> path(lib.begin(), lib.end());
6200+
llvm::sys::path::remove_filename(path);
6201+
llvm::sys::path::append(path, "modules.json");
6202+
if (TC.getVFS().exists(path))
6203+
return static_cast<std::string>(path);
6204+
6205+
return error;
6206+
}
6207+
6208+
case ToolChain::CST_Libstdcxx:
6209+
// libstdc++ does not provide Standard library modules yet.
6210+
return error;
6211+
}
6212+
6213+
return error;
6214+
}
6215+
61726216
std::string Driver::GetTemporaryPath(StringRef Prefix, StringRef Suffix) const {
61736217
SmallString<128> Path;
61746218
std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Test that -print-library-module-manifest-path finds the correct file.
2+
3+
// FIXME: Enable on all platforms.
4+
5+
// REQUIRES: x86-registered-target
6+
7+
// RUN: rm -rf %t && split-file %s %t && cd %t
8+
// RUN: mkdir -p %t/Inputs/usr/lib/x86_64-linux-gnu
9+
// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.so
10+
11+
// RUN: %clang -print-library-module-manifest-path \
12+
// RUN: -stdlib=libc++ \
13+
// RUN: --sysroot=%t/Inputs \
14+
// RUN: --target=x86_64-linux-gnu 2>&1 \
15+
// RUN: | FileCheck libcxx-no-module-json.cpp
16+
17+
// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/modules.json
18+
// RUN: %clang -print-library-module-manifest-path \
19+
// RUN: -stdlib=libc++ \
20+
// RUN: --sysroot=%t/Inputs \
21+
// RUN: --target=x86_64-linux-gnu 2>&1 \
22+
// RUN: | FileCheck libcxx.cpp
23+
24+
// RUN: %clang -print-library-module-manifest-path \
25+
// RUN: -stdlib=libstdc++ \
26+
// RUN: --sysroot=%t/Inputs \
27+
// RUN: --target=x86_64-linux-gnu 2>&1 \
28+
// RUN: | FileCheck libstdcxx.cpp
29+
30+
//--- libcxx-no-module-json.cpp
31+
32+
// CHECK: <NOT PRESENT>
33+
34+
//--- libcxx.cpp
35+
36+
// CHECK: {{.*}}/Inputs/usr/lib/x86_64-linux-gnu{{/|\\}}modules.json
37+
38+
//--- libstdcxx.cpp
39+
40+
// CHECK: <NOT PRESENT>

0 commit comments

Comments
 (0)