aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/actions/Artifact.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/Artifact.java60
1 files changed, 42 insertions, 18 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
index 374f8872ba..d1ae560ab1 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
@@ -40,17 +40,19 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
+import java.util.Objects;
import javax.annotation.Nullable;
/**
* An Artifact represents a file used by the build system, whether it's a source
* file or a derived (output) file. Not all Artifacts have a corresponding
- * FileTarget object in the <code>build.packages</code> API: for example,
+ * FileTarget object in the <code>build.lib.packages</code> API: for example,
* low-level intermediaries internal to a given rule, such as a Java class files
* or C++ object files. However all FileTargets have a corresponding Artifact.
*
- * <p>In any given call to Builder#buildArtifacts(), no two Artifacts in the
- * action graph may refer to the same path.
+ * <p>In any given call to
+ * {@link com.google.devtools.build.lib.skyframe.SkyframeExecutor#buildArtifacts}, no two Artifacts
+ * in the action graph may refer to the same path.
*
* <p>Artifacts generally fall into two classifications, source and derived, but
* there exist a few other cases that are fuzzy and difficult to classify. The
@@ -128,7 +130,6 @@ public class Artifact
return EvalUtils.compareByClass(this, o);
}
-
/** An object that can expand middleman artifacts. */
public interface ArtifactExpander {
@@ -182,10 +183,10 @@ public class Artifact
* </pre>
*
* <p>In a derived Artifact, the execPath will overlap with part of the root, which in turn will
- * be below of the execRoot.
+ * be below the execRoot.
* <pre>
* [path] == [/root][pathTail] == [/execRoot][execPath] == [/execRoot][rootPrefix][pathTail]
- * <pre>
+ * </pre>
*/
@VisibleForTesting
public Artifact(Path path, Root root, PathFragment execPath, ArtifactOwner owner) {
@@ -200,7 +201,6 @@ public class Artifact
this.hashCode = path.hashCode();
this.path = path;
this.root = root;
- this.execPath = execPath;
// These two lines establish the invariant that
// execPath == rootRelativePath <=> execPath.equals(rootRelativePath)
// This is important for isSourceArtifact.
@@ -210,6 +210,7 @@ public class Artifact
+ rootRel + " at " + path + " with root " + root);
}
this.rootRelativePath = rootRel.equals(execPath) ? execPath : rootRel;
+ this.execPath = externalfy(execPath);
this.owner = Preconditions.checkNotNull(owner, path);
}
@@ -350,7 +351,12 @@ public class Artifact
@SkylarkCallable(name = "is_source", structField = true,
doc = "Returns true if this is a source file, i.e. it is not generated")
public final boolean isSourceArtifact() {
- return execPath == rootRelativePath;
+ // All source roots should, you know, point to sources. However, for embedded binaries, they
+ // are actually created as derived artifacts, so we have to special-case isSourceArtifact to
+ // treat derived roots in the main repo where execPath==rootRelPath as source roots.
+ // Source artifacts have reference-identical execPaths and rootRelativePaths, so use
+ // of == instead of .equals() is intentional here.
+ return execPath == rootRelativePath || root.isSourceRoot();
}
/**
@@ -515,15 +521,9 @@ public class Artifact
* For targets in external repositories, this returns the path the artifact live at in the
* runfiles tree. For local targets, it returns the rootRelativePath.
*/
+ // TODO(kchodorow): remove.
public final PathFragment getRunfilesPath() {
- PathFragment relativePath = rootRelativePath;
- if (relativePath.segmentCount() > 1
- && relativePath.getSegment(0).equals(Label.EXTERNAL_PATH_PREFIX)) {
- // Turn external/repo/foo into ../repo/foo.
- relativePath = relativePath.relativeTo(Label.EXTERNAL_PATH_PREFIX);
- relativePath = new PathFragment("..").getRelative(relativePath);
- }
- return relativePath;
+ return externalfy(rootRelativePath);
}
@SkylarkCallable(
@@ -557,7 +557,31 @@ public class Artifact
+ "runfiles of a binary."
)
public final String getExecPathString() {
- return getExecPath().getPathString();
+ return getExecPath().toString();
+ }
+
+ private PathFragment externalfy(PathFragment relativePath) {
+ if (root.isMainRepo()) {
+ return relativePath;
+ }
+
+ PathFragment prefix;
+ if (root.isSourceRoot()) {
+ prefix = new PathFragment(Label.EXTERNAL_PATH_PREFIX)
+ .getRelative(root.getPath().getBaseName());
+ } else {
+ prefix = new PathFragment(Label.EXTERNAL_PATH_PREFIX)
+ .getRelative(root.getExecRoot().getBaseName());
+ }
+ return prefix.getRelative(relativePath);
+ }
+
+ /**
+ * Returns if this artifact is in the main repository or not.
+ */
+ // TODO(kchodorow): remove once execroot path is correct.
+ public boolean isInMainRepo() {
+ return root.isMainRepo();
}
/*
@@ -585,7 +609,7 @@ public class Artifact
// We don't bother to check root in the equivalence relation, because we
// assume that no root is an ancestor of another one.
Artifact that = (Artifact) other;
- return this.path.equals(that.path);
+ return Objects.equals(this.path, that.path);
}
@Override