Skip to content

Commit

Permalink
Find runfiles in directories that are themselves runfiles (C++)
Browse files Browse the repository at this point in the history
  • Loading branch information
fmeum committed Nov 26, 2021
1 parent b3bf5ab commit b79a5f0
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
29 changes: 26 additions & 3 deletions tools/cpp/runfiles/runfiles_src.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <unistd.h>
#endif // _WIN32

#include <algorithm>
#include <fstream>
#include <functional>
#include <map>
Expand All @@ -48,6 +49,12 @@ using std::vector;

namespace {

#ifdef _WIN32
const char kPathSeparator = '\\';
#else
const char kPathSeparator = '/';
#endif

bool starts_with(const string& s, const char* prefix) {
if (!prefix || !*prefix) {
return true;
Expand Down Expand Up @@ -198,9 +205,25 @@ string Runfiles::Rlocation(const string& path) const {
if (IsAbsolute(path)) {
return path;
}
const auto value = runfiles_map_.find(path);
if (value != runfiles_map_.end()) {
return value->second;
const auto exact_match = runfiles_map_.find(path);
if (exact_match != runfiles_map_.end()) {
return exact_match->second;
}
if (!runfiles_map_.empty()) {
// If path references a runfile that lies under a directory that itself is a
// runfile, then only the directory is listed in the manifest. Look up all
// prefixes of path in the manifest.
std::size_t prefix_end = path.size();
while ((prefix_end = path.find_last_of('/', prefix_end - 1)) !=
string::npos) {
const string prefix = path.substr(0, prefix_end);
const auto prefix_match = runfiles_map_.find(prefix);
if (prefix_match != runfiles_map_.end()) {
string path_suffix = path.substr(prefix_end + 1);
std::replace(path_suffix.begin(), path_suffix.end(), '/', kPathSeparator);
return prefix_match->second + kPathSeparator + path_suffix;
}
}
}
if (!directory_.empty()) {
return directory_ + "/" + path;
Expand Down
14 changes: 14 additions & 0 deletions tools/cpp/runfiles/runfiles_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,13 @@ TEST_F(RunfilesTest, ManifestBasedRunfilesRlocationAndEnvVars) {
EXPECT_EQ(r->Rlocation("/Foo"), "/Foo");
EXPECT_EQ(r->Rlocation("c:/Foo"), "c:/Foo");
EXPECT_EQ(r->Rlocation("c:\\Foo"), "c:\\Foo");
#ifdef _WIN32
EXPECT_EQ(r->Rlocation("a/b/file"), "c/d\\file");
EXPECT_EQ(r->Rlocation("a/b/deeply/nested/file"), "c/d\\deeply\\nested\\file");
#else
EXPECT_EQ(r->Rlocation("a/b/file"), "c/d/file");
EXPECT_EQ(r->Rlocation("a/b/deeply/nested/file"), "c/d/deeply/nested/file");
#endif
}

TEST_F(RunfilesTest, DirectoryBasedRunfilesRlocationAndEnvVars) {
Expand Down Expand Up @@ -316,6 +323,13 @@ TEST_F(RunfilesTest, ManifestAndDirectoryBasedRunfilesRlocationAndEnvVars) {
EXPECT_EQ(r->Rlocation("/Foo"), "/Foo");
EXPECT_EQ(r->Rlocation("c:/Foo"), "c:/Foo");
EXPECT_EQ(r->Rlocation("c:\\Foo"), "c:\\Foo");
#ifdef _WIN32
EXPECT_EQ(r->Rlocation("a/b/file"), "c/d\\file");
EXPECT_EQ(r->Rlocation("a/b/deeply/nested/file"), "c/d\\deeply\\nested\\file");
#else
EXPECT_EQ(r->Rlocation("a/b/file"), "c/d/file");
EXPECT_EQ(r->Rlocation("a/b/deeply/nested/file"), "c/d/deeply/nested/file");
#endif
AssertEnvvars(*r, mf->Path(), dir);
}

Expand Down

0 comments on commit b79a5f0

Please sign in to comment.