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 6d3fe727c52c9e..37ba54828f062a 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 @@ -237,6 +237,21 @@ public class ObjcCommandLineOptions extends FragmentOptions { ) public Label appleSdk; + @Option( + name = "incompatible_objc_compile_info_migration", + defaultValue = "true", + 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; + @Option( name = "incompatible_avoid_hardcoded_objc_compilation_flags", defaultValue = "false", 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 34ce90c5bf1419..63129828d660f2 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 @@ -100,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; @@ -137,6 +138,10 @@ static class Builder { this.context = Preconditions.checkNotNull(context); this.semantics = context.getAnalysisEnvironment().getStarlarkSemantics(); this.buildConfiguration = Preconditions.checkNotNull(buildConfiguration); + + ObjcConfiguration objcConfiguration = buildConfiguration.getFragment(ObjcConfiguration.class); + + this.compileInfoMigration = objcConfiguration.compileInfoMigration(); } public Builder setCompilationAttributes(CompilationAttributes baseCompilationAttributes) { @@ -176,8 +181,34 @@ Builder addDepCcDirectProviders(Iterable cppDeps) { return this; } - /** Add the providers for the build dependencies. */ - Builder addDeps(List deps) { + private Builder addDepsPreMigration(List deps) { + ImmutableList.Builder propagatedObjcDeps = ImmutableList.builder(); + ImmutableList.Builder cppDeps = ImmutableList.builder(); + ImmutableList.Builder cppDepLinkParams = ImmutableList.builder(); + + for (ConfiguredTargetAndData dep : deps) { + ConfiguredTarget depCT = dep.getConfiguredTarget(); + // It is redundant to process both ObjcProvider and CcInfo; doing so causes direct header + // field to include indirect headers from deps. + if (depCT.get(ObjcProvider.STARLARK_CONSTRUCTOR) != null) { + addAnyProviders(propagatedObjcDeps, depCT, ObjcProvider.STARLARK_CONSTRUCTOR); + } else { + addAnyProviders(cppDeps, depCT, CcInfo.PROVIDER); + if (isCcLibrary(dep)) { + cppDepLinkParams.add(depCT.get(CcInfo.PROVIDER).getCcLinkingContext()); + } + } + } + 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(); @@ -204,11 +235,28 @@ Builder addDeps(List deps) { return this; } - /** - * Adds providers for runtime frameworks included in the final app bundle but not linked with at - * build time. - */ - Builder addRuntimeDeps(List runtimeDeps) { + 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.STARLARK_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(); @@ -222,6 +270,18 @@ Builder addRuntimeDeps(List runtimeDeps) { return this; } + /** + * Adds providers for runtime frameworks included in the final app bundle but not linked with + * at build time. + */ + Builder addRuntimeDeps(List runtimeDeps) { + if (compileInfoMigration) { + return addRuntimeDepsPostMigration(runtimeDeps); + } else { + return addRuntimeDepsPreMigration(runtimeDeps); + } + } + private ImmutableList.Builder addAnyProviders( ImmutableList.Builder listBuilder, TransitiveInfoCollection collection, @@ -296,7 +356,7 @@ Builder setLinkedBinary(Artifact linkedBinary) { ObjcCommon build() { ObjcCompilationContext.Builder objcCompilationContextBuilder = - ObjcCompilationContext.builder(); + ObjcCompilationContext.builder(compileInfoMigration); ObjcProvider.Builder objcProvider = new ObjcProvider.NativeBuilder(semantics); 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 b9ec7cdf49e5f7..95420b30d57aa4 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,12 +126,12 @@ public CcCompilationContext createCcCompilationContext() { return builder.build(); } - /** Create and return an initial empty Builder for ObjcCompilationContext. */ - 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<>(); @@ -142,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); @@ -181,6 +183,9 @@ public Builder addQuoteIncludes(Iterable includes) { public Builder addDepObjcProviders(Iterable objcProviders) { for (ObjcProvider objcProvider : objcProviders) { + 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 1b71bdd2551234..28db40acd1204e 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 @@ -68,6 +68,7 @@ public class ObjcConfiguration extends Fragment implements ObjcConfigurationApi< private final boolean enableAppleBinaryNativeProtos; private final HeaderDiscovery.DotdPruningMode dotdPruningPlan; private final boolean shouldScanIncludes; + private final boolean compileInfoMigration; private final boolean avoidHardcodedCompilationFlags; public ObjcConfiguration(BuildOptions buildOptions) { @@ -100,6 +101,7 @@ public ObjcConfiguration(BuildOptions buildOptions) { ? HeaderDiscovery.DotdPruningMode.USE : HeaderDiscovery.DotdPruningMode.DO_NOT_USE; this.shouldScanIncludes = objcOptions.scanIncludes; + this.compileInfoMigration = objcOptions.incompatibleObjcCompileInfoMigration; this.avoidHardcodedCompilationFlags = objcOptions.incompatibleAvoidHardcodedObjcCompilationFlags; } @@ -260,4 +262,9 @@ public HeaderDiscovery.DotdPruningMode getDotdPruningPlan() { public boolean shouldScanIncludes() { return shouldScanIncludes; } + + /** 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 a1ee6faf63521f..0ddb99a2f5d060 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 @@ -96,9 +96,20 @@ 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. - CcInfo protobufCcInfo = - ruleContext.getPrerequisite(ObjcRuleClasses.PROTO_LIB_ATTR, CcInfo.PROVIDER); - CcCompilationContext protobufCcCompilationContext = protobufCcInfo.getCcCompilationContext(); + ObjcConfiguration objcConfiguration = + ruleContext.getConfiguration().getFragment(ObjcConfiguration.class); + CcCompilationContext protobufCcCompilationContext; + if (objcConfiguration.compileInfoMigration()) { + CcInfo protobufCcInfo = + ruleContext.getPrerequisite(ObjcRuleClasses.PROTO_LIB_ATTR, CcInfo.PROVIDER); + protobufCcCompilationContext = protobufCcInfo.getCcCompilationContext(); + } else { + ObjcProvider protobufObjcProvider = + ruleContext.getPrerequisite( + ObjcRuleClasses.PROTO_LIB_ATTR, + ObjcProvider.STARLARK_CONSTRUCTOR); + protobufCcCompilationContext = protobufObjcProvider.getCcCompilationContext(); + } aspectObjcProtoProvider.addProtobufHeaders( protobufCcCompilationContext.getDeclaredIncludeSrcs()); aspectObjcProtoProvider.addProtobufHeaderSearchPaths( diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java index 7cdbd2af508c8e..47a2a0821b96e7 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java @@ -84,8 +84,7 @@ private ConfiguredTarget getConfiguredTargetInAppleBinaryTransition(String label return getConfiguredTarget(label, childConfig); } - @Test - public void testJ2ObjCInformationExportedFromJ2ObjcLibrary() throws Exception { + private void testJ2ObjCInformationExportedFromJ2ObjcLibrary() throws Exception { ConfiguredTarget j2objcLibraryTarget = getConfiguredTarget( "//java/com/google/dummy/test:transpile"); ObjcProvider provider = j2objcLibraryTarget.get(ObjcProvider.STARLARK_CONSTRUCTOR); @@ -100,6 +99,23 @@ public void testJ2ObjCInformationExportedFromJ2ObjcLibrary() throws Exception { .containsExactly(execPath + "java/com/google/dummy/test/_j2objc/test"); } + @Test + public void testJ2ObjCInformationExportedFromJ2ObjcLibraryPreMigration() throws Exception { + useConfiguration( + "--proto_toolchain_for_java=//tools/proto/toolchains:java", + "--incompatible_objc_compile_info_migration=false"); + setBuildLanguageOptions("--incompatible_objc_provider_remove_compile_info=false"); + testJ2ObjCInformationExportedFromJ2ObjcLibrary(); + } + + @Test + public void testJ2ObjCInformationExportedFromJ2ObjcLibraryPostMigration() throws Exception { + useConfiguration( + "--proto_toolchain_for_java=//tools/proto/toolchains:java", + "--incompatible_objc_compile_info_migration=true"); + testJ2ObjCInformationExportedFromJ2ObjcLibrary(); + } + @Test public void testJ2ObjCInformationExportedWithGeneratedJavaSources() throws Exception { scratch.file("java/com/google/test/in.txt"); 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 1808a4e02f5af0..4ec42e02ad58a3 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 @@ -509,9 +509,24 @@ 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"); + setBuildLanguageOptions("--incompatible_objc_provider_remove_compile_info=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/ObjcProtoAspectTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspectTest.java index 0b753cdb16f26a..677c3089b0e9ab 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspectTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspectTest.java @@ -69,8 +69,7 @@ public void testObjcProtoAspectPropagatesProvider() throws Exception { assertThat(objcProtoProvider).isNotNull(); } - @Test - public void testObjcProtoAspectPropagatesProtobufProvider() throws Exception { + private void testObjcProtoAspectPropagatesProtobufProvider() throws Exception { MockObjcSupport.setupObjcProtoLibrary(scratch); scratch.file("x/data_filter.pbascii"); scratch.file( @@ -103,6 +102,19 @@ public void testObjcProtoAspectPropagatesProtobufProvider() throws Exception { .containsExactly(includePath, genIncludePath); } + @Test + public void testObjcProtoAspectPropagatesProtobufProviderPreMigration() throws Exception { + useConfiguration("--incompatible_objc_compile_info_migration=false"); + setBuildLanguageOptions("--incompatible_objc_provider_remove_compile_info=false"); + testObjcProtoAspectPropagatesProtobufProvider(); + } + + @Test + public void testObjcProtoAspectPropagatesProtobufProviderPostMigration() throws Exception { + useConfiguration("--incompatible_objc_compile_info_migration=true"); + testObjcProtoAspectPropagatesProtobufProvider(); + } + @Test public void testObjcProtoAspectDoesNotPropagateProviderWhenNoProtos() throws Exception { scratch.file("x/BUILD", 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 48a7cd102d213f..d5eff0edfb3a49 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 @@ -470,15 +470,42 @@ 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):", + " return [apple_common.new_objc_provider(", + " framework_search_paths=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/fx1.framework', 'fx/fx2.framework'],", + ")"); + return createLibraryTargetWriter("//lib:lib") + .setAndCreateFiles("srcs", "a.m", "b.m", "private.h") + .setList("deps", "//fx:fx") + .write(); + } + + private ConfiguredTarget addLibWithDepOnFrameworkImportPostMigration() throws Exception { scratch.file( "fx/defs.bzl", "def _custom_static_framework_import_impl(ctx):", diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcStarlarkTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcStarlarkTest.java index 457ea32d53b110..c92af81d027181 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcStarlarkTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcStarlarkTest.java @@ -257,7 +257,60 @@ public void testStarlarkProviderCanCheckForExistanceOfObjcProvider() throws Exce } @Test - public void testStarlarkExportsObjcProviderToNativeRule() throws Exception { + public void testStarlarkExportsObjcProviderToNativeRulePreMigration() 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_starlark/a.m"); + scratch.file( + "examples/apple_starlark/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'],", + " defines = ['mock_define']", + ")", + "objc_library(", + " name = 'lib_root',", + " deps = [':my_target']", + ")", + "apple_binary(", + " name = 'bin',", + " platform_type = 'ios',", + " deps = [':lib_root']", + ")"); + + useConfiguration("--incompatible_objc_compile_info_migration=false"); + setBuildLanguageOptions("--incompatible_objc_provider_remove_compile_info=false"); + ConfiguredTarget libRootTarget = getConfiguredTarget("//examples/apple_starlark:lib_root"); + ObjcProvider libRootObjcProvider = libRootTarget.get(ObjcProvider.STARLARK_CONSTRUCTOR); + assertThat(libRootObjcProvider.define().toList()).contains("mock_define"); + + ConfiguredTarget binaryTarget = getConfiguredTarget("//examples/apple_starlark:bin"); + AppleExecutableBinaryInfo executableProvider = + binaryTarget.get(AppleExecutableBinaryInfo.STARLARK_CONSTRUCTOR); + ObjcProvider objcProvider = executableProvider.getDepsObjcProvider(); + + assertThat(Artifact.toRootRelativePaths(objcProvider.get(ObjcProvider.LIBRARY))) + .contains("examples/apple_starlark/liblib.a"); + } + + @Test + public void testStarlarkExportsObjcProviderToNativeRulePostMigration() throws Exception { scratch.file("examples/rule/BUILD"); scratch.file( "examples/rule/apple_rules.bzl", @@ -289,6 +342,7 @@ public void testStarlarkExportsObjcProviderToNativeRule() throws Exception { " deps = [':my_target']", ")"); + useConfiguration("--incompatible_objc_compile_info_migration=true"); ConfiguredTarget binaryTarget = getConfiguredTarget("//examples/apple_starlark:bin"); AppleExecutableBinaryInfo executableProvider = binaryTarget.get(AppleExecutableBinaryInfo.STARLARK_CONSTRUCTOR); @@ -299,7 +353,46 @@ public void testStarlarkExportsObjcProviderToNativeRule() throws Exception { } @Test - public void testObjcRuleCanDependOnArbitraryStarlarkRuleThatProvidesObjc() throws Exception { + public void testObjcRuleCanDependOnArbitraryStarlarkRuleThatProvidesObjcPreMigration() + 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(define=depset(['mock_define']))", + " return [objc_provider]", + "my_rule = rule(implementation = my_rule_impl,", + " attrs = {})"); + + scratch.file("examples/apple_starlark/a.m"); + scratch.file( + "examples/apple_starlark/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=false"); + setBuildLanguageOptions("--incompatible_objc_provider_remove_compile_info=false"); + ConfiguredTarget libTarget = getConfiguredTarget("//examples/apple_starlark:lib"); + ObjcProvider libObjcProvider = libTarget.get(ObjcProvider.STARLARK_CONSTRUCTOR); + assertThat(libObjcProvider.define().toList()).contains("mock_define"); + } + + @Test + public void testObjcRuleCanDependOnArbitraryStarlarkRuleThatProvidesObjcPostMigration() + throws Exception { scratch.file("examples/rule/BUILD"); scratch.file( "examples/rule/apple_rules.bzl", @@ -328,6 +421,7 @@ public void testObjcRuleCanDependOnArbitraryStarlarkRuleThatProvidesObjc() throw " deps = [':lib']", ")"); + useConfiguration("--incompatible_objc_compile_info_migration=true"); ConfiguredTarget libTarget = getConfiguredTarget("//examples/apple_starlark:lib"); ObjcProvider libObjcProvider = libTarget.get(ObjcProvider.STARLARK_CONSTRUCTOR); assertThat(libObjcProvider.get(ObjcProvider.LINKOPT).toList()).contains("mock_linkopt"); @@ -1199,7 +1293,52 @@ public void testStarlarkCannotCreateObjcProviderWithMergeZipsPostAPIRemoval() th } @Test - public void testStarlarkCanCreateObjcProviderWithStrictDeps() throws Exception { + public void testStarlarkCanCreateObjcProviderWithStrictDepsPreMigration() throws Exception { + useConfiguration("--incompatible_objc_compile_info_migration=false"); + setBuildLanguageOptions("--incompatible_objc_provider_remove_compile_info=false"); + ConfiguredTarget starlarkTarget = + createObjcProviderStarlarkTarget( + " 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 starlarkProvider = starlarkTarget.get(ObjcProvider.STARLARK_CONSTRUCTOR); + assertThat(starlarkProvider.include()) + .containsExactly(PathFragment.create("path1"), PathFragment.create("path2")); + assertThat(starlarkProvider.getStrictDependencyIncludes()) + .containsExactly(PathFragment.create("path1")); + + scratch.file( + "examples/objc_starlark2/BUILD", + "objc_library(", + " name = 'direct_dep',", + " deps = ['//examples/objc_starlark:my_target']", + ")", + "objc_library(", + " name = 'indirect_dep',", + " deps = [':direct_dep']", + ")"); + + ObjcProvider starlarkProviderDirectDepender = + getConfiguredTarget("//examples/objc_starlark2:direct_dep") + .get(ObjcProvider.STARLARK_CONSTRUCTOR); + assertThat(starlarkProviderDirectDepender.include()) + .containsExactly(PathFragment.create("path2")); + + ObjcProvider starlarkProviderIndirectDepender = + getConfiguredTarget("//examples/objc_starlark2:indirect_dep") + .get(ObjcProvider.STARLARK_CONSTRUCTOR); + assertThat(starlarkProviderIndirectDepender.include()) + .containsExactly(PathFragment.create("path2")); + } + + @Test + public void testStarlarkCanCreateObjcProviderWithStrictDepsPostMigration() throws Exception { + useConfiguration("--incompatible_objc_compile_info_migration=true"); setBuildLanguageOptions("--incompatible_objc_provider_remove_compile_info=false"); ConfiguredTarget starlarkTarget = createObjcProviderStarlarkTarget(