Skip to content
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

Merged
merged 13 commits into from
Jan 22, 2024
11 changes: 11 additions & 0 deletions clang/include/clang/Driver/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,17 @@ class Driver {
// FIXME: This should be in CompilationInfo.
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const;

/// GetStdModuleManifestPath - Lookup the path to the Standard library module
mordante marked this conversation as resolved.
Show resolved Hide resolved
/// manifest.
///
/// \param C - The compilation.
/// \param TC - The tool chain for additional information on
/// directories to search.
//
// FIXME: This should be in CompilationInfo.
mordante marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -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_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
42 changes: 42 additions & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2164,6 +2164,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 @@ -6135,6 +6141,42 @@ 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 {

mordante marked this conversation as resolved.
Show resolved Hide resolved
std::string error = "<NOT PRESENT>";

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.
mordante marked this conversation as resolved.
Show resolved Hide resolved

// For example
/*
mordante marked this conversation as resolved.
Show resolved Hide resolved
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");
mordante marked this conversation as resolved.
Show resolved Hide resolved
if (TC.getVFS().exists(path))
return 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Test that -print-library-module-manifest-path finds the correct file.
mordante marked this conversation as resolved.
Show resolved Hide resolved

// 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: {{.*}}/Inputs/cxx23_modules/usr/lib/x86_64-linux-gnu/modules.json
Copy link
Member

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


// RUN: %clang -print-library-module-manifest-path \
// RUN: -stdlib=libstdc++ \
// RUN: --sysroot=%S/Inputs/cxx23_modules \
Copy link
Member

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?

Copy link
Member Author

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.

// RUN: --target=x86_64-linux-gnu 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-LIBSTDCXX %s
// CHECK-LIBSTDCXX: <NOT PRESENT>
Original file line number Diff line number Diff line change
@@ -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
mordante marked this conversation as resolved.
Show resolved Hide resolved

// 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: <NOT PRESENT>