blob: f70633a6aa557fab8d0aabb546bd348d7743236e [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.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcCompilationOutputsApi;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/** A structured representation of the compilation outputs of a C++ rule. */
public class CcCompilationOutputs implements CcCompilationOutputsApi {
/**
* All .o files built by the target.
*/
private final ImmutableList<Artifact> objectFiles;
/**
* All .pic.o files built by the target.
*/
private final ImmutableList<Artifact> picObjectFiles;
/**
* Maps all .o bitcode files coming from a ThinLTO C(++) compilation under our control to the
* corresponding minimized bitcode files that can be used for the LTO indexing step.
*/
private final ImmutableMap<Artifact, Artifact> ltoBitcodeFiles;
/**
* All .dwo files built by the target, corresponding to .o outputs.
*/
private final ImmutableList<Artifact> dwoFiles;
/**
* All .pic.dwo files built by the target, corresponding to .pic.o outputs.
*/
private final ImmutableList<Artifact> picDwoFiles;
/**
* All artifacts that are created if "--save_temps" is true.
*/
private final NestedSet<Artifact> temps;
/**
* All token .h.processed files created when preprocessing or parsing headers.
*/
private final ImmutableList<Artifact> headerTokenFiles;
private final List<IncludeScannable> lipoScannables;
private CcCompilationOutputs(
ImmutableList<Artifact> objectFiles,
ImmutableList<Artifact> picObjectFiles,
ImmutableMap<Artifact, Artifact> ltoBitcodeFiles,
ImmutableList<Artifact> dwoFiles,
ImmutableList<Artifact> picDwoFiles,
NestedSet<Artifact> temps,
ImmutableList<Artifact> headerTokenFiles,
ImmutableList<IncludeScannable> lipoScannables) {
this.objectFiles = objectFiles;
this.picObjectFiles = picObjectFiles;
this.ltoBitcodeFiles = ltoBitcodeFiles;
this.dwoFiles = dwoFiles;
this.picDwoFiles = picDwoFiles;
this.temps = temps;
this.headerTokenFiles = headerTokenFiles;
this.lipoScannables = lipoScannables;
}
/**
* Returns whether this set of outputs has any object or .pic object files.
*/
public boolean isEmpty() {
return picObjectFiles.isEmpty() && objectFiles.isEmpty();
}
/**
* Returns an unmodifiable view of the .o or .pic.o files set.
*
* @param usePic whether to return .pic.o files
*/
public ImmutableList<Artifact> getObjectFiles(boolean usePic) {
return usePic ? picObjectFiles : objectFiles;
}
/** Returns unmodifiable map of bitcode object files resulting from compilation. */
public ImmutableMap<Artifact, Artifact> getLtoBitcodeFiles() {
return ltoBitcodeFiles;
}
/**
* Returns an unmodifiable view of the .dwo files set.
*/
public ImmutableList<Artifact> getDwoFiles() {
return dwoFiles;
}
/**
* Returns an unmodifiable view of the .pic.dwo files set.
*/
public ImmutableList<Artifact> getPicDwoFiles() {
return picDwoFiles;
}
/**
* Returns an unmodifiable view of the temp files set.
*/
public NestedSet<Artifact> getTemps() {
return temps;
}
/**
* Returns an unmodifiable view of the .h.processed files.
*/
public Iterable<Artifact> getHeaderTokenFiles() {
return headerTokenFiles;
}
/**
* Returns the {@link IncludeScannable} objects this C++ compile action contributes to a
* LIPO context collector.
*/
public List<IncludeScannable> getLipoScannables() {
return lipoScannables;
}
/**
* Returns the output files that are considered "compiled" by this C++ compile action.
*/
NestedSet<Artifact> getFilesToCompile(
boolean isLipoContextCollector, boolean parseHeaders, boolean usePic) {
if (isLipoContextCollector) {
return NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER);
}
NestedSetBuilder<Artifact> files = NestedSetBuilder.stableOrder();
files.addAll(getObjectFiles(usePic));
if (parseHeaders) {
files.addAll(getHeaderTokenFiles());
}
return files.build();
}
/** Builder for CcCompilationOutputs. */
public static final class Builder {
private final Set<Artifact> objectFiles = new LinkedHashSet<>();
private final Set<Artifact> picObjectFiles = new LinkedHashSet<>();
private final ImmutableMap.Builder<Artifact, Artifact> ltoBitcodeFiles = ImmutableMap.builder();
private final Set<Artifact> dwoFiles = new LinkedHashSet<>();
private final Set<Artifact> picDwoFiles = new LinkedHashSet<>();
private final NestedSetBuilder<Artifact> temps = NestedSetBuilder.stableOrder();
private final Set<Artifact> headerTokenFiles = new LinkedHashSet<>();
private final List<IncludeScannable> lipoScannables = new ArrayList<>();
public CcCompilationOutputs build() {
return new CcCompilationOutputs(
ImmutableList.copyOf(objectFiles),
ImmutableList.copyOf(picObjectFiles),
ltoBitcodeFiles.build(),
ImmutableList.copyOf(dwoFiles),
ImmutableList.copyOf(picDwoFiles),
temps.build(),
ImmutableList.copyOf(headerTokenFiles),
ImmutableList.copyOf(lipoScannables));
}
public Builder merge(CcCompilationOutputs outputs) {
this.objectFiles.addAll(outputs.objectFiles);
this.picObjectFiles.addAll(outputs.picObjectFiles);
this.dwoFiles.addAll(outputs.dwoFiles);
this.picDwoFiles.addAll(outputs.picDwoFiles);
this.temps.addTransitive(outputs.temps);
this.headerTokenFiles.addAll(outputs.headerTokenFiles);
this.lipoScannables.addAll(outputs.lipoScannables);
this.ltoBitcodeFiles.putAll(outputs.ltoBitcodeFiles);
return this;
}
/** Adds an object file. */
public Builder addObjectFile(Artifact artifact) {
// We skip file extension checks for TreeArtifacts because they represent directory artifacts
// without a file extension.
Preconditions.checkArgument(
artifact.isTreeArtifact() || Link.OBJECT_FILETYPES.matches(artifact.getFilename()));
objectFiles.add(artifact);
return this;
}
public Builder addObjectFiles(Iterable<Artifact> artifacts) {
for (Artifact artifact : artifacts) {
Preconditions.checkArgument(Link.OBJECT_FILETYPES.matches(artifact.getFilename()));
}
Iterables.addAll(objectFiles, artifacts);
return this;
}
/** Adds a pic object file. */
public Builder addPicObjectFile(Artifact artifact) {
picObjectFiles.add(artifact);
return this;
}
public Builder addLtoBitcodeFile(Artifact fullBitcode, Artifact ltoIndexingBitcode) {
ltoBitcodeFiles.put(fullBitcode, ltoIndexingBitcode);
return this;
}
public Builder addPicObjectFiles(Iterable<Artifact> artifacts) {
for (Artifact artifact : artifacts) {
Preconditions.checkArgument(Link.OBJECT_FILETYPES.matches(artifact.getFilename()));
}
Iterables.addAll(picObjectFiles, artifacts);
return this;
}
public Builder addDwoFile(Artifact artifact) {
dwoFiles.add(artifact);
return this;
}
public Builder addPicDwoFile(Artifact artifact) {
picDwoFiles.add(artifact);
return this;
}
/**
* Adds temp files.
*/
public Builder addTemps(Iterable<Artifact> artifacts) {
temps.addAll(artifacts);
return this;
}
public Builder addHeaderTokenFile(Artifact artifact) {
headerTokenFiles.add(artifact);
return this;
}
/**
* Adds an {@link IncludeScannable} that this compilation output object contributes to a
* LIPO context collector.
*/
public Builder addLipoScannable(IncludeScannable scannable) {
lipoScannables.add(scannable);
return this;
}
}
}