Add objc_include_scanning flag
Currently this flag will do nothing -- actual functionality will be
submitted in a separate CL. I also made some changes in preparation
for the ability to support three modes of include processing: include
scanning, headering thinning, and no scanning.
RELNOTES: None
PiperOrigin-RevId: 268800639
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 e2bdfe5..a428530 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
@@ -232,6 +232,13 @@
"c-compile",
"c++-compile");
+ /** The kind of include processing to use. */
+ enum IncludeProcessingType {
+ HEADER_THINNING,
+ INCLUDE_SCANNING,
+ NO_PROCESSING;
+ }
+
/** Returns the location of the xcrunwrapper tool. */
public static final FilesToRunProvider xcrunwrapper(RuleContext ruleContext) {
return ruleContext.getExecutablePrerequisite("$xcrunwrapper", Mode.HOST);
@@ -259,21 +266,24 @@
private IncludeProcessing createIncludeProcessing(
Iterable<Artifact> privateHdrs, ObjcProvider objcProvider, @Nullable Artifact pchHdr) {
- if (isHeaderThinningEnabled()) {
- Iterable<Artifact> potentialInputs = Iterables.concat(privateHdrs, objcProvider.get(HEADER));
- if (!starlarkSemantics.incompatibleObjcFrameworkCleanup()) {
- potentialInputs =
- Iterables.concat(
- potentialInputs,
- objcProvider.get(STATIC_FRAMEWORK_FILE),
- objcProvider.get(DYNAMIC_FRAMEWORK_FILE));
- }
- if (pchHdr != null) {
- potentialInputs = Iterables.concat(potentialInputs, ImmutableList.of(pchHdr));
- }
- return new HeaderThinning(potentialInputs);
- } else {
- return NoProcessing.INSTANCE;
+ switch (includeProcessingType) {
+ case HEADER_THINNING:
+ Iterable<Artifact> potentialInputs =
+ Iterables.concat(privateHdrs, objcProvider.get(HEADER));
+ if (!starlarkSemantics.incompatibleObjcFrameworkCleanup()) {
+ potentialInputs =
+ Iterables.concat(
+ potentialInputs,
+ objcProvider.get(STATIC_FRAMEWORK_FILE),
+ objcProvider.get(DYNAMIC_FRAMEWORK_FILE));
+ }
+ if (pchHdr != null) {
+ potentialInputs = Iterables.concat(potentialInputs, ImmutableList.of(pchHdr));
+ }
+ return new HeaderThinning(potentialInputs);
+ case INCLUDE_SCANNING:
+ default:
+ return NoProcessing.INSTANCE;
}
}
@@ -508,9 +518,9 @@
ObjcProvider objcProvider, Collection<Artifact> privateHdrs, Artifact pchHdr) {
return new ObjcCppSemantics(
objcProvider,
+ includeProcessingType,
createIncludeProcessing(privateHdrs, objcProvider, pchHdr),
ruleContext.getFragment(ObjcConfiguration.class),
- isHeaderThinningEnabled(),
intermediateArtifacts,
buildConfiguration,
starlarkSemantics);
@@ -748,6 +758,7 @@
private final CcToolchainProvider toolchain;
private final boolean isTestRule;
private final boolean usePch;
+ private final IncludeProcessingType includeProcessingType;
/**
* Creates a new compilation support for the given rule and build configuration.
@@ -792,6 +803,14 @@
}
this.toolchain = toolchain;
+
+ if (objcConfiguration.shouldScanIncludes()) {
+ includeProcessingType = IncludeProcessingType.INCLUDE_SCANNING;
+ } else if (isHeaderThinningEnabled()) {
+ includeProcessingType = IncludeProcessingType.HEADER_THINNING;
+ } else {
+ includeProcessingType = IncludeProcessingType.NO_PROCESSING;
+ }
}
/** Builder for {@link CompilationSupport} */
@@ -1810,7 +1829,8 @@
CompilationArtifacts compilationArtifacts)
throws RuleErrorException {
// PIC is not used for Obj-C builds, if that changes this method will need to change
- if (!isHeaderThinningEnabled() || ccCompilationOutputs.getObjectFiles(false).isEmpty()) {
+ if (includeProcessingType != IncludeProcessingType.HEADER_THINNING
+ || ccCompilationOutputs.getObjectFiles(false).isEmpty()) {
return;
}
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 3321b72..f6e15e7 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
@@ -266,15 +266,26 @@
public int objcHeaderThinningPartitionSize;
@Option(
- name = "objc_header_scanner_tool",
- defaultValue = "@bazel_tools//tools/objc:header_scanner",
- converter = LabelConverter.class,
- documentationCategory = OptionDocumentationCategory.TOOLCHAIN,
- effectTags = {OptionEffectTag.CHANGES_INPUTS},
- help =
- "Location of tool to scan Objective-C code for inclusions and output a .headers_list "
- + "file."
- )
+ name = "experimental_objc_include_scanning",
+ defaultValue = "false",
+ documentationCategory = OptionDocumentationCategory.BUILD_TIME_OPTIMIZATION,
+ effectTags = {
+ OptionEffectTag.LOADING_AND_ANALYSIS,
+ OptionEffectTag.EXECUTION,
+ OptionEffectTag.CHANGES_INPUTS
+ },
+ help = "Whether to perform include scanning for objective C/C++.")
+ public boolean scanIncludes;
+
+ @Option(
+ name = "objc_header_scanner_tool",
+ defaultValue = "@bazel_tools//tools/objc:header_scanner",
+ converter = LabelConverter.class,
+ documentationCategory = OptionDocumentationCategory.TOOLCHAIN,
+ effectTags = {OptionEffectTag.CHANGES_INPUTS},
+ help =
+ "Location of tool to scan Objective-C code for inclusions and output a .headers_list "
+ + "file.")
public Label objcHeaderScannerTool;
@Option(
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 fd18583..9ba7762 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
@@ -68,6 +68,7 @@
private final HeaderDiscovery.DotdPruningMode dotdPruningPlan;
private final boolean experimentalHeaderThinning;
private final int objcHeaderThinningPartitionSize;
+ private final boolean shouldScanIncludes;
private final Label objcHeaderScannerTool;
private final Label appleSdk;
private final boolean strictObjcModuleMaps;
@@ -100,6 +101,7 @@
: HeaderDiscovery.DotdPruningMode.DO_NOT_USE;
this.experimentalHeaderThinning = objcOptions.experimentalObjcHeaderThinning;
this.objcHeaderThinningPartitionSize = objcOptions.objcHeaderThinningPartitionSize;
+ this.shouldScanIncludes = objcOptions.scanIncludes;
this.objcHeaderScannerTool = objcOptions.objcHeaderScannerTool;
this.appleSdk = objcOptions.appleSdk;
this.strictObjcModuleMaps = objcOptions.strictObjcModuleMaps;
@@ -270,6 +272,11 @@
return experimentalHeaderThinning;
}
+ /** Returns true iff we should do "include scanning" during this build. */
+ public boolean shouldScanIncludes() {
+ return shouldScanIncludes;
+ }
+
/** Returns the max number of source files to add to each header scanning action. */
public int objcHeaderThinningPartitionSize() {
return objcHeaderThinningPartitionSize;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfigurationLoader.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfigurationLoader.java
index babc7a3..8252241 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfigurationLoader.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfigurationLoader.java
@@ -42,6 +42,11 @@
"Experimental Objective-C header thinning (--experimental_objc_header_thinning) requires "
+ "Objective-C dotd pruning (--objc_use_dotd_pruning).");
}
+ if (objcOptions.experimentalObjcHeaderThinning && objcOptions.scanIncludes) {
+ throw new InvalidConfigurationException(
+ "Only one of header thinning (--experimental_objc_header_thinning) and include scanning "
+ + "(--objc_include_scanning) can be enabled.");
+ }
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java
index 060a51a..75306af 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.rules.objc;
+import static com.google.devtools.build.lib.rules.objc.CompilationSupport.IncludeProcessingType.HEADER_THINNING;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DYNAMIC_FRAMEWORK_FILE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.HEADER;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STATIC_FRAMEWORK_FILE;
@@ -31,6 +32,7 @@
import com.google.devtools.build.lib.rules.cpp.CppSemantics;
import com.google.devtools.build.lib.rules.cpp.HeaderDiscovery.DotdPruningMode;
import com.google.devtools.build.lib.rules.cpp.IncludeProcessing;
+import com.google.devtools.build.lib.rules.objc.CompilationSupport.IncludeProcessingType;
import com.google.devtools.build.lib.syntax.StarlarkSemantics;
import com.google.devtools.build.lib.util.FileTypeSet;
@@ -39,10 +41,10 @@
*/
public class ObjcCppSemantics implements CppSemantics {
+ private final IncludeProcessingType includeProcessingType;
private final IncludeProcessing includeProcessing;
private final ObjcProvider objcProvider;
private final ObjcConfiguration config;
- private final boolean isHeaderThinningEnabled;
private final IntermediateArtifacts intermediateArtifacts;
private final BuildConfiguration buildConfiguration;
private final StarlarkSemantics starlarkSemantics;
@@ -63,26 +65,25 @@
*
* @param objcProvider the provider that should be used in determining objc-specific inputs to
* actions
+ * @param includeProcessingType The type of include processing to be run.
* @param includeProcessing the closure providing the strategy for processing of includes for
* actions
* @param config the ObjcConfiguration for this build
- * @param isHeaderThinningEnabled true if headers_list artifacts should be generated and added as
- * input to compiling actions
* @param intermediateArtifacts used to create headers_list artifacts
* @param buildConfiguration the build configuration for this build
*/
public ObjcCppSemantics(
ObjcProvider objcProvider,
+ IncludeProcessingType includeProcessingType,
IncludeProcessing includeProcessing,
ObjcConfiguration config,
- boolean isHeaderThinningEnabled,
IntermediateArtifacts intermediateArtifacts,
BuildConfiguration buildConfiguration,
StarlarkSemantics starlarkSemantics) {
this.objcProvider = objcProvider;
+ this.includeProcessingType = includeProcessingType;
this.includeProcessing = includeProcessing;
this.config = config;
- this.isHeaderThinningEnabled = isHeaderThinningEnabled;
this.intermediateArtifacts = intermediateArtifacts;
this.buildConfiguration = buildConfiguration;
this.starlarkSemantics = starlarkSemantics;
@@ -105,7 +106,7 @@
.addTransitiveMandatoryInputs(objcProvider.get(DYNAMIC_FRAMEWORK_FILE));
}
- if (isHeaderThinningEnabled) {
+ if (includeProcessingType == HEADER_THINNING) {
Artifact sourceFile = actionBuilder.getSourceFile();
if (!sourceFile.isTreeArtifact()
&& SOURCES_FOR_HEADER_THINNING.matches(sourceFile.getFilename())) {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcConfigurationTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcConfigurationTest.java
new file mode 100644
index 0000000..5dd65ae
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcConfigurationTest.java
@@ -0,0 +1,43 @@
+// Copyright 2019 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.objc;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;
+
+import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
+import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Test case for Objective-C configuration. */
+@RunWith(JUnit4.class)
+public class ObjcConfigurationTest extends BuildViewTestCase {
+ @Test
+ public void disallowBothHeaderThinningAndIncludeScanning() {
+ InvalidConfigurationException e =
+ assertThrows(
+ InvalidConfigurationException.class,
+ () ->
+ useConfiguration(
+ "--experimental_objc_header_thinning", "--experimental_objc_include_scanning"));
+ assertThat(e)
+ .hasMessageThat()
+ .isEqualTo(
+ "Only one of header thinning (--experimental_objc_header_thinning) and include "
+ + "scanning (--objc_include_scanning) can be enabled.");
+ }
+}