-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Reland "[clang][modules] Print library module manifest path." #82160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reland "[clang][modules] Print library module manifest path." #82160
Conversation
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. llvm#75741 adds this feature in libc++. This reverts commit 82f424f. Disables the tests on non-X86 platforms as suggested.
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-clang Author: Mark de Wever (mordante) ChangesThis 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. Full diff: https://github.com/llvm/llvm-project/pull/82160.diff 4 Files Affected:
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index 908bc87c14b1ca..ac258dc384e688 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -611,6 +611,16 @@ class Driver {
// FIXME: This should be in CompilationInfo.
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const;
+ /// Lookup the path to the Standard library module manifest.
+ ///
+ /// \param C - The compilation.
+ /// \param TC - The tool chain for additional information on
+ /// directories to search.
+ //
+ // FIXME: This should be in CompilationInfo.
+ std::string GetStdModuleManifestPath(const Compilation &C,
+ const ToolChain &TC) const;
+
/// HandleAutocompletions - Handle --autocomplete by searching and printing
/// possible flags, descriptions, and its arguments.
void HandleAutocompletions(StringRef PassedFlags) const;
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 53f23f9abb4c96..2963cbc6af5328 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5371,6 +5371,9 @@ def print_resource_dir : Flag<["-", "--"], "print-resource-dir">,
def print_search_dirs : Flag<["-", "--"], "print-search-dirs">,
HelpText<"Print the paths used for finding libraries and programs">,
Visibility<[ClangOption, CLOption]>;
+def print_std_module_manifest_path : Flag<["-", "--"], "print-library-module-manifest-path">,
+ HelpText<"Print the path for the C++ Standard library module manifest">,
+ Visibility<[ClangOption, CLOption]>;
def print_targets : Flag<["-", "--"], "print-targets">,
HelpText<"Print the registered targets">,
Visibility<[ClangOption, CLOption]>;
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 5a323bf4c0c5f4..82ee18b4588aa5 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2197,6 +2197,12 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
return false;
}
+ if (C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
+ llvm::outs() << GetStdModuleManifestPath(C, C.getDefaultToolChain())
+ << '\n';
+ return false;
+ }
+
if (C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
if (std::optional<std::string> RuntimePath = TC.getRuntimePath())
llvm::outs() << *RuntimePath << '\n';
@@ -6183,6 +6189,44 @@ std::string Driver::GetProgramPath(StringRef Name, const ToolChain &TC) const {
return std::string(Name);
}
+std::string Driver::GetStdModuleManifestPath(const Compilation &C,
+ const ToolChain &TC) const {
+ std::string error = "<NOT PRESENT>";
+
+ switch (TC.GetCXXStdlibType(C.getArgs())) {
+ case ToolChain::CST_Libcxx: {
+ std::string lib = GetFilePath("libc++.so", TC);
+
+ // Note when there are multiple flavours of libc++ the module json needs to
+ // look at the command-line arguments for the proper json.
+ // These flavours do not exist at the moment, but there are plans to
+ // provide a variant that is built with sanitizer instrumentation enabled.
+
+ // For example
+ // StringRef modules = [&] {
+ // const SanitizerArgs &Sanitize = TC.getSanitizerArgs(C.getArgs());
+ // if (Sanitize.needsAsanRt())
+ // return "modules-asan.json";
+ // return "modules.json";
+ // }();
+
+ SmallString<128> path(lib.begin(), lib.end());
+ llvm::sys::path::remove_filename(path);
+ llvm::sys::path::append(path, "modules.json");
+ if (TC.getVFS().exists(path))
+ return static_cast<std::string>(path);
+
+ return error;
+ }
+
+ case ToolChain::CST_Libstdcxx:
+ // libstdc++ does not provide Standard library modules yet.
+ return error;
+ }
+
+ return error;
+}
+
std::string Driver::GetTemporaryPath(StringRef Prefix, StringRef Suffix) const {
SmallString<128> Path;
std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
diff --git a/clang/test/Driver/modules-print-library-module-manifest-path.cpp b/clang/test/Driver/modules-print-library-module-manifest-path.cpp
new file mode 100644
index 00000000000000..339d8b9a717684
--- /dev/null
+++ b/clang/test/Driver/modules-print-library-module-manifest-path.cpp
@@ -0,0 +1,38 @@
+// Test that -print-library-module-manifest-path finds the correct file.
+
+// REQUIRES: x86-registered-target
+
+// RUN: rm -rf %t && split-file %s %t && cd %t
+// RUN: mkdir -p %t/Inputs/usr/lib/x86_64-linux-gnu
+// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.so
+
+// RUN: %clang -print-library-module-manifest-path \
+// RUN: -stdlib=libc++ \
+// RUN: --sysroot=%t/Inputs \
+// RUN: --target=x86_64-linux-gnu 2>&1 \
+// RUN: | FileCheck libcxx-no-module-json.cpp
+
+// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/modules.json
+// RUN: %clang -print-library-module-manifest-path \
+// RUN: -stdlib=libc++ \
+// RUN: --sysroot=%t/Inputs \
+// RUN: --target=x86_64-linux-gnu 2>&1 \
+// RUN: | FileCheck libcxx.cpp
+
+// RUN: %clang -print-library-module-manifest-path \
+// RUN: -stdlib=libstdc++ \
+// RUN: --sysroot=%t/Inputs \
+// RUN: --target=x86_64-linux-gnu 2>&1 \
+// RUN: | FileCheck libstdcxx.cpp
+
+//--- libcxx-no-module-json.cpp
+
+// CHECK: <NOT PRESENT>
+
+//--- libcxx.cpp
+
+// CHECK: {{.*}}/Inputs/usr/lib/x86_64-linux-gnu{{/|\\}}modules.json
+
+//--- libstdcxx.cpp
+
+// CHECK: <NOT PRESENT>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
@mordante if we want this for 18, we need to land and backport it in this week. |
Thanks for the reminder, it got a bit under my radar. I'll ask a backport tomorrow unless a CI starts to complain again. |
Unfortunately, this is breaking VE buildbot again. I'll check the source of your problem, but can you please revert your patch once? |
Reverted. It is possible to reproduce erros by following commands.
|
The point is to build libraries and test clang at once. The
Yes. It contains 1st item at run time if you build libraries. As a result, Hope this helps you. |
Thanks for the revert and additional information. I was expecting that the test should not be affected by files outside of the |
I can indeed reproduce this. I'm not sure whether this is the expected result. There is no real documentation for |
It looks like that I failed to understand VE is under X86 also...
I am not sure. This is surprising to me too.
It looks like this is not special to VE but reproducible for every constructing the clang and libc++ at once. So I'll try to look at it if I can reproduce it locally. |
…2160) 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. llvm#75741 adds this feature in libc++. This reverts commit 82f424f. Disables the tests on non-X86 platforms as suggested.
I sent the new PR in #84881. See the comments there for details. |
Following of #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]>
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)
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)
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.