aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Rumou Duan <rduan@google.com>2015-10-07 01:18:54 +0000
committerGravatar Lukacs Berki <lberki@google.com>2015-10-07 07:12:00 +0000
commitc383d034d32231f2eaf58aa3efed562574d5fc32 (patch)
tree9fa2c7f4871a43a813a2be6ad66c09644ea7ce95 /src
parent3cd6c64d75ed9135db9b6cd96e03321359d9c5a9 (diff)
Add a mapping and relevant function calls in ObjcProvider to provide a way to construct and export a J2ObjC-code-and-dep-only view of the ObjcProvider, which is then used to create the compile action for J2ObjC-generated code at the binary level. This greatly reduces the number of input artifacts for such actions.
Also export header search paths at the edges (J2ObjcAsepct and J2ObjcProtoAspect) instead of in j2objc_library. This change removes some unnecessary header search paths. -- MOS_MIGRATED_REVID=104821185
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java14
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java42
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcSource.java26
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java97
6 files changed, 157 insertions, 34 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java
index 5bce8689eb..8eff14704d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java
@@ -31,6 +31,7 @@ import com.google.devtools.build.lib.packages.AspectDefinition;
import com.google.devtools.build.lib.packages.AspectParameters;
import com.google.devtools.build.lib.rules.proto.ProtoCommon;
import com.google.devtools.build.lib.rules.proto.ProtoSourcesProvider;
+import com.google.devtools.build.lib.vfs.PathFragment;
/**
* J2ObjC aspect for the proto_library rule.
@@ -132,13 +133,18 @@ public abstract class AbstractJ2ObjcProtoAspect implements ConfiguredAspectFacto
Iterable<Artifact> generatedSourceFiles = checkShouldCreateSources(ruleContext)
? ProtoCommon.getGeneratedOutputs(ruleContext, protoSources, ".j2objc.pb.m")
: ImmutableList.<Artifact>of();
+ PathFragment objcFileRootExecPath = ruleContext.getConfiguration().getGenfilesDirectory()
+ .getExecPath();
+ Iterable<PathFragment> headerSearchPaths = J2ObjcLibrary.j2objcSourceHeaderSearchPaths(
+ ruleContext, objcFileRootExecPath, protoSources);
return new J2ObjcSource(
ruleContext.getTarget().getLabel(),
generatedSourceFiles,
ProtoCommon.getGeneratedOutputs(ruleContext, protoSources, ".j2objc.pb.h"),
- ruleContext.getConfiguration().getGenfilesDirectory().getExecPath(),
- SourceType.PROTO);
+ objcFileRootExecPath,
+ SourceType.PROTO,
+ headerSearchPaths);
}
private static Iterable<Artifact> headerMappingFiles(RuleContext ruleContext,
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 d3ad0e17d7..be937b45b2 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
@@ -937,7 +937,7 @@ public final class CompilationSupport {
registerCompileAndArchiveActions(
compilationArtifact,
intermediateArtifacts,
- objcProvider,
+ objcProvider.toJ2ObjcOnlyProvider(),
moduleMap,
ruleContext.getConfiguration().isCodeCoverageEnabled(),
false);
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 f6a527bde6..84427d46f8 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
@@ -272,7 +272,7 @@ public class J2ObjcAspect implements ConfiguredAspectFactory {
private J2ObjcSource buildJ2ObjcSource(RuleContext ruleContext,
Iterable<Artifact> javaInputSourceFiles) {
PathFragment objcFileRootRelativePath = ruleContext.getUniqueDirectory("_j2objc");
- PathFragment objcFilePath = ruleContext
+ PathFragment objcFileRootExecPath = ruleContext
.getConfiguration()
.getBinFragment()
.getRelative(objcFileRootRelativePath);
@@ -280,8 +280,16 @@ public class J2ObjcAspect implements ConfiguredAspectFactory {
objcFileRootRelativePath, ".m");
Iterable<Artifact> objcHdrs = getOutputObjcFiles(ruleContext, javaInputSourceFiles,
objcFileRootRelativePath, ".h");
- return new J2ObjcSource(ruleContext.getRule().getLabel(), objcSrcs, objcHdrs, objcFilePath,
- SourceType.JAVA);
+ Iterable<PathFragment> headerSearchPaths = J2ObjcLibrary.j2objcSourceHeaderSearchPaths(
+ ruleContext, objcFileRootExecPath, javaInputSourceFiles);
+
+ return new J2ObjcSource(
+ ruleContext.getRule().getLabel(),
+ objcSrcs,
+ objcHdrs,
+ objcFileRootExecPath,
+ SourceType.JAVA,
+ headerSearchPaths);
}
private Iterable<Artifact> getOutputObjcFiles(RuleContext ruleContext,
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 4555959e2b..e072c0d5d6 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
@@ -60,9 +60,9 @@ public class J2ObjcLibrary implements RuleConfiguredTargetFactory {
ObjcProvider.Builder objcProviderBuilder =
new ObjcProvider.Builder()
- .addTransitiveAndPropagate(
+ .addJ2ObjcTransitiveAndPropagate(
ruleContext.getPrerequisite("$jre_emul_lib", Mode.TARGET, ObjcProvider.class))
- .addTransitiveAndPropagate(
+ .addJ2ObjcTransitiveAndPropagate(
ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProvider.class));
XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder();
@@ -74,23 +74,17 @@ public class J2ObjcLibrary implements RuleConfiguredTargetFactory {
if (j2ObjcSrcsProvider.hasProtos()) {
// Public J2 in Bazel provides no protobuf_lib, and if OSS users try to sneakily use
// undocumented functionality to reach here, the below code will error.
- objcProviderBuilder.addTransitiveAndPropagate(
+ objcProviderBuilder.addJ2ObjcTransitiveAndPropagate(
ruleContext.getPrerequisite("$protobuf_lib", Mode.TARGET, ObjcProvider.class));
xcodeSupport.addDependencies(
xcodeProviderBuilder, new Attribute("$protobuf_lib", Mode.TARGET));
}
for (J2ObjcSource j2objcSource : j2ObjcSrcsProvider.getSrcs()) {
- PathFragment genDirHeaderSearchPath =
- new PathFragment(
- j2objcSource.getObjcFilePath(), ruleContext.getConfiguration().getGenfilesFragment());
-
- objcProviderBuilder.addAll(ObjcProvider.HEADER, j2objcSource.getObjcHdrs());
- objcProviderBuilder.add(ObjcProvider.INCLUDE, j2objcSource.getObjcFilePath());
- objcProviderBuilder.add(ObjcProvider.INCLUDE, genDirHeaderSearchPath);
+ objcProviderBuilder.addJ2ObjcAll(ObjcProvider.HEADER, j2objcSource.getObjcHdrs());
+ objcProviderBuilder.addJ2ObjcAll(ObjcProvider.INCLUDE, j2objcSource.getHeaderSearchPaths());
xcodeProviderBuilder.addHeaders(j2objcSource.getObjcHdrs());
- xcodeProviderBuilder.addUserHeaderSearchPaths(
- ImmutableList.of(j2objcSource.getObjcFilePath(), genDirHeaderSearchPath));
+ xcodeProviderBuilder.addUserHeaderSearchPaths(j2objcSource.getHeaderSearchPaths());
}
if (ObjcRuleClasses.objcConfiguration(ruleContext).moduleMapsEnabled()) {
@@ -112,6 +106,30 @@ public class J2ObjcLibrary implements RuleConfiguredTargetFactory {
}
/**
+ * Returns header search paths necessary to compile the J2ObjC-generated code from a single
+ * target.
+ *
+ * @param ruleContext the rule context
+ * @param objcFileRootExecPath the exec path under which all J2ObjC-generated file resides
+ * @param sourcesToTranslate the source files to be translated by J2ObjC in a single target
+ */
+ public static Iterable<PathFragment> j2objcSourceHeaderSearchPaths(RuleContext ruleContext,
+ PathFragment objcFileRootExecPath, Iterable<Artifact> sourcesToTranslate) {
+ PathFragment genRoot = ruleContext.getConfiguration().getGenfilesFragment();
+ ImmutableList.Builder<PathFragment> headerSearchPaths = ImmutableList.builder();
+ headerSearchPaths.add(objcFileRootExecPath);
+ // We add another header search path with gen root if we have generated sources to translate.
+ for (Artifact sourceToTranslate : sourcesToTranslate) {
+ if (!sourceToTranslate.isSourceArtifact()) {
+ headerSearchPaths.add(new PathFragment(objcFileRootExecPath, genRoot));
+ return headerSearchPaths.build();
+ }
+ }
+
+ return headerSearchPaths.build();
+ }
+
+ /**
* Configures a module map for all the sources in {@code j2ObjcSrcsProvider}, registering
* an action to generate the module map and exposing that module map through {@code objcProvider}.
*/
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 bdc785854a..8d33c15b1b 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
@@ -50,6 +50,7 @@ public class J2ObjcSource {
private final Iterable<Artifact> objcHdrs;
private final PathFragment objcFilePath;
private final SourceType sourceType;
+ private final Iterable<PathFragment> headerSearchPaths;
/**
* Constructs a J2ObjcSource containing target information for j2objc transpilation.
@@ -60,14 +61,18 @@ public class J2ObjcSource {
* @param objcFilePath the {@code PathFragment} under which all the generated objc files are. It
* can be used as header search path for objc compilations.
* @param sourceType the type of files from which the ObjC files are generated.
+ * @param headerSearchPaths the {@code Iterable} of header search paths necessary for compiling
+ * the generated J2ObjC sources in {@link objcSrcs}
*/
public J2ObjcSource(Label targetLabel, Iterable<Artifact> objcSrcs,
- Iterable<Artifact> objcHdrs, PathFragment objcFilePath, SourceType sourceType) {
+ Iterable<Artifact> objcHdrs, PathFragment objcFilePath, SourceType sourceType,
+ Iterable<PathFragment> headerSearchPaths) {
this.targetLabel = targetLabel;
this.objcSrcs = objcSrcs;
this.objcHdrs = objcHdrs;
this.objcFilePath = objcFilePath;
this.sourceType = sourceType;
+ this.headerSearchPaths = headerSearchPaths;
}
/**
@@ -99,7 +104,8 @@ public class J2ObjcSource {
prunedSourceArtifacts.build(),
getObjcHdrs(),
getObjcFilePath(),
- getSourceType());
+ getSourceType(),
+ getHeaderSearchPaths());
}
/**
@@ -125,13 +131,20 @@ public class J2ObjcSource {
/**
* Returns the {@code PathFragment} which represents a directory where the generated ObjC files
- * reside and which can also be used as header search path in ObjC compilation.
+ * reside.
*/
public PathFragment getObjcFilePath() {
return objcFilePath;
}
/**
+ * Returns a list of header search paths necessary for compiling the generated J2ObjC sources.
+ */
+ public Iterable<PathFragment> getHeaderSearchPaths() {
+ return headerSearchPaths;
+ }
+
+ /**
* Returns the type of files from which the ObjC files inside this object are generated.
*/
public SourceType getSourceType() {
@@ -156,12 +169,15 @@ public class J2ObjcSource {
&& Iterators.elementsEqual(this.objcSrcs.iterator(), that.objcSrcs.iterator())
&& Iterators.elementsEqual(this.objcHdrs.iterator(), that.objcHdrs.iterator())
&& Objects.equal(this.objcFilePath, that.objcFilePath)
- && this.sourceType == that.sourceType;
+ && this.sourceType == that.sourceType
+ && Iterators.elementsEqual(
+ this.headerSearchPaths.iterator(), that.headerSearchPaths.iterator());
}
@Override
public int hashCode() {
- return Objects.hashCode(targetLabel, objcSrcs, objcHdrs, objcFilePath, sourceType);
+ return Objects.hashCode(targetLabel, objcSrcs, objcHdrs, objcFilePath, sourceType,
+ headerSearchPaths);
}
}
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 85e05dc10f..dbca5e0269 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
@@ -241,11 +241,16 @@ public final class ObjcProvider implements TransitiveInfoProvider {
// Items which should be passed to direct dependers, but not transitive dependers.
private final ImmutableMap<Key<?>, NestedSet<?>> nonPropagatedItems;
+ // Items which are relevent only for J2ObjC-translated sources.
+ private final ImmutableMap<Key<?>, NestedSet<?>> j2ObjcOnlyItems;
+
private ObjcProvider(
ImmutableMap<Key<?>, NestedSet<?>> items,
- ImmutableMap<Key<?>, NestedSet<?>> nonPropagatedItems) {
+ ImmutableMap<Key<?>, NestedSet<?>> nonPropagatedItems,
+ ImmutableMap<Key<?>, NestedSet<?>> j2ObjcOnlyItems) {
this.items = Preconditions.checkNotNull(items);
this.nonPropagatedItems = Preconditions.checkNotNull(nonPropagatedItems);
+ this.j2ObjcOnlyItems = Preconditions.checkNotNull(j2ObjcOnlyItems);
}
/**
@@ -280,12 +285,25 @@ public final class ObjcProvider implements TransitiveInfoProvider {
}
/**
+ * Returns a corresponding provider that contains only information relevent for J2ObjC-translated
+ * code. This trimmed provider offers a view that is used for compilation actions of
+ * J2ObjC-translated sources to avoid pulling in unnecessary dependent information from the rest
+ * of the transitive closure.
+ */
+ // TODO(rduan): Roll this back once J2ObjC compilation is moved to the edges in the dep graph.
+ public ObjcProvider toJ2ObjcOnlyProvider() {
+ return new ObjcProvider(j2ObjcOnlyItems, ImmutableMap.<Key<?>, NestedSet<?>>of(),
+ j2ObjcOnlyItems);
+ }
+
+ /**
* A builder for this context with an API that is optimized for collecting information from
* several transitive dependencies.
*/
public static final class Builder {
private final Map<Key<?>, NestedSetBuilder<?>> items = new HashMap<>();
private final Map<Key<?>, NestedSetBuilder<?>> nonPropagatedItems = new HashMap<>();
+ private final Map<Key<?>, NestedSetBuilder<?>> j2ObjcPropagatedItems = new HashMap<>();
private static void maybeAddEmptyBuilder(Map<Key<?>, NestedSetBuilder<?>> set, Key<?> key) {
if (!set.containsKey(key)) {
@@ -294,15 +312,14 @@ public final class ObjcProvider implements TransitiveInfoProvider {
}
@SuppressWarnings({"rawtypes", "unchecked"})
- private void uncheckedAddAll(Key key, Iterable toAdd, boolean propagate) {
- Map<Key<?>, NestedSetBuilder<?>> set = propagate ? items : nonPropagatedItems;
+ private void uncheckedAddAll(Key key, Iterable toAdd, Map<Key<?>, NestedSetBuilder<?>> set) {
maybeAddEmptyBuilder(set, key);
set.get(key).addAll(toAdd);
}
@SuppressWarnings({"rawtypes", "unchecked"})
- private void uncheckedAddTransitive(Key key, NestedSet toAdd, boolean propagate) {
- Map<Key<?>, NestedSetBuilder<?>> set = propagate ? items : nonPropagatedItems;
+ private void uncheckedAddTransitive(Key key, NestedSet toAdd,
+ Map<Key<?>, NestedSetBuilder<?>> set) {
maybeAddEmptyBuilder(set, key);
set.get(key).addTransitive(toAdd);
}
@@ -312,7 +329,7 @@ public final class ObjcProvider implements TransitiveInfoProvider {
* ObjcProvider.
*/
public <E> Builder addTransitiveAndPropagate(Key<E> key, NestedSet<E> items) {
- uncheckedAddTransitive(key, items, true);
+ uncheckedAddTransitive(key, items, this.items);
return this;
}
@@ -322,7 +339,26 @@ public final class ObjcProvider implements TransitiveInfoProvider {
*/
public Builder addTransitiveAndPropagate(ObjcProvider provider) {
for (Map.Entry<Key<?>, NestedSet<?>> typeEntry : provider.items.entrySet()) {
- uncheckedAddTransitive(typeEntry.getKey(), typeEntry.getValue(), true);
+ uncheckedAddTransitive(typeEntry.getKey(), typeEntry.getValue(), this.items);
+ }
+ for (Map.Entry<Key<?>, NestedSet<?>> typeEntry : provider.j2ObjcOnlyItems.entrySet()) {
+ uncheckedAddTransitive(typeEntry.getKey(), typeEntry.getValue(),
+ this.j2ObjcPropagatedItems);
+ }
+ return this;
+ }
+
+ /**
+ * Add all elements from provider relevent to J2ObjC (providers directly exporting
+ * J2ObjC-translated code, J2ObjC runtime deps, etc.), and propagate them to any (transitive)
+ * dependers on this ObjcProvider.
+ */
+ // TODO(rduan): Roll this back once J2ObjC compilation is moved to the edges in the dep graph.
+ public Builder addJ2ObjcTransitiveAndPropagate(ObjcProvider provider) {
+ addTransitiveAndPropagate(provider);
+ for (Map.Entry<Key<?>, NestedSet<?>> typeEntry : provider.items.entrySet()) {
+ uncheckedAddTransitive(typeEntry.getKey(), typeEntry.getValue(),
+ this.j2ObjcPropagatedItems);
}
return this;
}
@@ -348,6 +384,19 @@ public final class ObjcProvider implements TransitiveInfoProvider {
}
/**
+ * Add all elements from providers relevent to J2ObjC (providers directly exporting
+ * J2ObjC-translated code, J2ObjC runtime deps, etc.), and propagate them to any (transitive)
+ * dependers on this ObjcProvider.
+ */
+ // TODO(rduan): Roll this back once J2ObjC compilation is moved to the edges in the dep graph.
+ public Builder addJ2ObjcTransitiveAndPropagate(Iterable<ObjcProvider> providers) {
+ for (ObjcProvider provider : providers) {
+ addJ2ObjcTransitiveAndPropagate(provider);
+ }
+ return this;
+ }
+
+ /**
* Add elements from providers, but don't propagate them to any dependers on this ObjcProvider.
* These elements will be exposed to {@link #get(Key)} calls, but not to any ObjcProviders
* which add this provider to themselves.
@@ -355,7 +404,7 @@ public final class ObjcProvider implements TransitiveInfoProvider {
public Builder addTransitiveWithoutPropagating(Iterable<ObjcProvider> providers) {
for (ObjcProvider provider : providers) {
for (Map.Entry<Key<?>, NestedSet<?>> typeEntry : provider.items.entrySet()) {
- uncheckedAddTransitive(typeEntry.getKey(), typeEntry.getValue(), false);
+ uncheckedAddTransitive(typeEntry.getKey(), typeEntry.getValue(), this.nonPropagatedItems);
}
}
return this;
@@ -365,7 +414,18 @@ public final class ObjcProvider implements TransitiveInfoProvider {
* Add element, and propagate it to any (transitive) dependers on this ObjcProvider.
*/
public <E> Builder add(Key<E> key, E toAdd) {
- uncheckedAddAll(key, ImmutableList.of(toAdd), true);
+ uncheckedAddAll(key, ImmutableList.of(toAdd), this.items);
+ return this;
+ }
+
+ /**
+ * Add element relevent to J2ObjC (elements containing information for J2ObjC-translated code),
+ * and propagate it to any (transitive) dependers on this ObjcProvider.
+ */
+ // TODO(rduan): Roll this back once J2ObjC compilation is moved to the edges in the dep graph.
+ public <E> Builder addJ2Objc(Key<E> key, E toAdd) {
+ uncheckedAddAll(key, ImmutableList.of(toAdd), this.items);
+ uncheckedAddAll(key, ImmutableList.of(toAdd), this.j2ObjcPropagatedItems);
return this;
}
@@ -373,7 +433,18 @@ public final class ObjcProvider implements TransitiveInfoProvider {
* Add elements in toAdd, and propagate them to any (transitive) dependers on this ObjcProvider.
*/
public <E> Builder addAll(Key<E> key, Iterable<? extends E> toAdd) {
- uncheckedAddAll(key, toAdd, true);
+ uncheckedAddAll(key, toAdd, this.items);
+ return this;
+ }
+
+ /**
+ * Add elements relevent to J2ObjC (elements containing information for J2ObjC-translated code),
+ * and propagate them to any (transitive) dependers on this ObjcProvider.
+ */
+ // TODO(rduan): Roll this back once J2ObjC compilation is moved to the edges in the dep graph.
+ public <E> Builder addJ2ObjcAll(Key<E> key, Iterable<? extends E> toAdd) {
+ uncheckedAddAll(key, toAdd, this.items);
+ uncheckedAddAll(key, toAdd, this.j2ObjcPropagatedItems);
return this;
}
@@ -386,7 +457,11 @@ public final class ObjcProvider implements TransitiveInfoProvider {
for (Map.Entry<Key<?>, NestedSetBuilder<?>> typeEntry : nonPropagatedItems.entrySet()) {
nonPropagated.put(typeEntry.getKey(), typeEntry.getValue().build());
}
- return new ObjcProvider(propagated.build(), nonPropagated.build());
+ ImmutableMap.Builder<Key<?>, NestedSet<?>> j2ObjcPropagated = new ImmutableMap.Builder<>();
+ for (Map.Entry<Key<?>, NestedSetBuilder<?>> typeEntry : j2ObjcPropagatedItems.entrySet()) {
+ j2ObjcPropagated.put(typeEntry.getKey(), typeEntry.getValue().build());
+ }
+ return new ObjcProvider(propagated.build(), nonPropagated.build(), j2ObjcPropagated.build());
}
}
}