@@ -109,7 +109,7 @@ class OwnershipAnalysis {
109109public:
110110 std::vector<std::pair<BuildNode*, Command*>> outputNodesAndCommands;
111111
112- std::vector<BuildNode*> allDirectoryInputNodes ;
112+ std::vector<std::pair< BuildNode*, Command*>> directoryInputNodesAndCommands ;
113113
114114 OwnershipAnalysis (const BuildDescription::command_set& commands, BuildFileDelegate& fileDelegate): fileDelegate(fileDelegate) {
115115 // Extract outputs and directory inputs of all commands
@@ -123,7 +123,7 @@ class OwnershipAnalysis {
123123
124124 for (auto input: command->getInputs ()) {
125125 if (input->isDirectory ()) {
126- allDirectoryInputNodes .push_back (input);
126+ directoryInputNodesAndCommands .push_back (std::pair<BuildNode*, Command*>( input, command) );
127127 }
128128 }
129129 }
@@ -140,7 +140,7 @@ class OwnershipAnalysis {
140140 // / Establish ownerships
141141 bool establishOwnerships () {
142142 for (auto outputNodeAndCommand: outputNodesAndCommands) {
143- if (outputNodeAndCommand.second ->isExternalCommand () && outputNodeAndCommand.second ->excludeFromOwnershipAnalysis == false ) {
143+ if (outputNodeAndCommand.second ->isExternalCommand () && outputNodeAndCommand.second ->repairViaOwnershipAnalysis == true ) {
144144 Command *owner = includedOwnerOf (outputNodeAndCommand.first ->getName ());
145145 if (owner == nullptr ) {
146146 setOwner (outputNodeAndCommand.first , outputNodeAndCommand.second );
@@ -224,12 +224,14 @@ class OwnershipAnalysis {
224224 //
225225 // This ensures TaskC will wait until TaskB is finished.
226226 void amendOutputOfOwnersWithConsumedSubpaths () {
227- for (auto inputNode: allDirectoryInputNodes ) {
228- Command *owner = includedOwnerOf (inputNode ->getName ());
227+ for (auto directoryInputNodeAndCommand: directoryInputNodesAndCommands ) {
228+ Command *owner = includedOwnerOf (directoryInputNodeAndCommand. first ->getName ());
229229 if (owner != nullptr ) {
230230 auto ownerOutputs = owner->getOutputs ();
231- if (std::find (ownerOutputs.begin (), ownerOutputs.end (), inputNode) == ownerOutputs.end ()) {
232- owner->addOutput (inputNode);
231+ if (std::find (ownerOutputs.begin (), ownerOutputs.end (), directoryInputNodeAndCommand.first ) == ownerOutputs.end ()) {
232+ if (owner->repairViaOwnershipAnalysis ) {
233+ owner->addOutput (directoryInputNodeAndCommand.first );
234+ }
233235 }
234236 }
235237 }
@@ -245,25 +247,27 @@ class OwnershipAnalysis {
245247 // We should add "a.txt" and "b.txt" to mustScanAfterPaths of "unowned-directory/".
246248 // This ensures TaskC will wait until TaskA and TaskB are finished.
247249 void deferScanningUnownedInputsUntilSubpathsAvailable () {
248- auto unownedDirectoryInputNodes = std::vector<BuildNode*>();
249- std::copy_if (allDirectoryInputNodes .begin (),
250- allDirectoryInputNodes .end (),
251- std::back_inserter (unownedDirectoryInputNodes ),
252- [this ](const BuildNode* node ) -> bool {
253- return isIncludedUnownedNode (node) ;
250+ auto unownedDirectoryInputNodesAndConsumingCommands = std::vector<std::pair< BuildNode*, Command*> >();
251+ std::copy_if (directoryInputNodesAndCommands .begin (),
252+ directoryInputNodesAndCommands .end (),
253+ std::back_inserter (unownedDirectoryInputNodesAndConsumingCommands ),
254+ [this ](const std::pair< BuildNode*, Command*> directoryInputNodeAndCommand ) -> bool {
255+ return isIncludedUnownedNode (directoryInputNodeAndCommand. first ) && directoryInputNodeAndCommand. second -> repairViaOwnershipAnalysis ;
254256 });
255257
258+ // For each output node and its producing command (e.g. "unowned-directory/a.txt" and "TaskA"),
259+ // check if there exists an unowned node (e.g. "unowned-directory/" used by "TaskC") that is a parent of the produced node.
260+ // Only add "a.txt" to mustScanAfterPaths of "unowned-directory/" if TaskC is marked as "repairViaOwnershipAnalysis".
256261 for (auto outputNodeAndCommand: outputNodesAndCommands) {
257- auto unownedNode = std::find_if (unownedDirectoryInputNodes.begin (),
258- unownedDirectoryInputNodes.end (),
259- [=](BuildNode* unownedDirectory) -> bool {
260- return outputNodeAndCommand.first ->getName ().startswith (unownedDirectory->getName ()) && outputNodeAndCommand.second ->excludeFromOwnershipAnalysis == false ;
262+ auto repairableUnownedNode =
263+ std::find_if (unownedDirectoryInputNodesAndConsumingCommands.begin (),
264+ unownedDirectoryInputNodesAndConsumingCommands.end (),
265+ [=](std::pair<BuildNode*, Command*> unownedDirectoryAndCommand) -> bool {
266+ return outputNodeAndCommand.first ->getName ().startswith (unownedDirectoryAndCommand.first ->getName ()) && outputNodeAndCommand.second ->repairViaOwnershipAnalysis == true ;
261267 });
262268
263- if (unownedNode != unownedDirectoryInputNodes.end ()) {
264- auto mustScanAfterPath = outputNodeAndCommand.first ->getName ();
265- std::string filename = llvm::sys::path::filename (mustScanAfterPath);
266- (*unownedNode)->mustScanAfterPaths .push_back (outputNodeAndCommand.first ->getName ());
269+ if (repairableUnownedNode != unownedDirectoryInputNodesAndConsumingCommands.end ()) {
270+ (*repairableUnownedNode).first ->mustScanAfterPaths .push_back (outputNodeAndCommand.first ->getName ());
267271 }
268272 }
269273 }
0 commit comments