blob: fcaae5ecd30b657e9d5d0390e4bbb5f685ba1a17 [file] [log] [blame]
// Copyright 2015 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.objc;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.rules.cpp.LibraryToLink;
import javax.annotation.Nullable;
import net.starlark.java.eval.StarlarkValue;
/**
* Support for rules that compile sources. Provides ways to determine files that should be output,
* registering Xcode settings and generating the various actions that might be needed for
* compilation.
*
* <p>A subclass should express a particular strategy for compile and link action registration.
* Subclasses should implement the API without adding new visible methods - rule implementations
* should be able to use a {@link CompilationSupport} instance to compile and link source without
* knowing the subclass being used.
*
* <p>Methods on this class can be called in any order without impacting the result.
*/
public class CompilationSupport implements StarlarkValue {
@VisibleForTesting static final String OBJC_MODULE_CACHE_DIR_NAME = "_objc_module_cache";
@VisibleForTesting
static final String ABSOLUTE_INCLUDES_PATH_FORMAT =
"The path '%s' is absolute, but only relative paths are allowed.";
// These are added by Xcode when building, because the simulator is built on OSX
// frameworks so we aim compile to match the OSX objc runtime.
@VisibleForTesting
static final ImmutableList<String> SIMULATOR_COMPILE_FLAGS =
ImmutableList.of(
"-fexceptions", "-fasm-blocks", "-fobjc-abi-version=2", "-fobjc-legacy-dispatch");
@VisibleForTesting
static final String FILE_IN_SRCS_AND_HDRS_WARNING_FORMAT = "File '%s' is in both srcs and hdrs.";
@VisibleForTesting
static final String FILE_IN_SRCS_AND_NON_ARC_SRCS_ERROR_FORMAT =
"File '%s' is present in both srcs and non_arc_srcs which is forbidden.";
@VisibleForTesting
static final String BOTH_MODULE_NAME_AND_MODULE_MAP_SPECIFIED =
"Specifying both module_name and module_map is invalid, please remove one of them.";
static final ImmutableList<String> DEFAULT_COMPILER_FLAGS = ImmutableList.of("-DOS_IOS");
/** Returns information about the given rule's compilation artifacts. */
// TODO(bazel-team): Remove this information from ObjcCommon and move it internal to this class.
static CompilationArtifacts compilationArtifacts(RuleContext ruleContext) {
return compilationArtifacts(ruleContext, new IntermediateArtifacts(ruleContext));
}
/**
* Returns information about the given rule's compilation artifacts. Dependencies specified in the
* current rule's attributes are obtained via {@code ruleContext}. Output locations are determined
* using the given {@code intermediateArtifacts} object. The fact that these are distinct objects
* allows the caller to generate compilation actions pertaining to a configuration separate from
* the current rule's configuration.
*/
static CompilationArtifacts compilationArtifacts(
RuleContext ruleContext, IntermediateArtifacts intermediateArtifacts) {
return new CompilationArtifacts(ruleContext, intermediateArtifacts);
}
private CompilationSupport() {}
/**
* Returns the preferred static library for linking, or {@code null} if there is no static
* library.
*
* @param library the input library.
*/
@Nullable
public static Artifact getStaticLibraryForLinking(LibraryToLink library) {
if (library.getStaticLibrary() != null) {
return library.getStaticLibrary();
} else if (library.getPicStaticLibrary() != null) {
return library.getPicStaticLibrary();
} else {
return null;
}
}
/**
* Returns the preferred variant of the library for linking.
*
* @param library the input library.
*/
public static Artifact getLibraryForLinking(LibraryToLink library) {
if (library.getStaticLibrary() != null) {
return library.getStaticLibrary();
} else if (library.getPicStaticLibrary() != null) {
return library.getPicStaticLibrary();
} else if (library.getInterfaceLibrary() != null) {
return library.getInterfaceLibrary();
} else {
return library.getDynamicLibrary();
}
}
public static Optional<Artifact> getCustomModuleMap(RuleContext ruleContext) {
if (ruleContext.attributes().has("module_map", BuildType.LABEL)) {
return Optional.fromNullable(ruleContext.getPrerequisiteArtifact("module_map"));
}
return Optional.absent();
}
}