blob: e53543a9088ec8f8ec7526ddca8906d5657475ff [file] [log] [blame]
// Copyright 2014 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.
package com.google.devtools.build.lib.rules.cpp;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Streams;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.rules.cpp.CcLinkParams.LinkOptions;
import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper.CcLinkingContext;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcLinkingInfoApi;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.LibraryToLinkWrapperApi;
import com.google.devtools.build.lib.syntax.SkylarkList;
import java.util.Collection;
/** Wrapper for every C++ linking provider. */
@Immutable
@AutoCodec
public final class CcLinkingInfo implements CcLinkingInfoApi {
public static final CcLinkingInfo EMPTY =
CcLinkingInfo.Builder.create()
.setStaticModeParamsForDynamicLibrary(CcLinkParams.EMPTY)
.setStaticModeParamsForExecutable(CcLinkParams.EMPTY)
.setDynamicModeParamsForDynamicLibrary(CcLinkParams.EMPTY)
.setDynamicModeParamsForExecutable(CcLinkParams.EMPTY)
.build();
private final CcLinkParams staticModeParamsForExecutable;
private final CcLinkParams staticModeParamsForDynamicLibrary;
private final CcLinkParams dynamicModeParamsForExecutable;
private final CcLinkParams dynamicModeParamsForDynamicLibrary;
@AutoCodec.Instantiator
@VisibleForSerialization
CcLinkingInfo(
CcLinkParams staticModeParamsForExecutable,
CcLinkParams staticModeParamsForDynamicLibrary,
CcLinkParams dynamicModeParamsForExecutable,
CcLinkParams dynamicModeParamsForDynamicLibrary) {
this.staticModeParamsForExecutable = staticModeParamsForExecutable;
this.staticModeParamsForDynamicLibrary = staticModeParamsForDynamicLibrary;
this.dynamicModeParamsForExecutable = dynamicModeParamsForExecutable;
this.dynamicModeParamsForDynamicLibrary = dynamicModeParamsForDynamicLibrary;
}
public CcLinkParams getStaticModeParamsForExecutable() {
return staticModeParamsForExecutable;
}
public CcLinkParams getStaticModeParamsForDynamicLibrary() {
return staticModeParamsForDynamicLibrary;
}
public CcLinkParams getDynamicModeParamsForExecutable() {
return dynamicModeParamsForExecutable;
}
public CcLinkParams getDynamicModeParamsForDynamicLibrary() {
return dynamicModeParamsForDynamicLibrary;
}
@Override
public SkylarkList<String> getSkylarkUserLinkFlags() {
CcLinkingContext ccLinkingContext = LibraryToLinkWrapper.fromCcLinkingInfo(this);
return SkylarkList.createImmutable(
Streams.stream(ccLinkingContext.getUserLinkFlags())
.map(LinkOptions::get)
.flatMap(Collection::stream)
.collect(ImmutableList.toImmutableList()));
}
@Override
public SkylarkList<LibraryToLinkWrapperApi> getSkylarkLibrariesToLink() {
CcLinkingContext ccLinkingContext = LibraryToLinkWrapper.fromCcLinkingInfo(this);
return SkylarkList.createImmutable(ccLinkingContext.getLibraries().toList());
}
public static CcLinkingInfo merge(Collection<CcLinkingInfo> ccLinkingInfos) {
CcLinkParams.Builder staticModeParamsForDynamicLibraryBuilder = CcLinkParams.builder();
CcLinkParams.Builder staticModeParamsForExecutableBuilder = CcLinkParams.builder();
CcLinkParams.Builder dynamicModeParamsForDynamicLibraryBuilder = CcLinkParams.builder();
CcLinkParams.Builder dynamicModeParamsForExecutableBuilder = CcLinkParams.builder();
for (CcLinkingInfo ccLinkingInfo : ccLinkingInfos) {
staticModeParamsForDynamicLibraryBuilder.addTransitiveArgs(
ccLinkingInfo.getStaticModeParamsForDynamicLibrary());
staticModeParamsForExecutableBuilder.addTransitiveArgs(
ccLinkingInfo.getStaticModeParamsForExecutable());
dynamicModeParamsForDynamicLibraryBuilder.addTransitiveArgs(
ccLinkingInfo.getDynamicModeParamsForDynamicLibrary());
dynamicModeParamsForExecutableBuilder.addTransitiveArgs(
ccLinkingInfo.getDynamicModeParamsForExecutable());
}
return new CcLinkingInfo.Builder()
.setStaticModeParamsForDynamicLibrary(staticModeParamsForDynamicLibraryBuilder.build())
.setStaticModeParamsForExecutable(staticModeParamsForExecutableBuilder.build())
.setDynamicModeParamsForDynamicLibrary(dynamicModeParamsForDynamicLibraryBuilder.build())
.setDynamicModeParamsForExecutable(dynamicModeParamsForExecutableBuilder.build())
.build();
}
public CcLinkParams getCcLinkParams(boolean staticMode, boolean forDynamicLibrary) {
if (staticMode) {
if (forDynamicLibrary) {
return getStaticModeParamsForDynamicLibrary();
} else {
return getStaticModeParamsForExecutable();
}
} else {
if (forDynamicLibrary) {
return getDynamicModeParamsForDynamicLibrary();
} else {
return getDynamicModeParamsForExecutable();
}
}
}
/** A Builder for {@link CcLinkingInfo}. */
public static class Builder {
CcLinkParams staticModeParamsForDynamicLibrary;
CcLinkParams staticModeParamsForExecutable;
CcLinkParams dynamicModeParamsForDynamicLibrary;
CcLinkParams dynamicModeParamsForExecutable;
public static CcLinkingInfo.Builder create() {
return new CcLinkingInfo.Builder();
}
public Builder setStaticModeParamsForDynamicLibrary(CcLinkParams ccLinkParams) {
Preconditions.checkState(this.staticModeParamsForDynamicLibrary == null);
this.staticModeParamsForDynamicLibrary = ccLinkParams;
return this;
}
public Builder setStaticModeParamsForExecutable(CcLinkParams ccLinkParams) {
Preconditions.checkState(this.staticModeParamsForExecutable == null);
this.staticModeParamsForExecutable = ccLinkParams;
return this;
}
public Builder setDynamicModeParamsForDynamicLibrary(CcLinkParams ccLinkParams) {
Preconditions.checkState(this.dynamicModeParamsForDynamicLibrary == null);
this.dynamicModeParamsForDynamicLibrary = ccLinkParams;
return this;
}
public Builder setDynamicModeParamsForExecutable(CcLinkParams ccLinkParams) {
Preconditions.checkState(this.dynamicModeParamsForExecutable == null);
this.dynamicModeParamsForExecutable = ccLinkParams;
return this;
}
public CcLinkingInfo build() {
Preconditions.checkNotNull(staticModeParamsForExecutable);
Preconditions.checkNotNull(staticModeParamsForDynamicLibrary);
Preconditions.checkNotNull(dynamicModeParamsForExecutable);
Preconditions.checkNotNull(dynamicModeParamsForDynamicLibrary);
return new CcLinkingInfo(
staticModeParamsForExecutable,
staticModeParamsForDynamicLibrary,
dynamicModeParamsForExecutable,
dynamicModeParamsForDynamicLibrary);
}
}
@Override
public boolean equals(Object otherObject) {
if (!(otherObject instanceof CcLinkingInfo)) {
return false;
}
CcLinkingInfo other = (CcLinkingInfo) otherObject;
if (this == other) {
return true;
}
if (!this.staticModeParamsForExecutable.equals(other.staticModeParamsForExecutable)
|| !this.staticModeParamsForDynamicLibrary.equals(other.staticModeParamsForDynamicLibrary)
|| !this.dynamicModeParamsForExecutable.equals(other.dynamicModeParamsForExecutable)
|| !this.dynamicModeParamsForDynamicLibrary.equals(
other.dynamicModeParamsForDynamicLibrary)) {
return false;
}
return true;
}
@Override
public int hashCode() {
return Objects.hashCode(
staticModeParamsForExecutable,
staticModeParamsForDynamicLibrary,
dynamicModeParamsForExecutable,
dynamicModeParamsForDynamicLibrary);
}
}