From 1d1212a5c79f2164a66826633b0d35d59b0ec1e8 Mon Sep 17 00:00:00 2001 From: Cal Peyser Date: Thu, 17 Mar 2016 21:25:20 +0000 Subject: Introduce skylark provider for objc. -- MOS_MIGRATED_REVID=117485208 --- .../lib/rules/objc/BinaryLinkingTargetFactory.java | 5 +- .../devtools/build/lib/rules/objc/ObjcCommon.java | 2 +- .../devtools/build/lib/rules/objc/ObjcLibrary.java | 2 + .../build/lib/rules/objc/ObjcProvider.java | 149 ++++++++++++++++----- .../build/lib/syntax/SkylarkNestedSet.java | 2 +- 5 files changed, 121 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java index 433075199b..0b5b7ba848 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java @@ -163,7 +163,10 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory .addProvider(ObjcProvider.class, objcProvider) .addProvider( InstrumentedFilesProvider.class, - compilationSupport.getInstrumentedFilesProvider(common)); + compilationSupport.getInstrumentedFilesProvider(common)) + .addSkylarkTransitiveInfo( + ObjcProvider.OBJC_SKYLARK_PROVIDER_NAME, + common.getObjcProvider().toSkylarkProvider()); if (xcTestAppProvider.isPresent()) { // TODO(bazel-team): Stop exporting an XcTestAppProvider once objc_binary no longer creates an // application bundle. diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java index f48915012d..67c6ccbaff 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java @@ -91,6 +91,7 @@ import java.util.Set; // classes. Make sure to distinguish rule output (providers, runfiles, ...) from intermediate, // rule-internal information. Any provider created by a rule should not be read, only published. public final class ObjcCommon { + /** * Provides a way to access attributes that are common to all compilation rules. */ @@ -772,5 +773,4 @@ public final class ObjcCommon { } return errors; } - } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java index 6c9d26c9bc..9c03bf3053 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java @@ -142,6 +142,8 @@ public class ObjcLibrary implements RuleConfiguredTargetFactory { .addProvider( CcLinkParamsProvider.class, new CcLinkParamsProvider(new ObjcLibraryCcLinkParamsStore(common))) + .addSkylarkTransitiveInfo( + ObjcProvider.OBJC_SKYLARK_PROVIDER_NAME, common.getObjcProvider().toSkylarkProvider()) .build(); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java index ee95b6ebee..25e833104b 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java @@ -28,6 +28,8 @@ import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.rules.cpp.CppModuleMap; import com.google.devtools.build.lib.rules.cpp.LinkerInputs; +import com.google.devtools.build.lib.syntax.ClassObject.SkylarkClassObject; +import com.google.devtools.build.lib.syntax.SkylarkNestedSet; import com.google.devtools.build.lib.util.Preconditions; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.TargetControl; @@ -41,31 +43,71 @@ import java.util.Map; */ @Immutable public final class ObjcProvider implements TransitiveInfoProvider { + + /** + * The name skylark dependents can use to access a Skylark provider containing information + * from a target's ObjcProvider. + */ + public static final String OBJC_SKYLARK_PROVIDER_NAME = "objc"; + /** * Represents one of the things this provider can provide transitively. Things are provided as * {@link NestedSet}s of type E. */ public static class Key { private final Order order; + private final String skylarkKeyName; + private final Class type; - private Key(Order order) { + private Key(Order order, String skylarkKeyName, Class type) { this.order = Preconditions.checkNotNull(order); + this.skylarkKeyName = skylarkKeyName; + this.type = type; + } + + /** + * Returns the name of the collection represented by this key in the Skylark provider. + */ + public String getSkylarkKeyName() { + return skylarkKeyName; } + + /** + * Returns the type of nested set keyed in the ObjcProvider by this key. + */ + public Class getType() { + return type; + } + } + + /** + * All keys in ObjcProvider that will be passed in the corresponding Skylark provider. + */ + // Only keys for Artifact or primitive types can be in the Skylark provider, as other types + // are not supported as Skylark types. + private ImmutableList> keysForSkylark() { + return ImmutableList.>of(LIBRARY, IMPORTED_LIBRARY, LINKED_BINARY, FORCE_LOAD_LIBRARY, + FORCE_LOAD_FOR_XCODEGEN, HEADER, SOURCE, DEFINE, ASSET_CATALOG, GENERAL_RESOURCE_FILE, + SDK_DYLIB, XCDATAMODEL, MODULE_MAP, MERGE_ZIP, FRAMEWORK_FILE, DEBUG_SYMBOLS, + BREAKPAD_FILE, STORYBOARD, XIB, STRINGS, LINKOPT, J2OBJC_LIBRARY); } - public static final Key LIBRARY = new Key<>(LINK_ORDER); - public static final Key IMPORTED_LIBRARY = new Key<>(LINK_ORDER); + public static final Key LIBRARY = new Key<>(LINK_ORDER, "library", Artifact.class); + public static final Key IMPORTED_LIBRARY = + new Key<>(LINK_ORDER, "imported_library", Artifact.class); /** * Single-architecture linked binaries to be combined for the final multi-architecture binary. */ - public static final Key LINKED_BINARY = new Key<>(STABLE_ORDER); + public static final Key LINKED_BINARY = + new Key<>(STABLE_ORDER, "linked_binary", Artifact.class); /** * Indicates which libraries to load with {@code -force_load}. This is a subset of the union of * the {@link #LIBRARY} and {@link #IMPORTED_LIBRARY} sets. */ - public static final Key FORCE_LOAD_LIBRARY = new Key<>(LINK_ORDER); + public static final Key FORCE_LOAD_LIBRARY = + new Key<>(LINK_ORDER, "force_load_library", Artifact.class); /** * Libraries to pass with -force_load flags when setting the linkopts in Xcodegen. This is needed @@ -75,73 +117,86 @@ public final class ObjcProvider implements TransitiveInfoProvider { * {@code BUILT_PRODUCTS_DIR} while those not built by Xcode appear somewhere in the Bazel * workspace under {@code WORKSPACE_ROOT}. */ - public static final Key FORCE_LOAD_FOR_XCODEGEN = new Key<>(LINK_ORDER); + public static final Key FORCE_LOAD_FOR_XCODEGEN = + new Key<>(LINK_ORDER, "force_load_for_xcodegen", String.class); /** * Contains all header files. These may be either public or private headers. */ - public static final Key HEADER = new Key<>(STABLE_ORDER); + public static final Key HEADER = new Key<>(STABLE_ORDER, "header", Artifact.class); /** * Contains all source files. */ - public static final Key SOURCE = new Key<>(STABLE_ORDER); + public static final Key SOURCE = new Key<>(STABLE_ORDER, "source", Artifact.class); /** * Include search paths specified with {@code -I} on the command line. Also known as header search * paths (and distinct from user header search paths). */ - public static final Key INCLUDE = new Key<>(LINK_ORDER); + public static final Key INCLUDE = + new Key<>(LINK_ORDER, "include", PathFragment.class); /** * Include search paths specified with {@code -isystem} on the command line. */ - public static final Key INCLUDE_SYSTEM = new Key<>(LINK_ORDER); + public static final Key INCLUDE_SYSTEM = + new Key<>(LINK_ORDER, "include_system", PathFragment.class); /** * Key for values in {@code defines} attributes. These are passed as {@code -D} flags to all * invocations of the compiler for this target and all depending targets. */ - public static final Key DEFINE = new Key<>(STABLE_ORDER); + public static final Key DEFINE = new Key<>(STABLE_ORDER, "define", String.class); - public static final Key ASSET_CATALOG = new Key<>(STABLE_ORDER); + public static final Key ASSET_CATALOG = + new Key<>(STABLE_ORDER, "asset_catalog", Artifact.class); /** * Added to {@link TargetControl#getGeneralResourceFileList()} when running Xcodegen. */ - public static final Key GENERAL_RESOURCE_FILE = new Key<>(STABLE_ORDER); + public static final Key GENERAL_RESOURCE_FILE = + new Key<>(STABLE_ORDER, "general_resource_file", Artifact.class); /** * Resource directories added to {@link TargetControl#getGeneralResourceFileList()} when running * Xcodegen. When copying files inside resource directories to the app bundle, XCode will preserve * the directory structures of the copied files. */ - public static final Key GENERAL_RESOURCE_DIR = new Key<>(STABLE_ORDER); + public static final Key GENERAL_RESOURCE_DIR = + new Key<>(STABLE_ORDER, "general_resource_dir", PathFragment.class); /** * Exec paths of {@code .bundle} directories corresponding to imported bundles to link. * These are passed to Xcodegen. */ - public static final Key BUNDLE_IMPORT_DIR = new Key<>(STABLE_ORDER); + public static final Key BUNDLE_IMPORT_DIR = + new Key<>(STABLE_ORDER, "bundle_import_dir", PathFragment.class); /** * Files that are plopped into the final bundle at some arbitrary bundle path. Note that these are * not passed to Xcodegen, and these don't include information about where the file originated * from. */ - public static final Key BUNDLE_FILE = new Key<>(STABLE_ORDER); + public static final Key BUNDLE_FILE = + new Key<>(STABLE_ORDER, "bundle_file", BundleableFile.class); - public static final Key XCASSETS_DIR = new Key<>(STABLE_ORDER); - public static final Key SDK_DYLIB = new Key<>(STABLE_ORDER); - public static final Key SDK_FRAMEWORK = new Key<>(STABLE_ORDER); - public static final Key WEAK_SDK_FRAMEWORK = new Key<>(STABLE_ORDER); - public static final Key XCDATAMODEL = new Key<>(STABLE_ORDER); - public static final Key FLAG = new Key<>(STABLE_ORDER); + public static final Key XCASSETS_DIR = + new Key<>(STABLE_ORDER, "xcassets_dir", PathFragment.class); + public static final Key SDK_DYLIB = new Key<>(STABLE_ORDER, "sdk_dylib", String.class); + public static final Key SDK_FRAMEWORK = + new Key<>(STABLE_ORDER, "sdk_framework", SdkFramework.class); + public static final Key WEAK_SDK_FRAMEWORK = + new Key<>(STABLE_ORDER, "weak_sdk_framework", SdkFramework.class); + public static final Key XCDATAMODEL = + new Key<>(STABLE_ORDER, "xcdatamodel", Artifact.class); + public static final Key FLAG = new Key<>(STABLE_ORDER, "flag", Flag.class); /** * Clang module maps, used to enforce proper use of private header files. */ - public static final Key MODULE_MAP = new Key<>(STABLE_ORDER); + public static final Key MODULE_MAP = + new Key<>(STABLE_ORDER, "module_map", Artifact.class); /** * Information about this provider's module map, in the form of a {@link CppModuleMap}. This @@ -149,73 +204,83 @@ public final class ObjcProvider implements TransitiveInfoProvider { * get the module maps for direct but not transitive dependencies. You should only add module maps * for this key using {@link Builder#addWithoutPropagating}. */ - public static final Key TOP_LEVEL_MODULE_MAP = new Key<>(STABLE_ORDER); + public static final Key TOP_LEVEL_MODULE_MAP = + new Key<>(STABLE_ORDER, "top_level_module_map", CppModuleMap.class); /** * Merge zips to include in the bundle. The entries of these zip files are included in the final * bundle with the same path. The entries in the merge zips should not include the bundle root * path (e.g. {@code Foo.app}). */ - public static final Key MERGE_ZIP = new Key<>(STABLE_ORDER); + public static final Key MERGE_ZIP = + new Key<>(STABLE_ORDER, "merge_zip", Artifact.class); /** * Exec paths of {@code .framework} directories corresponding to frameworks to link. These cause * -F arguments (framework search paths) to be added to each compile action, and -framework (link * framework) arguments to be added to each link action. */ - public static final Key FRAMEWORK_DIR = new Key<>(LINK_ORDER); + public static final Key FRAMEWORK_DIR = + new Key<>(LINK_ORDER, "framework_dir", PathFragment.class); /** * Files in {@code .framework} directories that should be included as inputs when compiling and * linking. */ - public static final Key FRAMEWORK_FILE = new Key<>(STABLE_ORDER); + public static final Key FRAMEWORK_FILE = + new Key<>(STABLE_ORDER, "framework_file", Artifact.class); /** * Bundles which should be linked in as a nested bundle to the final application. */ - public static final Key NESTED_BUNDLE = new Key<>(STABLE_ORDER); + public static final Key NESTED_BUNDLE = + new Key<>(STABLE_ORDER, "nested_bundle", Bundling.class); /** * Artifact containing information on debug symbols. */ - public static final Key DEBUG_SYMBOLS = new Key<>(STABLE_ORDER); + public static final Key DEBUG_SYMBOLS = + new Key<>(STABLE_ORDER, "debug_symbols", Artifact.class); /** * Generated breakpad file containing debug information used by the breakpad crash reporting * system. */ - public static final Key BREAKPAD_FILE = new Key<>(STABLE_ORDER); + public static final Key BREAKPAD_FILE = + new Key<>(STABLE_ORDER, "breakpad_file", Artifact.class); /** * Artifacts for storyboard sources. */ - public static final Key STORYBOARD = new Key<>(STABLE_ORDER); + public static final Key STORYBOARD = + new Key<>(STABLE_ORDER, "storyboard", Artifact.class); /** * Artifacts for .xib file sources. */ - public static final Key XIB = new Key<>(STABLE_ORDER); + public static final Key XIB = new Key<>(STABLE_ORDER, "xib", Artifact.class); /** * Artifacts for strings source files. */ - public static final Key STRINGS = new Key<>(STABLE_ORDER); + public static final Key STRINGS = new Key<>(STABLE_ORDER, "strings", Artifact.class); /** * Linking information from cc dependencies. */ - public static final Key CC_LIBRARY = new Key<>(LINK_ORDER); + public static final Key CC_LIBRARY = + new Key<>(LINK_ORDER, "cc_library", LinkerInputs.LibraryToLink.class); /** * Linking options from dependencies. */ - public static final Key LINKOPT = new Key<>(LINK_ORDER); + public static final Key LINKOPT = new Key<>(LINK_ORDER, "linkopt", String.class); /** * Static libraries that are built from J2ObjC-translated Java code. */ - public static final Key J2OBJC_LIBRARY = new Key<>(LINK_ORDER); + public static final Key J2OBJC_LIBRARY = + new Key<>(LINK_ORDER, "j2objc_library", Artifact.class); /** * Flags that apply to a transitive build dependency tree. Each item in the enum corresponds to a @@ -284,6 +349,18 @@ public final class ObjcProvider implements TransitiveInfoProvider { return !get(XCASSETS_DIR).isEmpty(); } + /** + * Returns a {@code SkylarkClassObject} containing values from this provider that is suitable + * for a skylark provider. + */ + public SkylarkClassObject toSkylarkProvider() { + ImmutableMap.Builder providerBuilder = ImmutableMap.builder(); + for (Key key : keysForSkylark()) { + providerBuilder.put(key.getSkylarkKeyName(), new SkylarkNestedSet(key.getType(), get(key))); + } + return new SkylarkClassObject(providerBuilder.build(), "No such attribute '%s'"); + } + /** * A builder for this context with an API that is optimized for collecting information from * several transitive dependencies. diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java index f3e8c59df2..25ef2865e7 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java @@ -176,7 +176,7 @@ public final class SkylarkNestedSet implements Iterable, SkylarkValue { * A not type safe constructor for SkylarkNestedSet, specifying type as a Java class. * It's discouraged to use it unless type generic safety is guaranteed from the caller side. */ - SkylarkNestedSet(Class contentType, NestedSet set) { + public SkylarkNestedSet(Class contentType, NestedSet set) { this(SkylarkType.of(contentType), set); } -- cgit v1.2.3