-
Notifications
You must be signed in to change notification settings - Fork 12.4k
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
[clang][modules] Print library module manifest path. #76451
[clang][modules] Print library module manifest path. #76451
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++.
@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++. Full diff: https://github.com/llvm/llvm-project/pull/76451.diff 7 Files Affected:
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index 3ee1bcf2a69c9b..2e1e3b128744ff 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -602,6 +602,16 @@ class Driver {
// FIXME: This should be in CompilationInfo.
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const;
+ /// GetModuleManifestPath - Lookup the name of the Standard library 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 GetModuleManifestPath(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 2b93ddf033499c..890257e11485b6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5280,6 +5280,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_library_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 ff95c899c5f3d4..8d682f9238c6b8 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2164,6 +2164,12 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
return false;
}
+ if (C.getArgs().hasArg(options::OPT_print_library_module_manifest_path)) {
+ llvm::outs() << "module: ="
+ << GetModuleManifestPath(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';
@@ -6135,6 +6141,40 @@ std::string Driver::GetProgramPath(StringRef Name, const ToolChain &TC) const {
return std::string(Name);
}
+std::string Driver::GetModuleManifestPath(const Compilation &C,
+ const ToolChain &TC) const {
+
+ switch (TC.GetCXXStdlibType(C.getArgs())) {
+ case ToolChain::CST_Libcxx: {
+ std::string lib = "libc++.so";
+ std::string path = GetFilePath(lib, TC);
+
+ // Note when there are multiple flavours of libc++ the module json needs to
+ // look at the command-line arguments for the proper json.
+
+ // For example
+ /*
+ const SanitizerArgs &Sanitize = TC.getSanitizerArgs(C.getArgs());
+ if (Sanitize.needsAsanRt())
+ return path.replace(path.size() - lib.size(), lib.size(),
+ "modules-asan.json");
+ */
+
+ path = path.replace(path.size() - lib.size(), lib.size(), "modules.json");
+ if (TC.getVFS().exists(path))
+ return path;
+
+ return "";
+ }
+
+ case ToolChain::CST_Libstdcxx:
+ // libstdc++ does not provide Standard library modules yet.
+ return "";
+ }
+
+ return "";
+}
+
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/Inputs/cxx23_modules/usr/lib/x86_64-linux-gnu/libc++.so b/clang/test/Driver/Inputs/cxx23_modules/usr/lib/x86_64-linux-gnu/libc++.so
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/clang/test/Driver/Inputs/cxx23_modules/usr/lib/x86_64-linux-gnu/modules.json b/clang/test/Driver/Inputs/cxx23_modules/usr/lib/x86_64-linux-gnu/modules.json
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/clang/test/Driver/cxx23-modules-print-library-module-manifest-path.c b/clang/test/Driver/cxx23-modules-print-library-module-manifest-path.c
new file mode 100644
index 00000000000000..7ad2b10081bc5b
--- /dev/null
+++ b/clang/test/Driver/cxx23-modules-print-library-module-manifest-path.c
@@ -0,0 +1,15 @@
+// Test that -print-library-module-manifest-path finds the correct file.
+
+// RUN: %clang -print-library-module-manifest-path \
+// RUN: -stdlib=libc++ \
+// RUN: --sysroot=%S/Inputs/cxx23_modules \
+// RUN: --target=x86_64-linux-gnu 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-LIBCXX %s
+// CHECK-LIBCXX: module: ={{.*}}/Inputs/cxx23_modules/usr/lib/x86_64-linux-gnu/modules.json
+
+// RUN: %clang -print-library-module-manifest-path \
+// RUN: -stdlib=libstdc++ \
+// RUN: --sysroot=%S/Inputs/cxx23_modules \
+// RUN: --target=x86_64-linux-gnu 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-LIBSTDCXX %s
+// CHECK-LIBSTDCXX: module: =
diff --git a/clang/test/Driver/darwin-print-library-module-manifest-path.c b/clang/test/Driver/darwin-print-library-module-manifest-path.c
new file mode 100644
index 00000000000000..39d28589b146ae
--- /dev/null
+++ b/clang/test/Driver/darwin-print-library-module-manifest-path.c
@@ -0,0 +1,9 @@
+// Test that -print-library-module-manifest-path finds the correct file.
+//
+// Note this file is currently not available on Apple platforms
+
+// RUN: %clang -print-library-module-manifest-path \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --target=x86_64-unknown-linux-gnu 2>&1 \
+// RUN: | FileCheck %s
+// CHECK: module: =
|
clang/test/Driver/cxx23-modules-print-library-module-manifest-path.c
Outdated
Show resolved
Hide resolved
// RUN: --target=x86_64-linux-gnu 2>&1 \ | ||
// RUN: | FileCheck --check-prefix=CHECK-LIBCXX %s | ||
// CHECK-LIBCXX: module: ={{.*}}/Inputs/cxx23_modules/usr/lib/x86_64-linux-gnu/modules.json | ||
|
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.
Is there a path for libc++ like --gcc-toolchain=
so that we can choose the different locations for libstdc++?
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.
not sure, I've never used --gcc-toolchain either.
clang/test/Driver/cxx23-modules-print-library-module-manifest-path.c
Outdated
Show resolved
Hide resolved
If I understand correctly, this invents a new option just to print the std modules path. Is there a reason why we cannot just print this information as part of If for some reason a separate option is desirable, can we then also print this information as part of |
I had looked at |
True. I couldn't find a bug report for this so I filed one: #76614
If this is the right thing to do (i.e., printing this information as part of |
|
@ChuanqiXu9 can you do a full review? I'd like to have this reviewed so we can land it when the libc++ side is ready. |
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 generally.
// RUN: --sysroot=%S/Inputs/cxx23_modules \ | ||
// RUN: --target=x86_64-linux-gnu 2>&1 \ | ||
// RUN: | FileCheck --check-prefix=CHECK-LIBCXX %s | ||
// CHECK-LIBCXX: {{.*}}/Inputs/cxx23_modules/usr/lib/x86_64-linux-gnu/modules.json |
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.
Let's try to avoid use Inputs
pattern nowadays. We can use split-file
to multiple files into a single lit test. You can find the use example by searching split-file
in clang/test/Modules
clang/test/Driver/darwin-print-library-module-manifest-path.cpp
Outdated
Show resolved
Hide resolved
✅ With the latest revision this PR passed the C/C++ code formatter. |
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.
We need to delete clang/test/Driver/Inputs/cxx23_modules/usr/lib/x86_64-linux-gnu/libc++.so
and clang/test/Driver/Inputs/cxx23_modules/usr/lib/x86_64-linux-gnu/modules.json
, we should generate them with split-file
Are you sure that is the proper way? Should these tests not use a complete installation to make sure it works on installations? |
We can use
The intention is to remove the use of |
|
||
// RUN: %clang -print-library-module-manifest-path \ | ||
// RUN: -stdlib=libstdc++ \ | ||
// RUN: --sysroot=%S/Inputs/cxx23_modules \ |
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.
Does %S/Inputs/cxx23_modules
exist?
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.
No this is a left-over when it used on-disc files. Nice catch.
clang/test/Driver/cxx23-modules-print-library-module-manifest-path.cpp
Outdated
Show resolved
Hide resolved
clang/test/Driver/cxx23-modules-print-library-module-manifest-path.cpp
Outdated
Show resolved
Hide resolved
Installs the source files of the experimental libc++ modules. These source files (.cppm) are used by the Clang to build the std and std.compat modules. The design of this patch is based on a discussing in SG-15 on 12.12.2023. (SG-15 is the ISO C++ Tooling study group): - The modules are installed at a location, that is not known to build systems and compilers. - Next to the library there will be a module manifest json file. This json file contains the information to build the module from the libraries sources. This information includes the location where the sources are installed. @ruoso supplied the specification of this json file. - If possible, the compiler has an option to give the location of the module manifest file (#76451). Currently there is no build system support, but it expected to be added in the future. Fixes: #73089
@MaskRay can you have another look, it would be great to land this before LLVM 18 branches, thanks! |
clang/lib/Driver/Driver.cpp
Outdated
// return "modules-asan.json"; | ||
// return "modules.json"; | ||
// }(); | ||
StringRef modules = "modules.json"; |
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.
modules
is only used once. inline it
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 with a few nits. Can you double check modules.json is inside lib/
(usr/lib/x86_64-linux-gnu{{/|\\}}modules.json
) instead of some directory under include
?
Thanks for the review. The json will indeed be installed in the lib dir in libc++. |
Hi @mordante, Does this test, |
This reverts commit a301fb1. The changes caused failures like: https://lab.llvm.org/buildbot/#/builders/91/builds/22189
The build is still failing, so I've reverted these changes in 82f424f |
Thanks for reverting @AaronBallman I somehow missed this comment. @kaz7 it should work on all platforms AFAIK. I don't have access to a VE system. Looking at some VE tests I wonder whether the following patch would work. |
Installs the source files of the experimental libc++ modules. These source files (.cppm) are used by the Clang to build the std and std.compat modules. The design of this patch is based on a discussing in SG-15 on 12.12.2023. (SG-15 is the ISO C++ Tooling study group): - The modules are installed at a location, that is not known to build systems and compilers. - Next to the library there will be a module manifest json file. This json file contains the information to build the module from the libraries sources. This information includes the location where the sources are installed. @ruoso supplied the specification of this json file. - If possible, the compiler has an option to give the location of the module manifest file (llvm/llvm-project#76451). Currently there is no build system support, but it expected to be added in the future. Fixes: llvm/llvm-project#73089 NOKEYCHECK=True GitOrigin-RevId: 8b47bb657b5905d954b9041415020358802407d5
@kaz7 ping |
@kaz7 ping, can you have a look at the patch, I really like to reland this patch. |
(This is another example that the github review can't work well with the reverted patches...) @mordante I think you can add We can still improve this later. |
I've created #82160 as you suggested. |
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++.