aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2017-05-01 19:00:58 +0200
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2017-05-02 11:25:51 +0200
commit5da0dd559885e3175e28b9d4b11fc6408939f211 (patch)
tree24929477d3b1119e1df13ddd0e50a00a56cdb59d /src/main/java/com/google/devtools
parent248581e8c72687c85b5c41edaea6780c8701aa55 (diff)
Automated g4 rollback of commit e7fe50aa727df9ef0a3d37fa258d017971035515. *** Reason for rollback *** Roll forward. The bzl change is removed because it has to be submitted after next Blaze release. *** Original change description *** Automated g4 rollback of commit 5f31944b8942818aaf53571c76f5c6a9a9dafc72. *** Reason for rollback *** This caused some build breaks. *** Original change description *** Custom module map for j2objc_library PiperOrigin-RevId: 154726197
Diffstat (limited to 'src/main/java/com/google/devtools')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java17
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMap.java27
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMapAction.java63
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/UmbrellaHeaderAction.java124
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java18
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java35
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java8
10 files changed, 287 insertions, 21 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
index 3154b16a34..35b39eedea 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.lib.rules.cpp;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -1384,6 +1385,11 @@ public final class CcLibraryHelper {
featureConfiguration.isEnabled(CppRuleClasses.HEADER_MODULES)
|| featureConfiguration.isEnabled(CppRuleClasses.COMPILE_ALL_MODULES);
Iterable<CppModuleMap> dependentModuleMaps = collectModuleMaps();
+ Optional<Artifact> umbrellaHeader = cppModuleMap.getUmbrellaHeader();
+ if (umbrellaHeader.isPresent()) {
+ ruleContext.registerAction(
+ createUmbrellaHeaderAction(umbrellaHeader.get(), publicHeaders));
+ }
ruleContext.registerAction(
createModuleMapAction(cppModuleMap, publicHeaders, dependentModuleMaps, compiled));
if (model.getGeneratesPicHeaderModule()) {
@@ -1412,6 +1418,17 @@ public final class CcLibraryHelper {
return contextBuilder.build();
}
+ private UmbrellaHeaderAction createUmbrellaHeaderAction(Artifact umbrellaHeader,
+ PublicHeaders publicHeaders) {
+ return new UmbrellaHeaderAction(
+ ruleContext.getActionOwner(),
+ umbrellaHeader,
+ featureConfiguration.isEnabled(CppRuleClasses.ONLY_DOTH_HEADERS_IN_MODULE_MAPS)
+ ? Iterables.filter(publicHeaders.getModuleMapHeaders(), CppFileTypes.MODULE_MAP_HEADER)
+ : publicHeaders.getModuleMapHeaders(),
+ additionalExportedHeaders);
+ }
+
private CppModuleMapAction createModuleMapAction(
CppModuleMap moduleMap,
PublicHeaders publicHeaders,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMap.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMap.java
index aa365d4b1b..2d52c5acd8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMap.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMap.java
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.cpp;
+import com.google.common.base.Optional;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
@@ -24,9 +25,15 @@ public final class CppModuleMap {
// NOTE: If you add a field here, you'll likely need to update CppModuleMapAction.computeKey().
private final Artifact artifact;
private final String name;
+ private final Optional<Artifact> umbrellaHeader;
public CppModuleMap(Artifact artifact, String name) {
+ this(artifact, null, name);
+ }
+
+ public CppModuleMap(Artifact artifact, Artifact umbrellaHeader, String name) {
this.artifact = artifact;
+ this.umbrellaHeader = Optional.fromNullable(umbrellaHeader);
this.name = name;
}
@@ -38,8 +45,28 @@ public final class CppModuleMap {
return name;
}
+ /**
+ * Returns an optional umbrella header artifact. The headers declared in module maps are compiled
+ * using the #import directives which are incompatible with J2ObjC segmented headers. The headers
+ * generated by J2ObjC need to be compiled using the #include directives. We can #include all the
+ * headers in an umbrella header and then delcare the umbrella header in the module map.
+ */
+ public Optional<Artifact> getUmbrellaHeader() {
+ return umbrellaHeader;
+ }
+
@Override
public String toString() {
return name + "@" + artifact;
}
+
+ /**
+ * Specifies whether to generate an umbrella header.
+ */
+ public enum UmbrellaHeaderStrategy {
+ /** Generate an umbrella header. */
+ GENERATE,
+ /** Do not generate an umbrella header. */
+ DO_NOT_GENERATE
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMapAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMapAction.java
index a99751a8b1..652700f5a0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMapAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMapAction.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.rules.cpp;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -100,6 +101,7 @@ public final class CppModuleMapAction extends AbstractFileWriteAction {
StringBuilder content = new StringBuilder();
PathFragment fragment = cppModuleMap.getArtifact().getExecPath();
int segmentsToExecPath = fragment.segmentCount() - 1;
+ Optional<Artifact> umbrellaHeader = cppModuleMap.getUmbrellaHeader();
// For details about the different header types, see:
// http://clang.llvm.org/docs/Modules.html#header-declaration
@@ -108,22 +110,46 @@ public final class CppModuleMapAction extends AbstractFileWriteAction {
content.append(" export *\n");
HashSet<PathFragment> deduper = new HashSet<>();
- for (Artifact artifact : expandedHeaders(artifactExpander, publicHeaders)) {
- appendHeader(
- content, "", artifact.getExecPath(), leadingPeriods, /*canCompile=*/ true, deduper);
- }
- for (Artifact artifact : expandedHeaders(artifactExpander, privateHeaders)) {
+ if (umbrellaHeader.isPresent()) {
appendHeader(
content,
- "private",
- artifact.getExecPath(),
+ "",
+ umbrellaHeader.get().getExecPath(),
leadingPeriods,
- /*canCompile=*/ true,
- deduper);
- }
- for (PathFragment additionalExportedHeader : additionalExportedHeaders) {
- appendHeader(
- content, "", additionalExportedHeader, leadingPeriods, /*canCompile*/ false, deduper);
+ /*canCompile=*/ false,
+ deduper,
+ /*isUmbrellaHeader*/ true);
+ } else {
+ for (Artifact artifact : expandedHeaders(artifactExpander, publicHeaders)) {
+ appendHeader(
+ content,
+ "",
+ artifact.getExecPath(),
+ leadingPeriods,
+ /*canCompile=*/ true,
+ deduper,
+ /*isUmbrellaHeader*/ false);
+ }
+ for (Artifact artifact : expandedHeaders(artifactExpander, privateHeaders)) {
+ appendHeader(
+ content,
+ "private",
+ artifact.getExecPath(),
+ leadingPeriods,
+ /*canCompile=*/ true,
+ deduper,
+ /*isUmbrellaHeader*/ false);
+ }
+ for (PathFragment additionalExportedHeader : additionalExportedHeaders) {
+ appendHeader(
+ content,
+ "",
+ additionalExportedHeader,
+ leadingPeriods,
+ /*canCompile*/ false,
+ deduper,
+ /*isUmbrellaHeader*/ false);
+ }
}
for (CppModuleMap dep : dependencies) {
content.append(" use \"").append(dep.getName()).append("\"\n");
@@ -160,11 +186,16 @@ public final class CppModuleMapAction extends AbstractFileWriteAction {
}
private void appendHeader(StringBuilder content, String visibilitySpecifier, PathFragment path,
- String leadingPeriods, boolean canCompile, HashSet<PathFragment> deduper) {
+ String leadingPeriods, boolean canCompile, HashSet<PathFragment> deduper,
+ boolean isUmbrellaHeader) {
if (deduper.contains(path)) {
return;
}
deduper.add(path);
+ if (isUmbrellaHeader) {
+ content.append(" umbrella header \"umbrella.h\"\n");
+ return;
+ }
if (generateSubmodules) {
content.append(" module \"").append(path).append("\" {\n");
content.append(" export *\n ");
@@ -213,6 +244,10 @@ public final class CppModuleMapAction extends AbstractFileWriteAction {
f.addPath(path);
}
f.addPath(cppModuleMap.getArtifact().getExecPath());
+ Optional<Artifact> umbrellaHeader = cppModuleMap.getUmbrellaHeader();
+ if (umbrellaHeader.isPresent()) {
+ f.addPath(umbrellaHeader.get().getExecPath());
+ }
f.addString(cppModuleMap.getName());
f.addBoolean(moduleMapHomeIsCwd);
f.addBoolean(compiledModule);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/UmbrellaHeaderAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/UmbrellaHeaderAction.java
new file mode 100644
index 0000000000..14c3a0cfaa
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/UmbrellaHeaderAction.java
@@ -0,0 +1,124 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.rules.cpp;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.devtools.build.lib.actions.ActionExecutionContext;
+import com.google.devtools.build.lib.actions.ActionOwner;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
+import com.google.devtools.build.lib.analysis.actions.AbstractFileWriteAction;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.util.Fingerprint;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * Action for generating an umbrella header. All the headers are #included in the umbrella header.
+ */
+@Immutable
+public final class UmbrellaHeaderAction extends AbstractFileWriteAction {
+
+ private static final String GUID = "62ea2952-bf28-92c3-efb1-e34621646910";
+
+ // NOTE: If you add a field here, you'll likely need to add it to the cache key in computeKey().
+ private final Artifact umbrellaHeader;
+ private final ImmutableList<Artifact> publicHeaders;
+ private final ImmutableList<PathFragment> additionalExportedHeaders;
+
+ public UmbrellaHeaderAction(
+ ActionOwner owner,
+ Artifact umbrellaHeader,
+ Iterable<Artifact> publicHeaders,
+ Iterable<PathFragment> additionalExportedHeaders) {
+ super(
+ owner,
+ ImmutableList.copyOf(Iterables.filter(publicHeaders, Artifact.IS_TREE_ARTIFACT)),
+ umbrellaHeader,
+ /*makeExecutable=*/false);
+ this.umbrellaHeader = umbrellaHeader;
+ this.publicHeaders = ImmutableList.copyOf(publicHeaders);
+ this.additionalExportedHeaders = ImmutableList.copyOf(additionalExportedHeaders);
+ }
+
+ @Override
+ public DeterministicWriter newDeterministicWriter(ActionExecutionContext ctx) {
+ final ArtifactExpander artifactExpander = ctx.getArtifactExpander();
+ return new DeterministicWriter() {
+ @Override
+ public void writeOutputFile(OutputStream out) throws IOException {
+ StringBuilder content = new StringBuilder();
+ HashSet<PathFragment> deduper = new HashSet<>();
+ for (Artifact artifact : expandedHeaders(artifactExpander, publicHeaders)) {
+ appendHeader(content, artifact.getExecPath(), deduper);
+ }
+ for (PathFragment additionalExportedHeader : additionalExportedHeaders) {
+ appendHeader(content, additionalExportedHeader, deduper);
+ }
+ out.write(content.toString().getBytes(StandardCharsets.ISO_8859_1));
+ }
+ };
+ }
+
+ private static Iterable<Artifact> expandedHeaders(ArtifactExpander artifactExpander,
+ Iterable<Artifact> unexpandedHeaders) {
+ List<Artifact> expandedHeaders = new ArrayList<>();
+ for (Artifact unexpandedHeader : unexpandedHeaders) {
+ if (unexpandedHeader.isTreeArtifact()) {
+ artifactExpander.expand(unexpandedHeader, expandedHeaders);
+ } else {
+ expandedHeaders.add(unexpandedHeader);
+ }
+ }
+ return ImmutableList.copyOf(expandedHeaders);
+ }
+
+ private void appendHeader(StringBuilder content, PathFragment path,
+ HashSet<PathFragment> deduper) {
+ if (deduper.contains(path)) {
+ return;
+ }
+ deduper.add(path);
+ // #include headers. The #import directive is incompatible with J2ObjC segmented headers.
+ content.append("#include \"").append(path).append("\"");
+ content.append("\n");
+ }
+
+ @Override
+ public String getMnemonic() {
+ return "UmbrellaHeader";
+ }
+
+ @Override
+ protected String computeKey() {
+ Fingerprint f = new Fingerprint();
+ f.addString(GUID);
+ f.addPath(umbrellaHeader.getExecPath());
+ f.addInt(publicHeaders.size());
+ for (Artifact artifact : publicHeaders) {
+ f.addPath(artifact.getExecPath());
+ }
+ f.addInt(additionalExportedHeaders.size());
+ for (PathFragment path : additionalExportedHeaders) {
+ f.addPath(path);
+ }
+ return f.hexDigestAndReset();
+ }
+}
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 35e02bb404..5f9ceb4053 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
@@ -76,6 +76,7 @@ import com.google.devtools.build.lib.rules.cpp.CppHelper;
import com.google.devtools.build.lib.rules.cpp.CppModuleMap;
import com.google.devtools.build.lib.rules.cpp.CppModuleMapAction;
import com.google.devtools.build.lib.rules.cpp.FdoSupportProvider;
+import com.google.devtools.build.lib.rules.cpp.UmbrellaHeaderAction;
import com.google.devtools.build.lib.rules.objc.ObjcCommandLineOptions.ObjcCrosstoolMode;
import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector;
import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.InstrumentationSpec;
@@ -642,6 +643,11 @@ public abstract class CompilationSupport {
CppModuleMap moduleMap = intermediateArtifacts.moduleMap();
registerGenerateModuleMapAction(moduleMap, publicHeaders);
+ Optional<Artifact> umbrellaHeader = moduleMap.getUmbrellaHeader();
+ if (umbrellaHeader.isPresent()) {
+ registerGenerateUmbrellaHeaderAction(umbrellaHeader.get(), publicHeaders);
+ }
+
return this;
}
@@ -1221,6 +1227,18 @@ public abstract class CompilationSupport {
}
}
+ CompilationSupport registerGenerateUmbrellaHeaderAction(
+ Artifact umbrellaHeader, Iterable<Artifact> publicHeaders) {
+ ruleContext.registerAction(
+ new UmbrellaHeaderAction(
+ ruleContext.getActionOwner(),
+ umbrellaHeader,
+ publicHeaders,
+ ImmutableList.<PathFragment>of()));
+
+ return this;
+ }
+
/**
* Registers an action that will generate a clang module map.
* @param moduleMap the module map to generate
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java
index 96bdf501c5..b5d6f6b883 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java
@@ -381,7 +381,8 @@ public class CrosstoolCompilationSupport extends CompilationSupport {
ImmutableSortedSet.copyOf(compilationArtifacts.getNonArcSrcs());
Collection<Artifact> privateHdrs =
ImmutableSortedSet.copyOf(compilationArtifacts.getPrivateHdrs());
- Collection<Artifact> publicHdrs = ImmutableSortedSet.copyOf(attributes.hdrs());
+ Collection<Artifact> publicHdrs = ImmutableSortedSet.copyOf(
+ Iterables.concat(attributes.hdrs(), compilationArtifacts.getAdditionalHdrs()));
Artifact pchHdr = null;
if (ruleContext.attributes().has("pch", BuildType.LABEL)) {
pchHdr = ruleContext.getPrerequisiteArtifact("pch", Mode.TARGET);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
index 71cf24bc4e..ba324e670d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
@@ -23,6 +23,7 @@ import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.rules.cpp.CppCompileAction.DotdFile;
import com.google.devtools.build.lib.rules.cpp.CppHelper;
import com.google.devtools.build.lib.rules.cpp.CppModuleMap;
+import com.google.devtools.build.lib.rules.cpp.CppModuleMap.UmbrellaHeaderStrategy;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -48,22 +49,38 @@ public final class IntermediateArtifacts {
private final BuildConfiguration buildConfiguration;
private final String archiveFileNameSuffix;
private final String outputPrefix;
+ private final UmbrellaHeaderStrategy umbrellaHeaderStrategy;
IntermediateArtifacts(RuleContext ruleContext, String archiveFileNameSuffix,
String outputPrefix) {
- this(ruleContext, archiveFileNameSuffix, outputPrefix, ruleContext.getConfiguration());
+ this(ruleContext, archiveFileNameSuffix, outputPrefix, ruleContext.getConfiguration(),
+ UmbrellaHeaderStrategy.DO_NOT_GENERATE);
}
IntermediateArtifacts(RuleContext ruleContext, String archiveFileNameSuffix) {
- this(ruleContext, archiveFileNameSuffix, "", ruleContext.getConfiguration());
+ this(ruleContext, archiveFileNameSuffix, "", ruleContext.getConfiguration(),
+ UmbrellaHeaderStrategy.DO_NOT_GENERATE);
}
-
+
IntermediateArtifacts(RuleContext ruleContext, String archiveFileNameSuffix,
- String outputPrefix, BuildConfiguration buildConfiguration) {
+ UmbrellaHeaderStrategy umbrellaHeaderStrategy) {
+ this(ruleContext, archiveFileNameSuffix, "", ruleContext.getConfiguration(),
+ umbrellaHeaderStrategy);
+ }
+
+ IntermediateArtifacts(RuleContext ruleContext, String archiveFileNameSuffix, String outputPrefix,
+ BuildConfiguration buildConfiguration) {
+ this(ruleContext, archiveFileNameSuffix, outputPrefix, buildConfiguration,
+ UmbrellaHeaderStrategy.DO_NOT_GENERATE);
+ }
+
+ IntermediateArtifacts(RuleContext ruleContext, String archiveFileNameSuffix, String outputPrefix,
+ BuildConfiguration buildConfiguration, UmbrellaHeaderStrategy umbrellaHeaderStrategy) {
this.ruleContext = ruleContext;
this.buildConfiguration = buildConfiguration;
this.archiveFileNameSuffix = Preconditions.checkNotNull(archiveFileNameSuffix);
this.outputPrefix = Preconditions.checkNotNull(outputPrefix);
+ this.umbrellaHeaderStrategy = umbrellaHeaderStrategy;
}
/**
@@ -435,7 +452,15 @@ public final class IntermediateArtifacts {
.replace(":", "_");
// To get Swift to pick up module maps, we need to name them "module.modulemap" and have their
// parent directory in the module map search paths.
- return new CppModuleMap(appendExtensionInGenfiles(".modulemaps/module.modulemap"), moduleName);
+ if (umbrellaHeaderStrategy == UmbrellaHeaderStrategy.GENERATE) {
+ return new CppModuleMap(
+ appendExtensionInGenfiles(".modulemaps/module.modulemap"),
+ appendExtensionInGenfiles(".modulemaps/umbrella.h"),
+ moduleName);
+ } else {
+ return new CppModuleMap(
+ appendExtensionInGenfiles(".modulemaps/module.modulemap"), moduleName);
+ }
}
/**
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 3480cfcdef..016b687086 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
@@ -50,6 +50,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STATIC_FRAME
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STORYBOARD;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STRINGS;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.TOP_LEVEL_MODULE_MAP;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.UMBRELLA_HEADER;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.WEAK_SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCASSETS_DIR;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCDATAMODEL;
@@ -575,6 +576,10 @@ public final class ObjcCommon {
if (hasModuleMap) {
CppModuleMap moduleMap = intermediateArtifacts.moduleMap();
+ Optional<Artifact> umbrellaHeader = moduleMap.getUmbrellaHeader();
+ if (umbrellaHeader.isPresent()) {
+ objcProvider.add(UMBRELLA_HEADER, umbrellaHeader.get());
+ }
objcProvider.add(MODULE_MAP, moduleMap.getArtifact());
objcProvider.add(TOP_LEVEL_MODULE_MAP, moduleMap);
}
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 0fce2f483c..73d474b114 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
@@ -222,6 +222,13 @@ public final class ObjcProvider extends SkylarkClassObject implements Transitive
public static final Key<Flag> FLAG = new Key<>(STABLE_ORDER, "flag", Flag.class);
/**
+ * Clang umbrella header. Public headers are #included in umbrella headers to be compatible with
+ * J2ObjC segmented headers.
+ */
+ public static final Key<Artifact> UMBRELLA_HEADER =
+ new Key<>(STABLE_ORDER, "umbrella_header", Artifact.class);
+
+ /**
* Clang module maps, used to enforce proper use of private header files.
*/
public static final Key<Artifact> MODULE_MAP =
@@ -440,6 +447,7 @@ public final class ObjcProvider extends SkylarkClassObject implements Transitive
STATIC_FRAMEWORK_FILE,
STORYBOARD,
STRINGS,
+ UMBRELLA_HEADER,
WEAK_SDK_FRAMEWORK,
XCASSETS_DIR,
XCDATAMODEL,
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 3e48671493..55ac445662 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
@@ -55,6 +55,7 @@ import com.google.devtools.build.lib.rules.apple.AppleToolchain.RequiresXcodeCon
import com.google.devtools.build.lib.rules.apple.Platform;
import com.google.devtools.build.lib.rules.apple.Platform.PlatformType;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
+import com.google.devtools.build.lib.rules.cpp.CppModuleMap.UmbrellaHeaderStrategy;
import com.google.devtools.build.lib.rules.proto.ProtoSourceFileBlacklist;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.FileType;
@@ -117,9 +118,14 @@ public class ObjcRuleClasses {
// We need to append "_j2objc" to the name of the generated archive file to distinguish it from
// the C/C++ archive file created by proto_library targets with attribute cc_api_version
// specified.
+ // Generate an umbrella header for the module map. The headers declared in module maps are
+ // compiled using the #import directives which are incompatible with J2ObjC segmented headers.
+ // We need to #iclude all the headers in an umbrella header and then declare the umbrella header
+ // in the module map.
return new IntermediateArtifacts(
ruleContext,
- /*archiveFileNameSuffix=*/"_j2objc");
+ /*archiveFileNameSuffix=*/"_j2objc",
+ UmbrellaHeaderStrategy.GENERATE);
}
public static Artifact artifactByAppendingToBaseName(RuleContext context, String suffix) {