diff options
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.java | 60 |
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 |