Generate and use a manifest for prelude files. (#4291)

This removes the directory crawl because bazel doesn't remove files from
execroot when the rule generating them would no longer generate them.

Fixes #4288
This commit is contained in:
Jon Ross-Perkins
2024-09-10 20:59:49 +00:00
committed by GitHub
parent 2e299f5fc4
commit 6311552fcc
8 changed files with 85 additions and 43 deletions
+27 -26
View File
@@ -7,9 +7,11 @@
#include <memory>
#include "common/check.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "tools/cpp/runfiles/runfiles.h"
namespace Carbon {
@@ -76,43 +78,42 @@ auto InstallPaths::Make(llvm::StringRef install_prefix) -> InstallPaths {
return paths;
}
auto InstallPaths::FindPreludeFiles() const
auto InstallPaths::ReadPreludeManifest() const
-> ErrorOr<llvm::SmallVector<std::string>> {
// This is structured to avoid a vector copy on success.
ErrorOr<llvm::SmallVector<std::string>> result =
llvm::SmallVector<std::string>();
std::string dir = core_package();
llvm::SmallString<256> manifest;
llvm::sys::path::append(manifest, llvm::sys::path::Style::posix,
core_package(), "prelude_manifest.txt");
// Include <data>/core/prelude.carbon, which is the entry point into the
// prelude.
{
llvm::SmallString<256> prelude_file(dir);
llvm::sys::path::append(prelude_file, llvm::sys::path::Style::posix,
"prelude.carbon");
result->push_back(prelude_file.str().str());
auto fs = llvm::vfs::getRealFileSystem();
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> file =
fs->getBufferForFile(manifest);
if (!file) {
result = ErrorBuilder() << "Loading prelude manifest `" << manifest
<< "`: " << file.getError().message();
return result;
}
// Glob for <data>/core/prelude/**/*.carbon and add all the files we find.
llvm::SmallString<256> prelude_dir(dir);
llvm::sys::path::append(prelude_dir, llvm::sys::path::Style::posix,
"prelude");
std::error_code ec;
for (llvm::sys::fs::recursive_directory_iterator prelude_files_it(
prelude_dir, ec, /*follow_symlinks=*/false);
prelude_files_it != llvm::sys::fs::recursive_directory_iterator();
prelude_files_it.increment(ec)) {
if (ec) {
result = ErrorBuilder() << "Could not find prelude: " << ec.message();
return result;
}
auto prelude_file = prelude_files_it->path();
if (llvm::sys::path::extension(prelude_file) == ".carbon") {
result->push_back(prelude_file);
// The manifest should have one file per line.
llvm::StringRef buffer = file.get()->getBuffer();
while (true) {
auto [token, remainder] = llvm::getToken(buffer, "\n");
if (token.empty()) {
break;
}
llvm::SmallString<256> path;
llvm::sys::path::append(path, llvm::sys::path::Style::posix, core_package(),
token);
result->push_back(path.str().str());
buffer = remainder;
}
if (result->empty()) {
result = ErrorBuilder() << "Prelude manifest `" << manifest << "` is empty";
}
return result;
}