aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2015-05-12 20:29:32 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2015-05-15 09:40:06 +0000
commit71d843f41b0e968dca1d2b2b192265505a3eb7b1 (patch)
tree9d076e3924f1dfe57c5d9fff8b3b4a77bc198169 /src
parent5e14a92104c8862849d26badc764b5ea2b8f01bb (diff)
Add a genrule that generates a dummy J2ObjC dead code removal script in tools/objc/BUILD.
-- MOS_MIGRATED_REVID=93447039
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java59
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcConfiguration.java46
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcMappingFileProvider.java50
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcSource.java39
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcSrcsProvider.java26
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundle.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java35
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java3
16 files changed, 265 insertions, 34 deletions
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 fde2683978..e822a0f3fc 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
@@ -145,7 +145,8 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
Optional.of(xcodeProvider),
Optional.of(objcProvider),
xcTestAppProvider,
- Optional.<J2ObjcSrcsProvider>absent());
+ Optional.<J2ObjcSrcsProvider>absent(),
+ Optional.<J2ObjcMappingFileProvider>absent());
for (RunfilesSupport runfilesSupport : maybeRunfilesSupport.asSet()) {
target.setRunfilesSupport(runfilesSupport, runfilesSupport.getExecutable());
}
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 132cf86c4c..ed6edea8ab 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
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.rules.objc;
+import static com.google.devtools.build.lib.rules.objc.J2ObjcSource.SourceType;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DEFINE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FORCE_LOAD_LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_DIR;
@@ -48,6 +49,7 @@ import com.google.devtools.build.lib.analysis.actions.CommandLine;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes;
import com.google.devtools.build.lib.rules.objc.XcodeProvider.Builder;
import com.google.devtools.build.lib.shell.ShellUtils;
@@ -410,11 +412,28 @@ final class CompilationSupport {
*/
CompilationSupport registerJ2ObjcCompileAndArchiveActions(
OptionsProvider optionsProvider, ObjcProvider objcProvider) {
- for (J2ObjcSource j2ObjcSource : ObjcRuleClasses.j2ObjcSrcsProvider(ruleContext).getSrcs()) {
+ J2ObjcSrcsProvider provider = ObjcRuleClasses.j2ObjcSrcsProvider(ruleContext);
+ Iterable<J2ObjcSource> j2ObjcSources = provider.getSrcs();
+ J2ObjcConfiguration j2objcConfiguration = ruleContext.getFragment(J2ObjcConfiguration.class);
+
+ // Only perform J2ObjC dead code stripping if flag --j2objc_dead_code_removal is specified and
+ // users have specified entry classes.
+ boolean stripJ2ObjcDeadCode = j2objcConfiguration.removeDeadCode()
+ && !provider.getEntryClasses().isEmpty();
+
+ if (stripJ2ObjcDeadCode) {
+ registerJ2ObjcDeadCodeRemovalActions(j2ObjcSources, provider.getEntryClasses());
+ }
+
+ for (J2ObjcSource j2ObjcSource : j2ObjcSources) {
+ J2ObjcSource sourceToCompile =
+ j2ObjcSource.getSourceType() == SourceType.JAVA && stripJ2ObjcDeadCode
+ ? j2ObjcSource.toPrunedSource(ruleContext)
+ : j2ObjcSource;
IntermediateArtifacts intermediateArtifacts =
- ObjcRuleClasses.j2objcIntermediateArtifacts(ruleContext, j2ObjcSource);
+ ObjcRuleClasses.j2objcIntermediateArtifacts(ruleContext, sourceToCompile);
CompilationArtifacts compilationArtifact = new CompilationArtifacts.Builder()
- .addNonArcSrcs(j2ObjcSource.getObjcSrcs())
+ .addNonArcSrcs(sourceToCompile.getObjcSrcs())
.setIntermediateArtifacts(intermediateArtifacts)
.setPchFile(Optional.<Artifact>absent())
.build();
@@ -425,6 +444,40 @@ final class CompilationSupport {
return this;
}
+ private void registerJ2ObjcDeadCodeRemovalActions(Iterable<J2ObjcSource> j2ObjcSources,
+ Iterable<String> entryClasses) {
+ Artifact pruner = ruleContext.getPrerequisiteArtifact("$j2objc_dead_code_pruner", Mode.HOST);
+ J2ObjcMappingFileProvider provider = ObjcRuleClasses.j2ObjcMappingFileProvider(ruleContext);
+ NestedSet<Artifact> j2ObjcDependencyMappingFiles = provider.getDependencyMappingFiles();
+ NestedSet<Artifact> j2ObjcHeaderMappingFiles = provider.getHeaderMappingFiles();
+
+ for (J2ObjcSource j2ObjcSource : j2ObjcSources) {
+ if (j2ObjcSource.getSourceType() == SourceType.JAVA) {
+ Iterable<Artifact> sourceArtifacts = j2ObjcSource.getObjcSrcs();
+ Iterable<Artifact> prunedSourceArtifacts =
+ j2ObjcSource.toPrunedSource(ruleContext).getObjcSrcs();
+ PathFragment objcFilePath = j2ObjcSource.getObjcFilePath();
+ ruleContext.registerAction(new SpawnAction.Builder()
+ .setMnemonic("DummyPruner")
+ .setExecutable(pruner)
+ .addInput(pruner)
+ .addInputs(sourceArtifacts)
+ .addTransitiveInputs(j2ObjcDependencyMappingFiles)
+ .addTransitiveInputs(j2ObjcHeaderMappingFiles)
+ .setCommandLine(CustomCommandLine.builder()
+ .addJoinExecPaths("--input_files", ",", sourceArtifacts)
+ .addJoinExecPaths("--output_files", ",", prunedSourceArtifacts)
+ .addJoinExecPaths("--dependency_mapping_files", ",", j2ObjcDependencyMappingFiles)
+ .addJoinExecPaths("--header_mapping_files", ",", j2ObjcHeaderMappingFiles)
+ .add("--entry_classes").add(Joiner.on(",").join(entryClasses))
+ .add("--objc_file_path").add(objcFilePath.getPathString())
+ .build())
+ .addOutputs(prunedSourceArtifacts)
+ .build(ruleContext));
+ }
+ }
+ }
+
/**
* Sets compilation-related Xcode project information on the given provider builder.
*
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 d6d9cad47f..7d1f88b4d4 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
@@ -35,6 +35,14 @@ public class J2ObjcCommandLineOptions extends FragmentOptions {
)
public List<String> translationFlags;
+ @Option(name = "j2objc_dead_code_removal",
+ defaultValue = "false",
+ category = "undocumented",
+ help = "Whether to perform J2ObjC dead code removal to strip unused code from the final app "
+ + "bundle."
+ )
+ public boolean removeDeadCode;
+
@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 35b24d1ce9..116030b2ab 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
@@ -20,7 +20,8 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.ConfigurationEnvironment;
import com.google.devtools.build.lib.analysis.config.ConfigurationFragmentFactory;
-import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventHandler;
import java.util.Collections;
import java.util.Set;
@@ -56,8 +57,7 @@ public class J2ObjcConfiguration extends Fragment {
*/
public static class Loader implements ConfigurationFragmentFactory {
@Override
- public Fragment create(ConfigurationEnvironment env, BuildOptions buildOptions)
- throws InvalidConfigurationException {
+ public Fragment create(ConfigurationEnvironment env, BuildOptions buildOptions) {
return new J2ObjcConfiguration(buildOptions.get(J2ObjcCommandLineOptions.class));
}
@@ -67,23 +67,15 @@ public class J2ObjcConfiguration extends Fragment {
}
}
- private Iterable<String> translationFlags;
- private String cacheKey;
+ private final Set<String> translationFlags;
+ private final boolean removeDeadCode;
- J2ObjcConfiguration(J2ObjcCommandLineOptions j2ObjcOptions) throws InvalidConfigurationException {
- Set<String> translationFlags = ImmutableSet.<String>builder()
+ J2ObjcConfiguration(J2ObjcCommandLineOptions j2ObjcOptions) {
+ this.removeDeadCode = j2ObjcOptions.removeDeadCode;
+ this.translationFlags = ImmutableSet.<String>builder()
.addAll(j2ObjcOptions.translationFlags)
.addAll(J2OBJC_ALWAYS_ON_TRANSLATION_FLAGS)
.build();
-
- if (Collections.disjoint(translationFlags, J2OBJC_BLACKLISTED_TRANSLATION_FLAGS)) {
- this.translationFlags = translationFlags;
- this.cacheKey = Joiner.on(" ").join(this.translationFlags);
- } else {
- throw new InvalidConfigurationException(String.format(INVALID_TRANSLATION_FLAGS_MSG_TEMPLATE,
- Joiner.on(",").join(translationFlags),
- Joiner.on(",").join(J2OBJC_BLACKLISTED_TRANSLATION_FLAGS)));
- }
}
/**
@@ -96,6 +88,16 @@ public class J2ObjcConfiguration extends Fragment {
return translationFlags;
}
+ /**
+ * Returns whether to perform J2ObjC dead code removal. If true, the list of entry classes will be
+ * collected transitively throuh "entry_classes" attribute on j2objc_library and used as entry
+ * points to perform dead code analysis. Unused classes will then be removed from the final ObjC
+ * app bundle.
+ */
+ public boolean removeDeadCode() {
+ return removeDeadCode;
+ }
+
@Override
public String getName() {
return "J2ObjC";
@@ -103,6 +105,16 @@ public class J2ObjcConfiguration extends Fragment {
@Override
public String cacheKey() {
- return cacheKey;
+ return Joiner.on(" ").join(translationFlags) + "-" + String.valueOf(removeDeadCode);
+ }
+
+ @Override
+ public void reportInvalidOptions(EventHandler reporter, BuildOptions buildOptions) {
+ if (!Collections.disjoint(translationFlags, J2OBJC_BLACKLISTED_TRANSLATION_FLAGS)) {
+ String errorMsg = String.format(INVALID_TRANSLATION_FLAGS_MSG_TEMPLATE,
+ Joiner.on(",").join(translationFlags),
+ Joiner.on(",").join(J2OBJC_BLACKLISTED_TRANSLATION_FLAGS));
+ reporter.handle(Event.error(errorMsg));
+ }
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcMappingFileProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcMappingFileProvider.java
index 7ee799e3df..4714ca2d24 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcMappingFileProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcMappingFileProvider.java
@@ -17,6 +17,7 @@ package com.google.devtools.build.lib.rules.objc;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
/**
@@ -28,11 +29,26 @@ public final class J2ObjcMappingFileProvider implements TransitiveInfoProvider {
private final NestedSet<Artifact> headerMappingFiles;
private final NestedSet<Artifact> classMappingFiles;
+ private final NestedSet<Artifact> dependencyMappingFiles;
+ /**
+ * Constructs a {@link J2ObjcMappingFileProvider} with mapping files to export mappings required
+ * by J2ObjC translation and proto compilation.
+ *
+ * @param headerMappingFiles a nested set of header mapping files which map Java classes to
+ * their associated translated ObjC header. Used by J2ObjC to output correct import directives
+ * during translation.
+ * @param classMappingFiles a nested set of class mapping files which map Java class names to
+ * their associated ObjC class names. Used to support J2ObjC package prefixes.
+ * @param dependencyMappingFiles a nested set of dependency mapping files which map translated
+ * ObjC files to their translated direct dependency files. Used to support J2ObjC dead code
+ * analysis and removal.
+ */
public J2ObjcMappingFileProvider(NestedSet<Artifact> headerMappingFiles,
- NestedSet<Artifact> classMappingFiles) {
+ NestedSet<Artifact> classMappingFiles, NestedSet<Artifact> dependencyMappingFiles) {
this.headerMappingFiles = headerMappingFiles;
this.classMappingFiles = classMappingFiles;
+ this.dependencyMappingFiles = dependencyMappingFiles;
}
/**
@@ -52,4 +68,36 @@ public final class J2ObjcMappingFileProvider implements TransitiveInfoProvider {
public NestedSet<Artifact> getClassMappingFiles() {
return classMappingFiles;
}
+
+ /**
+ * Returns the mapping files containing file dependency information among the translated ObjC
+ * source files. They are used to strip unused translated files before the compilation and linking
+ * actions at binary level.
+ */
+ public NestedSet<Artifact> getDependencyMappingFiles() {
+ return dependencyMappingFiles;
+ }
+
+ /**
+ * A builder for this provider that is optimized for collection information from transitive
+ * dependencies.
+ */
+ public static final class Builder {
+ private final NestedSetBuilder<Artifact> headerMappingFiles = NestedSetBuilder.stableOrder();
+ private final NestedSetBuilder<Artifact> classMappingFiles = NestedSetBuilder.stableOrder();
+ private final NestedSetBuilder<Artifact> depEntryFiles = NestedSetBuilder.stableOrder();
+
+ public Builder addTransitive(J2ObjcMappingFileProvider provider) {
+ headerMappingFiles.addTransitive(provider.getHeaderMappingFiles());
+ classMappingFiles.addTransitive(provider.getClassMappingFiles());
+ depEntryFiles.addTransitive(provider.getDependencyMappingFiles());
+
+ return this;
+ }
+
+ public J2ObjcMappingFileProvider build() {
+ return new J2ObjcMappingFileProvider(
+ headerMappingFiles.build(), classMappingFiles.build(), depEntryFiles.build());
+ }
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcSource.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcSource.java
index 81ba292314..dc7251ee3a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcSource.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcSource.java
@@ -15,9 +15,13 @@
package com.google.devtools.build.lib.rules.objc;
import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.AnalysisUtils;
+import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.syntax.Label;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
/**
@@ -67,6 +71,41 @@ public class J2ObjcSource {
}
/**
+ * Returns a corresponding {@link J2ObjcSource} with source artifacts replaced by the outputs of
+ * the J2objC dead code removal script, for use after that action has processed the originals.
+ *
+ * <p>The script in question builds a dependency graph with entry classes specified
+ * transitively on j2objc_library rules as roots. Translated files from this (original)
+ * {@link J2ObjcSource} which are reachable in the graph from the roots will be copied over to the
+ * source file paths in the returned pruned {@link J2ObjcSource} with full original contents.
+ * Unreachable files will not be copied over and the artifacts pointed to by the returned pruned
+ * {@link J2ObjcSource} will only contain empty files.
+ *
+ * @param ruleContext the {@link RuleContext} of the current rule
+ */
+ public J2ObjcSource toPrunedSource(RuleContext ruleContext) {
+ ImmutableList.Builder<Artifact> prunedSourceArtifacts = ImmutableList.builder();
+
+ for (Artifact sourceArtifact : getObjcSrcs()) {
+ PathFragment scopedPath = AnalysisUtils.getUniqueDirectory(
+ ruleContext.getRule().getLabel(), new PathFragment("_j2objc_pruned"));
+ PathFragment prunedSourceArtifactPath = FileSystemUtils.appendWithoutExtension(
+ scopedPath.getRelative(sourceArtifact.getRootRelativePath()), "_pruned");
+
+ Artifact prunedArtifact = ruleContext.getAnalysisEnvironment().getDerivedArtifact(
+ prunedSourceArtifactPath, ruleContext.getBinOrGenfilesDirectory());
+ prunedSourceArtifacts.add(prunedArtifact);
+ }
+
+ return new J2ObjcSource(
+ getTargetLabel(),
+ prunedSourceArtifacts.build(),
+ getObjcHdrs(),
+ getObjcFilePath(),
+ getSourceType());
+ }
+
+ /**
* Returns the label of the associated target.
*/
public Label getTargetLabel() {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcSrcsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcSrcsProvider.java
index 1e577c5939..4a887ba492 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcSrcsProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcSrcsProvider.java
@@ -14,10 +14,13 @@
package com.google.devtools.build.lib.rules.objc;
+import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import java.util.Set;
+
/**
* This provider is exported by java_library rules to supply J2ObjC-translated ObjC sources to
* objc_binary for compilation and linking.
@@ -25,10 +28,23 @@ import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
@Immutable
public final class J2ObjcSrcsProvider implements TransitiveInfoProvider {
private final NestedSet<J2ObjcSource> srcs;
+ private final ImmutableSet<String> entryClasses;
private final boolean hasProtos;
- public J2ObjcSrcsProvider(NestedSet<J2ObjcSource> srcs, boolean hasProtos) {
+ /**
+ * Constructs a {@link J2ObjcSrcsProvider} to supply J2ObjC-translated ObjC sources to
+ * objc_binary for compilation and linking.
+ *
+ * @param srcs a nested set of {@link J2ObjcSource}s containing translated source files
+ * @param entryClasses a set of names of Java classes to used as entry point for J2ObjC dead code
+ * analysis. The Java class names should be in canonical format as defined by the Java
+ * Language Specification.
+ * @param hasProtos whether the translated files in this provider have J2ObjC proto files
+ */
+ public J2ObjcSrcsProvider(NestedSet<J2ObjcSource> srcs, ImmutableSet<String> entryClasses,
+ boolean hasProtos) {
this.srcs = srcs;
+ this.entryClasses = entryClasses;
this.hasProtos = hasProtos;
}
@@ -37,6 +53,14 @@ public final class J2ObjcSrcsProvider implements TransitiveInfoProvider {
}
/**
+ * Returns a set of entry classes specified on attribute entry_classes of j2objc_library targets
+ * transitively.
+ */
+ public Set<String> getEntryClasses() {
+ return entryClasses;
+ }
+
+ /**
* Returns whether the translated source files in the provider has proto files.
*/
public boolean hasProtos() {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundle.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundle.java
index 6585cbaf73..7eb806c1a5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundle.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundle.java
@@ -46,6 +46,7 @@ public class ObjcBundle implements RuleConfiguredTargetFactory {
Optional.<XcodeProvider>absent(),
Optional.of(common.getObjcProvider()),
Optional.<XcTestAppProvider>absent(),
- Optional.<J2ObjcSrcsProvider>absent());
+ Optional.<J2ObjcSrcsProvider>absent(),
+ Optional.<J2ObjcMappingFileProvider>absent());
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
index 4506e6e1ae..fcf9c315b4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
@@ -69,7 +69,8 @@ public class ObjcBundleLibrary implements RuleConfiguredTargetFactory {
Optional.of(xcodeProviderBuilder.build()),
Optional.of(nestedBundleProvider),
Optional.<XcTestAppProvider>absent(),
- Optional.<J2ObjcSrcsProvider>absent());
+ Optional.<J2ObjcSrcsProvider>absent(),
+ Optional.<J2ObjcMappingFileProvider>absent());
}
private OptionsProvider optionsProvider(RuleContext ruleContext) {
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 775a211555..20806aff82 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
@@ -589,7 +589,8 @@ public final class ObjcCommon {
public RuleConfiguredTargetBuilder configuredTargetBuilder(NestedSet<Artifact> filesToBuild,
Optional<XcodeProvider> maybeTargetProvider, Optional<ObjcProvider> maybeExportedProvider,
Optional<XcTestAppProvider> maybeXcTestAppProvider,
- Optional<J2ObjcSrcsProvider> maybeJ2ObjcSrcsProvider) {
+ Optional<J2ObjcSrcsProvider> maybeJ2ObjcSrcsProvider,
+ Optional<J2ObjcMappingFileProvider> maybeJ2ObjcMappingFileProvider) {
NestedSet<Artifact> allFilesToBuild = NestedSetBuilder.<Artifact>stableOrder()
.addTransitive(filesToBuild)
.build();
@@ -615,6 +616,10 @@ public final class ObjcCommon {
for (J2ObjcSrcsProvider j2ObjcSrcsProvider : maybeJ2ObjcSrcsProvider.asSet()) {
target.addProvider(J2ObjcSrcsProvider.class, j2ObjcSrcsProvider);
}
+ for (J2ObjcMappingFileProvider j2ObjcMappingFileProvider
+ : maybeJ2ObjcMappingFileProvider.asSet()) {
+ target.addProvider(J2ObjcMappingFileProvider.class, j2ObjcMappingFileProvider);
+ }
return target;
}
@@ -632,8 +637,9 @@ public final class ObjcCommon {
public ConfiguredTarget configuredTarget(NestedSet<Artifact> filesToBuild,
Optional<XcodeProvider> maybeTargetProvider, Optional<ObjcProvider> maybeExportedProvider,
Optional<XcTestAppProvider> maybeXcTestAppProvider,
- Optional<J2ObjcSrcsProvider> maybeJ2ObjcSrcsProvider) {
+ Optional<J2ObjcSrcsProvider> maybeJ2ObjcSrcsProvider,
+ Optional<J2ObjcMappingFileProvider> maybeJ2ObjcMappingFileProvider) {
return configuredTargetBuilder(filesToBuild, maybeTargetProvider, maybeExportedProvider,
- maybeXcTestAppProvider, maybeJ2ObjcSrcsProvider).build();
+ maybeXcTestAppProvider, maybeJ2ObjcSrcsProvider, maybeJ2ObjcMappingFileProvider).build();
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java
index c6a003757e..5e670f6dd5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java
@@ -55,6 +55,7 @@ public class ObjcFramework implements RuleConfiguredTargetFactory {
Optional.<XcodeProvider>absent(),
Optional.of(common.getObjcProvider()),
Optional.<XcTestAppProvider>absent(),
- Optional.<J2ObjcSrcsProvider>absent());
+ Optional.<J2ObjcSrcsProvider>absent(),
+ Optional.<J2ObjcMappingFileProvider>absent());
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java
index 6c4bf2290a..dc80de46d5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java
@@ -66,6 +66,7 @@ public class ObjcImport implements RuleConfiguredTargetFactory {
Optional.of(xcodeProviderBuilder.build()),
Optional.of(common.getObjcProvider()),
Optional.<XcTestAppProvider>absent(),
- Optional.<J2ObjcSrcsProvider>absent());
+ Optional.<J2ObjcSrcsProvider>absent(),
+ Optional.<J2ObjcMappingFileProvider>absent());
}
}
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 7d62173376..28c9314d55 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
@@ -111,7 +111,8 @@ public class ObjcLibrary implements RuleConfiguredTargetFactory {
Optional.of(xcodeProviderBuilder.build()),
Optional.of(common.getObjcProvider()),
Optional.<XcTestAppProvider>absent(),
- Optional.of(ObjcRuleClasses.j2ObjcSrcsProvider(ruleContext)));
+ Optional.of(ObjcRuleClasses.j2ObjcSrcsProvider(ruleContext)),
+ Optional.of(ObjcRuleClasses.j2ObjcMappingFileProvider(ruleContext)));
}
private OptionsProvider optionsProvider(RuleContext ruleContext) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java
index c11c7bb213..ae6464dd95 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java
@@ -215,7 +215,8 @@ public class ObjcProtoLibrary implements RuleConfiguredTargetFactory {
Optional.of(xcodeProvider),
Optional.of(common.getObjcProvider()),
Optional.<XcTestAppProvider>absent(),
- Optional.<J2ObjcSrcsProvider>absent());
+ Optional.<J2ObjcSrcsProvider>absent(),
+ Optional.<J2ObjcMappingFileProvider>absent());
}
private NestedSet<Artifact> maybeGetProtoSources(RuleContext ruleContext) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
index e038039b73..024fbe1211 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
@@ -153,12 +153,14 @@ public class ObjcRuleClasses {
builder.addAll(currentSource.asSet());
boolean hasProtos = currentSource.isPresent()
&& currentSource.get().getSourceType() == J2ObjcSource.SourceType.PROTO;
+ ImmutableSet.Builder<String> entryClasses = ImmutableSet.builder();
if (ruleContext.attributes().has("deps", Type.LABEL_LIST)) {
for (J2ObjcSrcsProvider provider :
ruleContext.getPrerequisites("deps", Mode.TARGET, J2ObjcSrcsProvider.class)) {
builder.addTransitive(provider.getSrcs());
hasProtos |= provider.hasProtos();
+ entryClasses.addAll(provider.getEntryClasses());
}
}
@@ -167,10 +169,35 @@ public class ObjcRuleClasses {
ruleContext.getPrerequisites("exports", Mode.TARGET, J2ObjcSrcsProvider.class)) {
builder.addTransitive(provider.getSrcs());
hasProtos |= provider.hasProtos();
+ entryClasses.addAll(provider.getEntryClasses());
}
}
- return new J2ObjcSrcsProvider(builder.build(), hasProtos);
+ if (ruleContext.attributes().has("entry_classes", Type.STRING_LIST)) {
+ entryClasses.addAll(ruleContext.attributes().get("entry_classes", Type.STRING_LIST));
+ }
+
+ return new J2ObjcSrcsProvider(builder.build(), entryClasses.build(), hasProtos);
+ }
+
+
+ /**
+ * Returns a {@link J2ObjcMappingFileProvider} containing J2ObjC mapping files from rules
+ * that can be reached transitively through the "deps" attribute.
+ *
+ * @param ruleContext the rule context of the current rule
+ * @return a {@link J2ObjcMappingFileProvider} containing J2ObjC mapping files information from
+ * the transitive closure.
+ */
+ public static J2ObjcMappingFileProvider j2ObjcMappingFileProvider(RuleContext ruleContext) {
+ J2ObjcMappingFileProvider.Builder builder = new J2ObjcMappingFileProvider.Builder();
+ Iterable<J2ObjcMappingFileProvider> providers =
+ ruleContext.getPrerequisites("deps", Mode.TARGET, J2ObjcMappingFileProvider.class);
+ for (J2ObjcMappingFileProvider provider : providers) {
+ builder.addTransitive(provider);
+ }
+
+ return builder.build();
}
public static Artifact artifactByAppendingToBaseName(RuleContext context, String suffix) {
@@ -669,6 +696,12 @@ public class ObjcRuleClasses {
return configuration.getFragment(ObjcConfiguration.class).getDumpSymsLabel();
}
}))
+ .add(attr("$j2objc_dead_code_pruner", LABEL)
+ .allowedFileTypes(FileType.of(".py"))
+ .cfg(HOST)
+ .exec()
+ .singleArtifact()
+ .value(env.getLabel("//tools/objc:j2objc_dead_code_pruner")))
.build();
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java
index bdbad39901..b3e27c1363 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java
@@ -108,7 +108,8 @@ public abstract class ReleaseBundlingTargetFactory implements RuleConfiguredTarg
Optional.of(xcodeProviderBuilder.build()),
exposedObjcProvider,
Optional.of(releaseBundlingSupport.xcTestAppProvider()),
- Optional.<J2ObjcSrcsProvider>absent());
+ Optional.<J2ObjcSrcsProvider>absent(),
+ Optional.<J2ObjcMappingFileProvider>absent());
configureTarget(target, ruleContext, releaseBundlingSupport);
return target.build();
}