Skip to content

Commit 5233e64

Browse files
OSS-Fuzz Teamcopybara-github
authored andcommitted
Indexing: Allow out-of-band source trees
Indexer-PiperOrigin-RevId: 810487818
1 parent ad191dd commit 5233e64

File tree

4 files changed

+76
-18
lines changed

4 files changed

+76
-18
lines changed

infra/indexer/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ set(CMAKE_EXE_LINKER_FLAGS "-fuse-ld=lld -lc++")
1515
include(FetchContent)
1616
FetchContent_Declare(
1717
absl
18-
URL https://github.com/abseil/abseil-cpp/archive/d9e4955c65cd4367dd6bf46f4ccb8cd3d100540b.zip
18+
URL https://github.com/abseil/abseil-cpp/archive/987c57f325f7fa8472fa84e1f885f7534d391b0d.zip
19+
# https://github.com/abseil/abseil-cpp/releases/tag/20250814.0
1920
)
2021
FetchContent_MakeAvailable(absl)
2122

infra/indexer/index/file_copier.cc

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,24 @@ void PreparePath(std::string& path) {
4141

4242
FileCopier::FileCopier(absl::string_view base_path,
4343
absl::string_view index_path,
44-
const std::vector<std::string>& extra_paths)
44+
const std::vector<std::string>& extra_paths,
45+
Behavior behavior)
4546
: base_path_(base_path),
4647
extra_paths_(extra_paths),
47-
index_path_(index_path) {
48+
index_path_(index_path),
49+
behavior_(behavior) {
50+
if (behavior_ == Behavior::kNoOp) {
51+
return;
52+
}
53+
4854
PreparePath(base_path_);
4955
for (std::string& extra_path : extra_paths_) {
5056
PreparePath(extra_path);
5157
}
5258
}
5359

5460
std::string FileCopier::AbsoluteToIndexPath(absl::string_view path) const {
55-
CHECK(path.starts_with("/")) << "Absolute path expected";
61+
CHECK(path.starts_with("/")) << "Absolute path expected: " << path;
5662

5763
std::string result = std::string(path);
5864
if (!base_path_.empty() && absl::StartsWith(path, base_path_)) {
@@ -70,12 +76,20 @@ std::string FileCopier::AbsoluteToIndexPath(absl::string_view path) const {
7076
}
7177

7278
void FileCopier::RegisterIndexedFile(absl::string_view index_path) {
73-
absl::MutexLock lock(&mutex_);
79+
if (behavior_ == Behavior::kNoOp) {
80+
return;
81+
}
82+
83+
absl::MutexLock lock(mutex_);
7484
indexed_files_.emplace(index_path);
7585
}
7686

7787
void FileCopier::CopyIndexedFiles() {
78-
absl::MutexLock lock(&mutex_);
88+
if (behavior_ == Behavior::kNoOp) {
89+
return;
90+
}
91+
92+
absl::MutexLock lock(mutex_);
7993

8094
for (const std::string& indexed_path : indexed_files_) {
8195
std::filesystem::path src_path = indexed_path;
@@ -101,9 +115,14 @@ void FileCopier::CopyIndexedFiles() {
101115
<< dst_path.parent_path()
102116
<< " (error: " << error_code.message() << ")";
103117

104-
QCHECK(std::filesystem::copy_file(src_path, dst_path, error_code))
105-
<< "Failed to copy file " << src_path << " to " << dst_path
106-
<< " (error: " << error_code.message() << ")";
118+
using std::filesystem::copy_options;
119+
const copy_options options = behavior_ == Behavior::kOverwriteExistingFiles
120+
? copy_options::overwrite_existing
121+
: copy_options::none;
122+
std::filesystem::copy_file(src_path, dst_path, options, error_code);
123+
QCHECK(!error_code) << "Failed to copy file " << src_path << " to "
124+
<< dst_path << " (error: " << error_code.message()
125+
<< ")";
107126
}
108127
}
109128
} // namespace indexer

infra/indexer/index/file_copier.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@ namespace indexer {
3232
// all InMemoryIndexes for the current project.
3333
class FileCopier {
3434
public:
35+
enum class Behavior { kNoOp, kFailOnExistingFiles, kOverwriteExistingFiles };
36+
3537
FileCopier(absl::string_view base_path, absl::string_view index_path,
36-
const std::vector<std::string>& extra_paths);
38+
const std::vector<std::string>& extra_paths,
39+
Behavior behavior = Behavior::kFailOnExistingFiles);
3740
FileCopier(const FileCopier&) = delete;
3841

3942
// Takes an absolute path. Rewrites this path into the representation it will
@@ -51,6 +54,7 @@ class FileCopier {
5154
std::string base_path_;
5255
std::vector<std::string> extra_paths_;
5356
const std::filesystem::path index_path_;
57+
const Behavior behavior_;
5458

5559
absl::Mutex mutex_;
5660
absl::flat_hash_set<std::string> indexed_files_ ABSL_GUARDED_BY(mutex_);

infra/indexer/main.cc

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
#include <sched.h>
16-
1715
#include <filesystem> // NOLINT
1816
#include <memory>
1917
#include <string>
@@ -24,7 +22,6 @@
2422
#include "init.h"
2523
#include "indexer/frontend/frontend.h"
2624
#include "indexer/index/file_copier.h"
27-
#include "indexer/index/in_memory_index.h"
2825
#include "indexer/index/sqlite.h"
2926
#include "indexer/merge_queue.h"
3027
#include "absl/flags/flag.h"
@@ -39,7 +36,9 @@
3936
ABSL_FLAG(std::string, source_dir, "", "Source directory");
4037
ABSL_FLAG(std::string, build_dir, "", "Build directory");
4138
ABSL_FLAG(std::string, index_dir, "",
42-
"Output index file directory (should be empty if it exists)");
39+
"Output index file directory (should be empty if it exists for a new "
40+
"index or contain the old index for a --delta); required unless"
41+
"--database_only is specified");
4342
ABSL_FLAG(std::vector<std::string>, extra_dirs, {"/"},
4443
"Additional source directory/-ies (comma-separated)");
4544
ABSL_FLAG(std::string, dry_run_regex, "",
@@ -51,25 +50,42 @@ ABSL_FLAG(int, merge_queue_size, 16, "Length of merge queues");
5150
ABSL_FLAG(bool, enable_expensive_checks, false,
5251
"Enable expensive database integrity checks");
5352
ABSL_FLAG(bool, ignore_indexing_errors, false, "Ignore indexing errors");
53+
ABSL_FLAG(bool, delta, false,
54+
"Has no effect with --database_only (which can however be directly "
55+
"pointed to the delta database filename for the same effect). Expects"
56+
" --index_dir to point to an existing database. Stores a delta"
57+
" database alongside it only for the translation units in"
58+
"`compile_commands.json` (for incremental indexing). IMPORTANT: The "
59+
"latter should contain all the translation units dependent on any "
60+
"files changed since the original index was built. Source files that "
61+
"get indexed are copied to --index_dir (again)");
62+
ABSL_FLAG(std::string, database_only, "",
63+
"Do not copy source files, only build the index database at the given"
64+
" location (--index_dir is not effective in that case)");
65+
66+
static constexpr char kIndexDbName[] = "db.sqlite";
67+
static constexpr char kDeltaDbName[] = "delta.sqlite";
5468

5569
int main(int argc, char** argv) {
56-
using oss_fuzz::indexer::InMemoryIndex;
70+
using oss_fuzz::indexer::FileCopier;
5771
using oss_fuzz::indexer::MergeQueue;
72+
using oss_fuzz::indexer::SaveAsSqlite;
5873
using clang::tooling::AllTUsToolExecutor;
5974
using clang::tooling::CompilationDatabase;
6075

6176
#ifdef NO_CHANGE_ROOT_AND_USER
6277
// When running inside a container, we cannot drop privileges.
6378
InitGoogleExceptChangeRootAndUser(argv[0], &argc, &argv, true);
6479
#else
65-
InitGoogle(absl::NullSafeStringView(argv[0]), &argc, &argv, true);
80+
InitGoogle(argv[0], &argc, &argv, true);
6681
#endif
6782

6883
const std::string& source_dir = absl::GetFlag(FLAGS_source_dir);
6984
const std::string& build_dir = absl::GetFlag(FLAGS_build_dir);
7085
const std::string& index_dir = absl::GetFlag(FLAGS_index_dir);
86+
const std::string& database_only = absl::GetFlag(FLAGS_database_only);
7187
const std::vector<std::string>& extra_dirs = absl::GetFlag(FLAGS_extra_dirs);
72-
auto index_path = std::filesystem::path(index_dir) / "db.sqlite";
88+
const bool delta = absl::GetFlag(FLAGS_delta);
7389

7490
#ifndef NDEBUG
7591
LOG(ERROR) << "indexer is built without optimisations. Use 'blaze run -c opt'"
@@ -88,7 +104,25 @@ int main(int argc, char** argv) {
88104
clang::tooling::Filter.setValue(dry_run_regex);
89105
}
90106

91-
oss_fuzz::indexer::FileCopier file_copier(source_dir, index_dir, extra_dirs);
107+
std::string index_path = database_only;
108+
FileCopier::Behavior behavior = FileCopier::Behavior::kNoOp;
109+
if (database_only.empty()) {
110+
if (delta) {
111+
index_path = std::filesystem::path(index_dir) / kDeltaDbName;
112+
behavior = FileCopier::Behavior::kOverwriteExistingFiles;
113+
} else {
114+
index_path = std::filesystem::path(index_dir) / kIndexDbName;
115+
if (std::filesystem::exists(index_path)) {
116+
LOG(ERROR) << "Index database '" << index_path
117+
<< "' already exists. Either specify an empty --index_dir or"
118+
"use --delta or --database_only";
119+
return 1;
120+
}
121+
behavior = FileCopier::Behavior::kFailOnExistingFiles;
122+
}
123+
}
124+
125+
FileCopier file_copier(source_dir, index_dir, extra_dirs, behavior);
92126

93127
std::unique_ptr<MergeQueue> merge_queue = MergeQueue::Create(
94128
absl::GetFlag(FLAGS_merge_queues), absl::GetFlag(FLAGS_merge_queue_size));

0 commit comments

Comments
 (0)