9
9
10
10
#include " absl/algorithm/container.h"
11
11
#include " absl/container/flat_hash_set.h"
12
+ #include " boost/process/child.hpp"
13
+ #include " boost/process/io.hpp"
14
+ #include " boost/process/search_path.hpp"
12
15
#include " rapidjson/error/en.h"
13
16
#include " rapidjson/rapidjson.h"
14
17
#include " rapidjson/reader.h"
@@ -412,7 +415,7 @@ CompilationDatabaseFile CompilationDatabaseFile::openAndExitOnErrors(
412
415
}
413
416
414
417
void ResumableParser::initialize (CompilationDatabaseFile compdb,
415
- size_t refillCount) {
418
+ size_t refillCount, bool inferResourceDir ) {
416
419
auto averageJobSize = compdb.sizeInBytes () / compdb.commandCount ();
417
420
// Some customers have averageJobSize = 150KiB.
418
421
// If numWorkers == 300 (very high core count machine),
@@ -427,6 +430,7 @@ void ResumableParser::initialize(CompilationDatabaseFile compdb,
427
430
rapidjson::FileReadStream (compdb.file , this ->jsonStreamBuffer .data (),
428
431
this ->jsonStreamBuffer .size ());
429
432
this ->reader .IterativeParseInit ();
433
+ this ->inferResourceDir = inferResourceDir;
430
434
}
431
435
432
436
void ResumableParser::parseMore (
@@ -451,8 +455,78 @@ void ResumableParser::parseMore(
451
455
for (auto &cmd : this ->handler ->commands ) {
452
456
out.emplace_back (std::move (cmd));
453
457
}
458
+ if (this ->inferResourceDir ) {
459
+ for (auto &cmd : out) {
460
+ if (cmd.CommandLine .empty ()) {
461
+ continue ;
462
+ }
463
+ this ->tryInferResourceDir (cmd.CommandLine );
464
+ }
465
+ }
454
466
this ->handler ->commands .clear ();
455
467
}
456
468
469
+ void ResumableParser::tryInferResourceDir (
470
+ std::vector<std::string> &commandLine) {
471
+ auto &clangPath = commandLine.front ();
472
+ auto it = this ->resourceDirMap .find (clangPath);
473
+ if (it != this ->resourceDirMap .end ()) {
474
+ commandLine.push_back (" -resource-dir" );
475
+ commandLine.push_back (it->second );
476
+ return ;
477
+ }
478
+ std::string clangInvocationPath = clangPath;
479
+ if (clangPath.find (std::filesystem::path::preferred_separator)
480
+ == std::string::npos) {
481
+ clangInvocationPath = boost::process::search_path (clangPath).native ();
482
+ if (clangInvocationPath.empty ()) {
483
+ this ->emitResourceDirError (fmt::format (
484
+ " scip-clang needs to be invoke '{0}' (found via the compilation"
485
+ " database) to determine the resource directory, but couldn't find"
486
+ " '{0}' on PATH. Hint: Use a modified PATH to invoke scip-clang,"
487
+ " or change the compilation database to use absolute paths"
488
+ " for the compiler." ,
489
+ clangPath));
490
+ return ;
491
+ }
492
+ }
493
+ std::vector<std::string> args = {clangInvocationPath, " -print-resource-dir" };
494
+ std::string resourceDir;
495
+ BOOST_TRY {
496
+ spdlog::debug (" attempting to find resource dir by invoking '{}'" ,
497
+ fmt::join (args, " " ));
498
+ boost::process::ipstream inputStream;
499
+ boost::process::child worker (args, boost::process::std_out > inputStream);
500
+ worker.wait ();
501
+ std::getline (inputStream, resourceDir);
502
+ }
503
+ BOOST_CATCH (boost::process::process_error & ex) {
504
+ this ->emitResourceDirError (
505
+ fmt::format (" failed to get resource dir (invocation: '{}'): {}" ,
506
+ fmt::join (args, " " ), ex.what ()));
507
+ return ;
508
+ }
509
+ BOOST_CATCH_END
510
+ spdlog::debug (" get resource dir '{}'" , resourceDir);
511
+ if (!std::filesystem::exists (resourceDir)) {
512
+ this ->emitResourceDirError (
513
+ fmt::format (" '{}' returned '{}' but the directory does not exist" ,
514
+ fmt::join (args, " " ), resourceDir));
515
+ return ;
516
+ }
517
+ auto [newIt, inserted] =
518
+ this ->resourceDirMap .emplace (clangPath, std::move (resourceDir));
519
+ ENFORCE (inserted);
520
+ commandLine.push_back (" -resource-dir" );
521
+ commandLine.push_back (newIt->second );
522
+ }
523
+
524
+ void ResumableParser::emitResourceDirError (std::string &&error) {
525
+ auto [it, inserted] = this ->emittedErrors .emplace (std::move (error));
526
+ if (inserted) {
527
+ spdlog::error (" {}" , *it);
528
+ }
529
+ }
530
+
457
531
} // namespace compdb
458
532
} // namespace scip_clang
0 commit comments