diff --git a/src/main/java/com/google/devtools/build/lib/analysis/LocationExpander.java b/src/main/java/com/google/devtools/build/lib/analysis/LocationExpander.java index ddcf5510ac174d..c942d28717e642 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/LocationExpander.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/LocationExpander.java @@ -467,6 +467,11 @@ static Map> buildLocationMap( Iterables.addAll( depsDataAndTools, ruleContext.getPrerequisitesIf("deps", FilesToRunProvider.class)); } + if (ruleContext.getRule().isAttrDefined("implementation_deps", BuildType.LABEL_LIST)) { + Iterables.addAll( + depsDataAndTools, + ruleContext.getPrerequisitesIf("implementation_deps", FilesToRunProvider.class)); + } if (allowDataAttributeEntriesInLabel && ruleContext.getRule().isAttrDefined("data", BuildType.LABEL_LIST)) { Iterables.addAll( diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java index f84fb332e6bb56..99aa6889c0610c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java @@ -111,6 +111,8 @@ static class Builder { private final List ccCompilationContexts = new ArrayList<>(); private final List ccLinkingContexts = new ArrayList<>(); private final List directCCompilationContexts = new ArrayList<>(); + private final List implementationCcCompilationContexts = + new ArrayList<>(); // List of CcLinkingContext to be merged into ObjcProvider, to be done for deps that don't have // ObjcProviders. // TODO(b/171413861): remove after objc link info migration. @@ -179,6 +181,13 @@ Builder addCcLinkingContexts(Iterable ccInfos) { return this; } + @CanIgnoreReturnValue + Builder addImplementationCcCompilationContexts(Iterable ccInfos) { + ccInfos.forEach( + ccInfo -> implementationCcCompilationContexts.add(ccInfo.getCcCompilationContext())); + return this; + } + @CanIgnoreReturnValue Builder addCcInfos(Iterable ccInfos) { addCcCompilationContexts(ccInfos); @@ -291,6 +300,8 @@ ObjcCommon build() { ImmutableList.copyOf(this.ccLinkingContexts); ImmutableList directCCompilationContexts = ImmutableList.copyOf(this.directCCompilationContexts); + ImmutableList implementationCcCompilationContexts = + ImmutableList.copyOf(this.implementationCcCompilationContexts); ImmutableList ccLinkingContextsForMerging = ImmutableList.copyOf(this.ccLinkingContextsForMerging); @@ -310,7 +321,8 @@ ObjcCommon build() { .addDirectCcCompilationContexts(directCCompilationContexts) // TODO(bazel-team): This pulls in stl via // CcCompilationHelper.getStlCcCompilationContext(), but probably shouldn't. - .addCcCompilationContexts(ccCompilationContexts); + .addCcCompilationContexts(ccCompilationContexts) + .addImplementationCcCompilationContexts(implementationCcCompilationContexts); for (CcLinkingContext ccLinkingContext : ccLinkingContextsForMerging) { ImmutableList linkOpts = ccLinkingContext.getFlattenedUserLinkFlags(); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCompilationContext.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCompilationContext.java index e3f2471b703ac7..154382ce594be0 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCompilationContext.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCompilationContext.java @@ -53,6 +53,7 @@ public final class ObjcCompilationContext implements StarlarkValue { private final ImmutableList strictDependencyIncludes; private final ImmutableList directCcCompilationContexts; private final ImmutableList ccCompilationContexts; + private final ImmutableList implementationCcCompilationContexts; ObjcCompilationContext( Iterable defines, @@ -64,7 +65,8 @@ public final class ObjcCompilationContext implements StarlarkValue { Iterable quoteIncludes, Iterable strictDependencyIncludes, Iterable directCcCompilationContexts, - Iterable ccCompilationContexts) { + Iterable ccCompilationContexts, + Iterable implementationCcCompilationContexts) { this.defines = ImmutableList.copyOf(defines); this.publicHeaders = ImmutableList.copyOf(publicHeaders); this.publicTextualHeaders = ImmutableList.copyOf(publicTextualHeaders); @@ -75,6 +77,8 @@ public final class ObjcCompilationContext implements StarlarkValue { this.strictDependencyIncludes = ImmutableList.copyOf(strictDependencyIncludes); this.directCcCompilationContexts = ImmutableList.copyOf(directCcCompilationContexts); this.ccCompilationContexts = ImmutableList.copyOf(ccCompilationContexts); + this.implementationCcCompilationContexts = + ImmutableList.copyOf(implementationCcCompilationContexts); } public ImmutableList getDefines() { @@ -159,11 +163,23 @@ public ImmutableList getCcCompilationContexts() { return ccCompilationContexts; } + public ImmutableList getImplementationCcCompilationContexts() { + return implementationCcCompilationContexts; + } + @StarlarkMethod(name = "cc_compilation_contexts", documented = false, structField = true) public Sequence getCcCompilationContextsForStarlark() { return StarlarkList.immutableCopyOf(getCcCompilationContexts()); } + @StarlarkMethod( + name = "implementation_cc_compilation_contexts", + documented = false, + structField = true) + public Sequence getImplementationCcCompilationContextsForStarlark() { + return StarlarkList.immutableCopyOf(getImplementationCcCompilationContexts()); + } + public CcCompilationContext createCcCompilationContext() { CcCompilationContext.Builder builder = CcCompilationContext.builder( @@ -200,6 +216,8 @@ static class Builder { private final List strictDependencyIncludes = new ArrayList<>(); private final List directCcCompilationContexts = new ArrayList<>(); private final List ccCompilationContexts = new ArrayList<>(); + private final List implementationCcCompilationContexts = + new ArrayList<>(); Builder() {} @@ -266,6 +284,13 @@ public Builder addDirectCcCompilationContexts( return this; } + @CanIgnoreReturnValue + public Builder addImplementationCcCompilationContexts( + Iterable ccCompilationContexts) { + Iterables.addAll(this.implementationCcCompilationContexts, ccCompilationContexts); + return this; + } + @CanIgnoreReturnValue public Builder addCcCompilationContext(CcCompilationContext ccCompilationContext) { this.ccCompilationContexts.add(ccCompilationContext); @@ -283,7 +308,8 @@ ObjcCompilationContext build() { quoteIncludes, strictDependencyIncludes, directCcCompilationContexts, - ccCompilationContexts); + ccCompilationContexts, + implementationCcCompilationContexts); } } } 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 f6ed945625d85d..4b3e044fd740a7 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 @@ -453,6 +453,19 @@ Header file to prepend to every source file being compiled (both arc .direct_compile_time_input() .mandatoryProviders(AppleDynamicFrameworkInfo.STARLARK_CONSTRUCTOR.id()) .allowedFileTypes()) + /* + The list of other libraries that the library target depends on. Unlike with + deps, the headers and include paths of these libraries (and all their + transitive deps) are only used for compilation of this library, and not libraries that + depend on it. Libraries specified with implementation_deps are still linked + in binary targets that depend on this library. + */ + .add( + attr("implementation_deps", LABEL_LIST) + .direct_compile_time_input() + .allowedRuleClasses(ALLOWED_CC_DEPS_RULE_CLASSES) + .mandatoryProviders(ObjcProvider.STARLARK_CONSTRUCTOR.id()) + .allowedFileTypes()) /* Extra -D flags to pass to the compiler. They should be in the form KEY=VALUE or simply KEY and are diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcStarlarkInternal.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcStarlarkInternal.java index dc5fd1d24180d7..87c6aa8a042aa3 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcStarlarkInternal.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcStarlarkInternal.java @@ -268,6 +268,11 @@ public InstrumentedFilesInfo createInstrumentedFilesInfo( positional = false, defaultValue = "[]", named = true), + @Param( + name = "implementation_cc_compilation_contexts", + positional = false, + defaultValue = "[]", + named = true), @Param(name = "defines", positional = false, defaultValue = "[]", named = true), @Param(name = "includes", positional = false, defaultValue = "[]", named = true), }) @@ -278,6 +283,7 @@ public ObjcCompilationContext createCompilationContext( Sequence providers, Sequence directCcCompilationContexts, Sequence ccCompilationContexts, + Sequence implementationCcCompilationContexts, Sequence defines, Sequence includes) throws InterruptedException, EvalException { @@ -293,6 +299,11 @@ public ObjcCompilationContext createCompilationContext( .addCcCompilationContexts( Sequence.cast( ccCompilationContexts, CcCompilationContext.class, "cc_compilation_contexts")) + .addImplementationCcCompilationContexts( + Sequence.cast( + implementationCcCompilationContexts, + CcCompilationContext.class, + "implementation_cc_compilation_contexts")) .addDefines(Sequence.cast(defines, String.class, "defines")) .addIncludes( Sequence.cast(includes, String.class, "includes").stream() diff --git a/src/main/starlark/builtins_bzl/common/objc/compilation_support.bzl b/src/main/starlark/builtins_bzl/common/objc/compilation_support.bzl index 7d1d26ba12f061..eaa67ab6416f57 100644 --- a/src/main/starlark/builtins_bzl/common/objc/compilation_support.bzl +++ b/src/main/starlark/builtins_bzl/common/objc/compilation_support.bzl @@ -72,6 +72,7 @@ def _build_common_variables( empty_compilation_artifacts = False, deps = [], runtime_deps = [], + implementation_deps = [], extra_disabled_features = [], extra_enabled_features = [], extra_import_libraries = [], @@ -95,6 +96,7 @@ def _build_common_variables( compilation_artifacts = compilation_artifacts, deps = deps, runtime_deps = runtime_deps, + implementation_deps = implementation_deps, intermediate_artifacts = intermediate_artifacts, alwayslink = alwayslink, has_module_map = has_module_map, @@ -193,6 +195,7 @@ def _compile( system_includes = objc_compilation_context.system_includes, quote_includes = objc_compilation_context.quote_includes, compilation_contexts = objc_compilation_context.cc_compilation_contexts, + implementation_compilation_contexts = objc_compilation_context.implementation_cc_compilation_contexts, user_compile_flags = user_compile_flags, grep_includes = _get_grep_includes(common_variables.ctx), module_map = module_map, diff --git a/src/main/starlark/builtins_bzl/common/objc/objc_common.bzl b/src/main/starlark/builtins_bzl/common/objc/objc_common.bzl index bbd9f6ed6ce394..10c5b5efca8ba2 100644 --- a/src/main/starlark/builtins_bzl/common/objc/objc_common.bzl +++ b/src/main/starlark/builtins_bzl/common/objc/objc_common.bzl @@ -28,6 +28,7 @@ def _create_context_and_provider( extra_import_libraries, deps, runtime_deps, + implementation_deps, attr_linkopts): objc_providers = [] cc_compilation_contexts = [] @@ -57,6 +58,31 @@ def _create_context_and_provider( if CcInfo in runtime_dep: cc_compilation_contexts.append(runtime_dep[CcInfo].compilation_context) + implementation_cc_compilation_contexts = [] + for impl_dep in implementation_deps: + if apple_common.Objc in impl_dep: + # For implementation deps, we only need to propagate linker inputs + # with Objc provider, but no compilation artifacts + # (eg module_map, umbrella_header). + implementation_dep_objc_provider_kwargs = { + "force_load_library": impl_dep[apple_common.Objc].force_load_library, + "imported_library": impl_dep[apple_common.Objc].imported_library, + "library": impl_dep[apple_common.Objc].library, + "linkopt": impl_dep[apple_common.Objc].linkopt, + "sdk_dylib": impl_dep[apple_common.Objc].sdk_dylib, + "sdk_framework": impl_dep[apple_common.Objc].sdk_framework, + "source": impl_dep[apple_common.Objc].source, + "weak_sdk_framework": impl_dep[apple_common.Objc].weak_sdk_framework, + } + objc_provider = apple_common.new_objc_provider(**implementation_dep_objc_provider_kwargs) + objc_providers.append(objc_provider) + elif CcInfo in impl_dep: + cc_linking_contexts_for_merging.append(impl_dep[CcInfo].linking_context) + + if CcInfo in impl_dep: + implementation_cc_compilation_contexts.append(impl_dep[CcInfo].compilation_context) + cc_linking_contexts.append(impl_dep[CcInfo].linking_context) + link_order_keys = [ "imported_library", "cc_library", @@ -82,6 +108,7 @@ def _create_context_and_provider( objc_compilation_context_kwargs = { "providers": objc_providers + runtime_objc_providers, "cc_compilation_contexts": cc_compilation_contexts, + "implementation_cc_compilation_contexts": implementation_cc_compilation_contexts, "public_hdrs": [], "private_hdrs": [], "public_textual_hdrs": [], diff --git a/src/main/starlark/builtins_bzl/common/objc/objc_library.bzl b/src/main/starlark/builtins_bzl/common/objc/objc_library.bzl index fc62bdfccbe55d..47f5377ae0ed27 100644 --- a/src/main/starlark/builtins_bzl/common/objc/objc_library.bzl +++ b/src/main/starlark/builtins_bzl/common/objc/objc_library.bzl @@ -45,6 +45,7 @@ def _objc_library_impl(ctx): use_pch = True, deps = ctx.attr.deps, runtime_deps = ctx.attr.runtime_deps, + implementation_deps = ctx.attr.implementation_deps, attr_linkopts = ctx.attr.linkopts, alwayslink = ctx.attr.alwayslink, ) @@ -89,6 +90,7 @@ objc_library = rule( attrs = common_attrs.union( { "data": attr.label_list(allow_files = True), + "implementation_deps": attr.label_list(providers = [CcInfo], allow_files = False), }, common_attrs.CC_TOOLCHAIN_RULE, common_attrs.LICENSES, 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 485108326535e7..80d06e2dd1bcab 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 @@ -128,15 +128,21 @@ public void testCompilesSources() throws Exception { .write(); createLibraryTargetWriter("//objc/lib2") + .setAndCreateFiles("srcs", "b.m") + .setAndCreateFiles("hdrs", "private.h") + .write(); + + createLibraryTargetWriter("//objc/lib3") .setAndCreateFiles("srcs", "a.m") .setAndCreateFiles("hdrs", "hdr.h") .setList("deps", "//objc/lib1") + .setList("implementation_deps", "//objc/lib2") .write(); createLibraryTargetWriter("//objc:x") .setAndCreateFiles("srcs", "a.m", "private.h") .setAndCreateFiles("hdrs", "hdr.h") - .setList("deps", "//objc/lib2:lib2") + .setList("deps", "//objc/lib3:lib3") .write(); CppCompileAction compileA = (CppCompileAction) compileAction("//objc:x", "a.o"); @@ -1077,20 +1083,34 @@ public void testProvidesObjcLibraryAndHeaders() throws Exception { .setAndCreateFiles("srcs", "a.m", "b.m", "private.h") .setAndCreateFiles("hdrs", "a.h", "b.h") .write(); + ConfiguredTarget impltarget = + createLibraryTargetWriter("//objc_impl:lib") + .setAndCreateFiles("srcs", "a.m", "b.m", "private.h") + .setAndCreateFiles("hdrs", "a.h", "b.h") + .write(); ConfiguredTarget depender = - createLibraryTargetWriter("//objc2:lib") + createLibraryTargetWriter("//objc_depender:lib") .setAndCreateFiles("srcs", "a.m", "b.m", "private.h") .setAndCreateFiles("hdrs", "c.h", "d.h") .setList("deps", "//objc:lib") + .setList("implementation_deps", "//objc_impl:lib") .write(); assertThat(getArifactPaths(target, LIBRARY)).containsExactly("objc/liblib.a"); - assertThat(getArifactPaths(depender, LIBRARY)).containsExactly( - "objc/liblib.a", "objc2/liblib.a"); + assertThat(getArifactPaths(depender, LIBRARY)) + .containsExactly("objc/liblib.a", "objc_impl/liblib.a", "objc_depender/liblib.a"); + assertThat(getArifactPaths(impltarget, LIBRARY)).containsExactly("objc_impl/liblib.a"); assertThat(getArifactPathsOfHeaders(target)) .containsExactly("objc/a.h", "objc/b.h", "objc/private.h"); + assertThat(getArifactPathsOfHeaders(impltarget)) + .containsExactly("objc_impl/a.h", "objc_impl/b.h", "objc_impl/private.h"); assertThat(getArifactPathsOfHeaders(depender)) .containsExactly( - "objc/a.h", "objc/b.h", "objc/private.h", "objc2/c.h", "objc2/d.h", "objc2/private.h"); + "objc/a.h", + "objc/b.h", + "objc/private.h", + "objc_depender/c.h", + "objc_depender/d.h", + "objc_depender/private.h"); } private static Iterable getArifactPaths(