1 //===- ExternalCommand.h ----------------------------------------*- C++ -*-===// 2 // 3 // This source file is part of the Swift.org open source project 4 // 5 // Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors 6 // Licensed under Apache License v2.0 with Runtime Library Exception 7 // 8 // See http://swift.org/LICENSE.txt for license information 9 // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLBUILD_BUILDSYSTEM_EXTERNALCOMMAND_H 14 #define LLBUILD_BUILDSYSTEM_EXTERNALCOMMAND_H 15 16 #include "llbuild/BuildSystem/BuildDescription.h" 17 #include "llbuild/BuildSystem/BuildSystem.h" 18 #include "llbuild/BuildSystem/BuildValue.h" 19 #include "llbuild/BuildSystem/CommandResult.h" 20 21 #include "llvm/ADT/Optional.h" 22 #include "llvm/ADT/StringRef.h" 23 24 #include <string> 25 #include <vector> 26 27 namespace llbuild { 28 namespace core { 29 30 class Task; 31 32 } 33 34 namespace buildsystem { 35 36 class BuildNode; 37 class BuildSystem; 38 struct QueueJobContext; 39 40 /// This is a base class for defining commands which are run externally to the 41 /// build system and interact using files. It defines common base behaviors 42 /// which make sense for all such tools. 43 class ExternalCommand : public Command { 44 std::vector<BuildNode*> inputs; 45 std::vector<BuildNode*> outputs; 46 std::string description; 47 48 /// Whether to allow missing inputs. 49 bool allowMissingInputs = false; 50 51 /// Whether to allow modified outputs. 52 // 53 // FIXME: This is currently useful as a mechanism for defining builds in which 54 // an output is intentionally modified by another command. However, this isn't 55 // a very robust mechanism, and we should ultimately move to a model whereby 56 // we can reconstruct exactly the state of each individual command (by having 57 // a durable storage for the outputs outside of the file system). 58 bool allowModifiedOutputs = false; 59 60 /// Whether to treat the command as always being out-of-date. 61 bool alwaysOutOfDate = false; 62 63 // Build specific data. 64 // 65 // FIXME: We should probably factor this out somewhere else, so we can enforce 66 // it is never used when initialized incorrectly. 67 68 /// The previous build result command signature, if available. 69 uint64_t priorResultCommandSignature; 70 71 /// If not None, the command should be skipped with the provided BuildValue. 72 llvm::Optional<BuildValue> skipValue; 73 74 /// If true, the command had a missing input (this implies ShouldSkip is 75 /// true). 76 bool hasMissingInput = false; 77 78 /// If true, the command can legally be updated if the output state allows it. 79 bool canUpdateIfNewer = true; 80 81 /// Whether a prior result has been found. 82 bool hasPriorResult = false; 83 84 /// Compute the output result for the command. 85 BuildValue computeCommandResult(BuildSystemCommandInterface& bsci); 86 87 /// Check if it is legal to only update the result (versus rerunning) 88 /// because the outputs are newer than all of the inputs. 89 bool canUpdateIfNewerWithResult(const BuildValue& result); 90 91 protected: getInputs()92 const std::vector<BuildNode*>& getInputs() { return inputs; } 93 getOutputs()94 const std::vector<BuildNode*>& getOutputs() { return outputs; } 95 getDescription()96 StringRef getDescription() { return description; } 97 98 /// This function must be overriden by subclasses for any additional keys. 99 virtual uint64_t getSignature(); 100 101 /// Extension point for subclasses, to actually execute the command. 102 virtual CommandResult executeExternalCommand(BuildSystemCommandInterface& bsci, 103 core::Task* task, 104 QueueJobContext* context) = 0; 105 106 public: 107 using Command::Command; 108 109 virtual void configureDescription(const ConfigureContext&, 110 StringRef value) override; 111 112 virtual void configureInputs(const ConfigureContext&, 113 const std::vector<Node*>& value) override; 114 115 virtual void configureOutputs(const ConfigureContext&, 116 const std::vector<Node*>& value) override; 117 118 virtual bool configureAttribute(const ConfigureContext& ctx, StringRef name, 119 StringRef value) override; 120 virtual bool configureAttribute(const ConfigureContext& ctx, StringRef name, 121 ArrayRef<StringRef> values) override; 122 virtual bool configureAttribute( 123 const ConfigureContext&, StringRef name, 124 ArrayRef<std::pair<StringRef, StringRef>> values) override; 125 126 virtual BuildValue getResultForOutput(Node* node, 127 const BuildValue& value) override; 128 129 virtual bool isResultValid(BuildSystem&, const BuildValue& value) override; 130 131 virtual void start(BuildSystemCommandInterface& bsci, 132 core::Task* task) override; 133 134 virtual void providePriorValue(BuildSystemCommandInterface&, core::Task*, 135 const BuildValue&) override; 136 137 virtual void provideValue(BuildSystemCommandInterface& bsci, core::Task*, 138 uintptr_t inputID, 139 const BuildValue& value) override; 140 141 virtual BuildValue execute(BuildSystemCommandInterface& bsci, 142 core::Task* task, 143 QueueJobContext* context) override; 144 }; 145 146 } 147 } 148 149 #endif 150