26
26
#include " clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h"
27
27
#include " llvm/ADT/ArrayRef.h"
28
28
#include " llvm/ADT/ScopeExit.h"
29
+ #include " llvm/ADT/SmallVector.h"
29
30
#include " llvm/ADT/Statistic.h"
30
31
#include " llvm/Bitstream/BitstreamReader.h"
31
32
#include " llvm/CAS/ActionCache.h"
33
+ #include " llvm/CAS/BuiltinUnifiedCASDatabases.h"
32
34
#include " llvm/CAS/CASProvidingFileSystem.h"
33
35
#include " llvm/CAS/CachingOnDiskFileSystem.h"
34
36
#include " llvm/CAS/HierarchicalTreeBuilder.h"
39
41
#include " llvm/Support/Compiler.h"
40
42
#include " llvm/Support/Error.h"
41
43
#include " llvm/Support/ErrorHandling.h"
44
+ #include " llvm/Support/FileSystem.h"
42
45
#include " llvm/Support/ManagedStatic.h"
43
46
#include " llvm/Support/Path.h"
44
47
#include " llvm/Support/PrefixMapper.h"
50
53
#include " llvm/Support/raw_ostream.h"
51
54
#include < cstdio>
52
55
#include < mutex>
56
+ #include < optional>
53
57
#include < shared_mutex>
54
58
55
59
#if LLVM_ON_UNIX
@@ -630,8 +634,8 @@ namespace {
630
634
struct ScanServer {
631
635
const char *Argv0 = nullptr ;
632
636
SmallString<128 > BasePath;
633
- // / List of cas options.
634
- ArrayRef< const char *> CASArgs ;
637
+ CASOptions CASOpts;
638
+ bool ProduceIncludeTree = true ;
635
639
int PidFD = -1 ;
636
640
int ListenSocket = -1 ;
637
641
// / \p std::nullopt means it runs indefinitely.
@@ -640,7 +644,7 @@ struct ScanServer {
640
644
641
645
~ScanServer () { shutdown (); }
642
646
643
- void start (bool Exclusive);
647
+ void start (bool Exclusive, ArrayRef< const char *> CASArgs );
644
648
int listen ();
645
649
646
650
// / Tear down the socket and bind file immediately but wait till all existing
@@ -705,13 +709,13 @@ int cc1depscand_main(ArrayRef<const char *> Argv, const char *Argv0,
705
709
// particular "build session", to shutdown, then have it stay alive until the
706
710
// session is finished.
707
711
bool LongRunning = false ;
708
-
712
+ ArrayRef< const char *> CASArgs;
709
713
for (const auto *A = Argv.begin () + 2 ; A != Argv.end (); ++A) {
710
714
StringRef Arg (*A);
711
715
if (Arg == " -long-running" )
712
716
LongRunning = true ;
713
717
else if (Arg == " -cas-args" ) {
714
- Server. CASArgs = ArrayRef (A + 1 , Argv.end ());
718
+ CASArgs = ArrayRef (A + 1 , Argv.end ());
715
719
break ;
716
720
}
717
721
}
@@ -722,7 +726,7 @@ int cc1depscand_main(ArrayRef<const char *> Argv, const char *Argv0,
722
726
reportError (Twine (" cannot create basedir: " ) + EC.message ());
723
727
724
728
if (Command == " -serve" ) {
725
- Server.start (/* Exclusive*/ true );
729
+ Server.start (/* Exclusive*/ true , CASArgs );
726
730
return Server.listen ();
727
731
728
732
} else if (Command == " -execute" ) {
@@ -733,7 +737,7 @@ int cc1depscand_main(ArrayRef<const char *> Argv, const char *Argv0,
733
737
}
734
738
735
739
// Make sure to start the server before executing the command.
736
- Server.start (/* Exclusive*/ true );
740
+ Server.start (/* Exclusive*/ true , CASArgs );
737
741
std::thread ServerThread ([&Server]() { Server.listen (); });
738
742
739
743
setenv (" CLANG_CACHE_SCAN_DAEMON_SOCKET_PATH" , Server.BasePath .c_str (),
@@ -784,11 +788,59 @@ int cc1depscand_main(ArrayRef<const char *> Argv, const char *Argv0,
784
788
openAndReplaceFD (1 , LogOutPath);
785
789
openAndReplaceFD (2 , LogErrPath);
786
790
787
- Server.start (/* Exclusive*/ false );
791
+ Server.start (/* Exclusive*/ false , CASArgs );
788
792
return Server.listen ();
789
793
}
790
794
791
- void ScanServer::start (bool Exclusive) {
795
+ static std::optional<StringRef>
796
+ findLLVMCasBinary (const char *Argv0, llvm::SmallVectorImpl<char > &Storage) {
797
+ using namespace llvm ::sys;
798
+ std::string Path = fs::getMainExecutable (Argv0, (void *)cc1depscan_main);
799
+ Storage.assign (Path.begin (), Path.end ());
800
+ path::remove_filename (Storage);
801
+ path::append (Storage, " llvm-cas" );
802
+ StringRef PathStr (Storage.data (), Storage.size ());
803
+ if (fs::exists (PathStr))
804
+ return PathStr;
805
+ // Look for a corresponding usr/local/bin/llvm-cas
806
+ PathStr = path::parent_path (PathStr);
807
+ if (path::filename (PathStr) != " bin" )
808
+ return std::nullopt;
809
+ PathStr = path::parent_path (PathStr);
810
+ Storage.truncate (PathStr.size ());
811
+ path::append (Storage, " local" , " bin" , " llvm-cas" );
812
+ PathStr = StringRef{Storage.data (), Storage.size ()};
813
+ if (fs::exists (PathStr))
814
+ return PathStr;
815
+ return std::nullopt;
816
+ }
817
+
818
+ void ScanServer::start (bool Exclusive, ArrayRef<const char *> CASArgs) {
819
+ // Parse CAS options and validate if needed.
820
+ DiagnosticsEngine Diags (new DiagnosticIDs (), new DiagnosticOptions ());
821
+
822
+ const OptTable &Opts = clang::driver::getDriverOptTable ();
823
+ unsigned MissingArgIndex, MissingArgCount;
824
+ auto ParsedCASArgs =
825
+ Opts.ParseArgs (CASArgs, MissingArgIndex, MissingArgCount);
826
+ CompilerInvocation::ParseCASArgs (CASOpts, ParsedCASArgs, Diags);
827
+ CASOpts.ensurePersistentCAS ();
828
+ ProduceIncludeTree =
829
+ ParsedCASArgs.hasArg (driver::options::OPT_fdepscan_include_tree);
830
+
831
+ static std::once_flag ValidateOnce;
832
+ std::call_once (ValidateOnce, [&] {
833
+ if (getenv (" LLVM_CAS_DISABLE_VALIDATION" ))
834
+ return ;
835
+ if (CASOpts.CASPath .empty () || !CASOpts.PluginPath .empty ())
836
+ return ;
837
+ SmallString<64 > LLVMCasStorage;
838
+ ExitOnErr (llvm::cas::validateOnDiskUnifiedCASDatabasesIfNeeded (
839
+ CASOpts.getResolvedCASPath (), /* CheckHash=*/ true ,
840
+ /* AllowRecovery=*/ true ,
841
+ /* Force=*/ false , findLLVMCasBinary (Argv0, LLVMCasStorage)));
842
+ });
843
+
792
844
// Check the pidfile.
793
845
SmallString<128 > PidPath;
794
846
(BasePath + " .pid" ).toVector (PidPath);
@@ -827,16 +879,6 @@ int ScanServer::listen() {
827
879
llvm::DefaultThreadPool Pool;
828
880
829
881
DiagnosticsEngine Diags (new DiagnosticIDs (), new DiagnosticOptions ());
830
- CASOptions CASOpts;
831
- const OptTable &Opts = clang::driver::getDriverOptTable ();
832
- unsigned MissingArgIndex, MissingArgCount;
833
- auto ParsedCASArgs =
834
- Opts.ParseArgs (CASArgs, MissingArgIndex, MissingArgCount);
835
- CompilerInvocation::ParseCASArgs (CASOpts, ParsedCASArgs, Diags);
836
- CASOpts.ensurePersistentCAS ();
837
- bool ProduceIncludeTree =
838
- ParsedCASArgs.hasArg (driver::options::OPT_fdepscan_include_tree);
839
-
840
882
std::shared_ptr<llvm::cas::ObjectStore> CAS;
841
883
std::shared_ptr<llvm::cas::ActionCache> Cache;
842
884
std::tie (CAS, Cache) = CASOpts.getOrCreateDatabases (Diags);
0 commit comments