aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java31
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java14
3 files changed, 50 insertions, 4 deletions
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 6c2f99cf7b..6e08eaf3e8 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
@@ -45,6 +45,8 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
@@ -101,6 +103,14 @@ public final class CompilationSupport {
private static final String FRAMEWORK_SUFFIX = ".framework";
+ private static final Predicate<String> INCLUDE_DIR_OPTION_IN_COPTS =
+ new Predicate<String>() {
+ @Override
+ public boolean apply(String copt) {
+ return copt.startsWith("-I") && copt.length() > 2;
+ }
+ };
+
/**
* Iterable wrapper providing strong type safety for arguments to binary linking.
*/
@@ -744,15 +754,30 @@ public final class CompilationSupport {
for (CompilationArtifacts artifacts : common.getCompilationArtifacts().asSet()) {
xcodeProviderBuilder.setCompilationArtifacts(artifacts);
}
+
+ // The include directory options ("-I") are parsed out of copts. The include directories are
+ // added as non-propagated header search paths local to the associated Xcode target.
+ Iterable<String> copts = Iterables.concat(
+ objcConfiguration.getCopts(), attributes.copts(), attributes.optionsCopts());
+ Iterable<String> includeDirOptions = Iterables.filter(copts, INCLUDE_DIR_OPTION_IN_COPTS);
+ Iterable<String> coptsWithoutIncludeDirs = Iterables.filter(
+ copts, Predicates.not(INCLUDE_DIR_OPTION_IN_COPTS));
+ ImmutableList.Builder<PathFragment> nonPropagatedHeaderSearchPaths =
+ new ImmutableList.Builder<>();
+ for (String includeDirOption : includeDirOptions) {
+ nonPropagatedHeaderSearchPaths.add(new PathFragment(includeDirOption.substring(2)));
+ }
+
xcodeProviderBuilder
.addHeaders(attributes.hdrs())
.addUserHeaderSearchPaths(ObjcCommon.userHeaderSearchPaths(ruleContext.getConfiguration()))
.addHeaderSearchPaths("$(WORKSPACE_ROOT)", attributes.headerSearchPaths())
.addHeaderSearchPaths("$(SDKROOT)/usr/include", attributes.sdkIncludes())
+ .addNonPropagatedHeaderSearchPaths(
+ "$(WORKSPACE_ROOT)", nonPropagatedHeaderSearchPaths.build())
.addCompilationModeCopts(objcConfiguration.getCoptsForCompilationMode())
- .addCopts(objcConfiguration.getCopts())
- .addCopts(attributes.copts())
- .addCopts(attributes.optionsCopts());
+ .addCopts(coptsWithoutIncludeDirs);
+
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 d753115812..04be1426cd 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
@@ -224,6 +224,10 @@ public class ObjcRuleClasses {
<a href="#sh-tokenization">Bourne shell tokenization</a>.
These flags will only apply to this target, and not those upon which
it depends, or those which depend on it.
+ <p>
+ Note that for the generated Xcode project, directory paths specified using "-I" flags in
+ copts are parsed out, prepended with "$(WORKSPACE_ROOT)/" if they are relative paths, and
+ added to the header search paths for the associated Xcode target.
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
.add(attr("copts", STRING_LIST))
.build();
@@ -568,6 +572,11 @@ public class ObjcRuleClasses {
genfiles and bin roots (e.g. <code>blaze-genfiles/pkg/includedir</code>
and <code>blaze-out/pkg/includedir</code>) are included in addition to the
actual client root.
+ <p>
+ Unlike <a href="#objc_library.copts">COPTS</a>, these flags are added for this rule
+ and every rule that depends on it. (Note: not the rules it depends upon!) Be
+ very careful, since this may have far-reaching effects. When in doubt, add
+ "-I" flags to <a href="#objc_library.copts">COPTS</a> instead.
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
.add(attr("includes", Type.STRING_LIST))
/* <!-- #BLAZE_RULE($objc_compile_dependency_rule).ATTRIBUTE(sdk_includes) -->
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java
index 5fd9612c1f..c763052f4a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java
@@ -133,6 +133,15 @@ public final class XcodeProvider implements TransitiveInfoProvider {
}
/**
+ * Adds non-propagated header search paths for this target. Each relative path is interpreted
+ * relative to the given root, such as {@code "$(WORKSPACE_ROOT)"}.
+ */
+ public Builder addNonPropagatedHeaderSearchPaths(String root, Iterable<PathFragment> paths) {
+ this.nonPropagatedHeaderSearchPaths.addAll(rootEach(root, paths));
+ return this;
+ }
+
+ /**
* Sets the Info.plist for the bundle represented by this provider.
*/
public Builder setBundleInfoplist(Artifact bundleInfoplist) {
@@ -656,7 +665,8 @@ public final class XcodeProvider implements TransitiveInfoProvider {
/**
* Prepends the given path to each path in {@code paths}. Empty paths are
- * transformed to the value of {@code variable} rather than {@code variable + "/."}
+ * transformed to the value of {@code variable} rather than {@code variable + "/."}. Absolute
+ * paths are returned without modifications.
*/
@VisibleForTesting
static Iterable<String> rootEach(final String prefix, Iterable<PathFragment> paths) {
@@ -669,6 +679,8 @@ public final class XcodeProvider implements TransitiveInfoProvider {
public String apply(PathFragment input) {
if (input.getSafePathString().equals(".")) {
return prefix;
+ } else if (input.isAbsolute()) {
+ return input.getSafePathString();
} else {
return prefix + "/" + input.getSafePathString();
}