Skip to content

Commit 0e1e1fc

Browse files
ChuanqiXu9mordante
andauthored
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]>
1 parent 0269790 commit 0e1e1fc

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
@@ -615,6 +615,16 @@ class Driver {
615615
// FIXME: This should be in CompilationInfo.
616616
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const;
617617

618+
/// Lookup the path to the Standard library module manifest.
619+
///
620+
/// \param C - The compilation.
621+
/// \param TC - The tool chain for additional information on
622+
/// directories to search.
623+
//
624+
// FIXME: This should be in CompilationInfo.
625+
std::string GetStdModuleManifestPath(const Compilation &C,
626+
const ToolChain &TC) const;
627+
618628
/// HandleAutocompletions - Handle --autocomplete by searching and printing
619629
/// possible flags, descriptions, and its arguments.
620630
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
@@ -5399,6 +5399,9 @@ def print_resource_dir : Flag<["-", "--"], "print-resource-dir">,
53995399
def print_search_dirs : Flag<["-", "--"], "print-search-dirs">,
54005400
HelpText<"Print the paths used for finding libraries and programs">,
54015401
Visibility<[ClangOption, CLOption]>;
5402+
def print_std_module_manifest_path : Flag<["-", "--"], "print-library-module-manifest-path">,
5403+
HelpText<"Print the path for the C++ Standard library module manifest">,
5404+
Visibility<[ClangOption, CLOption]>;
54025405
def print_targets : Flag<["-", "--"], "print-targets">,
54035406
HelpText<"Print the registered targets">,
54045407
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';
@@ -6186,6 +6192,44 @@ std::string Driver::GetProgramPath(StringRef Name, const ToolChain &TC) const {
61866192
return std::string(Name);
61876193
}
61886194

6195+
std::string Driver::GetStdModuleManifestPath(const Compilation &C,
6196+
const ToolChain &TC) const {
6197+
std::string error = "<NOT PRESENT>";
6198+
6199+
switch (TC.GetCXXStdlibType(C.getArgs())) {
6200+
case ToolChain::CST_Libcxx: {
6201+
std::string lib = GetFilePath("libc++.so", TC);
6202+
6203+
// Note when there are multiple flavours of libc++ the module json needs to
6204+
// look at the command-line arguments for the proper json.
6205+
// These flavours do not exist at the moment, but there are plans to
6206+
// provide a variant that is built with sanitizer instrumentation enabled.
6207+
6208+
// For example
6209+
// StringRef modules = [&] {
6210+
// const SanitizerArgs &Sanitize = TC.getSanitizerArgs(C.getArgs());
6211+
// if (Sanitize.needsAsanRt())
6212+
// return "modules-asan.json";
6213+
// return "modules.json";
6214+
// }();
6215+
6216+
SmallString<128> path(lib.begin(), lib.end());
6217+
llvm::sys::path::remove_filename(path);
6218+
llvm::sys::path::append(path, "modules.json");
6219+
if (TC.getVFS().exists(path))
6220+
return static_cast<std::string>(path);
6221+
6222+
return error;
6223+
}
6224+
6225+
case ToolChain::CST_Libstdcxx:
6226+
// libstdc++ does not provide Standard library modules yet.
6227+
return error;
6228+
}
6229+
6230+
return error;
6231+
}
6232+
61896233
std::string Driver::GetTemporaryPath(StringRef Prefix, StringRef Suffix) const {
61906234
SmallString<128> Path;
61916235
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)