diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java index da5f6e36f0a8bd..4c5d7e73462009 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java @@ -265,4 +265,19 @@ public class ObjcCommandLineOptions extends FragmentOptions { + "configuration." ) public Label appleSdk; + + @Option( + name = "incompatible_objc_compile_info_migration", + defaultValue = "false", + documentationCategory = OptionDocumentationCategory.TOOLCHAIN, + effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS, OptionEffectTag.CHANGES_INPUTS}, + metadataTags = { + OptionMetadataTag.INCOMPATIBLE_CHANGE, + OptionMetadataTag.TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES, + }, + help = + "If true, native rules can assume compile info has been migrated to CcInfo. See " + + "https://github.com/bazelbuild/bazel/issues/10854 for details and migration " + + "instructions") + public boolean incompatibleObjcCompileInfoMigration; } 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 258712b82acacf..c496cf1545cfee 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 @@ -38,6 +38,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; +import com.google.common.collect.Streams; import com.google.common.collect.UnmodifiableIterator; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.ConfiguredTarget; @@ -99,6 +100,7 @@ public enum Purpose { } static class Builder { + private final boolean compileInfoMigration; private final Purpose purpose; private final RuleContext context; private final StarlarkSemantics semantics; @@ -115,6 +117,7 @@ static class Builder { private Optional linkedBinary = Optional.absent(); private Iterable depCcHeaderProviders = ImmutableList.of(); private Iterable depCcLinkProviders = ImmutableList.of(); + private Iterable depCcDirectProviders = ImmutableList.of(); /** * Builder for {@link ObjcCommon} obtaining both attribute data and configuration data from the @@ -135,6 +138,10 @@ static class Builder { this.context = Preconditions.checkNotNull(context); this.semantics = context.getAnalysisEnvironment().getSkylarkSemantics(); this.buildConfiguration = Preconditions.checkNotNull(buildConfiguration); + + ObjcConfiguration objcConfiguration = buildConfiguration.getFragment(ObjcConfiguration.class); + + this.compileInfoMigration = objcConfiguration.compileInfoMigration(); } public Builder setCompilationAttributes(CompilationAttributes baseCompilationAttributes) { @@ -155,9 +162,27 @@ Builder setCompilationArtifacts(CompilationArtifacts compilationArtifacts) { return this; } - Builder addDeps(List deps) { - ImmutableList.Builder propagatedObjcDeps = - ImmutableList.builder(); + private static ImmutableList getCcCompilationContexts( + Iterable ccInfos) { + return Streams.stream(ccInfos) + .map(CcInfo::getCcCompilationContext) + .collect(ImmutableList.toImmutableList()); + } + + Builder addDepCcHeaderProviders(Iterable cppDeps) { + this.depCcHeaderProviders = + Iterables.concat(this.depCcHeaderProviders, getCcCompilationContexts(cppDeps)); + return this; + } + + Builder addDepCcDirectProviders(Iterable cppDeps) { + this.depCcDirectProviders = + Iterables.concat(this.depCcDirectProviders, getCcCompilationContexts(cppDeps)); + return this; + } + + private Builder addDepsPreMigration(List deps) { + ImmutableList.Builder propagatedObjcDeps = ImmutableList.builder(); ImmutableList.Builder cppDeps = ImmutableList.builder(); ImmutableList.Builder cppDepLinkParams = ImmutableList.builder(); @@ -174,15 +199,74 @@ Builder addDeps(List deps) { } } } - ImmutableList.Builder ccCompilationContextBuilder = - ImmutableList.builder(); - for (CcInfo ccInfo : cppDeps.build()) { - ccCompilationContextBuilder.add(ccInfo.getCcCompilationContext()); + addDepObjcProviders(propagatedObjcDeps.build()); + ImmutableList ccInfos = cppDeps.build(); + addDepCcHeaderProviders(ccInfos); + addDepCcDirectProviders(ccInfos); + this.depCcLinkProviders = Iterables.concat(this.depCcLinkProviders, cppDepLinkParams.build()); + + return this; + } + + private Builder addDepsPostMigration(List deps) { + ImmutableList.Builder propagatedObjcDeps = ImmutableList.builder(); + ImmutableList.Builder cppDeps = ImmutableList.builder(); + ImmutableList.Builder directCppDeps = ImmutableList.builder(); + ImmutableList.Builder cppDepLinkParams = ImmutableList.builder(); + + for (ConfiguredTargetAndData dep : deps) { + ConfiguredTarget depCT = dep.getConfiguredTarget(); + if (depCT.get(ObjcProvider.SKYLARK_CONSTRUCTOR) != null) { + addAnyProviders(propagatedObjcDeps, depCT, ObjcProvider.SKYLARK_CONSTRUCTOR); + } else { + // This is the way we inject cc_library attributes into direct fields. + addAnyProviders(directCppDeps, depCT, CcInfo.PROVIDER); + } + addAnyProviders(cppDeps, depCT, CcInfo.PROVIDER); + if (isCcLibrary(dep)) { + cppDepLinkParams.add(depCT.get(CcInfo.PROVIDER).getCcLinkingContext()); + } } addDepObjcProviders(propagatedObjcDeps.build()); - this.depCcHeaderProviders = - Iterables.concat(this.depCcHeaderProviders, ccCompilationContextBuilder.build()); + addDepCcHeaderProviders(cppDeps.build()); + addDepCcDirectProviders(directCppDeps.build()); this.depCcLinkProviders = Iterables.concat(this.depCcLinkProviders, cppDepLinkParams.build()); + + return this; + } + + Builder addDeps(List deps) { + if (compileInfoMigration) { + return addDepsPostMigration(deps); + } else { + return addDepsPreMigration(deps); + } + } + + private Builder addRuntimeDepsPreMigration( + List runtimeDeps) { + ImmutableList.Builder propagatedDeps = ImmutableList.builder(); + + for (TransitiveInfoCollection dep : runtimeDeps) { + addAnyProviders(propagatedDeps, dep, ObjcProvider.SKYLARK_CONSTRUCTOR); + } + this.runtimeDepObjcProviders = + Iterables.concat(this.runtimeDepObjcProviders, propagatedDeps.build()); + return this; + } + + private Builder addRuntimeDepsPostMigration( + List runtimeDeps) { + ImmutableList.Builder propagatedObjcDeps = ImmutableList.builder(); + ImmutableList.Builder cppDeps = ImmutableList.builder(); + + for (TransitiveInfoCollection dep : runtimeDeps) { + addAnyProviders(propagatedObjcDeps, dep, ObjcProvider.SKYLARK_CONSTRUCTOR); + addAnyProviders(cppDeps, dep, CcInfo.PROVIDER); + } + this.runtimeDepObjcProviders = + Iterables.concat(this.runtimeDepObjcProviders, propagatedObjcDeps.build()); + addDepCcHeaderProviders(cppDeps.build()); return this; } @@ -191,15 +275,11 @@ Builder addDeps(List deps) { * at build time. */ Builder addRuntimeDeps(List runtimeDeps) { - ImmutableList.Builder propagatedDeps = - ImmutableList.builder(); - - for (TransitiveInfoCollection dep : runtimeDeps) { - addAnyProviders(propagatedDeps, dep, ObjcProvider.SKYLARK_CONSTRUCTOR); + if (compileInfoMigration) { + return addRuntimeDepsPostMigration(runtimeDeps); + } else { + return addRuntimeDepsPreMigration(runtimeDeps); } - this.runtimeDepObjcProviders = Iterables.concat( - this.runtimeDepObjcProviders, propagatedDeps.build()); - return this; } private ImmutableList.Builder addAnyProviders( @@ -276,7 +356,7 @@ Builder setLinkedBinary(Artifact linkedBinary) { ObjcCommon build() { ObjcCompilationContext.Builder objcCompilationContextBuilder = - ObjcCompilationContext.builder(); + ObjcCompilationContext.builder(compileInfoMigration); ObjcProvider.Builder objcProvider = new ObjcProvider.NativeBuilder(semantics); @@ -292,7 +372,7 @@ ObjcCommon build() { // CcCompilationHelper.getStlCcCompilationContext(), but probably shouldn't. .addDepCcCompilationContexts(depCcHeaderProviders); - for (CcCompilationContext headerProvider : depCcHeaderProviders) { + for (CcCompilationContext headerProvider : depCcDirectProviders) { objcProvider.addAllDirect(HEADER, headerProvider.getDeclaredIncludeSrcs().toList()); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCompilationContext.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCompilationContext.java index f408c3df147ae3..3ed6e99259fa01 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCompilationContext.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCompilationContext.java @@ -32,7 +32,7 @@ */ @Immutable public final class ObjcCompilationContext { - public static final ObjcCompilationContext EMPTY = builder().build(); + public static final ObjcCompilationContext EMPTY = builder(false).build(); private final ImmutableList defines; @@ -126,11 +126,12 @@ public CcCompilationContext createCcCompilationContext() { return builder.build(); } - public static Builder builder() { - return new Builder(); + public static Builder builder(boolean compileInfoMigration) { + return new Builder(compileInfoMigration); } static class Builder { + private final boolean compileInfoMigration; private final List defines = new ArrayList<>(); private final List publicHeaders = new ArrayList<>(); private final List publicTextualHeaders = new ArrayList<>(); @@ -141,7 +142,9 @@ static class Builder { private final List strictDependencyIncludes = new ArrayList<>(); private final List depCcCompilationContexts = new ArrayList<>(); - Builder() {} + Builder(boolean compileInfoMigration) { + this.compileInfoMigration = compileInfoMigration; + } public Builder addDefines(Iterable defines) { Iterables.addAll(this.defines, defines); @@ -180,8 +183,9 @@ public Builder addQuoteIncludes(Iterable includes) { public Builder addDepObjcProviders(Iterable objcProviders) { for (ObjcProvider objcProvider : objcProviders) { - this.depCcCompilationContexts.add(objcProvider.getCcCompilationContext()); - + if (!compileInfoMigration) { + this.depCcCompilationContexts.add(objcProvider.getCcCompilationContext()); + } this.strictDependencyIncludes.addAll(objcProvider.getStrictDependencyIncludes()); } return this; diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java index afde04167a9fdd..3380b1942b1297 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java @@ -67,6 +67,7 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment private final HeaderDiscovery.DotdPruningMode dotdPruningPlan; private final boolean shouldScanIncludes; private final Label appleSdk; + private final boolean compileInfoMigration; ObjcConfiguration(ObjcCommandLineOptions objcOptions, CoreOptions options) { this.iosSimulatorDevice = objcOptions.iosSimulatorDevice; @@ -95,6 +96,7 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment : HeaderDiscovery.DotdPruningMode.DO_NOT_USE; this.shouldScanIncludes = objcOptions.scanIncludes; this.appleSdk = objcOptions.appleSdk; + this.compileInfoMigration = objcOptions.incompatibleObjcCompileInfoMigration; } /** @@ -258,4 +260,9 @@ public boolean shouldScanIncludes() { public Label getAppleSdk() { return appleSdk; } + + /** Whether native rules can assume compile info has been migrated to CcInfo. */ + public boolean compileInfoMigration() { + return compileInfoMigration; + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java index 7987a90b642190..6e0055762b1d0e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java @@ -28,6 +28,8 @@ import com.google.devtools.build.lib.packages.AspectParameters; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.SkylarkNativeAspect; +import com.google.devtools.build.lib.rules.cpp.CcCompilationContext; +import com.google.devtools.build.lib.rules.cpp.CcInfo; import com.google.devtools.build.lib.rules.proto.ProtoInfo; import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData; import com.google.devtools.build.lib.vfs.PathFragment; @@ -98,14 +100,25 @@ public ConfiguredAspect create( // Propagate protobuf's headers and search paths so the BinaryLinkingTargetFactory subclasses // (i.e. objc_binary) don't have to depend on it. - ObjcProvider protobufObjcProvider = - ruleContext.getPrerequisite( - ObjcRuleClasses.PROTO_LIB_ATTR, Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR); + ObjcConfiguration objcConfiguration = + ruleContext.getConfiguration().getFragment(ObjcConfiguration.class); + CcCompilationContext protobufCcCompilationContext; + if (objcConfiguration.compileInfoMigration()) { + CcInfo protobufCcInfo = + ruleContext.getPrerequisite( + ObjcRuleClasses.PROTO_LIB_ATTR, Mode.TARGET, CcInfo.PROVIDER); + protobufCcCompilationContext = protobufCcInfo.getCcCompilationContext(); + } else { + ObjcProvider protobufObjcProvider = + ruleContext.getPrerequisite( + ObjcRuleClasses.PROTO_LIB_ATTR, Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR); + protobufCcCompilationContext = protobufObjcProvider.getCcCompilationContext(); + } aspectObjcProtoProvider.addProtobufHeaders( - protobufObjcProvider.getCcCompilationContext().getDeclaredIncludeSrcs()); + protobufCcCompilationContext.getDeclaredIncludeSrcs()); aspectObjcProtoProvider.addProtobufHeaderSearchPaths( NestedSetBuilder.linkOrder() - .addAll(protobufObjcProvider.getCcCompilationContext().getIncludeDirs()) + .addAll(protobufCcCompilationContext.getIncludeDirs()) .build()); } diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java index 1bc8def7d98dbd..fde8dc17e4d9c8 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java @@ -503,9 +503,23 @@ public void testArchivesPrecompiledObjectFiles() throws Exception { } @Test - public void testCompileWithFrameworkImportsIncludesFlags() throws Exception { - useConfiguration("--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL); - addBinWithTransitiveDepOnFrameworkImport(); + public void testCompileWithFrameworkImportsIncludesFlagsPreMigration() throws Exception { + useConfiguration( + "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL, + "--incompatible_objc_compile_info_migration=false"); + addBinWithTransitiveDepOnFrameworkImport(false); + CommandAction compileAction = compileAction("//lib:lib", "a.o"); + + assertThat(compileAction.getArguments()).doesNotContain("-framework"); + assertThat(Joiner.on("").join(compileAction.getArguments())).contains("-Ffx"); + } + + @Test + public void testCompileWithFrameworkImportsIncludesFlagsPostMigration() throws Exception { + useConfiguration( + "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL, + "--incompatible_objc_compile_info_migration=true"); + addBinWithTransitiveDepOnFrameworkImport(true); CommandAction compileAction = compileAction("//lib:lib", "a.o"); assertThat(compileAction.getArguments()).doesNotContain("-framework"); diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java index 9695dfa9dbd258..60daf41d286377 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java @@ -466,15 +466,19 @@ protected void assertRequiresDarwin(Action action) { assertHasRequirement(action, ExecutionRequirements.REQUIRES_DARWIN); } - protected ConfiguredTarget addBinWithTransitiveDepOnFrameworkImport() throws Exception { - ConfiguredTarget lib = addLibWithDepOnFrameworkImport(); + protected ConfiguredTarget addBinWithTransitiveDepOnFrameworkImport(boolean compileInfoMigration) + throws Exception { + ConfiguredTarget lib = + compileInfoMigration + ? addLibWithDepOnFrameworkImportPostMigration() + : addLibWithDepOnFrameworkImportPreMigration(); return createBinaryTargetWriter("//bin:bin") .setList("deps", lib.getLabel().toString()) .write(); } - private ConfiguredTarget addLibWithDepOnFrameworkImport() throws Exception { + private ConfiguredTarget addLibWithDepOnFrameworkImportPreMigration() throws Exception { scratch.file( "fx/defs.bzl", "def _custom_static_framework_import_impl(ctx):", @@ -497,6 +501,35 @@ private ConfiguredTarget addLibWithDepOnFrameworkImport() throws Exception { .write(); } + private ConfiguredTarget addLibWithDepOnFrameworkImportPostMigration() throws Exception { + scratch.file( + "fx/defs.bzl", + "def _custom_static_framework_import_impl(ctx):", + " return [", + " apple_common.new_objc_provider(),", + " CcInfo(", + " compilation_context=cc_common.create_compilation_context(", + " framework_includes=depset(ctx.attr.framework_search_paths)", + " ),", + " )", + " ]", + "custom_static_framework_import = rule(", + " _custom_static_framework_import_impl,", + " attrs={'framework_search_paths': attr.string_list()},", + ")"); + scratch.file( + "fx/BUILD", + "load(':defs.bzl', 'custom_static_framework_import')", + "custom_static_framework_import(", + " name = 'fx',", + " framework_search_paths = ['fx'],", + ")"); + return createLibraryTargetWriter("//lib:lib") + .setAndCreateFiles("srcs", "a.m", "b.m", "private.h") + .setList("deps", "//fx:fx") + .write(); + } + protected CommandAction compileAction(String ownerLabel, String objFileName) throws Exception { Action archiveAction = archiveAction(ownerLabel); return (CommandAction) diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java index 0fb9679505b7dc..eee81ce72332e7 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java @@ -259,7 +259,7 @@ public void testSkylarkProviderCanCheckForExistanceOfObjcProvider() throws Excep } @Test - public void testSkylarkExportsObjcProviderToNativeRule() throws Exception { + public void testSkylarkExportsObjcProviderToNativeRulePreMigration() throws Exception { scratch.file("examples/rule/BUILD"); scratch.file( "examples/rule/apple_rules.bzl", @@ -296,6 +296,7 @@ public void testSkylarkExportsObjcProviderToNativeRule() throws Exception { " deps = [':lib_root']", ")"); + useConfiguration("--incompatible_objc_compile_info_migration=false"); ConfiguredTarget libRootTarget = getConfiguredTarget("//examples/apple_skylark:lib_root"); ObjcProvider libRootObjcProvider = libRootTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR); assertThat(libRootObjcProvider.define().toList()).contains("mock_define"); @@ -310,7 +311,51 @@ public void testSkylarkExportsObjcProviderToNativeRule() throws Exception { } @Test - public void testObjcRuleCanDependOnArbitrarySkylarkRuleThatProvidesObjc() throws Exception { + public void testSkylarkExportsObjcProviderToNativeRulePostMigration() throws Exception { + scratch.file("examples/rule/BUILD"); + scratch.file( + "examples/rule/apple_rules.bzl", + "def my_rule_impl(ctx):", + " dep = ctx.attr.deps[0]", + " objc_provider = dep.objc", + " return [objc_provider]", + "swift_library = rule(implementation = my_rule_impl,", + " attrs = {", + " 'deps': attr.label_list(allow_files = False, mandatory = False, providers = ['objc'])", + "})"); + + scratch.file("examples/apple_skylark/a.m"); + scratch.file( + "examples/apple_skylark/BUILD", + "package(default_visibility = ['//visibility:public'])", + "load('//examples/rule:apple_rules.bzl', 'swift_library')", + "swift_library(", + " name='my_target',", + " deps=[':lib'],", + ")", + "objc_library(", + " name = 'lib',", + " srcs = ['a.m'],", + ")", + "apple_binary(", + " name = 'bin',", + " platform_type = 'ios',", + " deps = [':my_target']", + ")"); + + useConfiguration("--incompatible_objc_compile_info_migration=true"); + ConfiguredTarget binaryTarget = getConfiguredTarget("//examples/apple_skylark:bin"); + AppleExecutableBinaryInfo executableProvider = + binaryTarget.get(AppleExecutableBinaryInfo.SKYLARK_CONSTRUCTOR); + ObjcProvider objcProvider = executableProvider.getDepsObjcProvider(); + + assertThat(Artifact.toRootRelativePaths(objcProvider.get(ObjcProvider.LIBRARY))) + .contains("examples/apple_skylark/liblib.a"); + } + + @Test + public void testObjcRuleCanDependOnArbitrarySkylarkRuleThatProvidesObjcPreMigration() + throws Exception { scratch.file("examples/rule/BUILD"); scratch.file( "examples/rule/apple_rules.bzl", @@ -339,11 +384,49 @@ public void testObjcRuleCanDependOnArbitrarySkylarkRuleThatProvidesObjc() throws " deps = [':lib']", ")"); + useConfiguration("--incompatible_objc_compile_info_migration=false"); ConfiguredTarget libTarget = getConfiguredTarget("//examples/apple_skylark:lib"); ObjcProvider libObjcProvider = libTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR); assertThat(libObjcProvider.define().toList()).contains("mock_define"); } + @Test + public void testObjcRuleCanDependOnArbitrarySkylarkRuleThatProvidesObjcPostMigration() + throws Exception { + scratch.file("examples/rule/BUILD"); + scratch.file( + "examples/rule/apple_rules.bzl", + "def my_rule_impl(ctx):", + " objc_provider = apple_common.new_objc_provider(linkopt=depset(['mock_linkopt']))", + " return [objc_provider]", + "my_rule = rule(implementation = my_rule_impl,", + " attrs = {})"); + + scratch.file("examples/apple_skylark/a.m"); + scratch.file( + "examples/apple_skylark/BUILD", + "package(default_visibility = ['//visibility:public'])", + "load('//examples/rule:apple_rules.bzl', 'my_rule')", + "my_rule(", + " name='my_target'", + ")", + "objc_library(", + " name = 'lib',", + " srcs = ['a.m'],", + " deps = [':my_target']", + ")", + "apple_binary(", + " name = 'bin',", + " platform_type = 'ios',", + " deps = [':lib']", + ")"); + + useConfiguration("--incompatible_objc_compile_info_migration=true"); + ConfiguredTarget libTarget = getConfiguredTarget("//examples/apple_skylark:lib"); + ObjcProvider libObjcProvider = libTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR); + assertThat(libObjcProvider.get(ObjcProvider.LINKOPT).toList()).contains("mock_linkopt"); + } + @Test public void testSkylarkCanAccessAppleConfiguration() throws Exception { scratch.file("examples/rule/BUILD"); @@ -1068,7 +1151,8 @@ public void testSkylarkCanCreateObjcProviderWithQuoteIncludes() throws Exception } @Test - public void testSkylarkCanCreateObjcProviderWithStrictDeps() throws Exception { + public void testSkylarkCanCreateObjcProviderWithStrictDepsPreMigration() throws Exception { + useConfiguration("--incompatible_objc_compile_info_migration=false"); ConfiguredTarget skylarkTarget = createObjcProviderSkylarkTarget( " strict_includes = depset(['path1'])", @@ -1109,6 +1193,38 @@ public void testSkylarkCanCreateObjcProviderWithStrictDeps() throws Exception { .containsExactly(PathFragment.create("path2")); } + @Test + public void testSkylarkCanCreateObjcProviderWithStrictDepsPostMigration() throws Exception { + useConfiguration("--incompatible_objc_compile_info_migration=true"); + ConfiguredTarget skylarkTarget = + createObjcProviderSkylarkTarget( + " strict_includes = depset(['path1'])", + " propagated_includes = depset(['path2'])", + " strict_provider = apple_common.new_objc_provider\\", + "(include=strict_includes)", + " created_provider = apple_common.new_objc_provider\\", + "(include=propagated_includes, direct_dep_providers=[strict_provider])", + " return [created_provider]"); + + ObjcProvider skylarkProvider = skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR); + assertThat(skylarkProvider.include()) + .containsExactly(PathFragment.create("path1"), PathFragment.create("path2")); + assertThat(skylarkProvider.getStrictDependencyIncludes()) + .containsExactly(PathFragment.create("path1")); + + scratch.file( + "examples/objc_skylark2/BUILD", + "objc_library(", + " name = 'direct_dep',", + " deps = ['//examples/objc_skylark:my_target']", + ")"); + + ObjcProvider skylarkProviderDirectDepender = + getConfiguredTarget("//examples/objc_skylark2:direct_dep") + .get(ObjcProvider.SKYLARK_CONSTRUCTOR); + assertThat(skylarkProviderDirectDepender.include()).isEmpty(); + } + @Test public void testSkylarkStrictDepsDoesNotSupportDefine() throws Exception { AssertionError e =