diff options
author | 2017-07-13 19:26:31 +0200 | |
---|---|---|
committer | 2017-07-14 10:52:03 +0200 | |
commit | fba07bb72570245d26bd8795709c5a004fc9026a (patch) | |
tree | f00bf33b05ea22c73d050cf1bfae3b27796da53f /src | |
parent | 98375a24ab40bfe0ff124401ca2d95740f67e072 (diff) |
Add module_map attribute to objc_library
This allows users to specify a custom module map.
PiperOrigin-RevId: 161827651
Diffstat (limited to 'src')
10 files changed, 97 insertions, 11 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 7b7230c27b..e940d57823 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 @@ -303,6 +303,7 @@ public final class CcLibraryHelper { private final FdoSupportProvider fdoSupport; private String linkedArtifactNameSuffix = ""; private boolean useDeps = true; + private boolean generateModuleMap = true; /** * Creates a CcLibraryHelper. @@ -1388,13 +1389,17 @@ 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()) { + + if (generateModuleMap) { + Optional<Artifact> umbrellaHeader = cppModuleMap.getUmbrellaHeader(); + if (umbrellaHeader.isPresent()) { + ruleContext.registerAction( + createUmbrellaHeaderAction(umbrellaHeader.get(), publicHeaders)); + } + ruleContext.registerAction( - createUmbrellaHeaderAction(umbrellaHeader.get(), publicHeaders)); + createModuleMapAction(cppModuleMap, publicHeaders, dependentModuleMaps, compiled)); } - ruleContext.registerAction( - createModuleMapAction(cppModuleMap, publicHeaders, dependentModuleMaps, compiled)); if (model.getGeneratesPicHeaderModule()) { contextBuilder.setPicHeaderModule(model.getPicHeaderModule(cppModuleMap.getArtifact())); } @@ -1594,4 +1599,12 @@ public final class CcLibraryHelper { public void registerAdditionalModuleMap(CppModuleMap cppModuleMap) { this.additionalCppModuleMaps.add(Preconditions.checkNotNull(cppModuleMap)); } + + /** + * Don't generate a module map for this target if a custom module map is provided. + */ + public CcLibraryHelper doNotGenerateModuleMap() { + generateModuleMap = false; + return this; + } } 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 5945dbc413..39ed3e564c 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 @@ -875,7 +875,7 @@ public abstract class CompilationSupport { } } - if (attributes.enableModules()) { + if (attributes.enableModules() && !getCustomModuleMap(ruleContext).isPresent()) { copts.add("-fmodules"); } if (copts.contains("-fmodules")) { @@ -1484,4 +1484,11 @@ public abstract class CompilationSupport { return null; } } + + public static Optional<Artifact> getCustomModuleMap(RuleContext ruleContext) { + if (ruleContext.attributes().has("module_map", BuildType.LABEL)) { + return Optional.fromNullable(ruleContext.getPrerequisiteArtifact("module_map", Mode.TARGET)); + } + return Optional.absent(); + } } 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 ad0fed4039..ff1d068a54 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 @@ -464,6 +464,9 @@ public class CrosstoolCompilationSupport extends CompilationSupport { if (!useDeps) { result.doNotUseDeps(); } + if (getCustomModuleMap(ruleContext).isPresent()) { + result.doNotGenerateModuleMap(); + } return result; } @@ -490,7 +493,8 @@ public class CrosstoolCompilationSupport extends CompilationSupport { .add(isHost ? "host" : "nonhost") .add(configuration.getCompilationMode().toString()); - if (configuration.getFragment(ObjcConfiguration.class).moduleMapsEnabled()) { + if (configuration.getFragment(ObjcConfiguration.class).moduleMapsEnabled() + && !getCustomModuleMap(ruleContext).isPresent()) { activatedCrosstoolSelectables.add(OBJC_MODULE_FEATURE_NAME); } if (!CompilationAttributes.Builder.fromRuleContext(ruleContext).build().enableModules()) { 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 f6d037b4cb..668790132b 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 @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.rules.objc; +import com.google.common.base.Optional; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Root; import com.google.devtools.build.lib.analysis.RuleContext; @@ -440,9 +441,13 @@ public final class IntermediateArtifacts { .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. - if (umbrellaHeaderStrategy == UmbrellaHeaderStrategy.GENERATE) { + + Optional<Artifact> customModuleMap = CompilationSupport.getCustomModuleMap(ruleContext); + if (customModuleMap.isPresent()) { + return new CppModuleMap(customModuleMap.get(), moduleName); + } else if (umbrellaHeaderStrategy == UmbrellaHeaderStrategy.GENERATE) { + // 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"), appendExtensionInGenfiles(".modulemaps/umbrella.h"), diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java index 7a703fe818..82de6228ac 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java @@ -335,7 +335,7 @@ public class LegacyCompilationSupport extends CompilationSupport { } // Add module map arguments. - if (moduleMap.isPresent()) { + if (moduleMap.isPresent() && !getCustomModuleMap(ruleContext).isPresent()) { // If modules are enabled for the rule, -fmodules is added to the copts already. (This implies // module map usage). Otherwise, we need to pass -fmodule-maps. if (!attributes.enableModules()) { 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 453776db23..411a7957f7 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 @@ -716,6 +716,15 @@ public class ObjcRuleClasses { @import path_to_package_target; <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ .add(attr("enable_modules", BOOLEAN)) + /* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(module_map) --> + A custom Clang module map for this target. Use of a custom module map is discouraged. Most + users should use module maps generated by Bazel. + If specified, Bazel will not generate a module map for this target, but will pass the + provided module map to the compiler. + <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ + .add( + attr("module_map", LABEL) + .allowedFileTypes(FileType.of(".modulemap"))) /* Provides the label for header_scanner tool that is used to scan inclusions for ObjC sources and provide a list of required headers via a .header_list file. diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/AppleBinaryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/AppleBinaryTest.java index 90f42a89f8..65cb196269 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/AppleBinaryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/AppleBinaryTest.java @@ -1413,4 +1413,9 @@ public class AppleBinaryTest extends ObjcRuleTestCase { assertThat(Joiner.on(" ").join(testLinkAction.getArguments())) .contains("@loader_path/Frameworks"); } + + @Test + public void testCustomModuleMap() throws Exception { + checkCustomModuleMap(RULE_TYPE); + } } diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcBinaryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcBinaryTest.java index 563dd887b4..2dd537a51a 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcBinaryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcBinaryTest.java @@ -910,4 +910,9 @@ public class ObjcBinaryTest extends ObjcRuleTestCase { public void testFilesToCompileOutputGroup() throws Exception { checkFilesToCompileOutputGroup(RULE_TYPE); } + + @Test + public void testCustomModuleMap() throws Exception { + checkCustomModuleMap(RULE_TYPE); + } } diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java index 9840d460a6..f64d6551ff 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java @@ -1543,4 +1543,9 @@ public class ObjcLibraryTest extends ObjcRuleTestCase { CommandAction compileAction = compileAction("//x:objc", "source.o"); assertThat(compileAction.getArguments()).contains("-dummy"); } + + @Test + public void testCustomModuleMap() throws Exception { + checkCustomModuleMap(RULE_TYPE); + } } diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java index 005c4ee927..645110da7b 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java @@ -22,6 +22,7 @@ import static com.google.devtools.build.lib.rules.objc.LegacyCompilationSupport. import static com.google.devtools.build.lib.rules.objc.ObjcProvider.GENERAL_RESOURCE_FILE; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.HEADER; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.INCLUDE; +import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MODULE_MAP; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STORYBOARD; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule.FAMILIES_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule.INFOPLIST_ATTR; @@ -4893,4 +4894,36 @@ public abstract class ObjcRuleTestCase extends BuildViewTestCase { getOutputGroup(target, OutputGroupProvider.FILES_TO_COMPILE))) .isEqualTo("a.o"); } + + protected void checkCustomModuleMap(RuleType ruleType) throws Exception { + useConfiguration("--experimental_objc_enable_module_maps"); + ruleType.scratchTarget(scratch, "srcs", "['a.m']", "deps", "['//z:testModuleMap']"); + scratch.file("x/a.m"); + scratch.file("z/b.m"); + scratch.file("z/b.h"); + scratch.file("y/module.modulemap", "module my_module_b { export *\n header b.h }"); + scratch.file("z/BUILD", + "objc_library(", + "name = 'testModuleMap',", + "hdrs = ['b.h'],", + "srcs = ['b.m'],", + "module_map = '//y:mm'", + ")"); + scratch.file("y/BUILD", + "filegroup(", + "name = 'mm',", + "srcs = ['module.modulemap']", + ")"); + + CommandAction compileActionA = compileAction("//z:testModuleMap", "b.o"); + assertThat(compileActionA.getArguments()).doesNotContain("-fmodule-maps"); + assertThat(compileActionA.getArguments()).doesNotContain("-fmodule-name"); + + ObjcProvider provider = providerForTarget("//z:testModuleMap"); + assertThat(Artifact.toExecPaths(provider.get(MODULE_MAP))) + .containsExactly("y/module.modulemap"); + + provider = providerForTarget("//x:x"); + assertThat(Artifact.toExecPaths(provider.get(MODULE_MAP))).contains("y/module.modulemap"); + } } |