aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2015-09-15 00:00:54 +0000
committerGravatar John Field <jfield@google.com>2015-09-15 20:26:21 +0000
commit415aae660a932ead71628072610948afd11d7dc2 (patch)
treec2b038ca199463663974c3d2eee5f13a38a15c70
parent1c289af299227a73de2eb8903696d906105451ef (diff)
Generate module maps for each objc_* target with compilation support.
This uses CppModuleMap and CppModuleMapAction to generate clang module maps for the target and its transitive dependencies. To enable this feature, you must pass -experimental_objc_enable_module_maps to bazel. For objc_* targets that need to use the "modules" language features (@import, Swift interop, etc), set the "enable_modules" attribute to 1. -- MOS_MIGRATED_REVID=103045673
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java197
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java56
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java20
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java23
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java62
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java24
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java17
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java35
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java123
12 files changed, 457 insertions, 115 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 21f4518f6f..9e757e2bdc 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
@@ -201,6 +201,7 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
"non_propagated_deps", Mode.TARGET, ObjcProvider.class))
.setIntermediateArtifacts(intermediateArtifacts)
.setAlwayslink(false)
+ .setHasModuleMap()
.addExtraImportLibraries(ObjcRuleClasses.j2ObjcLibraries(ruleContext))
.setLinkedBinary(intermediateArtifacts.strippedSingleArchitectureBinary());
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 d31e9891fa..f8d41c3b4d 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
@@ -27,6 +27,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIB
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.INCLUDE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.INCLUDE_SYSTEM;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MODULE_MAP;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_DYLIB;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.WEAK_SDK_FRAMEWORK;
@@ -66,6 +67,8 @@ import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.packages.Type;
+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.LinkerInputs;
import com.google.devtools.build.lib.rules.java.J2ObjcConfiguration;
import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes;
@@ -112,6 +115,17 @@ public final class CompilationSupport {
};
/**
+ * Predicate to remove '.inc' files from an iterable.
+ */
+ private static final Predicate<Artifact> NON_INC_FILES =
+ new Predicate<Artifact>() {
+ @Override
+ public boolean apply(Artifact artifact) {
+ return !artifact.getFilename().endsWith(".inc");
+ }
+ };
+
+ /**
* Iterable wrapper providing strong type safety for arguments to binary linking.
*/
static final class ExtraLinkArgs extends IterableWrapper<String> {
@@ -161,10 +175,20 @@ public final class CompilationSupport {
*/
CompilationSupport registerCompileAndArchiveActions(ObjcCommon common) {
if (common.getCompilationArtifacts().isPresent()) {
+ registerGenerateModuleMapAction(common.getCompilationArtifacts());
+ IntermediateArtifacts intermediateArtifacts =
+ ObjcRuleClasses.intermediateArtifacts(ruleContext);
+ Optional<CppModuleMap> moduleMap;
+ if (ObjcRuleClasses.objcConfiguration(ruleContext).moduleMapsEnabled()) {
+ moduleMap = Optional.of(intermediateArtifacts.moduleMap());
+ } else {
+ moduleMap = Optional.<CppModuleMap>absent();
+ }
registerCompileAndArchiveActions(
common.getCompilationArtifacts().get(),
- ObjcRuleClasses.intermediateArtifacts(ruleContext),
+ intermediateArtifacts,
common.getObjcProvider(),
+ moduleMap,
ruleContext.getConfiguration().isCodeCoverageEnabled());
}
return this;
@@ -174,25 +198,42 @@ public final class CompilationSupport {
* Creates actions to compile each source file individually, and link all the compiled object
* files into a single archive library.
*/
- private void registerCompileAndArchiveActions(CompilationArtifacts compilationArtifacts,
- IntermediateArtifacts intermediateArtifacts, ObjcProvider objcProvider,
+ private void registerCompileAndArchiveActions(
+ CompilationArtifacts compilationArtifacts,
+ IntermediateArtifacts intermediateArtifacts,
+ ObjcProvider objcProvider,
+ Optional<CppModuleMap> moduleMap,
boolean isCodeCoverageEnabled) {
ImmutableList.Builder<Artifact> objFiles = new ImmutableList.Builder<>();
for (Artifact sourceFile : compilationArtifacts.getSrcs()) {
Artifact objFile = intermediateArtifacts.objFile(sourceFile);
objFiles.add(objFile);
if (ObjcRuleClasses.SWIFT_SOURCES.matches(sourceFile.getFilename())) {
- registerSwiftCompileAction(sourceFile, objFile, intermediateArtifacts);
+ registerSwiftCompileAction(sourceFile, objFile, intermediateArtifacts, objcProvider);
} else {
- registerCompileAction(sourceFile, objFile, objcProvider, intermediateArtifacts,
- compilationArtifacts, ImmutableList.of("-fobjc-arc"), isCodeCoverageEnabled);
+ registerCompileAction(
+ sourceFile,
+ objFile,
+ objcProvider,
+ moduleMap,
+ intermediateArtifacts,
+ compilationArtifacts,
+ ImmutableList.of("-fobjc-arc"),
+ isCodeCoverageEnabled);
}
}
for (Artifact nonArcSourceFile : compilationArtifacts.getNonArcSrcs()) {
Artifact objFile = intermediateArtifacts.objFile(nonArcSourceFile);
objFiles.add(objFile);
- registerCompileAction(nonArcSourceFile, objFile, objcProvider, intermediateArtifacts,
- compilationArtifacts, ImmutableList.of("-fno-objc-arc"), isCodeCoverageEnabled);
+ registerCompileAction(
+ nonArcSourceFile,
+ objFile,
+ objcProvider,
+ moduleMap,
+ intermediateArtifacts,
+ compilationArtifacts,
+ ImmutableList.of("-fno-objc-arc"),
+ isCodeCoverageEnabled);
}
if (compilationArtifacts.hasSwiftSources()) {
@@ -208,6 +249,7 @@ public final class CompilationSupport {
Artifact sourceFile,
Artifact objFile,
ObjcProvider objcProvider,
+ Optional<CppModuleMap> moduleMap,
IntermediateArtifacts intermediateArtifacts,
CompilationArtifacts compilationArtifacts,
Iterable<String> otherFlags,
@@ -259,6 +301,28 @@ public final class CompilationSupport {
.add("-MD")
.addExecPath("-MF", dotdFile);
+ if (moduleMap.isPresent()) {
+ // -fmodule-map-file only loads the module in Xcode 7, so we add the module maps's directory
+ // to the include path instead.
+ // TODO(bazel-team): Use -fmodule-map-file when Xcode 6 support is dropped.
+ commandLine
+ .add(attributes.enableModules() ? "-fmodules" : "-fmodule-maps")
+ .add("-iquote")
+ .add(
+ moduleMap
+ .get()
+ .getArtifact()
+ .getExecPath()
+ .getParentDirectory()
+ .toString())
+ .add("-fmodule-name=" + moduleMap.get().getName());
+ if (attributes.enableModules()) {
+ String cachePath =
+ ruleContext.getConfiguration().getGenfilesFragment() + "/_objc_module_cache";
+ commandLine.add("-fmodules-cache-path=" + cachePath);
+ }
+ }
+
// TODO(bazel-team): Remote private headers from inputs once they're added to the provider.
ruleContext.registerAction(ObjcRuleClasses.spawnOnDarwinActionBuilder(ruleContext)
.setMnemonic("ObjcCompile")
@@ -270,6 +334,7 @@ public final class CompilationSupport {
.addOutputs(gcnoFiles.build())
.addOutput(dotdFile)
.addTransitiveInputs(objcProvider.get(HEADER))
+ .addTransitiveInputs(objcProvider.get(MODULE_MAP))
.addInputs(compilationArtifacts.getPrivateHdrs())
.addTransitiveInputs(objcProvider.get(FRAMEWORK_FILE))
.addInputs(compilationArtifacts.getPchFile().asSet())
@@ -285,7 +350,8 @@ public final class CompilationSupport {
private void registerSwiftCompileAction(
Artifact sourceFile,
Artifact objFile,
- IntermediateArtifacts intermediateArtifacts) {
+ IntermediateArtifacts intermediateArtifacts,
+ ObjcProvider objcProvider) {
ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
// Compiling a single swift file requires knowledge of all of the other
@@ -331,16 +397,27 @@ public final class CompilationSupport {
inputHeaders.add(bridgingHeader.get());
}
- ruleContext.registerAction(ObjcRuleClasses.spawnOnDarwinActionBuilder(ruleContext)
- .setMnemonic("SwiftCompile")
- .setExecutable(SWIFT)
- .setCommandLine(commandLine.build())
- .addInput(sourceFile)
- .addInputs(otherSwiftSources)
- .addInputs(inputHeaders.build())
- .addOutput(objFile)
- .addOutput(intermediateArtifacts.swiftModuleFile(sourceFile))
- .build(ruleContext));
+ // Import the Objective-C module map.
+ // TODO(bazel-team): Find a way to import the module map directly, instead of the parent
+ // directory?
+ if (objcConfiguration.moduleMapsEnabled()) {
+ PathFragment moduleMapPath = intermediateArtifacts.moduleMap().getArtifact().getExecPath();
+ commandLine.add("-I").add(moduleMapPath.getParentDirectory().toString());
+ }
+
+ ruleContext.registerAction(
+ ObjcRuleClasses.spawnOnDarwinActionBuilder(ruleContext)
+ .setMnemonic("SwiftCompile")
+ .setExecutable(SWIFT)
+ .setCommandLine(commandLine.build())
+ .addInput(sourceFile)
+ .addInputs(otherSwiftSources)
+ .addInputs(inputHeaders.build())
+ .addTransitiveInputs(objcProvider.get(HEADER))
+ .addTransitiveInputs(objcProvider.get(MODULE_MAP))
+ .addOutput(objFile)
+ .addOutput(intermediateArtifacts.swiftModuleFile(sourceFile))
+ .build(ruleContext));
}
/**
@@ -459,6 +536,53 @@ public final class CompilationSupport {
return this;
}
+ /**
+ * Registers an action that will generate a clang module map for this target, using the hdrs
+ * attribute of this rule.
+ */
+ public CompilationSupport registerGenerateModuleMapAction(
+ Optional<CompilationArtifacts> compilationArtifacts) {
+ if (ObjcRuleClasses.objcConfiguration(ruleContext).moduleMapsEnabled()) {
+ Iterable<Artifact> publicHeaders = attributes.hdrs();
+ Iterable<Artifact> privateHeaders = ImmutableList.<Artifact>of();
+ if (compilationArtifacts.isPresent()) {
+ CompilationArtifacts artifacts = compilationArtifacts.get();
+ publicHeaders = Iterables.concat(publicHeaders, artifacts.getAdditionalHdrs());
+ privateHeaders = Iterables.concat(privateHeaders, artifacts.getPrivateHdrs());
+ }
+ CppModuleMap moduleMap = ObjcRuleClasses.intermediateArtifacts(ruleContext).moduleMap();
+ registerGenerateModuleMapAction(moduleMap, publicHeaders, privateHeaders);
+ }
+ return this;
+ }
+
+ /**
+ * Registers an action that will generate a clang module map.
+ *
+ * @param moduleMap the module map to generate
+ * @param publicHeaders the headers that should be directly accessible by dependers
+ * @param privateHeaders the headers that should only be directly accessible by this module
+ */
+ private void registerGenerateModuleMapAction(
+ CppModuleMap moduleMap, Iterable<Artifact> publicHeaders, Iterable<Artifact> privateHeaders) {
+ // The current clang (clang-600.0.57) on Darwin doesn't support 'textual', so we can't have
+ // '.inc' files in the module map (since they're implictly textual).
+ // TODO(bazel-team): Remove filtering once clang-700 is the base clang we support.
+ publicHeaders = Iterables.filter(publicHeaders, NON_INC_FILES);
+ privateHeaders = Iterables.filter(privateHeaders, NON_INC_FILES);
+ ruleContext.registerAction(
+ new CppModuleMapAction(
+ ruleContext.getActionOwner(),
+ moduleMap,
+ privateHeaders,
+ publicHeaders,
+ attributes.moduleMapsForDirectDeps(),
+ ImmutableList.<PathFragment>of(),
+ /*compiledModule=*/ true,
+ /*moduleMapHomeIsCwd=*/ false,
+ /*generateSubModules=*/ true));
+ }
+
private void registerLinkAction(ObjcProvider objcProvider, ExtraLinkArgs extraLinkArgs,
Iterable<Artifact> extraLinkInputs, Optional<Artifact> dsymBundle) {
ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
@@ -688,7 +812,22 @@ public final class CompilationSupport {
.setIntermediateArtifacts(intermediateArtifacts)
.setPchFile(Optional.<Artifact>absent())
.build();
- registerCompileAndArchiveActions(compilationArtifact, intermediateArtifacts, objcProvider,
+ // The module map that the above intermediateArtifacts would point to is a combination of
+ // the current target and the java target. Instead, we want the one generated for that
+ // source, but there is no easy way to get that. So for now, compile the source with the
+ // module map (and therefore module name) for this rule.
+ // TODO(bazel-team): Generate module maps along with the J2Objc sources, and use that here.
+ Optional<CppModuleMap> moduleMap;
+ if (ObjcRuleClasses.objcConfiguration(ruleContext).moduleMapsEnabled()) {
+ moduleMap = Optional.of(ObjcRuleClasses.intermediateArtifacts(ruleContext).moduleMap());
+ } else {
+ moduleMap = Optional.<CppModuleMap>absent();
+ }
+ registerCompileAndArchiveActions(
+ compilationArtifact,
+ intermediateArtifacts,
+ objcProvider,
+ moduleMap,
ruleContext.getConfiguration().isCodeCoverageEnabled());
}
}
@@ -696,6 +835,24 @@ public final class CompilationSupport {
return this;
}
+ /**
+ * Registers actions that generates a module map for all {@link J2ObjcSource}s in
+ * {@link J2ObjcSrcsProvider}.
+ *
+ * @return this compilation support
+ */
+ public CompilationSupport registerJ2ObjcGenerateModuleMapAction(J2ObjcSrcsProvider provider) {
+ if (ObjcRuleClasses.objcConfiguration(ruleContext).moduleMapsEnabled()) {
+ CppModuleMap moduleMap = ObjcRuleClasses.intermediateArtifacts(ruleContext).moduleMap();
+ ImmutableSet.Builder<Artifact> headers = ImmutableSet.builder();
+ for (J2ObjcSource j2ObjcSource : provider.getSrcs()) {
+ headers.addAll(j2ObjcSource.getObjcHdrs());
+ }
+ registerGenerateModuleMapAction(moduleMap, headers.build(), ImmutableList.<Artifact>of());
+ }
+ return this;
+ }
+
private void registerJ2ObjcDeadCodeRemovalActions(Iterable<J2ObjcSource> j2ObjcSources,
Iterable<String> entryClasses) {
Artifact pruner = ruleContext.getPrerequisiteArtifact("$j2objc_dead_code_pruner", Mode.HOST);
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 59f9b07f67..923ed6c79f 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
@@ -17,8 +17,10 @@ package com.google.devtools.build.lib.rules.objc;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Root;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.rules.cpp.CppModuleMap;
import com.google.devtools.build.lib.syntax.Label;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -28,7 +30,7 @@ import com.google.devtools.build.lib.vfs.PathFragment;
*/
// TODO(bazel-team): This should really be named DerivedArtifacts as it contains methods for
// final as well as intermediate artifacts.
-final class IntermediateArtifacts {
+public final class IntermediateArtifacts {
/**
* Extension used on the temporary zipped dsym bundle location. Must contain {@code .dSYM} for
@@ -100,6 +102,16 @@ final class IntermediateArtifacts {
}
/**
+ * Returns a derived artifact in the genfiles directory obtained by appending some extension to
+ * the end of the {@link PathFragment} corresponding to the owner {@link Label}.
+ */
+ private Artifact appendExtensionInGenfiles(String extension) {
+ PathFragment name = new PathFragment(ruleContext.getLabel().getName());
+ return scopedArtifact(
+ name.replaceName(name.getBaseName() + extension), /* inGenfiles = */ true);
+ }
+
+ /**
* The output of using {@code actoolzip} to run {@code actool} for a given bundle which is
* merged under the {@code .app} or {@code .bundle} directory root.
*/
@@ -161,23 +173,34 @@ final class IntermediateArtifacts {
return appendExtension("_lipobin");
}
- private Artifact scopedArtifact(PathFragment scopeRelative) {
+ private Artifact scopedArtifact(PathFragment scopeRelative, boolean inGenfiles) {
+ Root root =
+ inGenfiles
+ ? ruleContext.getConfiguration().getGenfilesDirectory()
+ : ruleContext.getConfiguration().getBinDirectory();
if (scopingLabel.isPresent()) {
// The path of this artifact will be
// RULE_PACKAGE/_intermediate_scoped/RULE_LABEL/SCOPING_PACKAGE/SCOPING_LABEL/SCOPERELATIVE
- return ruleContext.getUniqueDirectoryArtifact("_intermediate_scoped",
- scopingLabel.get().getPackageIdentifier().getPathFragment()
+ return ruleContext.getUniqueDirectoryArtifact(
+ "_intermediate_scoped",
+ scopingLabel
+ .get()
+ .getPackageIdentifier()
+ .getPathFragment()
.getRelative(scopingLabel.get().getName())
.getRelative(scopeRelative),
- ruleContext.getConfiguration().getBinDirectory());
+ root);
} else {
// The path of this artifact will be
// RULE_PACKAGE/SCOPERELATIVE
- return ruleContext.getPackageRelativeArtifact(scopeRelative,
- ruleContext.getConfiguration().getBinDirectory());
+ return ruleContext.getPackageRelativeArtifact(scopeRelative, root);
}
}
+ private Artifact scopedArtifact(PathFragment scopeRelative) {
+ return scopedArtifact(scopeRelative, /* inGenfiles = */ false);
+ }
+
/**
* The {@code .a} file which contains all the compiled sources for a rule.
*/
@@ -339,4 +362,23 @@ final class IntermediateArtifacts {
public Artifact dotdFile(Artifact source) {
return inUniqueObjsDir(source, ".d");
}
+
+ /**
+ * {@link CppModuleMap} that provides the clang module map for this target.
+ */
+ public CppModuleMap moduleMap() {
+ if (!ObjcRuleClasses.objcConfiguration(ruleContext).moduleMapsEnabled()) {
+ throw new IllegalStateException();
+ }
+ String moduleName =
+ ruleContext
+ .getLabel()
+ .toString()
+ .replace("//", "")
+ .replace("/", "_")
+ .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);
+ }
}
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 0281538fbe..2e2b23eca0 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
@@ -27,6 +27,7 @@ import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+import com.google.devtools.build.lib.rules.cpp.CppModuleMap;
import com.google.devtools.build.lib.rules.java.J2ObjcConfiguration;
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -97,6 +98,10 @@ public class J2ObjcLibrary implements RuleConfiguredTargetFactory {
ImmutableList.of(j2objcSource.getObjcFilePath(), genDirHeaderSearchPath));
}
+ if (ObjcRuleClasses.objcConfiguration(ruleContext).moduleMapsEnabled()) {
+ configureModuleMap(ruleContext, objcProviderBuilder, j2ObjcSrcsProvider);
+ }
+
ObjcProvider objcProvider = objcProviderBuilder.build();
xcodeSupport.addXcodeSettings(xcodeProviderBuilder, objcProvider, LIBRARY_STATIC);
@@ -111,6 +116,21 @@ public class J2ObjcLibrary implements RuleConfiguredTargetFactory {
.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}.
+ */
+ private void configureModuleMap(
+ RuleContext ruleContext,
+ ObjcProvider.Builder objcProvider,
+ J2ObjcSrcsProvider j2ObjcSrcsProvider) {
+ new CompilationSupport(ruleContext).registerJ2ObjcGenerateModuleMapAction(j2ObjcSrcsProvider);
+
+ CppModuleMap moduleMap = ObjcRuleClasses.intermediateArtifacts(ruleContext).moduleMap();
+ objcProvider.add(ObjcProvider.MODULE_MAP, moduleMap.getArtifact());
+ objcProvider.add(ObjcProvider.TOP_LEVEL_MODULE_MAP, moduleMap);
+ }
+
private static void checkAttributes(RuleContext ruleContext) {
checkAttributes(ruleContext, "deps");
checkAttributes(ruleContext, "exports");
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java
index c4f70e36fe..08a69a6818 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java
@@ -152,12 +152,23 @@ public class ObjcCommandLineOptions extends FragmentOptions {
help = "Uses these strings as objc fastbuild compiler options.")
public List<String> fastbuildOptions;
- @Option(name = "objc_enable_binary_stripping",
- defaultValue = "false",
- category = "flags",
- help = "Whether to perform symbol and dead-code strippings on linked binaries. Binary "
- + "strippings will be performed if both this flag and --compilationMode=opt are "
- + "specified.")
+ @Option(
+ name = "experimental_objc_enable_module_maps",
+ defaultValue = "false",
+ category = "undocumented",
+ help = "Enables module map generation and interpretation."
+ )
+ public boolean enableModuleMaps;
+
+ @Option(
+ name = "objc_enable_binary_stripping",
+ defaultValue = "false",
+ category = "flags",
+ help =
+ "Whether to perform symbol and dead-code strippings on linked binaries. Binary "
+ + "strippings will be performed if both this flag and --compilationMode=opt are "
+ + "specified."
+ )
public boolean enableBinaryStripping;
// This option exists because two configurations are not allowed to have the same cache key
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 657062b730..775c53db8e 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
@@ -37,11 +37,13 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.INCLUDE_SYST
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.INSTRUMENTED_SOURCE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LINKED_BINARY;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MODULE_MAP;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_DYLIB;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SOURCE;
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.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;
@@ -63,10 +65,12 @@ import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.rules.cpp.CcCommon;
import com.google.devtools.build.lib.rules.cpp.CcLinkParamsProvider;
import com.google.devtools.build.lib.rules.cpp.CppCompilationContext;
+import com.google.devtools.build.lib.rules.cpp.CppModuleMap;
import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.util.RegexFilter;
import com.google.devtools.build.lib.vfs.PathFragment;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -188,6 +192,46 @@ public final class ObjcCommon {
}
return optionsProvider.getCopts();
}
+
+ /**
+ * The clang module maps of direct dependencies of this rule. These are needed to generate
+ * this rule's module map.
+ */
+ public List<CppModuleMap> moduleMapsForDirectDeps() {
+ // Make sure all dependencies that have headers are included here. If a module map is missing,
+ // its private headers will be treated as public!
+ ArrayList<CppModuleMap> moduleMaps = new ArrayList<>();
+ collectModuleMapsFromAttributeIfExists(moduleMaps, "deps");
+ collectModuleMapsFromAttributeIfExists(moduleMaps, "non_propagated_deps");
+ return moduleMaps;
+ }
+
+ /**
+ * Collects all module maps from the targets in a certain attribute and adds them into
+ * {@code moduleMaps}.
+ *
+ * @param moduleMaps an {@link ArrayList} to collect the module maps into
+ * @param attribute the name of a label list attribute to collect module maps from
+ */
+ private void collectModuleMapsFromAttributeIfExists(
+ ArrayList<CppModuleMap> moduleMaps, String attribute) {
+ if (ruleContext.attributes().has(attribute, Type.LABEL_LIST)) {
+ Iterable<ObjcProvider> providers =
+ ruleContext.getPrerequisites(attribute, Mode.TARGET, ObjcProvider.class);
+ for (ObjcProvider provider : providers) {
+ moduleMaps.addAll(provider.get(TOP_LEVEL_MODULE_MAP).toCollection());
+ }
+ }
+ }
+
+ /**
+ * Returns whether this target uses language features that require clang modules, such as
+ * @import.
+ */
+ public boolean enableModules() {
+ return ruleContext.attributes().has("enable_modules", Type.BOOLEAN)
+ && ruleContext.attributes().get("enable_modules", Type.BOOLEAN);
+ }
}
/**
@@ -248,6 +292,7 @@ public final class ObjcCommon {
private Iterable<PathFragment> userHeaderSearchPaths = ImmutableList.of();
private IntermediateArtifacts intermediateArtifacts;
private boolean alwayslink;
+ private boolean hasModuleMap;
private Iterable<Artifact> extraImportLibraries = ImmutableList.of();
private Optional<Artifact> linkedBinary = Optional.absent();
private Optional<Artifact> breakpadFile = Optional.absent();
@@ -341,6 +386,17 @@ public final class ObjcCommon {
}
/**
+ * Specifies that this target has a clang module map. This should be called if this target
+ * compiles sources or exposes headers for other targets to use. Note that this does not add
+ * the action to generate the module map. It simply indicates that it should be added to the
+ * provider.
+ */
+ Builder setHasModuleMap() {
+ this.hasModuleMap = true;
+ return this;
+ }
+
+ /**
* Adds additional static libraries to be linked into the final ObjC application bundle.
*/
Builder addExtraImportLibraries(Iterable<Artifact> extraImportLibraries) {
@@ -506,6 +562,12 @@ public final class ObjcCommon {
}
}
+ if (hasModuleMap && ObjcRuleClasses.objcConfiguration(context).moduleMapsEnabled()) {
+ CppModuleMap moduleMap = intermediateArtifacts.moduleMap();
+ objcProvider.add(MODULE_MAP, moduleMap.getArtifact());
+ objcProvider.add(TOP_LEVEL_MODULE_MAP, moduleMap);
+ }
+
objcProvider.addAll(LINKED_BINARY, linkedBinary.asSet())
.addAll(BREAKPAD_FILE, breakpadFile.asSet());
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
index 8f073a18ad..9209c4ebda 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
@@ -66,6 +66,7 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment {
private final boolean perProtoIncludes;
private final List<String> fastbuildOptions;
private final boolean enableBinaryStripping;
+ private final boolean moduleMapsEnabled;
private final ConfigurationDistinguisher configurationDistinguisher;
@Nullable private final Path clientWorkspaceRoot;
@@ -104,6 +105,7 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment {
this.perProtoIncludes = objcOptions.perProtoIncludes;
this.fastbuildOptions = ImmutableList.copyOf(objcOptions.fastbuildOptions);
this.enableBinaryStripping = objcOptions.enableBinaryStripping;
+ this.moduleMapsEnabled = objcOptions.enableModuleMaps;
this.configurationDistinguisher = objcOptions.configurationDistinguisher;
this.clientWorkspaceRoot = directories != null ? directories.getWorkspace() : null;
}
@@ -261,6 +263,13 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment {
}
/**
+ * Whether module map generation and interpretation is enabled.
+ */
+ public boolean moduleMapsEnabled() {
+ return moduleMapsEnabled;
+ }
+
+ /**
* Returns the unique identifier distinguishing configurations that are otherwise the same.
*
* <p>Use this value for situations in which two configurations create two outputs that are the
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 c3b35c22cc..143858de7d 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
@@ -16,6 +16,7 @@ package com.google.devtools.build.lib.rules.objc;
import static com.google.devtools.build.lib.rules.objc.XcodeProductType.LIBRARY_STATIC;
+import com.google.common.base.Optional;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
@@ -32,21 +33,24 @@ import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes;
public class ObjcImport implements RuleConfiguredTargetFactory {
@Override
public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException {
- ObjcCommon common = new ObjcCommon.Builder(ruleContext)
- .setCompilationAttributes(new CompilationAttributes(ruleContext))
- .setResourceAttributes(new ResourceAttributes(ruleContext))
- .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
- .setAlwayslink(ruleContext.attributes().get("alwayslink", Type.BOOLEAN))
- .addExtraImportLibraries(
- ruleContext.getPrerequisiteArtifacts("archives", Mode.TARGET).list())
- .addDepObjcProviders(
- ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
- .build();
+ ObjcCommon common =
+ new ObjcCommon.Builder(ruleContext)
+ .setCompilationAttributes(new CompilationAttributes(ruleContext))
+ .setResourceAttributes(new ResourceAttributes(ruleContext))
+ .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
+ .setAlwayslink(ruleContext.attributes().get("alwayslink", Type.BOOLEAN))
+ .setHasModuleMap()
+ .addExtraImportLibraries(
+ ruleContext.getPrerequisiteArtifacts("archives", Mode.TARGET).list())
+ .addDepObjcProviders(
+ ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
+ .build();
XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder();
NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.stableOrder();
new CompilationSupport(ruleContext)
+ .registerGenerateModuleMapAction(Optional.<CompilationArtifacts>absent())
.addXcodeSettings(xcodeProviderBuilder, common)
.validateAttributes();
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 98f4fe9597..e03d9ba814 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
@@ -68,14 +68,15 @@ public class ObjcLibrary implements RuleConfiguredTargetFactory {
.addDepObjcProviders(ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProvider.class))
.addDepObjcProviders(
ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
- .addNonPropagatedDepObjcProviders(ruleContext.getPrerequisites("non_propagated_deps",
- Mode.TARGET, ObjcProvider.class))
+ .addNonPropagatedDepObjcProviders(
+ ruleContext.getPrerequisites("non_propagated_deps", Mode.TARGET, ObjcProvider.class))
.addDepCcHeaderProviders(
ruleContext.getPrerequisites("deps", Mode.TARGET, CppCompilationContext.class))
.addDepCcLinkProviders(
ruleContext.getPrerequisites("deps", Mode.TARGET, CcLinkParamsProvider.class))
.setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
.setAlwayslink(alwayslink)
+ .setHasModuleMap()
.addExtraImportLibraries(extraImportLibraries)
.addDepObjcProviders(extraDepObjcProviders)
.build();
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 4057c25d50..8349b48d29 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
@@ -175,13 +175,16 @@ public class ObjcProtoLibrary implements RuleConfiguredTargetFactory {
}
ImmutableSet<PathFragment> searchPathEntries = searchPathEntriesBuilder.build();
- ObjcCommon common = new ObjcCommon.Builder(ruleContext)
- .setCompilationArtifacts(compilationArtifacts)
- .addUserHeaderSearchPaths(searchPathEntries)
- .addDepObjcProviders(ruleContext.getPrerequisites(
- ObjcProtoLibraryRule.LIBPROTOBUF_ATTR, Mode.TARGET, ObjcProvider.class))
- .setIntermediateArtifacts(intermediateArtifacts)
- .build();
+ ObjcCommon common =
+ new ObjcCommon.Builder(ruleContext)
+ .setCompilationArtifacts(compilationArtifacts)
+ .addUserHeaderSearchPaths(searchPathEntries)
+ .addDepObjcProviders(
+ ruleContext.getPrerequisites(
+ ObjcProtoLibraryRule.LIBPROTOBUF_ATTR, Mode.TARGET, ObjcProvider.class))
+ .setIntermediateArtifacts(intermediateArtifacts)
+ .setHasModuleMap()
+ .build();
NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.<Artifact>stableOrder()
.addAll(common.getCompiledArchive().asSet())
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 e8be3684fa..bbee7c675c 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
@@ -27,6 +27,7 @@ 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.rules.cpp.CppModuleMap;
import com.google.devtools.build.lib.rules.cpp.LinkerInputs;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.TargetControl;
@@ -150,6 +151,19 @@ public final class ObjcProvider implements TransitiveInfoProvider {
public static final Key<Flag> FLAG = new Key<>(STABLE_ORDER);
/**
+ * Clang module maps, used to enforce proper use of private header files.
+ */
+ public static final Key<Artifact> MODULE_MAP = new Key<>(STABLE_ORDER);
+
+ /**
+ * Information about this provider's module map, in the form of a {@link CppModuleMap}. This
+ * is intransitive, and can be used to get just the target's module map to pass to clang or to
+ * get the module maps for direct but not transitive dependencies. You should only add module maps
+ * for this key using {@link Builder#addWithoutPropagating}.
+ */
+ public static final Key<CppModuleMap> TOP_LEVEL_MODULE_MAP = new Key<>(STABLE_ORDER);
+
+ /**
* Merge zips to include in the bundle. The entries of these zip files are included in the final
* bundle with the same path. The entries in the merge zips should not include the bundle root
* path (e.g. {@code Foo.app}).
@@ -287,9 +301,10 @@ public final class ObjcProvider implements TransitiveInfoProvider {
}
@SuppressWarnings({"rawtypes", "unchecked"})
- private void uncheckedAddAll(Key key, Iterable toAdd) {
- maybeAddEmptyBuilder(items, key);
- items.get(key).addAll(toAdd);
+ private void uncheckedAddAll(Key key, Iterable toAdd, boolean propagate) {
+ Map<Key<?>, NestedSetBuilder<?>> set = propagate ? items : nonPropagatedItems;
+ maybeAddEmptyBuilder(set, key);
+ set.get(key).addAll(toAdd);
}
@SuppressWarnings({"rawtypes", "unchecked"})
@@ -357,7 +372,7 @@ 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));
+ uncheckedAddAll(key, ImmutableList.of(toAdd), true);
return this;
}
@@ -365,7 +380,17 @@ 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);
+ uncheckedAddAll(key, toAdd, true);
+ return this;
+ }
+
+ /**
+ * Add element, but don't propagate 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.
+ */
+ public <E> Builder addWithoutPropagating(Key<E> key, E toAdd) {
+ uncheckedAddAll(key, ImmutableList.of(toAdd), false);
return this;
}
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 04be1426cd..7b53bcae59 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
@@ -74,8 +74,8 @@ public class ObjcRuleClasses {
throw new UnsupportedOperationException("static-only");
}
- static IntermediateArtifacts intermediateArtifacts(RuleContext ruleContext) {
- return new IntermediateArtifacts(ruleContext, /*archiveFileNameSuffix=*/"");
+ public static IntermediateArtifacts intermediateArtifacts(RuleContext ruleContext) {
+ return new IntermediateArtifacts(ruleContext, /*archiveFileNameSuffix=*/ "");
}
/**
@@ -617,68 +617,75 @@ public class ObjcRuleClasses {
public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
return builder
/* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(srcs) -->
- The list of C, C++, Objective-C, and Objective-C++ source and header
- files that are processed to create the library target.
- ${SYNOPSIS}
- These are your checked-in files, plus any generated files.
- Source files are compiled into .o files with Clang. Header files
- may be included/imported by any source or header in the srcs attribute
- of this target, but not by headers in hdrs or any targets that depend
- on this rule.
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(attr("srcs", LABEL_LIST)
- .direct_compile_time_input()
- .allowedFileTypes(SRCS_TYPE))
+ The list of C, C++, Objective-C, and Objective-C++ source and header
+ files that are processed to create the library target.
+ ${SYNOPSIS}
+ These are your checked-in files, plus any generated files.
+ Source files are compiled into .o files with Clang. Header files
+ may be included/imported by any source or header in the srcs attribute
+ of this target, but not by headers in hdrs or any targets that depend
+ on this rule.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(attr("srcs", LABEL_LIST).direct_compile_time_input().allowedFileTypes(SRCS_TYPE))
/* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(non_arc_srcs) -->
- The list of Objective-C files that are processed to create the
- library target that DO NOT use ARC.
- ${SYNOPSIS}
- The files in this attribute are treated very similar to those in the
- srcs attribute, but are compiled without ARC enabled.
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(attr("non_arc_srcs", LABEL_LIST)
- .direct_compile_time_input()
- .allowedFileTypes(NON_ARC_SRCS_TYPE))
+ The list of Objective-C files that are processed to create the
+ library target that DO NOT use ARC.
+ ${SYNOPSIS}
+ The files in this attribute are treated very similar to those in the
+ srcs attribute, but are compiled without ARC enabled.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(
+ attr("non_arc_srcs", LABEL_LIST)
+ .direct_compile_time_input()
+ .allowedFileTypes(NON_ARC_SRCS_TYPE))
/* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(pch) -->
- Header file to prepend to every source file being compiled (both arc
- and non-arc).
- ${SYNOPSIS}
- Note that the file will not be precompiled - this is simply a
- convenience, not a build-speed enhancement.
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(attr("pch", LABEL)
- .direct_compile_time_input()
- .allowedFileTypes(FileType.of(".pch")))
+ Header file to prepend to every source file being compiled (both arc
+ and non-arc).
+ ${SYNOPSIS}
+ Note that the file will not be precompiled - this is simply a
+ convenience, not a build-speed enhancement.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(attr("pch", LABEL).direct_compile_time_input().allowedFileTypes(FileType.of(".pch")))
/* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(deps) -->
- The list of targets that are linked together to form the final bundle.
- ${SYNOPSIS}
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .override(attr("deps", LABEL_LIST)
- .direct_compile_time_input()
- .allowedRuleClasses(ALLOWED_DEPS_RULE_CLASSES)
- .allowedFileTypes())
+ The list of targets that are linked together to form the final bundle.
+ ${SYNOPSIS}
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .override(
+ attr("deps", LABEL_LIST)
+ .direct_compile_time_input()
+ .allowedRuleClasses(ALLOWED_DEPS_RULE_CLASSES)
+ .allowedFileTypes())
/* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(non_propagated_deps) -->
- The list of targets that are required in order to build this target,
- but which are not included in the final bundle.
- ${SYNOPSIS}
- This attribute should only rarely be used, and probably only for proto
- dependencies.
- ${SYNOPSIS}
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(attr("non_propagated_deps", LABEL_LIST)
- .direct_compile_time_input()
- .allowedRuleClasses(ALLOWED_DEPS_RULE_CLASSES)
- .allowedFileTypes())
+ The list of targets that are required in order to build this target,
+ but which are not included in the final bundle.
+ ${SYNOPSIS}
+ This attribute should only rarely be used, and probably only for proto
+ dependencies.
+ ${SYNOPSIS}
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(
+ attr("non_propagated_deps", LABEL_LIST)
+ .direct_compile_time_input()
+ .allowedRuleClasses(ALLOWED_DEPS_RULE_CLASSES)
+ .allowedFileTypes())
/* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(defines) -->
- Extra <code>-D</code> flags to pass to the compiler. They should be in
- the form <code>KEY=VALUE</code> or simply <code>KEY</code> and are
- passed not only the compiler for this target (as <code>copts</code>
- are) but also to all <code>objc_</code> dependers of this target.
- ${SYNOPSIS}
- Subject to <a href="#make_variables">"Make variable"</a> substitution and
- <a href="#sh-tokenization">Bourne shell tokenization</a>.
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ Extra <code>-D</code> flags to pass to the compiler. They should be in
+ the form <code>KEY=VALUE</code> or simply <code>KEY</code> and are
+ passed not only the compiler for this target (as <code>copts</code>
+ are) but also to all <code>objc_</code> dependers of this target.
+ ${SYNOPSIS}
+ Subject to <a href="#make_variables">"Make variable"</a> substitution and
+ <a href="#sh-tokenization">Bourne shell tokenization</a>.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
.add(attr("defines", STRING_LIST))
+ /* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(enable_modules) -->
+ Enables clang module support (via -fmodules).
+ ${SYNOPSIS}
+ Setting this to 1 will allow you to @import system headers and other targets:
+ @import UIKit;
+ @import path_to_package_target;
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(attr("enable_modules", BOOLEAN))
.build();
}
@Override