diff options
9 files changed, 151 insertions, 24 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java index 919bdc8713..8c60aaa1ed 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java @@ -73,7 +73,6 @@ import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; 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.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction; @@ -785,6 +784,7 @@ public final class CompilationSupport { throws InterruptedException { Artifact outputArchive = ruleContext.getImplicitOutputArtifact(CompilationSupport.FULLY_LINKED_LIB); + ImmutableList<Artifact> objcLibraries = objcLibraries(objcProvider); ImmutableList<Artifact> ccLibraries = ccLibraries(objcProvider); ruleContext.registerAction(ObjcRuleClasses.spawnAppleEnvActionBuilder( ruleContext, appleConfiguration.getIosCpuPlatform()) @@ -795,12 +795,12 @@ public final class CompilationSupport { .add("-arch_only").add(appleConfiguration.getIosCpu()) .add("-syslibroot").add(AppleToolchain.sdkDir()) .add("-o").add(outputArchive.getExecPathString()) - .addExecPaths(objcProvider.get(LIBRARY)) + .addExecPaths(objcLibraries) .addExecPaths(objcProvider.get(IMPORTED_LIBRARY)) .addExecPaths(ccLibraries) .build()) .addInputs(ccLibraries) - .addTransitiveInputs(objcProvider.get(LIBRARY)) + .addInputs(objcLibraries) .addTransitiveInputs(objcProvider.get(IMPORTED_LIBRARY)) .addOutput(outputArchive) .build(ruleContext)); @@ -975,9 +975,10 @@ public final class CompilationSupport { ? intermediateArtifacts.unstrippedSingleArchitectureBinary() : intermediateArtifacts.strippedSingleArchitectureBinary(); + ImmutableList<Artifact> objcLibraries = objcLibraries(objcProvider); ImmutableList<Artifact> ccLibraries = ccLibraries(objcProvider); - NestedSet<Artifact> bazelBuiltLibraries = Iterables.isEmpty(prunedJ2ObjcArchives) - ? objcProvider.get(LIBRARY) : substituteJ2ObjcPrunedLibraries(objcProvider); + ImmutableList<Artifact> bazelBuiltLibraries = Iterables.isEmpty(prunedJ2ObjcArchives) + ? objcLibraries : substituteJ2ObjcPrunedLibraries(objcProvider); CommandLine commandLine = linkCommandLine( extraLinkArgs, @@ -996,7 +997,7 @@ public final class CompilationSupport { .addOutput(binaryToLink) .addOutputs(dsymBundleZip.asSet()) .addOutputs(linkmap.asSet()) - .addTransitiveInputs(bazelBuiltLibraries) + .addInputs(bazelBuiltLibraries) .addTransitiveInputs(objcProvider.get(IMPORTED_LIBRARY)) .addTransitiveInputs(objcProvider.get(STATIC_FRAMEWORK_FILE)) .addTransitiveInputs(objcProvider.get(DYNAMIC_FRAMEWORK_FILE)) @@ -1033,6 +1034,16 @@ public final class CompilationSupport { } } + private ImmutableList<Artifact> objcLibraries(ObjcProvider objcProvider) { + ImmutableList.Builder<Artifact> objcLibraryBuilder = ImmutableList.builder(); + // JRE libraries must be ordered after all regular objc libraries. + NestedSet<Artifact> jreLibs = objcProvider.get(ObjcProvider.JRE_LIBRARY); + objcLibraryBuilder.addAll(Iterables.filter( + objcProvider.get(LIBRARY), Predicates.not(Predicates.in(jreLibs.toSet())))); + objcLibraryBuilder.addAll(jreLibs); + return objcLibraryBuilder.build(); + } + private ImmutableList<Artifact> ccLibraries(ObjcProvider objcProvider) { ImmutableList.Builder<Artifact> ccLibraryBuilder = ImmutableList.builder(); for (LinkerInputs.LibraryToLink libraryToLink : objcProvider.get(ObjcProvider.CC_LIBRARY)) { @@ -1063,11 +1074,11 @@ public final class CompilationSupport { * Returns a nested set of Bazel-built ObjC libraries with all unpruned J2ObjC libraries * substituted with pruned ones. */ - private NestedSet<Artifact> substituteJ2ObjcPrunedLibraries(ObjcProvider objcProvider) { + private ImmutableList<Artifact> substituteJ2ObjcPrunedLibraries(ObjcProvider objcProvider) { ImmutableList.Builder<Artifact> libraries = new ImmutableList.Builder<>(); Set<Artifact> unprunedJ2ObjcLibs = objcProvider.get(ObjcProvider.J2OBJC_LIBRARY).toSet(); - for (Artifact library : objcProvider.get(LIBRARY)) { + for (Artifact library : objcLibraries(objcProvider)) { // If we match an unpruned J2ObjC library, add the pruned version of the J2ObjC static library // instead. if (unprunedJ2ObjcLibs.contains(library)) { @@ -1076,7 +1087,7 @@ public final class CompilationSupport { libraries.add(library); } } - return NestedSetBuilder.wrap(Order.NAIVE_LINK_ORDER, libraries.build()); + return libraries.build(); } private CommandLine linkCommandLine( diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java index 895312c30f..5ec92b80be 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java @@ -35,13 +35,17 @@ import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction; import com.google.devtools.build.lib.analysis.actions.SpawnAction; +import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.AspectDefinition; import com.google.devtools.build.lib.packages.AspectParameters; +import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel; +import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.NativeAspectClass; +import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.rules.apple.AppleConfiguration; import com.google.devtools.build.lib.rules.apple.AppleToolchain; import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider; @@ -72,11 +76,26 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF } private static final Iterable<Attribute> DEPENDENT_ATTRIBUTES = ImmutableList.of( - new Attribute("$jre_emul_lib", Mode.TARGET), + new Attribute(":jre_lib", Mode.TARGET), new Attribute("deps", Mode.TARGET), new Attribute("exports", Mode.TARGET), new Attribute("runtime_deps", Mode.TARGET)); + private static final Label JRE_CORE_LIB = + Label.parseAbsoluteUnchecked("//third_party/java/j2objc:jre_core_lib"); + + private static final Label JRE_EMUL_LIB = + Label.parseAbsoluteUnchecked("//third_party/java/j2objc:jre_emul_lib"); + + private static final LateBoundLabel<BuildConfiguration> JRE_LIB = + new LateBoundLabel<BuildConfiguration>(JRE_CORE_LIB, J2ObjcConfiguration.class) { + @Override + public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) { + return configuration.getFragment(J2ObjcConfiguration.class).explicitJreDeps() + ? JRE_CORE_LIB : JRE_EMUL_LIB; + } + }; + /** * Adds additional attribute aspects and attributes to the given AspectDefinition.Builder. */ @@ -110,8 +129,7 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF .add(attr("$jre_emul_jar", LABEL).cfg(HOST) .value(Label.parseAbsoluteUnchecked( toolsRepository + "//third_party/java/j2objc:jre_emul.jar"))) - .add(attr("$jre_emul_lib", LABEL) - .value(Label.parseAbsoluteUnchecked("//third_party/java/j2objc:jre_emul_lib"))) + .add(attr(":jre_lib", LABEL).value(JRE_LIB)) .add(attr("$xcrunwrapper", LABEL).cfg(HOST).exec() .value(Label.parseAbsoluteUnchecked( toolsRepository + "//tools/objc:xcrunwrapper"))) diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java index 64b9069b87..8f438d1825 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java @@ -45,6 +45,13 @@ public class J2ObjcCommandLineOptions extends FragmentOptions { ) public boolean removeDeadCode; + @Option(name = "explicit_jre_deps", + defaultValue = "false", + category = "flags", + help = "Requires JRE dependencies to be declared in j2objc_library's jre_deps attribute." + ) + public boolean explicitJreDeps; + @Override public void addAllLabels(Multimap<String, Label> labelMap) {} } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcConfiguration.java index 55570792bf..0653d43a98 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcConfiguration.java @@ -77,9 +77,11 @@ public class J2ObjcConfiguration extends Fragment { private final Set<String> translationFlags; private final boolean removeDeadCode; + private final boolean explicitJreDeps; J2ObjcConfiguration(J2ObjcCommandLineOptions j2ObjcOptions) { this.removeDeadCode = j2ObjcOptions.removeDeadCode; + this.explicitJreDeps = j2ObjcOptions.explicitJreDeps; this.translationFlags = ImmutableSet.<String>builder() .addAll(j2ObjcOptions.translationFlags) .addAll(J2OBJC_ALWAYS_ON_TRANSLATION_FLAGS) @@ -106,6 +108,14 @@ public class J2ObjcConfiguration extends Fragment { return removeDeadCode; } + /** + * Returns whether explicit JRE dependencies are required. If true, all j2objc_library rules will + * implicitly depend on jre_core_lib instead of jre_full_lib. + */ + public boolean explicitJreDeps() { + return explicitJreDeps; + } + @Override public void reportInvalidOptions(EventHandler reporter, BuildOptions buildOptions) { if (!Collections.disjoint(translationFlags, J2OBJC_BLACKLISTED_TRANSLATION_FLAGS)) { diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java index a4a2ba5229..eda1d6a11e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java @@ -15,6 +15,8 @@ package com.google.devtools.build.lib.rules.objc; import static com.google.devtools.build.lib.collect.nestedset.Order.STABLE_ORDER; +import static com.google.devtools.build.lib.rules.objc.ObjcProvider.JRE_LIBRARY; +import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY; import static com.google.devtools.build.lib.rules.objc.XcodeProductType.LIBRARY_STATIC; import com.google.common.collect.ImmutableList; @@ -63,14 +65,21 @@ public class J2ObjcLibrary implements RuleConfiguredTargetFactory { .addEntryClasses(ruleContext.attributes().get("entry_classes", Type.STRING_LIST)) .build(); + Iterable<ObjcProvider> jreDeps = + ruleContext.getPrerequisites("jre_deps", Mode.TARGET, ObjcProvider.class); ObjcProvider.Builder objcProviderBuilder = new ObjcProvider.Builder() + .addTransitiveAndPropagate(jreDeps) .addTransitiveAndPropagate( ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProvider.class)); + for (ObjcProvider prereq : jreDeps) { + objcProviderBuilder.addTransitiveAndPropagate(JRE_LIBRARY, prereq.get(LIBRARY)); + } XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder(); XcodeSupport xcodeSupport = new XcodeSupport(ruleContext) + .addJreDependencies(xcodeProviderBuilder) .addDependencies(xcodeProviderBuilder, new Attribute("deps", Mode.TARGET)); ObjcProvider objcProvider = objcProviderBuilder.build(); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryBaseRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryBaseRule.java index 5dcadd9791..904f232119 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryBaseRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryBaseRule.java @@ -15,11 +15,14 @@ package com.google.devtools.build.lib.rules.objc; import static com.google.devtools.build.lib.packages.Attribute.attr; +import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; import static com.google.devtools.build.lib.syntax.Type.STRING_LIST; import com.google.devtools.build.lib.analysis.BaseRuleClasses; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; +import com.google.devtools.build.lib.packages.Attribute.ValidityPredicate; +import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.packages.RuleClass.Builder; import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; @@ -32,17 +35,38 @@ public class J2ObjcLibraryBaseRule implements RuleDefinition { public RuleClass build(Builder builder, RuleDefinitionEnvironment env) { // TODO(rduan): Add support for package prefixes. return builder - /* <!-- #BLAZE_RULE(j2objc_library).ATTRIBUTE(entry_classes) --> - The list of Java classes whose translated ObjC counterparts will be referenced directly - by user ObjC code. This attibute is required if flag <code>--j2objc_dead_code_removal - </code> is on. The Java classes should be specified in their canonical names as defined by - <a href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.7">the Java - Language Specification.</a> - When flag <code>--j2objc_dead_code_removal</code> is specified, the list of entry classes - will be collected transitively and used as entry points to perform dead code analysis. - Unused classes will then be removed from the final ObjC app bundle. - <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ + /* <!-- #BLAZE_RULE(j2objc_library).ATTRIBUTE(entry_classes) --> + The list of Java classes whose translated ObjC counterparts will be referenced directly + by user ObjC code. This attibute is required if flag <code>--j2objc_dead_code_removal + </code> is on. The Java classes should be specified in their canonical names as defined by + <a href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.7">the Java + Language Specification.</a> + When flag <code>--j2objc_dead_code_removal</code> is specified, the list of entry classes + will be collected transitively and used as entry points to perform dead code analysis. + Unused classes will then be removed from the final ObjC app bundle. + <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ .add(attr("entry_classes", STRING_LIST)) + /* <!-- #BLAZE_RULE(j2objc_library).ATTRIBUTE(jre_deps) --> + The list of additional JRE emulation libraries required by all Java code translated by this + <code>j2objc_library</code> rule. When --explicit_jre_deps is enabled only core JRE + functionality is included by default, so specifying additional JRE dependencies here is + necessary. Use with --explicit_jre_deps to reduce the size of dependent binary targets. + --explicit_jre_deps will eventually become the default behavior. + <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ + .add(attr("jre_deps", LABEL_LIST) + .direct_compile_time_input() + .allowedRuleClasses("objc_library") + .allowedFileTypes() + .validityPredicate( + new ValidityPredicate() { + @Override + public String checkValid(Rule from, Rule to) { + if (!to.getRuleTags().contains("j2objc_jre_lib")) { + return "Only J2ObjC JRE libraries are allowed"; + } + return null; + } + })) .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 a0fbdc308e..fa2df6aab9 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 @@ -82,11 +82,19 @@ public final class ObjcProvider extends SkylarkClassObject implements Transitive } public static final Key<Artifact> LIBRARY = new Key<>(LINK_ORDER, "library", Artifact.class); - + public static final Key<Artifact> IMPORTED_LIBRARY = new Key<>(LINK_ORDER, "imported_library", Artifact.class); /** + * J2ObjC JRE emulation libraries and their dependencies. Separate from LIBRARY because these + * dependencies are specified further up the tree from where the dependency actually exists and + * they must be forced to the end of the link order. + */ + public static final Key<Artifact> JRE_LIBRARY = + new Key<>(LINK_ORDER, "jre_library", Artifact.class); + + /** * Single-architecture linked binaries to be combined for the final multi-architecture binary. */ public static final Key<Artifact> LINKED_BINARY = @@ -352,6 +360,7 @@ public final class ObjcProvider extends SkylarkClassObject implements Transitive ImmutableList.<Key<?>>of( LIBRARY, IMPORTED_LIBRARY, + JRE_LIBRARY, LINKED_BINARY, FORCE_LOAD_LIBRARY, HEADER, diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java index 10fd279e68..38e39348a6 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java @@ -57,6 +57,7 @@ import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.XcodeprojBu import java.util.Arrays; import java.util.EnumSet; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -91,6 +92,7 @@ public final class XcodeProvider implements TransitiveInfoProvider { NestedSetBuilder.linkOrder(); private final NestedSetBuilder<XcodeProvider> nonPropagatedDependencies = NestedSetBuilder.linkOrder(); + private final NestedSetBuilder<XcodeProvider> jreDependencies = NestedSetBuilder.linkOrder(); private final ImmutableList.Builder<XcodeprojBuildSetting> xcodeprojBuildSettings = new ImmutableList.Builder<>(); private final ImmutableList.Builder<XcodeprojBuildSetting> @@ -181,6 +183,18 @@ public final class XcodeProvider implements TransitiveInfoProvider { return addDependencies(dependencies, /*doPropagate=*/false); } + /** + * Adds {@link XcodeProvider}s corresponding to direct J2ObjC JRE dependencies of this target + * which should be added in the {@code .xcodeproj} file and propagated up the dependency chain. + */ + public Builder addJreDependencies(Iterable<XcodeProvider> dependencies) { + for (XcodeProvider dependency : dependencies) { + this.jreDependencies.add(dependency); + this.jreDependencies.addTransitive(dependency.propagatedDependencies); + } + return addDependencies(dependencies, /*doPropagate=*/true); + } + private Builder addDependencies(Iterable<XcodeProvider> dependencies, boolean doPropagate) { for (XcodeProvider dependency : dependencies) { // TODO(bazel-team): This is messy. Maybe we should make XcodeProvider be able to specify @@ -195,6 +209,7 @@ public final class XcodeProvider implements TransitiveInfoProvider { if (doPropagate) { this.propagatedDependencies.add(dependency); this.propagatedDependencies.addTransitive(dependency.propagatedDependencies); + this.jreDependencies.addTransitive(dependency.jreDependencies); this.addTransitiveSets(dependency); } else { this.nonPropagatedDependencies.add(dependency); @@ -431,6 +446,7 @@ public final class XcodeProvider implements TransitiveInfoProvider { private final Optional<Artifact> bundleInfoplist; private final NestedSet<XcodeProvider> propagatedDependencies; private final NestedSet<XcodeProvider> nonPropagatedDependencies; + private final NestedSet<XcodeProvider> jreDependencies; private final ImmutableList<XcodeprojBuildSetting> xcodeprojBuildSettings; private final ImmutableList<XcodeprojBuildSetting> companionTargetXcodeprojBuildSettings; private final ImmutableList<String> copts; @@ -456,6 +472,7 @@ public final class XcodeProvider implements TransitiveInfoProvider { this.bundleInfoplist = builder.bundleInfoplist; this.propagatedDependencies = builder.propagatedDependencies.build(); this.nonPropagatedDependencies = builder.nonPropagatedDependencies.build(); + this.jreDependencies = builder.jreDependencies.build(); this.xcodeprojBuildSettings = builder.xcodeprojBuildSettings.build(); this.companionTargetXcodeprojBuildSettings = builder.companionTargetXcodeprojBuildSettings.build(); @@ -599,7 +616,12 @@ public final class XcodeProvider implements TransitiveInfoProvider { // For builds with --ios_multi_cpus set, we may have several copies of some XCodeProviders // in the dependencies (one per cpu architecture). We deduplicate the corresponding // xcode target names with a LinkedHashSet before adding to the TargetControl. + Set<String> jreTargetNames = new HashSet<>(); + for (XcodeProvider jreDependency : jreDependencies) { + jreTargetNames.add(jreDependency.dependencyXcodeTargetName()); + } Set<DependencyControl> dependencySet = new LinkedHashSet<>(); + Set<DependencyControl> jreDependencySet = new LinkedHashSet<>(); for (XcodeProvider dependency : propagatedDependencies) { // Only add a library target to a binary's dependencies if it has source files to compile // and it is not from the "non_propagated_deps" attribute. Xcode cannot build targets @@ -618,7 +640,9 @@ public final class XcodeProvider implements TransitiveInfoProvider { if (hasSources || (dependency.productType == XcodeProductType.BUNDLE || (dependency.productType == XcodeProductType.WATCH_OS1_APPLICATION))) { String dependencyXcodeTargetName = dependency.dependencyXcodeTargetName(); - dependencySet.add(DependencyControl.newBuilder() + Set<DependencyControl> set = jreTargetNames.contains(dependencyXcodeTargetName) + ? jreDependencySet : dependencySet; + set.add(DependencyControl.newBuilder() .setTargetLabel(dependencyXcodeTargetName) .build()); } @@ -627,6 +651,10 @@ public final class XcodeProvider implements TransitiveInfoProvider { for (DependencyControl dependencyControl : dependencySet) { targetControl.addDependency(dependencyControl); } + // Make sure that JRE dependencies are ordered after other propagated dependencies. + for (DependencyControl dependencyControl : jreDependencySet) { + targetControl.addDependency(dependencyControl); + } } for (XcodeProvider justTestHost : testHost.asSet()) { targetControl.addDependency(DependencyControl.newBuilder() diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java index b24971e4ad..802fc8f658 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java @@ -202,6 +202,17 @@ public final class XcodeSupport { } /** + * Adds J2ObjC JRE dependencies to the given provider builder from the given attribute. + * + * @return this xcode support + */ + XcodeSupport addJreDependencies(Builder xcodeProviderBuilder) { + xcodeProviderBuilder.addJreDependencies( + ruleContext.getPrerequisites("jre_deps", Mode.TARGET, XcodeProvider.class)); + return this; + } + + /** * Generates an extra {@link XcodeProductType#LIBRARY_STATIC} Xcode target with the same * compilation artifacts as the main Xcode target associated with this Xcode support. The extra * Xcode library target, instead of the main Xcode target, will act as a dependency for all |