aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java
diff options
context:
space:
mode:
authorGravatar Lukacs Berki <lberki@google.com>2016-01-26 14:47:15 +0000
committerGravatar Lukacs Berki <lberki@google.com>2016-01-26 14:50:23 +0000
commit41f4456ac2348bef66739194853a1ddadcbb887e (patch)
tree06946ed64729aae994719a85286b6392edf811fc /src/main/java
parent213ae7a17f047ecf46fec190beb23f10f58268aa (diff)
Make runfiles tree creation on Windows depend on the artifacts of the actual runfiles.
This is necessary because the plan for Windows calls for knowing if the target of the symlink is a directory or a file, thus, we cannot create runfiles trees before the artifacts in them are built. This probably comes with a performance hit due to the extra scheduling constraints. This makes almost every test pass save: - test_tmpdir in bazel_test_test, which I hereby dismiss as a fluke - test_http_archive_tgz in external_integration_test (Maybe a permissions issue due to copying things?) - A bunch of test in external_correctness_test, probably related to the fact that since we are copying things, we don't notice changes to the original files. -- MOS_MIGRATED_REVID=113050025
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/MiddlemanFactory.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeAction.java26
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java7
4 files changed, 36 insertions, 11 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/MiddlemanFactory.java b/src/main/java/com/google/devtools/build/lib/actions/MiddlemanFactory.java
index aecfd359bc..24c436c190 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/MiddlemanFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/MiddlemanFactory.java
@@ -23,6 +23,8 @@ import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Iterator;
+import javax.annotation.Nullable;
+
/**
* A factory to create middleman objects.
*/
@@ -82,8 +84,8 @@ public final class MiddlemanFactory {
* @param middlemanDir the directory in which to place the middleman.
*/
public Artifact createRunfilesMiddleman(
- ActionOwner owner, Artifact owningArtifact, Iterable<Artifact> inputs, Root middlemanDir,
- String tag) {
+ ActionOwner owner, @Nullable Artifact owningArtifact, Iterable<Artifact> inputs,
+ Root middlemanDir, String tag) {
if (hasExactlyOneInput(inputs)) { // Optimization: No middleman for just one input.
return Iterables.getOnlyElement(inputs);
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java b/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java
index 0a5335686c..b657e8d1ea 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java
@@ -113,7 +113,7 @@ public class RunfilesSupport {
Artifact artifactsMiddleman = createArtifactsMiddleman(ruleContext, runfiles.getAllArtifacts());
runfilesInputManifest = createRunfilesInputManifestArtifact(ruleContext);
- this.runfilesManifest = createRunfilesAction(ruleContext, runfiles);
+ this.runfilesManifest = createRunfilesAction(ruleContext, runfiles, artifactsMiddleman);
this.runfilesMiddleman = createRunfilesMiddleman(
ruleContext, artifactsMiddleman, runfilesManifest);
sourcesManifest = createSourceManifest(ruleContext, runfiles);
@@ -272,7 +272,8 @@ public class RunfilesSupport {
* generated files, etc.) into a single tree, so that programs can access them
* using the workspace-relative name.
*/
- private Artifact createRunfilesAction(ActionConstructionContext context, Runfiles runfiles) {
+ private Artifact createRunfilesAction(ActionConstructionContext context, Runfiles runfiles,
+ Artifact artifactsMiddleman) {
// Compute the names of the runfiles directory and its MANIFEST file.
Artifact inputManifest = getRunfilesInputManifest();
context.getAnalysisEnvironment().registerAction(
@@ -292,7 +293,8 @@ public class RunfilesSupport {
Artifact outputManifest = context.getDerivedArtifact(
outputManifestPath, config.getBinDirectory());
context.getAnalysisEnvironment().registerAction(new SymlinkTreeAction(
- context.getActionOwner(), inputManifest, outputManifest, /*filesetTree=*/false));
+ context.getActionOwner(), inputManifest, artifactsMiddleman, outputManifest,
+ /*filesetTree=*/false));
return outputManifest;
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeAction.java b/src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeAction.java
index 7b38198cad..7501f09189 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeAction.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeAction.java
@@ -24,6 +24,8 @@ import com.google.devtools.build.lib.actions.ResourceSet;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.util.Preconditions;
+import javax.annotation.Nullable;
+
/**
* Action responsible for the symlink tree creation.
* Used to generate runfiles and fileset symlink farms.
@@ -40,22 +42,36 @@ public class SymlinkTreeAction extends AbstractAction {
* Creates SymlinkTreeAction instance.
*
* @param owner action owner
- * @param inputManifest exec path to the input runfiles manifest
- * @param outputManifest exec path to the generated symlink tree manifest
+ * @param inputManifest the input runfiles manifest
+ * @param artifactMiddleman the middleman artifact representing all the files the symlinks
+ * point to (on Windows we need to know if the target of a "symlink" is
+ * a directory or a file so we need to build it before)
+ * @param outputManifest the generated symlink tree manifest
* (must have "MANIFEST" base name). Symlink tree root
* will be set to the artifact's parent directory.
* @param filesetTree true if this is fileset symlink tree,
* false if this is a runfiles symlink tree.
*/
- public SymlinkTreeAction(ActionOwner owner, Artifact inputManifest, Artifact outputManifest,
- boolean filesetTree) {
- super(owner, ImmutableList.of(inputManifest), ImmutableList.of(outputManifest));
+ public SymlinkTreeAction(ActionOwner owner, Artifact inputManifest,
+ @Nullable Artifact artifactMiddleman, Artifact outputManifest, boolean filesetTree) {
+ super(owner, computeInputs(inputManifest, artifactMiddleman), ImmutableList.of(outputManifest));
Preconditions.checkArgument(outputManifest.getPath().getBaseName().equals("MANIFEST"));
this.inputManifest = inputManifest;
this.outputManifest = outputManifest;
this.filesetTree = filesetTree;
}
+ private static ImmutableList<Artifact> computeInputs(
+ Artifact inputManifest, Artifact artifactMiddleman) {
+ ImmutableList.Builder<Artifact> result = ImmutableList.<Artifact>builder()
+ .add(inputManifest);
+ if (artifactMiddleman != null
+ && !artifactMiddleman.getPath().getFileSystem().supportsSymbolicLinksNatively()) {
+ result.add(artifactMiddleman);
+ }
+ return result.build();
+ }
+
public Artifact getInputManifest() {
return inputManifest;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java b/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java
index 032d9737ab..598b4fadbf 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java
@@ -151,8 +151,13 @@ public final class NativeLibs {
.addRootSymlinks(symlinks)
.build());
Artifact outputManifest = AndroidBinary.getDxArtifact(ruleContext, "native_symlinks/MANIFEST");
+ Artifact nativeLibsMiddleman =
+ ruleContext.getAnalysisEnvironment().getMiddlemanFactory().createRunfilesMiddleman(
+ ruleContext.getActionOwner(), null, symlinks.values(),
+ ruleContext.getConfiguration().getMiddlemanDirectory(), "android_native_libs");
+
ruleContext.registerAction(new SymlinkTreeAction(
- ruleContext.getActionOwner(), inputManifest, outputManifest, false));
+ ruleContext.getActionOwner(), inputManifest, nativeLibsMiddleman, outputManifest, false));
return outputManifest;
}