Skip to content

Commit 17ad7ca

Browse files
ChuanqiXu9mordante
authored andcommitted
Reland Print library module manifest path again (llvm#84881)
Following of llvm#82160 The reason why the above PR fails is that the `--sysroot` has lower priority than the libc++ built from the same source. On the one hand, it matches the codes behavior. We will add the built libc++ project paths in the ToolChain class. But we will only add the path related to sysroot in Linux class, which is derived from the ToolChain classes. So the paths of just built libc++ is in the front of the paths relative to sysroot. On the other hand, the behavior should be good from the higher level. Since the just built libc++ has the same version number with the just built clang, so it makes sense that these 2 compilers just matches. So for patch it self, I hacked it by using resource dir in the test since the resource dir has the higher priority, which is not strongly correct since we won't do that in practice. @kaz7 would you like to test on your environment to avoid this get reverted again? On the libc++ side, it shows that it lacks a `modules.json` file for the just built libc++ directory. If we don't have that, it will be problematic to use std modules from the just built clang and libc++ pair. Then it is not good. And I feel it may be problematic for future compiler/standard library developers. So I feel this is somewhat a libc++ issue that need to be fixed. Also if we don't like the hacked test in the current patch, we must wait for libc++ to fix this to proceed. But I feel this is somewhat odd since the test of clang shouldn't dependent on libc++. CC: @mordante --------- Co-authored-by: Mark de Wever <[email protected]> (cherry picked from commit 0e1e1fc)
1 parent 53ea0de commit 17ad7ca

File tree

4 files changed

+93
-0
lines changed

4 files changed

+93
-0
lines changed

clang/include/clang/Driver/Driver.h

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

605+
/// Lookup the path to the Standard library module manifest.
606+
///
607+
/// \param C - The compilation.
608+
/// \param TC - The tool chain for additional information on
609+
/// directories to search.
610+
//
611+
// FIXME: This should be in CompilationInfo.
612+
std::string GetStdModuleManifestPath(const Compilation &C,
613+
const ToolChain &TC) const;
614+
605615
/// HandleAutocompletions - Handle --autocomplete by searching and printing
606616
/// possible flags, descriptions, and its arguments.
607617
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
@@ -5320,6 +5320,9 @@ def print_resource_dir : Flag<["-", "--"], "print-resource-dir">,
53205320
def print_search_dirs : Flag<["-", "--"], "print-search-dirs">,
53215321
HelpText<"Print the paths used for finding libraries and programs">,
53225322
Visibility<[ClangOption, CLOption]>;
5323+
def print_std_module_manifest_path : Flag<["-", "--"], "print-library-module-manifest-path">,
5324+
HelpText<"Print the path for the C++ Standard library module manifest">,
5325+
Visibility<[ClangOption, CLOption]>;
53235326
def print_targets : Flag<["-", "--"], "print-targets">,
53245327
HelpText<"Print the registered targets">,
53255328
Visibility<[ClangOption, CLOption]>;

clang/lib/Driver/Driver.cpp

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

2197+
if (C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2198+
llvm::outs() << GetStdModuleManifestPath(C, C.getDefaultToolChain())
2199+
<< '\n';
2200+
return false;
2201+
}
2202+
21972203
if (C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
21982204
if (std::optional<std::string> RuntimePath = TC.getRuntimePath())
21992205
llvm::outs() << *RuntimePath << '\n';
@@ -6166,6 +6172,44 @@ std::string Driver::GetProgramPath(StringRef Name, const ToolChain &TC) const {
61666172
return std::string(Name);
61676173
}
61686174

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

0 commit comments

Comments
 (0)