Skip to content

Commit

Permalink
Reland "[clang][modules] Print library module manifest path." (#82160)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mordante committed Mar 3, 2024
1 parent 5f05839 commit 0c89427
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 0 deletions.
10 changes: 10 additions & 0 deletions clang/include/clang/Driver/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,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;
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -5364,6 +5364,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]>;
Expand Down
44 changes: 44 additions & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -6169,6 +6175,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);
Expand Down
40 changes: 40 additions & 0 deletions clang/test/Driver/modules-print-library-module-manifest-path.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Test that -print-library-module-manifest-path finds the correct file.

// FIXME: Enable on all platforms.

// 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>

0 comments on commit 0c89427

Please sign in to comment.