// Copyright 2016 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.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.packages.Info;
import com.google.devtools.build.lib.packages.Provider;
import com.google.devtools.build.lib.rules.apple.ApplePlatform;
import com.google.devtools.build.lib.rules.apple.ApplePlatform.PlatformType;
import com.google.devtools.build.lib.rules.apple.AppleToolchain;
import com.google.devtools.build.lib.rules.apple.DottedVersion;
import com.google.devtools.build.lib.rules.apple.XcodeConfigProvider;
import com.google.devtools.build.lib.rules.apple.XcodeVersionProperties;
import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import com.google.devtools.build.lib.syntax.BuiltinFunction;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Map.Entry;
import javax.annotation.Nullable;
/**
* A class that exposes apple rule implementation internals to skylark.
*/
@SkylarkModule(
name = "apple_common",
doc = "Functions for skylark to access internals of the apple rule implementations."
)
public class AppleSkylarkCommon {
@VisibleForTesting
public static final String BAD_KEY_ERROR = "Argument %s not a recognized key, 'providers',"
+ " or 'direct_dep_providers'.";
@VisibleForTesting
public static final String BAD_SET_TYPE_ERROR =
"Value for key %s must be a set of %s, instead found set of %s.";
@VisibleForTesting
public static final String BAD_PROVIDERS_ITER_ERROR =
"Value for argument 'providers' must be a list of ObjcProvider instances, instead found %s.";
@VisibleForTesting
public static final String BAD_PROVIDERS_ELEM_ERROR =
"Value for argument 'providers' must be a list of ObjcProvider instances, instead found "
+ "iterable with %s.";
@VisibleForTesting
public static final String NOT_SET_ERROR = "Value for key %s must be a set, instead found %s.";
@VisibleForTesting
public static final String MISSING_KEY_ERROR = "No value for required key %s was present.";
@Nullable private Info platformType;
@Nullable private Info platform;
@SkylarkCallable(
name = "apple_toolchain",
doc = "Utilities for resolving items from the apple toolchain."
)
public AppleToolchain getAppleToolchain() {
return new AppleToolchain();
}
@SkylarkCallable(
name = "platform_type",
doc =
"An enum-like struct that contains the following fields corresponding to Apple platform "
+ "types:
ios
macos
tvos
watchos
" + "These values can be passed to methods that expect a platform type, like the 'apple' " + "configuration fragment's " + "multi_arch_platform method.
" + "Example:
" + "
\n" + "ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.ios)\n" + "", structField = true ) public Info getPlatformTypeStruct() { if (platformType == null) { platformType = PlatformType.getSkylarkStruct(); } return platformType; } @SkylarkCallable( name = "platform", doc = "An enum-like struct that contains the following fields corresponding to Apple " + "platforms:
ios_device
ios_simulator
macos
tvos_device
tvos_simulator
watchos_device
watchos_device
"
+ "These values can be passed to methods that expect a platform, like "
+ "apple.sdk_version_for_platform.",
structField = true
)
public Info getPlatformStruct() {
if (platform == null) {
platform = ApplePlatform.getSkylarkStruct();
}
return platform;
}
@SkylarkCallable(
name = XcodeVersionProperties.SKYLARK_NAME,
doc =
"The constructor/key for the XcodeVersionProperties
provider.
"
+ "If a target propagates the XcodeVersionProperties
provider,"
+ " use this as the key with which to retrieve it. Example:
"
+ "
\n" + "dep = ctx.attr.deps[0]\n" + "p = dep[apple_common.XcodeVersionProperties]\n" + "", structField = true ) public Provider getXcodeVersionPropertiesConstructor() { return XcodeVersionProperties.SKYLARK_CONSTRUCTOR; } @SkylarkCallable( name = XcodeConfigProvider.SKYLARK_NAME, doc = "The constructor/key for the
XcodeVersionConfig
provider.",
structField = true
)
public Provider getXcodeVersionConfigConstructor() {
return XcodeConfigProvider.PROVIDER;
}
@SkylarkCallable(
// TODO(b/63899207): This currently does not match ObjcProvider.SKYLARK_NAME as it requires
// a migration of existing skylark rules.
name = "Objc",
doc =
"The constructor/key for the Objc
provider."
+ "If a target propagates the Objc
provider, use this as the "
+ "key with which to retrieve it. Example:
"
+ "
\n" + "dep = ctx.attr.deps[0]\n" + "p = dep[apple_common.Objc]\n" + "", structField = true ) public Provider getObjcProviderConstructor() { return ObjcProvider.SKYLARK_CONSTRUCTOR; } @SkylarkCallable( name = AppleDynamicFrameworkProvider.SKYLARK_NAME, doc = "The constructor/key for the
AppleDynamicFramework
provider."
+ "If a target propagates the AppleDynamicFramework
provider, use this "
+ "as the key with which to retrieve it. Example:
"
+ "
\n" + "dep = ctx.attr.deps[0]\n" + "p = dep[apple_common.AppleDynamicFramework]\n" + "", structField = true ) public Provider getAppleDynamicFrameworkConstructor() { return AppleDynamicFrameworkProvider.SKYLARK_CONSTRUCTOR; } @SkylarkCallable( name = AppleDylibBinaryProvider.SKYLARK_NAME, doc = "The constructor/key for the
AppleDylibBinary
provider."
+ "If a target propagates the AppleDylibBinary
provider, use this as the "
+ "key with which to retrieve it. Example:
"
+ "
\n" + "dep = ctx.attr.deps[0]\n" + "p = dep[apple_common.AppleDylibBinary]\n" + "", structField = true ) public Provider getAppleDylibBinaryConstructor() { return AppleDylibBinaryProvider.SKYLARK_CONSTRUCTOR; } @SkylarkCallable( name = AppleExecutableBinaryProvider.SKYLARK_NAME, doc = "The constructor/key for the
AppleExecutableBinary
provider."
+ "If a target propagates the AppleExecutableBinary
provider,"
+ " use this as the key with which to retrieve it. Example:
"
+ "
\n" + "dep = ctx.attr.deps[0]\n" + "p = dep[apple_common.AppleExecutableBinary]\n" + "", structField = true ) public Provider getAppleExecutableBinaryConstructor() { return AppleExecutableBinaryProvider.SKYLARK_CONSTRUCTOR; } @SkylarkCallable( name = AppleStaticLibraryProvider.SKYLARK_NAME, doc = "The constructor/key for the
AppleStaticLibrary
provider."
+ "If a target propagates the AppleStaticLibrary
provider, use "
+ "this as the key with which to retrieve it. Example:
"
+ "
\n" + "dep = ctx.attr.deps[0]\n" + "p = dep[apple_common.AppleStaticLibrary]\n" + "", structField = true ) public Provider getAppleStaticLibraryProvider() { return AppleStaticLibraryProvider.SKYLARK_CONSTRUCTOR; } @SkylarkCallable( name = AppleDebugOutputsProvider.SKYLARK_NAME, doc = "The constructor/key for the
AppleDebugOutputs
provider."
+ "If a target propagates the AppleDebugOutputs
provider, use this as the "
+ "key with which to retrieve it. Example:
"
+ "
\n" + "dep = ctx.attr.deps[0]\n" + "p = dep[apple_common.AppleDebugOutputs]\n" + "", structField = true ) public Provider getAppleDebugOutputsConstructor() { return AppleDebugOutputsProvider.SKYLARK_CONSTRUCTOR; } @SkylarkCallable( name = AppleLoadableBundleBinaryProvider.SKYLARK_NAME, doc = "The constructor/key for the
AppleLoadableBundleBinary
provider."
+ "If a target propagates the AppleLoadableBundleBinary
provider, "
+ "use this as the key with which to retrieve it. Example:
"
+ "
\n" + "dep = ctx.attr.deps[0]\n" + "p = dep[apple_common.AppleLoadableBundleBinary]\n" + "", structField = true ) public Provider getAppleLoadableBundleBinaryConstructor() { return AppleLoadableBundleBinaryProvider.SKYLARK_CONSTRUCTOR; } @SkylarkCallable( name = IosDeviceProvider.SKYLARK_NAME, doc = "Deprecated. Use the new Skylark testing rules instead. Returns the provider " + "constructor for IosDeviceProvider. Use this as a key to access the attributes " + "exposed by ios_device.", structField = true ) public Provider getIosDeviceProviderConstructor() { return IosDeviceProvider.SKYLARK_CONSTRUCTOR; } @SkylarkSignature( name = "new_objc_provider", objectType = AppleSkylarkCommon.class, returnType = ObjcProvider.class, doc = "Creates a new ObjcProvider instance.", parameters = { @Param(name = "self", type = AppleSkylarkCommon.class, doc = "The apple_common instance."), @Param( name = "uses_swift", type = Boolean.class, defaultValue = "False", named = true, positional = false, doc = "Whether this provider should enable Swift support." ) }, extraKeywords = @Param( name = "kwargs", type = SkylarkDict.class, defaultValue = "{}", doc = "Dictionary of arguments." ) ) public static final BuiltinFunction NEW_OBJC_PROVIDER = new BuiltinFunction("new_objc_provider") { @SuppressWarnings("unused") // This method is registered statically for skylark, and never called directly. public ObjcProvider invoke( AppleSkylarkCommon self, Boolean usesSwift, SkylarkDict