Skip to content

Commit 9b3a7eb

Browse files
authored
Add implementation deps support for Objective-C (#18372)
1 parent 80b20b1 commit 9b3a7eb

File tree

9 files changed

+127
-8
lines changed

9 files changed

+127
-8
lines changed

src/main/java/com/google/devtools/build/lib/analysis/LocationExpander.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,11 @@ static Map<Label, Collection<Artifact>> buildLocationMap(
467467
Iterables.addAll(
468468
depsDataAndTools, ruleContext.getPrerequisitesIf("deps", FilesToRunProvider.class));
469469
}
470+
if (ruleContext.getRule().isAttrDefined("implementation_deps", BuildType.LABEL_LIST)) {
471+
Iterables.addAll(
472+
depsDataAndTools,
473+
ruleContext.getPrerequisitesIf("implementation_deps", FilesToRunProvider.class));
474+
}
470475
if (allowDataAttributeEntriesInLabel
471476
&& ruleContext.getRule().isAttrDefined("data", BuildType.LABEL_LIST)) {
472477
Iterables.addAll(

src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ static class Builder {
111111
private final List<CcCompilationContext> ccCompilationContexts = new ArrayList<>();
112112
private final List<CcLinkingContext> ccLinkingContexts = new ArrayList<>();
113113
private final List<CcCompilationContext> directCCompilationContexts = new ArrayList<>();
114+
private final List<CcCompilationContext> implementationCcCompilationContexts =
115+
new ArrayList<>();
114116
// List of CcLinkingContext to be merged into ObjcProvider, to be done for deps that don't have
115117
// ObjcProviders.
116118
// TODO(b/171413861): remove after objc link info migration.
@@ -179,6 +181,13 @@ Builder addCcLinkingContexts(Iterable<CcInfo> ccInfos) {
179181
return this;
180182
}
181183

184+
@CanIgnoreReturnValue
185+
Builder addImplementationCcCompilationContexts(Iterable<CcInfo> ccInfos) {
186+
ccInfos.forEach(
187+
ccInfo -> implementationCcCompilationContexts.add(ccInfo.getCcCompilationContext()));
188+
return this;
189+
}
190+
182191
@CanIgnoreReturnValue
183192
Builder addCcInfos(Iterable<CcInfo> ccInfos) {
184193
addCcCompilationContexts(ccInfos);
@@ -291,6 +300,8 @@ ObjcCommon build() {
291300
ImmutableList.copyOf(this.ccLinkingContexts);
292301
ImmutableList<CcCompilationContext> directCCompilationContexts =
293302
ImmutableList.copyOf(this.directCCompilationContexts);
303+
ImmutableList<CcCompilationContext> implementationCcCompilationContexts =
304+
ImmutableList.copyOf(this.implementationCcCompilationContexts);
294305
ImmutableList<CcLinkingContext> ccLinkingContextsForMerging =
295306
ImmutableList.copyOf(this.ccLinkingContextsForMerging);
296307

@@ -310,7 +321,8 @@ ObjcCommon build() {
310321
.addDirectCcCompilationContexts(directCCompilationContexts)
311322
// TODO(bazel-team): This pulls in stl via
312323
// CcCompilationHelper.getStlCcCompilationContext(), but probably shouldn't.
313-
.addCcCompilationContexts(ccCompilationContexts);
324+
.addCcCompilationContexts(ccCompilationContexts)
325+
.addImplementationCcCompilationContexts(implementationCcCompilationContexts);
314326

315327
for (CcLinkingContext ccLinkingContext : ccLinkingContextsForMerging) {
316328
ImmutableList<String> linkOpts = ccLinkingContext.getFlattenedUserLinkFlags();

src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCompilationContext.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public final class ObjcCompilationContext implements StarlarkValue {
5353
private final ImmutableList<PathFragment> strictDependencyIncludes;
5454
private final ImmutableList<CcCompilationContext> directCcCompilationContexts;
5555
private final ImmutableList<CcCompilationContext> ccCompilationContexts;
56+
private final ImmutableList<CcCompilationContext> implementationCcCompilationContexts;
5657

5758
ObjcCompilationContext(
5859
Iterable<String> defines,
@@ -64,7 +65,8 @@ public final class ObjcCompilationContext implements StarlarkValue {
6465
Iterable<PathFragment> quoteIncludes,
6566
Iterable<PathFragment> strictDependencyIncludes,
6667
Iterable<CcCompilationContext> directCcCompilationContexts,
67-
Iterable<CcCompilationContext> ccCompilationContexts) {
68+
Iterable<CcCompilationContext> ccCompilationContexts,
69+
Iterable<CcCompilationContext> implementationCcCompilationContexts) {
6870
this.defines = ImmutableList.copyOf(defines);
6971
this.publicHeaders = ImmutableList.copyOf(publicHeaders);
7072
this.publicTextualHeaders = ImmutableList.copyOf(publicTextualHeaders);
@@ -75,6 +77,8 @@ public final class ObjcCompilationContext implements StarlarkValue {
7577
this.strictDependencyIncludes = ImmutableList.copyOf(strictDependencyIncludes);
7678
this.directCcCompilationContexts = ImmutableList.copyOf(directCcCompilationContexts);
7779
this.ccCompilationContexts = ImmutableList.copyOf(ccCompilationContexts);
80+
this.implementationCcCompilationContexts =
81+
ImmutableList.copyOf(implementationCcCompilationContexts);
7882
}
7983

8084
public ImmutableList<String> getDefines() {
@@ -159,11 +163,23 @@ public ImmutableList<CcCompilationContext> getCcCompilationContexts() {
159163
return ccCompilationContexts;
160164
}
161165

166+
public ImmutableList<CcCompilationContext> getImplementationCcCompilationContexts() {
167+
return implementationCcCompilationContexts;
168+
}
169+
162170
@StarlarkMethod(name = "cc_compilation_contexts", documented = false, structField = true)
163171
public Sequence<CcCompilationContext> getCcCompilationContextsForStarlark() {
164172
return StarlarkList.immutableCopyOf(getCcCompilationContexts());
165173
}
166174

175+
@StarlarkMethod(
176+
name = "implementation_cc_compilation_contexts",
177+
documented = false,
178+
structField = true)
179+
public Sequence<CcCompilationContext> getImplementationCcCompilationContextsForStarlark() {
180+
return StarlarkList.immutableCopyOf(getImplementationCcCompilationContexts());
181+
}
182+
167183
public CcCompilationContext createCcCompilationContext() {
168184
CcCompilationContext.Builder builder =
169185
CcCompilationContext.builder(
@@ -200,6 +216,8 @@ static class Builder {
200216
private final List<PathFragment> strictDependencyIncludes = new ArrayList<>();
201217
private final List<CcCompilationContext> directCcCompilationContexts = new ArrayList<>();
202218
private final List<CcCompilationContext> ccCompilationContexts = new ArrayList<>();
219+
private final List<CcCompilationContext> implementationCcCompilationContexts =
220+
new ArrayList<>();
203221

204222
Builder() {}
205223

@@ -266,6 +284,13 @@ public Builder addDirectCcCompilationContexts(
266284
return this;
267285
}
268286

287+
@CanIgnoreReturnValue
288+
public Builder addImplementationCcCompilationContexts(
289+
Iterable<CcCompilationContext> ccCompilationContexts) {
290+
Iterables.addAll(this.implementationCcCompilationContexts, ccCompilationContexts);
291+
return this;
292+
}
293+
269294
@CanIgnoreReturnValue
270295
public Builder addCcCompilationContext(CcCompilationContext ccCompilationContext) {
271296
this.ccCompilationContexts.add(ccCompilationContext);
@@ -283,7 +308,8 @@ ObjcCompilationContext build() {
283308
quoteIncludes,
284309
strictDependencyIncludes,
285310
directCcCompilationContexts,
286-
ccCompilationContexts);
311+
ccCompilationContexts,
312+
implementationCcCompilationContexts);
287313
}
288314
}
289315
}

src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,19 @@ Header file to prepend to every source file being compiled (both arc
453453
.direct_compile_time_input()
454454
.mandatoryProviders(AppleDynamicFrameworkInfo.STARLARK_CONSTRUCTOR.id())
455455
.allowedFileTypes())
456+
/* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(implementation_deps) -->
457+
The list of other libraries that the library target depends on. Unlike with
458+
<code>deps</code>, the headers and include paths of these libraries (and all their
459+
transitive deps) are only used for compilation of this library, and not libraries that
460+
depend on it. Libraries specified with <code>implementation_deps</code> are still linked
461+
in binary targets that depend on this library.
462+
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
463+
.add(
464+
attr("implementation_deps", LABEL_LIST)
465+
.direct_compile_time_input()
466+
.allowedRuleClasses(ALLOWED_CC_DEPS_RULE_CLASSES)
467+
.mandatoryProviders(ObjcProvider.STARLARK_CONSTRUCTOR.id())
468+
.allowedFileTypes())
456469
/* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(defines) -->
457470
Extra <code>-D</code> flags to pass to the compiler. They should be in
458471
the form <code>KEY=VALUE</code> or simply <code>KEY</code> and are

src/main/java/com/google/devtools/build/lib/rules/objc/ObjcStarlarkInternal.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,11 @@ public InstrumentedFilesInfo createInstrumentedFilesInfo(
268268
positional = false,
269269
defaultValue = "[]",
270270
named = true),
271+
@Param(
272+
name = "implementation_cc_compilation_contexts",
273+
positional = false,
274+
defaultValue = "[]",
275+
named = true),
271276
@Param(name = "defines", positional = false, defaultValue = "[]", named = true),
272277
@Param(name = "includes", positional = false, defaultValue = "[]", named = true),
273278
})
@@ -278,6 +283,7 @@ public ObjcCompilationContext createCompilationContext(
278283
Sequence<?> providers,
279284
Sequence<?> directCcCompilationContexts,
280285
Sequence<?> ccCompilationContexts,
286+
Sequence<?> implementationCcCompilationContexts,
281287
Sequence<?> defines,
282288
Sequence<?> includes)
283289
throws InterruptedException, EvalException {
@@ -293,6 +299,11 @@ public ObjcCompilationContext createCompilationContext(
293299
.addCcCompilationContexts(
294300
Sequence.cast(
295301
ccCompilationContexts, CcCompilationContext.class, "cc_compilation_contexts"))
302+
.addImplementationCcCompilationContexts(
303+
Sequence.cast(
304+
implementationCcCompilationContexts,
305+
CcCompilationContext.class,
306+
"implementation_cc_compilation_contexts"))
296307
.addDefines(Sequence.cast(defines, String.class, "defines"))
297308
.addIncludes(
298309
Sequence.cast(includes, String.class, "includes").stream()

src/main/starlark/builtins_bzl/common/objc/compilation_support.bzl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ def _build_common_variables(
7272
empty_compilation_artifacts = False,
7373
deps = [],
7474
runtime_deps = [],
75+
implementation_deps = [],
7576
extra_disabled_features = [],
7677
extra_enabled_features = [],
7778
extra_import_libraries = [],
@@ -95,6 +96,7 @@ def _build_common_variables(
9596
compilation_artifacts = compilation_artifacts,
9697
deps = deps,
9798
runtime_deps = runtime_deps,
99+
implementation_deps = implementation_deps,
98100
intermediate_artifacts = intermediate_artifacts,
99101
alwayslink = alwayslink,
100102
has_module_map = has_module_map,
@@ -193,6 +195,7 @@ def _compile(
193195
system_includes = objc_compilation_context.system_includes,
194196
quote_includes = objc_compilation_context.quote_includes,
195197
compilation_contexts = objc_compilation_context.cc_compilation_contexts,
198+
implementation_compilation_contexts = objc_compilation_context.implementation_cc_compilation_contexts,
196199
user_compile_flags = user_compile_flags,
197200
grep_includes = _get_grep_includes(common_variables.ctx),
198201
module_map = module_map,

src/main/starlark/builtins_bzl/common/objc/objc_common.bzl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def _create_context_and_provider(
2828
extra_import_libraries,
2929
deps,
3030
runtime_deps,
31+
implementation_deps,
3132
attr_linkopts):
3233
objc_providers = []
3334
cc_compilation_contexts = []
@@ -57,6 +58,31 @@ def _create_context_and_provider(
5758
if CcInfo in runtime_dep:
5859
cc_compilation_contexts.append(runtime_dep[CcInfo].compilation_context)
5960

61+
implementation_cc_compilation_contexts = []
62+
for impl_dep in implementation_deps:
63+
if apple_common.Objc in impl_dep:
64+
# For implementation deps, we only need to propagate linker inputs
65+
# with Objc provider, but no compilation artifacts
66+
# (eg module_map, umbrella_header).
67+
implementation_dep_objc_provider_kwargs = {
68+
"force_load_library": impl_dep[apple_common.Objc].force_load_library,
69+
"imported_library": impl_dep[apple_common.Objc].imported_library,
70+
"library": impl_dep[apple_common.Objc].library,
71+
"linkopt": impl_dep[apple_common.Objc].linkopt,
72+
"sdk_dylib": impl_dep[apple_common.Objc].sdk_dylib,
73+
"sdk_framework": impl_dep[apple_common.Objc].sdk_framework,
74+
"source": impl_dep[apple_common.Objc].source,
75+
"weak_sdk_framework": impl_dep[apple_common.Objc].weak_sdk_framework,
76+
}
77+
objc_provider = apple_common.new_objc_provider(**implementation_dep_objc_provider_kwargs)
78+
objc_providers.append(objc_provider)
79+
elif CcInfo in impl_dep:
80+
cc_linking_contexts_for_merging.append(impl_dep[CcInfo].linking_context)
81+
82+
if CcInfo in impl_dep:
83+
implementation_cc_compilation_contexts.append(impl_dep[CcInfo].compilation_context)
84+
cc_linking_contexts.append(impl_dep[CcInfo].linking_context)
85+
6086
link_order_keys = [
6187
"imported_library",
6288
"cc_library",
@@ -82,6 +108,7 @@ def _create_context_and_provider(
82108
objc_compilation_context_kwargs = {
83109
"providers": objc_providers + runtime_objc_providers,
84110
"cc_compilation_contexts": cc_compilation_contexts,
111+
"implementation_cc_compilation_contexts": implementation_cc_compilation_contexts,
85112
"public_hdrs": [],
86113
"private_hdrs": [],
87114
"public_textual_hdrs": [],

src/main/starlark/builtins_bzl/common/objc/objc_library.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def _objc_library_impl(ctx):
4545
use_pch = True,
4646
deps = ctx.attr.deps,
4747
runtime_deps = ctx.attr.runtime_deps,
48+
implementation_deps = ctx.attr.implementation_deps,
4849
attr_linkopts = ctx.attr.linkopts,
4950
alwayslink = ctx.attr.alwayslink,
5051
)
@@ -89,6 +90,7 @@ objc_library = rule(
8990
attrs = common_attrs.union(
9091
{
9192
"data": attr.label_list(allow_files = True),
93+
"implementation_deps": attr.label_list(providers = [CcInfo], allow_files = False),
9294
},
9395
common_attrs.CC_TOOLCHAIN_RULE,
9496
common_attrs.LICENSES,

src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,21 @@ public void testCompilesSources() throws Exception {
128128
.write();
129129

130130
createLibraryTargetWriter("//objc/lib2")
131+
.setAndCreateFiles("srcs", "b.m")
132+
.setAndCreateFiles("hdrs", "private.h")
133+
.write();
134+
135+
createLibraryTargetWriter("//objc/lib3")
131136
.setAndCreateFiles("srcs", "a.m")
132137
.setAndCreateFiles("hdrs", "hdr.h")
133138
.setList("deps", "//objc/lib1")
139+
.setList("implementation_deps", "//objc/lib2")
134140
.write();
135141

136142
createLibraryTargetWriter("//objc:x")
137143
.setAndCreateFiles("srcs", "a.m", "private.h")
138144
.setAndCreateFiles("hdrs", "hdr.h")
139-
.setList("deps", "//objc/lib2:lib2")
145+
.setList("deps", "//objc/lib3:lib3")
140146
.write();
141147

142148
CppCompileAction compileA = (CppCompileAction) compileAction("//objc:x", "a.o");
@@ -1077,20 +1083,34 @@ public void testProvidesObjcLibraryAndHeaders() throws Exception {
10771083
.setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
10781084
.setAndCreateFiles("hdrs", "a.h", "b.h")
10791085
.write();
1086+
ConfiguredTarget impltarget =
1087+
createLibraryTargetWriter("//objc_impl:lib")
1088+
.setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
1089+
.setAndCreateFiles("hdrs", "a.h", "b.h")
1090+
.write();
10801091
ConfiguredTarget depender =
1081-
createLibraryTargetWriter("//objc2:lib")
1092+
createLibraryTargetWriter("//objc_depender:lib")
10821093
.setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
10831094
.setAndCreateFiles("hdrs", "c.h", "d.h")
10841095
.setList("deps", "//objc:lib")
1096+
.setList("implementation_deps", "//objc_impl:lib")
10851097
.write();
10861098
assertThat(getArifactPaths(target, LIBRARY)).containsExactly("objc/liblib.a");
1087-
assertThat(getArifactPaths(depender, LIBRARY)).containsExactly(
1088-
"objc/liblib.a", "objc2/liblib.a");
1099+
assertThat(getArifactPaths(depender, LIBRARY))
1100+
.containsExactly("objc/liblib.a", "objc_impl/liblib.a", "objc_depender/liblib.a");
1101+
assertThat(getArifactPaths(impltarget, LIBRARY)).containsExactly("objc_impl/liblib.a");
10891102
assertThat(getArifactPathsOfHeaders(target))
10901103
.containsExactly("objc/a.h", "objc/b.h", "objc/private.h");
1104+
assertThat(getArifactPathsOfHeaders(impltarget))
1105+
.containsExactly("objc_impl/a.h", "objc_impl/b.h", "objc_impl/private.h");
10911106
assertThat(getArifactPathsOfHeaders(depender))
10921107
.containsExactly(
1093-
"objc/a.h", "objc/b.h", "objc/private.h", "objc2/c.h", "objc2/d.h", "objc2/private.h");
1108+
"objc/a.h",
1109+
"objc/b.h",
1110+
"objc/private.h",
1111+
"objc_depender/c.h",
1112+
"objc_depender/d.h",
1113+
"objc_depender/private.h");
10941114
}
10951115

10961116
private static Iterable<String> getArifactPaths(

0 commit comments

Comments
 (0)