Skip to content

Commit ae7b9c5

Browse files
ivan-golubcopybara-github
authored andcommitted
Add implementation deps support for Objective-C
Implements feature #17646 Closes #17962. PiperOrigin-RevId: 528970146 Change-Id: Ic4b9000dfc1eebeef31db32fcab146f1b88f6c35
1 parent bea329a commit ae7b9c5

File tree

9 files changed

+127
-9
lines changed

9 files changed

+127
-9
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
@@ -470,6 +470,11 @@ static Map<Label, Collection<Artifact>> buildLocationMap(
470470
Iterables.addAll(
471471
depsDataAndTools, ruleContext.getPrerequisitesIf("deps", FilesToRunProvider.class));
472472
}
473+
if (ruleContext.getRule().isAttrDefined("implementation_deps", BuildType.LABEL_LIST)) {
474+
Iterables.addAll(
475+
depsDataAndTools,
476+
ruleContext.getPrerequisitesIf("implementation_deps", FilesToRunProvider.class));
477+
}
473478
if (allowDataAttributeEntriesInLabel
474479
&& ruleContext.getRule().isAttrDefined("data", BuildType.LABEL_LIST)) {
475480
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

@@ -309,7 +320,8 @@ ObjcCommon build() {
309320
.addDirectCcCompilationContexts(directCCompilationContexts)
310321
// TODO(bazel-team): This pulls in stl via
311322
// CcCompilationHelper.getStlCcCompilationContext(), but probably shouldn't.
312-
.addCcCompilationContexts(ccCompilationContexts);
323+
.addCcCompilationContexts(ccCompilationContexts)
324+
.addImplementationCcCompilationContexts(implementationCcCompilationContexts);
313325

314326
for (CcLinkingContext ccLinkingContext : ccLinkingContextsForMerging) {
315327
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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,18 @@ Header file to prepend to every source file being compiled (both arc
382382
.direct_compile_time_input()
383383
.mandatoryProviders(CcInfo.PROVIDER.id())
384384
.allowedFileTypes())
385+
/* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(implementation_deps) -->
386+
The list of other libraries that the library target depends on. Unlike with
387+
<code>deps</code>, the headers and include paths of these libraries (and all their
388+
transitive deps) are only used for compilation of this library, and not libraries that
389+
depend on it. Libraries specified with <code>implementation_deps</code> are still linked
390+
in binary targets that depend on this library.
391+
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
392+
.add(
393+
attr("implementation_deps", LABEL_LIST)
394+
.direct_compile_time_input()
395+
.mandatoryProviders(CcInfo.PROVIDER.id())
396+
.allowedFileTypes())
385397
/* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(defines) -->
386398
Extra <code>-D</code> flags to pass to the compiler. They should be in
387399
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
@@ -239,6 +239,11 @@ public Sequence<NativeInfo> createj2objcProvidersFromDeps(StarlarkRuleContext st
239239
positional = false,
240240
defaultValue = "[]",
241241
named = true),
242+
@Param(
243+
name = "implementation_cc_compilation_contexts",
244+
positional = false,
245+
defaultValue = "[]",
246+
named = true),
242247
@Param(name = "defines", positional = false, defaultValue = "[]", named = true),
243248
@Param(name = "includes", positional = false, defaultValue = "[]", named = true),
244249
})
@@ -249,6 +254,7 @@ public ObjcCompilationContext createCompilationContext(
249254
Sequence<?> providers,
250255
Sequence<?> directCcCompilationContexts,
251256
Sequence<?> ccCompilationContexts,
257+
Sequence<?> implementationCcCompilationContexts,
252258
Sequence<?> defines,
253259
Sequence<?> includes)
254260
throws InterruptedException, EvalException {
@@ -264,6 +270,11 @@ public ObjcCompilationContext createCompilationContext(
264270
.addCcCompilationContexts(
265271
Sequence.cast(
266272
ccCompilationContexts, CcCompilationContext.class, "cc_compilation_contexts"))
273+
.addImplementationCcCompilationContexts(
274+
Sequence.cast(
275+
implementationCcCompilationContexts,
276+
CcCompilationContext.class,
277+
"implementation_cc_compilation_contexts"))
267278
.addDefines(Sequence.cast(defines, String.class, "defines"))
268279
.addIncludes(
269280
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
@@ -40,6 +40,7 @@ def _build_common_variables(
4040
use_pch = False,
4141
empty_compilation_artifacts = False,
4242
deps = [],
43+
implementation_deps = [],
4344
extra_disabled_features = [],
4445
extra_enabled_features = [],
4546
extra_import_libraries = [],
@@ -62,6 +63,7 @@ def _build_common_variables(
6263
compilation_attributes = compilation_attributes,
6364
compilation_artifacts = compilation_artifacts,
6465
deps = deps,
66+
implementation_deps = implementation_deps,
6567
intermediate_artifacts = intermediate_artifacts,
6668
alwayslink = alwayslink,
6769
has_module_map = has_module_map,
@@ -160,6 +162,7 @@ def _compile(
160162
system_includes = objc_compilation_context.system_includes,
161163
quote_includes = objc_compilation_context.quote_includes,
162164
compilation_contexts = objc_compilation_context.cc_compilation_contexts,
165+
implementation_compilation_contexts = objc_compilation_context.implementation_cc_compilation_contexts,
163166
user_compile_flags = user_compile_flags,
164167
grep_includes = _get_grep_includes(common_variables.ctx),
165168
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
@@ -47,6 +47,7 @@ def _create_context_and_provider(
4747
has_module_map,
4848
extra_import_libraries,
4949
deps,
50+
implementation_deps,
5051
attr_linkopts):
5152
objc_providers = []
5253
cc_compilation_contexts = []
@@ -69,6 +70,31 @@ def _create_context_and_provider(
6970
cc_compilation_contexts.append(dep[CcInfo].compilation_context)
7071
cc_linking_contexts.append(dep[CcInfo].linking_context)
7172

73+
implementation_cc_compilation_contexts = []
74+
for impl_dep in implementation_deps:
75+
if apple_common.Objc in impl_dep:
76+
# For implementation deps, we only need to propagate linker inputs
77+
# with Objc provider, but no compilation artifacts
78+
# (eg module_map, umbrella_header).
79+
implementation_dep_objc_provider_kwargs = {
80+
"force_load_library": impl_dep[apple_common.Objc].force_load_library,
81+
"imported_library": impl_dep[apple_common.Objc].imported_library,
82+
"library": impl_dep[apple_common.Objc].library,
83+
"linkopt": impl_dep[apple_common.Objc].linkopt,
84+
"sdk_dylib": impl_dep[apple_common.Objc].sdk_dylib,
85+
"sdk_framework": impl_dep[apple_common.Objc].sdk_framework,
86+
"source": impl_dep[apple_common.Objc].source,
87+
"weak_sdk_framework": impl_dep[apple_common.Objc].weak_sdk_framework,
88+
}
89+
objc_provider = apple_common.new_objc_provider(**implementation_dep_objc_provider_kwargs)
90+
objc_providers.append(objc_provider)
91+
elif CcInfo in impl_dep:
92+
cc_linking_contexts_for_merging.append(impl_dep[CcInfo].linking_context)
93+
94+
if CcInfo in impl_dep:
95+
implementation_cc_compilation_contexts.append(impl_dep[CcInfo].compilation_context)
96+
cc_linking_contexts.append(impl_dep[CcInfo].linking_context)
97+
7298
link_order_keys = [
7399
"imported_library",
74100
"cc_library",
@@ -94,6 +120,7 @@ def _create_context_and_provider(
94120
objc_compilation_context_kwargs = {
95121
"providers": objc_providers,
96122
"cc_compilation_contexts": cc_compilation_contexts,
123+
"implementation_cc_compilation_contexts": implementation_cc_compilation_contexts,
97124
"public_hdrs": [],
98125
"private_hdrs": [],
99126
"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
@@ -63,6 +63,7 @@ def _objc_library_impl(ctx):
6363
toolchain = cc_toolchain,
6464
use_pch = True,
6565
deps = ctx.attr.deps,
66+
implementation_deps = ctx.attr.implementation_deps,
6667
attr_linkopts = ctx.attr.linkopts,
6768
alwayslink = ctx.fragments.objc.target_should_alwayslink(ctx),
6869
)
@@ -115,6 +116,7 @@ objc_library = rule(
115116
attrs = common_attrs.union(
116117
{
117118
"data": attr.label_list(allow_files = True),
119+
"implementation_deps": attr.label_list(providers = [CcInfo], allow_files = False),
118120
},
119121
common_attrs.ALWAYSLINK_RULE,
120122
common_attrs.CC_TOOLCHAIN_RULE,

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

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,21 @@ public void testCompilesSources() throws Exception {
120120
.write();
121121

122122
createLibraryTargetWriter("//objc/lib2")
123+
.setAndCreateFiles("srcs", "b.m")
124+
.setAndCreateFiles("hdrs", "private.h")
125+
.write();
126+
127+
createLibraryTargetWriter("//objc/lib3")
123128
.setAndCreateFiles("srcs", "a.m")
124129
.setAndCreateFiles("hdrs", "hdr.h")
125130
.setList("deps", "//objc/lib1")
131+
.setList("implementation_deps", "//objc/lib2")
126132
.write();
127133

128134
createLibraryTargetWriter("//objc:x")
129135
.setAndCreateFiles("srcs", "a.m", "private.h")
130136
.setAndCreateFiles("hdrs", "hdr.h")
131-
.setList("deps", "//objc/lib2:lib2")
137+
.setList("deps", "//objc/lib3:lib3")
132138
.write();
133139

134140
CppCompileAction compileA = (CppCompileAction) compileAction("//objc:x", "a.o");
@@ -1065,24 +1071,38 @@ public void testProvidesObjcLibraryAndHeaders() throws Exception {
10651071
.setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
10661072
.setAndCreateFiles("hdrs", "a.h", "b.h")
10671073
.write();
1074+
ConfiguredTarget impltarget =
1075+
createLibraryTargetWriter("//objc_impl:lib")
1076+
.setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
1077+
.setAndCreateFiles("hdrs", "a.h", "b.h")
1078+
.write();
10681079
ConfiguredTarget depender =
1069-
createLibraryTargetWriter("//objc2:lib")
1080+
createLibraryTargetWriter("//objc_depender:lib")
10701081
.setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
10711082
.setAndCreateFiles("hdrs", "c.h", "d.h")
10721083
.setList("deps", "//objc:lib")
1084+
.setList("implementation_deps", "//objc_impl:lib")
10731085
.write();
10741086

10751087
assertThat(getArifactPaths(target, LIBRARY)).containsExactly("objc/liblib.a");
1076-
assertThat(getArifactPaths(depender, LIBRARY)).containsExactly(
1077-
"objc/liblib.a", "objc2/liblib.a");
1088+
assertThat(getArifactPaths(impltarget, LIBRARY)).containsExactly("objc_impl/liblib.a");
1089+
assertThat(getArifactPaths(depender, LIBRARY))
1090+
.containsExactly("objc/liblib.a", "objc_impl/liblib.a", "objc_depender/liblib.a");
10781091
assertThat(getArifactPathsOfLibraries(target)).containsExactly("objc/liblib.a");
10791092
assertThat(getArifactPathsOfLibraries(depender))
1080-
.containsExactly("objc/liblib.a", "objc2/liblib.a");
1093+
.containsExactly("objc/liblib.a", "objc_impl/liblib.a", "objc_depender/liblib.a");
10811094
assertThat(getArifactPathsOfHeaders(target))
10821095
.containsExactly("objc/a.h", "objc/b.h", "objc/private.h");
1096+
assertThat(getArifactPathsOfHeaders(impltarget))
1097+
.containsExactly("objc_impl/a.h", "objc_impl/b.h", "objc_impl/private.h");
10831098
assertThat(getArifactPathsOfHeaders(depender))
10841099
.containsExactly(
1085-
"objc/a.h", "objc/b.h", "objc/private.h", "objc2/c.h", "objc2/d.h", "objc2/private.h");
1100+
"objc/a.h",
1101+
"objc/b.h",
1102+
"objc/private.h",
1103+
"objc_depender/c.h",
1104+
"objc_depender/d.h",
1105+
"objc_depender/private.h");
10861106
}
10871107

10881108
private static Iterable<String> getArifactPaths(

0 commit comments

Comments
 (0)