// 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.skylarkbuildapi.cpp.CcCompilationOutputsApi; import com.google.devtools.build.lib.syntax.SkylarkList; import java.util.LinkedHashSet; 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 objectFiles; /** * All .pic.o files built by the target. */ private final ImmutableList 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 ltoBitcodeFiles; /** * All .dwo files built by the target, corresponding to .o outputs. */ private final ImmutableList dwoFiles; /** * All .pic.dwo files built by the target, corresponding to .pic.o outputs. */ private final ImmutableList picDwoFiles; /** * All artifacts that are created if "--save_temps" is true. */ private final NestedSet temps; /** * All token .h.processed files created when preprocessing or parsing headers. */ private final ImmutableList headerTokenFiles; private CcCompilationOutputs( ImmutableList objectFiles, ImmutableList picObjectFiles, ImmutableMap ltoBitcodeFiles, ImmutableList dwoFiles, ImmutableList picDwoFiles, NestedSet temps, ImmutableList headerTokenFiles) { this.objectFiles = objectFiles; this.picObjectFiles = picObjectFiles; this.ltoBitcodeFiles = ltoBitcodeFiles; this.dwoFiles = dwoFiles; this.picDwoFiles = picDwoFiles; this.temps = temps; this.headerTokenFiles = headerTokenFiles; } /** * 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 getObjectFiles(boolean usePic) { return usePic ? picObjectFiles : objectFiles; } @Override public SkylarkList getSkylarkObjectFiles(boolean usePic) { return SkylarkList.createImmutable(getObjectFiles(usePic)); } /** Returns unmodifiable map of bitcode object files resulting from compilation. */ public ImmutableMap getLtoBitcodeFiles() { return ltoBitcodeFiles; } /** * Returns an unmodifiable view of the .dwo files set. */ public ImmutableList getDwoFiles() { return dwoFiles; } /** * Returns an unmodifiable view of the .pic.dwo files set. */ public ImmutableList getPicDwoFiles() { return picDwoFiles; } /** * Returns an unmodifiable view of the temp files set. */ public NestedSet getTemps() { return temps; } /** * Returns an unmodifiable view of the .h.processed files. */ public Iterable getHeaderTokenFiles() { return headerTokenFiles; } /** Returns the output files that are considered "compiled" by this C++ compile action. */ NestedSet getFilesToCompile(boolean parseHeaders, boolean usePic) { NestedSetBuilder 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 objectFiles = new LinkedHashSet<>(); private final Set picObjectFiles = new LinkedHashSet<>(); private final ImmutableMap.Builder ltoBitcodeFiles = ImmutableMap.builder(); private final Set dwoFiles = new LinkedHashSet<>(); private final Set picDwoFiles = new LinkedHashSet<>(); private final NestedSetBuilder temps = NestedSetBuilder.stableOrder(); private final Set headerTokenFiles = new LinkedHashSet<>(); 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)); } 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.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 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 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 artifacts) { temps.addAll(artifacts); return this; } public Builder addHeaderTokenFile(Artifact artifact) { headerTokenFiles.add(artifact); return this; } } }