| package com.google.devtools.build.lib.rules.cpp; |
| // Copyright 2018 The Bazel Authors. All rights reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| import com.google.auto.value.AutoValue; |
| import com.google.common.base.Joiner; |
| import com.google.common.base.MoreObjects; |
| import com.google.common.base.Objects; |
| import com.google.common.base.Preconditions; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.Streams; |
| import com.google.devtools.build.lib.actions.ActionKeyContext; |
| import com.google.devtools.build.lib.actions.Artifact; |
| import com.google.devtools.build.lib.analysis.skylark.SymbolGenerator; |
| import com.google.devtools.build.lib.bugreport.BugReport; |
| import com.google.devtools.build.lib.collect.nestedset.NestedSet; |
| import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; |
| import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; |
| import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcLinkingContextApi; |
| import com.google.devtools.build.lib.skylarkbuildapi.cpp.LibraryToLinkApi; |
| import com.google.devtools.build.lib.syntax.SkylarkList; |
| import com.google.devtools.build.lib.util.Fingerprint; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.List; |
| import javax.annotation.Nullable; |
| |
| /** |
| * Encapsulates information for linking a library. |
| * |
| * <p>TODO(b/118663806): This class which shall be renamed later to LibraryToLink (once the old |
| * LibraryToLink implementation is removed) will have all the information necessary for linking a |
| * library in all of its variants : static params for executable, static params for dynamic library, |
| * dynamic params for executable and dynamic params for dynamic library. |
| */ |
| @AutoValue |
| public abstract class LibraryToLink implements LibraryToLinkApi<Artifact> { |
| |
| public Artifact getDynamicLibraryForRuntimeOrNull(boolean linkingStatically) { |
| if (getDynamicLibrary() == null) { |
| return null; |
| } |
| if (linkingStatically && (getStaticLibrary() != null || getPicStaticLibrary() != null)) { |
| return null; |
| } |
| return getDynamicLibrary(); |
| } |
| |
| /** Structure of CcLinkingContext. */ |
| public static class CcLinkingContext implements CcLinkingContextApi { |
| public static final CcLinkingContext EMPTY = CcLinkingContext.builder().build(); |
| |
| /** A list of link options contributed by a single configured target/aspect. */ |
| @Immutable |
| public static final class LinkOptions { |
| private final ImmutableList<String> linkOptions; |
| private final Object symbolForEquality; |
| |
| private LinkOptions(Iterable<String> linkOptions, Object symbolForEquality) { |
| this.linkOptions = ImmutableList.copyOf(linkOptions); |
| this.symbolForEquality = Preconditions.checkNotNull(symbolForEquality); |
| } |
| |
| public ImmutableList<String> get() { |
| return linkOptions; |
| } |
| |
| public static LinkOptions of( |
| Iterable<String> linkOptions, SymbolGenerator<?> symbolGenerator) { |
| return new LinkOptions(linkOptions, symbolGenerator.generate()); |
| } |
| |
| @Override |
| public int hashCode() { |
| // Symbol is sufficient for equality check. |
| return symbolForEquality.hashCode(); |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| if (!(obj instanceof LinkOptions)) { |
| return false; |
| } |
| LinkOptions that = (LinkOptions) obj; |
| if (!this.symbolForEquality.equals(that.symbolForEquality)) { |
| return false; |
| } |
| if (this.linkOptions.equals(that.linkOptions)) { |
| return true; |
| } |
| BugReport.sendBugReport( |
| new IllegalStateException( |
| "Unexpected inequality with equal symbols: " + this + ", " + that)); |
| return false; |
| } |
| |
| @Override |
| public String toString() { |
| return '[' + Joiner.on(",").join(linkOptions) + "] (owner: " + symbolForEquality; |
| } |
| } |
| |
| /** |
| * A linkstamp that also knows about its declared includes. |
| * |
| * <p>This object is required because linkstamp files may include other headers which will have |
| * to be provided during compilation. |
| */ |
| public static final class Linkstamp { |
| private final Artifact artifact; |
| private final NestedSet<Artifact> declaredIncludeSrcs; |
| private final byte[] nestedDigest; |
| |
| // TODO(janakr): if action key context is not available, the digest can be computed lazily, |
| // only if we are doing an equality comparison and artifacts are equal. That should never |
| // happen, so doing an expensive digest should be ok then. If this is ever moved to Starlark |
| // and Starlark doesn't support custom equality or amortized deep equality of nested sets, a |
| // Symbol can be used as an equality proxy, similar to what LinkOptions does above. |
| Linkstamp( |
| Artifact artifact, |
| NestedSet<Artifact> declaredIncludeSrcs, |
| ActionKeyContext actionKeyContext) { |
| this.artifact = Preconditions.checkNotNull(artifact); |
| this.declaredIncludeSrcs = Preconditions.checkNotNull(declaredIncludeSrcs); |
| Fingerprint fp = new Fingerprint(); |
| actionKeyContext.addNestedSetToFingerprint(fp, this.declaredIncludeSrcs); |
| nestedDigest = fp.digestAndReset(); |
| } |
| |
| /** Returns the linkstamp artifact. */ |
| public Artifact getArtifact() { |
| return artifact; |
| } |
| |
| /** Returns the declared includes. */ |
| public NestedSet<Artifact> getDeclaredIncludeSrcs() { |
| return declaredIncludeSrcs; |
| } |
| |
| @Override |
| public int hashCode() { |
| // Artifact should be enough to disambiguate basically all the time. |
| return artifact.hashCode(); |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| if (!(obj instanceof Linkstamp)) { |
| return false; |
| } |
| Linkstamp other = (Linkstamp) obj; |
| return artifact.equals(other.artifact) |
| && Arrays.equals(this.nestedDigest, other.nestedDigest); |
| } |
| } |
| |
| private final NestedSet<LibraryToLink> libraries; |
| private final NestedSet<LinkOptions> userLinkFlags; |
| private final NestedSet<Linkstamp> linkstamps; |
| private final NestedSet<Artifact> nonCodeInputs; |
| private final ExtraLinkTimeLibraries extraLinkTimeLibraries; |
| |
| public CcLinkingContext( |
| NestedSet<LibraryToLink> libraries, |
| NestedSet<LinkOptions> userLinkFlags, |
| NestedSet<Linkstamp> linkstamps, |
| NestedSet<Artifact> nonCodeInputs, |
| ExtraLinkTimeLibraries extraLinkTimeLibraries) { |
| this.libraries = libraries; |
| this.userLinkFlags = userLinkFlags; |
| this.linkstamps = linkstamps; |
| this.nonCodeInputs = nonCodeInputs; |
| this.extraLinkTimeLibraries = extraLinkTimeLibraries; |
| } |
| |
| public static CcLinkingContext merge(List<CcLinkingContext> ccLinkingContexts) { |
| CcLinkingContext.Builder mergedCcLinkingContext = CcLinkingContext.builder(); |
| ExtraLinkTimeLibraries.Builder mergedExtraLinkTimeLibraries = |
| ExtraLinkTimeLibraries.builder(); |
| for (CcLinkingContext ccLinkingContext : ccLinkingContexts) { |
| mergedCcLinkingContext |
| .addLibraries(ccLinkingContext.getLibraries()) |
| .addUserLinkFlags(ccLinkingContext.getUserLinkFlags()) |
| .addLinkstamps(ccLinkingContext.getLinkstamps()) |
| .addNonCodeInputs(ccLinkingContext.getNonCodeInputs()); |
| if (ccLinkingContext.getExtraLinkTimeLibraries() != null) { |
| mergedExtraLinkTimeLibraries.addTransitive(ccLinkingContext.getExtraLinkTimeLibraries()); |
| } |
| } |
| mergedCcLinkingContext.setExtraLinkTimeLibraries(mergedExtraLinkTimeLibraries.build()); |
| return mergedCcLinkingContext.build(); |
| } |
| |
| public List<Artifact> getStaticModeParamsForExecutableLibraries() { |
| ImmutableList.Builder<Artifact> libraryListBuilder = ImmutableList.builder(); |
| for (LibraryToLink libraryToLink : getLibraries()) { |
| if (libraryToLink.getStaticLibrary() != null) { |
| libraryListBuilder.add(libraryToLink.getStaticLibrary()); |
| } else if (libraryToLink.getPicStaticLibrary() != null) { |
| libraryListBuilder.add(libraryToLink.getPicStaticLibrary()); |
| } else if (libraryToLink.getInterfaceLibrary() != null) { |
| libraryListBuilder.add(libraryToLink.getInterfaceLibrary()); |
| } else { |
| libraryListBuilder.add(libraryToLink.getDynamicLibrary()); |
| } |
| } |
| return libraryListBuilder.build(); |
| } |
| |
| public List<Artifact> getStaticModeParamsForDynamicLibraryLibraries() { |
| ImmutableList.Builder<Artifact> artifactListBuilder = ImmutableList.builder(); |
| for (LibraryToLink library : getLibraries()) { |
| if (library.getPicStaticLibrary() != null) { |
| artifactListBuilder.add(library.getPicStaticLibrary()); |
| } else if (library.getStaticLibrary() != null) { |
| artifactListBuilder.add(library.getStaticLibrary()); |
| } else if (library.getInterfaceLibrary() != null) { |
| artifactListBuilder.add(library.getInterfaceLibrary()); |
| } else { |
| artifactListBuilder.add(library.getDynamicLibrary()); |
| } |
| } |
| return artifactListBuilder.build(); |
| } |
| |
| public List<Artifact> getDynamicModeParamsForExecutableLibraries() { |
| ImmutableList.Builder<Artifact> artifactListBuilder = ImmutableList.builder(); |
| for (LibraryToLink library : getLibraries()) { |
| if (library.getInterfaceLibrary() != null) { |
| artifactListBuilder.add(library.getInterfaceLibrary()); |
| } else if (library.getDynamicLibrary() != null) { |
| artifactListBuilder.add(library.getDynamicLibrary()); |
| } else if (library.getStaticLibrary() != null) { |
| artifactListBuilder.add(library.getStaticLibrary()); |
| } else if (library.getPicStaticLibrary() != null) { |
| artifactListBuilder.add(library.getPicStaticLibrary()); |
| } |
| } |
| return artifactListBuilder.build(); |
| } |
| |
| public List<Artifact> getDynamicModeParamsForDynamicLibraryLibraries() { |
| ImmutableList.Builder<Artifact> artifactListBuilder = ImmutableList.builder(); |
| for (LibraryToLink library : getLibraries()) { |
| if (library.getInterfaceLibrary() != null) { |
| artifactListBuilder.add(library.getInterfaceLibrary()); |
| } else if (library.getDynamicLibrary() != null) { |
| artifactListBuilder.add(library.getDynamicLibrary()); |
| } else if (library.getPicStaticLibrary() != null) { |
| artifactListBuilder.add(library.getPicStaticLibrary()); |
| } else if (library.getStaticLibrary() != null) { |
| artifactListBuilder.add(library.getStaticLibrary()); |
| } |
| } |
| return artifactListBuilder.build(); |
| } |
| |
| public List<Artifact> getDynamicLibrariesForRuntime(boolean linkingStatically) { |
| return LibraryToLink.getDynamicLibrariesForRuntime(linkingStatically, libraries); |
| } |
| |
| public NestedSet<LibraryToLink> getLibraries() { |
| return libraries; |
| } |
| |
| @Override |
| public SkylarkList<String> getSkylarkUserLinkFlags() { |
| return SkylarkList.createImmutable(getFlattenedUserLinkFlags()); |
| } |
| |
| @Override |
| public SkylarkList<LibraryToLinkApi> getSkylarkLibrariesToLink() { |
| return SkylarkList.createImmutable(libraries.toList()); |
| } |
| |
| public NestedSet<LinkOptions> getUserLinkFlags() { |
| return userLinkFlags; |
| } |
| |
| public ImmutableList<String> getFlattenedUserLinkFlags() { |
| return Streams.stream(userLinkFlags) |
| .map(LinkOptions::get) |
| .flatMap(Collection::stream) |
| .collect(ImmutableList.toImmutableList()); |
| } |
| |
| public NestedSet<Linkstamp> getLinkstamps() { |
| return linkstamps; |
| } |
| |
| public NestedSet<Artifact> getNonCodeInputs() { |
| return nonCodeInputs; |
| } |
| |
| public ExtraLinkTimeLibraries getExtraLinkTimeLibraries() { |
| return extraLinkTimeLibraries; |
| } |
| |
| public static Builder builder() { |
| return new Builder(); |
| } |
| |
| /** Builder for {@link CcLinkingContext}. */ |
| public static class Builder { |
| private final NestedSetBuilder<LibraryToLink> libraries = NestedSetBuilder.linkOrder(); |
| private final NestedSetBuilder<LinkOptions> userLinkFlags = NestedSetBuilder.linkOrder(); |
| private final NestedSetBuilder<Linkstamp> linkstamps = NestedSetBuilder.compileOrder(); |
| private final NestedSetBuilder<Artifact> nonCodeInputs = NestedSetBuilder.linkOrder(); |
| private ExtraLinkTimeLibraries extraLinkTimeLibraries = null; |
| |
| public Builder addLibraries(NestedSet<LibraryToLink> libraries) { |
| this.libraries.addTransitive(libraries); |
| return this; |
| } |
| |
| public Builder addUserLinkFlags(NestedSet<LinkOptions> userLinkFlags) { |
| this.userLinkFlags.addTransitive(userLinkFlags); |
| return this; |
| } |
| |
| Builder addLinkstamps(NestedSet<Linkstamp> linkstamps) { |
| this.linkstamps.addTransitive(linkstamps); |
| return this; |
| } |
| |
| Builder addNonCodeInputs(NestedSet<Artifact> nonCodeInputs) { |
| this.nonCodeInputs.addTransitive(nonCodeInputs); |
| return this; |
| } |
| |
| public Builder setExtraLinkTimeLibraries(ExtraLinkTimeLibraries extraLinkTimeLibraries) { |
| Preconditions.checkState(this.extraLinkTimeLibraries == null); |
| this.extraLinkTimeLibraries = extraLinkTimeLibraries; |
| return this; |
| } |
| |
| public CcLinkingContext build() { |
| return new CcLinkingContext( |
| libraries.build(), |
| userLinkFlags.build(), |
| linkstamps.build(), |
| nonCodeInputs.build(), |
| extraLinkTimeLibraries); |
| } |
| } |
| |
| @Override |
| public boolean equals(Object otherObject) { |
| if (!(otherObject instanceof CcLinkingContext)) { |
| return false; |
| } |
| CcLinkingContext other = (CcLinkingContext) otherObject; |
| if (this == other) { |
| return true; |
| } |
| return this.libraries.shallowEquals(other.libraries) |
| && this.userLinkFlags.shallowEquals(other.userLinkFlags) |
| && this.linkstamps.shallowEquals(other.linkstamps) |
| && this.nonCodeInputs.shallowEquals(other.nonCodeInputs); |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hashCode( |
| libraries.shallowHashCode(), |
| userLinkFlags.shallowHashCode(), |
| linkstamps.shallowHashCode(), |
| nonCodeInputs.shallowHashCode()); |
| } |
| |
| @Override |
| public String toString() { |
| return MoreObjects.toStringHelper(this) |
| .add("userLinkFlags", userLinkFlags) |
| .add("linkstamps", linkstamps) |
| .add("libraries", libraries) |
| .add("nonCodeInputs", nonCodeInputs) |
| .toString(); |
| } |
| } |
| |
| private LinkerInputs.LibraryToLink picStaticLibraryToLink; |
| private LinkerInputs.LibraryToLink staticLibraryToLink; |
| private LinkerInputs.LibraryToLink dynamicLibraryToLink; |
| private LinkerInputs.LibraryToLink interfaceLibraryToLink; |
| |
| public abstract String getLibraryIdentifier(); |
| |
| @Nullable |
| @Override |
| public abstract Artifact getStaticLibrary(); |
| |
| @Nullable |
| public abstract ImmutableList<Artifact> getObjectFiles(); |
| |
| @Nullable |
| public abstract ImmutableMap<Artifact, LtoBackendArtifacts> getSharedNonLtoBackends(); |
| |
| @Nullable |
| public abstract LtoCompilationContext getLtoCompilationContext(); |
| |
| @Nullable |
| @Override |
| public abstract Artifact getPicStaticLibrary(); |
| |
| @Nullable |
| public abstract ImmutableList<Artifact> getPicObjectFiles(); |
| |
| @Nullable |
| public abstract ImmutableMap<Artifact, LtoBackendArtifacts> getPicSharedNonLtoBackends(); |
| |
| @Nullable |
| public abstract LtoCompilationContext getPicLtoCompilationContext(); |
| |
| @Nullable |
| @Override |
| public abstract Artifact getDynamicLibrary(); |
| |
| @Nullable |
| public abstract Artifact getResolvedSymlinkDynamicLibrary(); |
| |
| @Nullable |
| @Override |
| public abstract Artifact getInterfaceLibrary(); |
| |
| @Nullable |
| public abstract Artifact getResolvedSymlinkInterfaceLibrary(); |
| |
| @Override |
| public abstract boolean getAlwayslink(); |
| |
| // TODO(plf): This is just needed for Go, do not expose to Skylark and try to remove it. This was |
| // introduced to let a linker input declare that it needs debug info in the executable. |
| // Specifically, this was introduced for linking Go into a C++ binary when using the gccgo |
| // compiler. |
| abstract boolean getMustKeepDebug(); |
| |
| public static Builder builder() { |
| return new AutoValue_LibraryToLink.Builder().setMustKeepDebug(false).setAlwayslink(false); |
| } |
| |
| LinkerInputs.LibraryToLink getStaticLibraryToLink() { |
| Preconditions.checkNotNull(getStaticLibrary(), this); |
| if (staticLibraryToLink != null) { |
| return staticLibraryToLink; |
| } |
| staticLibraryToLink = |
| LinkerInputs.newInputLibrary( |
| getStaticLibrary(), |
| getAlwayslink() |
| ? ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY |
| : ArtifactCategory.STATIC_LIBRARY, |
| getLibraryIdentifier(), |
| getObjectFiles(), |
| getLtoCompilationContext(), |
| getSharedNonLtoBackends(), |
| getMustKeepDebug()); |
| return staticLibraryToLink; |
| } |
| |
| LinkerInputs.LibraryToLink getPicStaticLibraryToLink() { |
| Preconditions.checkNotNull(getPicStaticLibrary(), this); |
| if (picStaticLibraryToLink != null) { |
| return picStaticLibraryToLink; |
| } |
| picStaticLibraryToLink = |
| LinkerInputs.newInputLibrary( |
| getPicStaticLibrary(), |
| getAlwayslink() |
| ? ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY |
| : ArtifactCategory.STATIC_LIBRARY, |
| getLibraryIdentifier(), |
| getPicObjectFiles(), |
| getPicLtoCompilationContext(), |
| getPicSharedNonLtoBackends(), |
| getMustKeepDebug()); |
| return picStaticLibraryToLink; |
| } |
| |
| LinkerInputs.LibraryToLink getDynamicLibraryToLink() { |
| Preconditions.checkNotNull(getDynamicLibrary(), this); |
| if (dynamicLibraryToLink != null) { |
| return dynamicLibraryToLink; |
| } |
| if (getResolvedSymlinkDynamicLibrary() != null) { |
| dynamicLibraryToLink = |
| LinkerInputs.solibLibraryToLink( |
| getDynamicLibrary(), getResolvedSymlinkDynamicLibrary(), getLibraryIdentifier()); |
| } else { |
| dynamicLibraryToLink = |
| LinkerInputs.newInputLibrary( |
| getDynamicLibrary(), |
| ArtifactCategory.DYNAMIC_LIBRARY, |
| getLibraryIdentifier(), |
| /* objectFiles */ ImmutableSet.of(), |
| LtoCompilationContext.EMPTY, |
| /* sharedNonLtoBackends */ ImmutableMap.of(), |
| getMustKeepDebug()); |
| } |
| return dynamicLibraryToLink; |
| } |
| |
| LinkerInputs.LibraryToLink getInterfaceLibraryToLink() { |
| Preconditions.checkNotNull(getInterfaceLibrary()); |
| if (interfaceLibraryToLink != null) { |
| return interfaceLibraryToLink; |
| } |
| if (getResolvedSymlinkInterfaceLibrary() != null) { |
| interfaceLibraryToLink = |
| LinkerInputs.solibLibraryToLink( |
| getInterfaceLibrary(), getResolvedSymlinkInterfaceLibrary(), getLibraryIdentifier()); |
| } else { |
| interfaceLibraryToLink = |
| LinkerInputs.newInputLibrary( |
| getInterfaceLibrary(), |
| ArtifactCategory.INTERFACE_LIBRARY, |
| getLibraryIdentifier(), |
| /* objectFiles */ ImmutableSet.of(), |
| LtoCompilationContext.EMPTY, |
| /* sharedNonLtoBackends */ ImmutableMap.of(), |
| getMustKeepDebug()); |
| } |
| return interfaceLibraryToLink; |
| } |
| |
| public static List<Artifact> getDynamicLibrariesForRuntime( |
| boolean linkingStatically, Iterable<LibraryToLink> libraries) { |
| ImmutableList.Builder<Artifact> dynamicLibrariesForRuntimeBuilder = ImmutableList.builder(); |
| for (LibraryToLink libraryToLink : libraries) { |
| Artifact artifact = libraryToLink.getDynamicLibraryForRuntimeOrNull(linkingStatically); |
| if (artifact != null) { |
| dynamicLibrariesForRuntimeBuilder.add(artifact); |
| } |
| } |
| return dynamicLibrariesForRuntimeBuilder.build(); |
| } |
| |
| public static List<Artifact> getDynamicLibrariesForLinking(Iterable<LibraryToLink> libraries) { |
| ImmutableList.Builder<Artifact> dynamicLibrariesForLinkingBuilder = ImmutableList.builder(); |
| for (LibraryToLink libraryToLink : libraries) { |
| if (libraryToLink.getInterfaceLibrary() != null) { |
| dynamicLibrariesForLinkingBuilder.add(libraryToLink.getInterfaceLibrary()); |
| } else if (libraryToLink.getDynamicLibrary() != null) { |
| dynamicLibrariesForLinkingBuilder.add(libraryToLink.getDynamicLibrary()); |
| } |
| } |
| return dynamicLibrariesForLinkingBuilder.build(); |
| } |
| |
| /** Builder for LibraryToLink. */ |
| @AutoValue.Builder |
| public abstract static class Builder { |
| |
| public abstract Builder setLibraryIdentifier(String libraryIdentifier); |
| |
| public abstract Builder setStaticLibrary(Artifact staticLibrary); |
| |
| public abstract Builder setObjectFiles(ImmutableList<Artifact> objectFiles); |
| |
| abstract Builder setLtoCompilationContext(LtoCompilationContext ltoCompilationContext); |
| |
| abstract Builder setSharedNonLtoBackends( |
| ImmutableMap<Artifact, LtoBackendArtifacts> sharedNonLtoBackends); |
| |
| abstract Builder setPicStaticLibrary(Artifact picStaticLibrary); |
| |
| abstract Builder setPicObjectFiles(ImmutableList<Artifact> picObjectFiles); |
| |
| abstract Builder setPicLtoCompilationContext(LtoCompilationContext picLtoCompilationContext); |
| |
| abstract Builder setPicSharedNonLtoBackends( |
| ImmutableMap<Artifact, LtoBackendArtifacts> picSharedNonLtoBackends); |
| |
| public abstract Builder setDynamicLibrary(Artifact dynamicLibrary); |
| |
| abstract Builder setResolvedSymlinkDynamicLibrary(Artifact resolvedSymlinkDynamicLibrary); |
| |
| abstract Builder setInterfaceLibrary(Artifact interfaceLibrary); |
| |
| abstract Builder setResolvedSymlinkInterfaceLibrary(Artifact resolvedSymlinkInterfaceLibrary); |
| |
| public abstract Builder setAlwayslink(boolean alwayslink); |
| |
| public abstract Builder setMustKeepDebug(boolean mustKeepDebug); |
| |
| // Methods just for validation, not to be called externally. |
| abstract LibraryToLink autoBuild(); |
| |
| abstract String getLibraryIdentifier(); |
| |
| abstract Artifact getStaticLibrary(); |
| |
| abstract ImmutableList<Artifact> getObjectFiles(); |
| |
| abstract ImmutableMap<Artifact, LtoBackendArtifacts> getSharedNonLtoBackends(); |
| |
| abstract LtoCompilationContext getLtoCompilationContext(); |
| |
| abstract Artifact getPicStaticLibrary(); |
| |
| abstract ImmutableList<Artifact> getPicObjectFiles(); |
| |
| abstract ImmutableMap<Artifact, LtoBackendArtifacts> getPicSharedNonLtoBackends(); |
| |
| abstract LtoCompilationContext getPicLtoCompilationContext(); |
| |
| abstract Artifact getDynamicLibrary(); |
| |
| abstract Artifact getResolvedSymlinkDynamicLibrary(); |
| |
| abstract Artifact getInterfaceLibrary(); |
| |
| abstract Artifact getResolvedSymlinkInterfaceLibrary(); |
| |
| public LibraryToLink build() { |
| Preconditions.checkNotNull(getLibraryIdentifier()); |
| Preconditions.checkState( |
| (getObjectFiles() == null |
| && getLtoCompilationContext() == null |
| && getSharedNonLtoBackends() == null) |
| || getStaticLibrary() != null); |
| Preconditions.checkState( |
| (getPicObjectFiles() == null |
| && getPicLtoCompilationContext() == null |
| && getPicSharedNonLtoBackends() == null) |
| || getPicStaticLibrary() != null); |
| Preconditions.checkState( |
| getResolvedSymlinkDynamicLibrary() == null || getDynamicLibrary() != null); |
| Preconditions.checkState( |
| getResolvedSymlinkInterfaceLibrary() == null |
| || getResolvedSymlinkInterfaceLibrary() != null); |
| Preconditions.checkState( |
| getStaticLibrary() != null |
| || getPicStaticLibrary() != null |
| || getDynamicLibrary() != null |
| || getInterfaceLibrary() != null); |
| |
| return autoBuild(); |
| } |
| } |
| } |
| |