diff --git a/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/rules/cpp/CcInfo.java b/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/rules/cpp/CcInfo.java index b13a20068a1..9cbd835a865 100644 --- a/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/rules/cpp/CcInfo.java +++ b/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/rules/cpp/CcInfo.java @@ -55,10 +55,6 @@ public CcLinkingInfo getCcLinkingInfo() { return ccLinkingInfo; } - public CcLinkingContext getCcLinkingContext() { - return LibraryToLinkWrapper.fromCcLinkingInfo(ccLinkingInfo); - } - public static CcInfo merge(Collection ccInfos) { ImmutableList.Builder ccCompilationContexts = ImmutableList.builder(); ImmutableList.Builder ccLinkingInfos = ImmutableList.builder(); diff --git a/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java b/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java index 9e73228003b..49f968bd198 100644 --- a/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java +++ b/dataset/GitHub_Java/bazelbuild.bazel/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java @@ -362,9 +362,18 @@ protected Iterable userFlagsToIterable(CppConfiguration cppConfiguration } /** - * This method returns a {@link LibraryToLinkWrapper} object that will be used to contain linking - * artifacts and information for a single library that will later be used by a linking action. + * This method returns either {@link LibraryToLink} object (old API) or a {@link + * LibraryToLinkWrapper} object (new API) that will be used to contain linking artifacts and + * information for a single library that will later be used by a linking action. * + *

This method supports the old and the new API. Attributes of the old API are marked + * deprecated. They cannot be mixed. If using the old API a {@link CcLinkingInfo} object is + * returned, if using the new API then a {@link + * com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper.CcLinkingContext} + * + * @param skylarkRuleContextObject deprecated + * @param libraryObject deprecated + * @param skylarkArtifactCategoryObject deprecated * @param actionsObject SkylarkActionFactory * @param featureConfigurationObject FeatureConfiguration * @param staticLibraryObject Artifact @@ -378,6 +387,9 @@ protected Iterable userFlagsToIterable(CppConfiguration cppConfiguration */ @Override public Object createLibraryLinkerInput( + Object skylarkRuleContextObject, + Object libraryObject, + Object skylarkArtifactCategoryObject, Object actionsObject, Object featureConfigurationObject, Object ccToolchainProviderObject, @@ -389,6 +401,10 @@ public Object createLibraryLinkerInput( Location location, Environment environment) throws EvalException, InterruptedException { + SkylarkRuleContext skylarkRuleContext = + nullIfNone(skylarkRuleContextObject, SkylarkRuleContext.class); + Artifact library = nullIfNone(libraryObject, Artifact.class); + String skylarkArtifactCategory = nullIfNone(skylarkArtifactCategoryObject, String.class); SkylarkActionFactory skylarkActionFactory = nullIfNone(actionsObject, SkylarkActionFactory.class); FeatureConfiguration featureConfiguration = @@ -400,49 +416,101 @@ public Object createLibraryLinkerInput( Artifact dynamicLibrary = nullIfNone(dynamicLibraryObject, Artifact.class); Artifact interfaceLibrary = nullIfNone(interfaceLibraryObject, Artifact.class); - Artifact notNullArtifactForIdentifier = null; - if (staticLibrary != null) { - notNullArtifactForIdentifier = staticLibrary; - } else if (picStaticLibrary != null) { - notNullArtifactForIdentifier = picStaticLibrary; - } else if (dynamicLibrary != null) { - notNullArtifactForIdentifier = dynamicLibrary; - } else if (interfaceLibrary != null) { - notNullArtifactForIdentifier = interfaceLibrary; - } else { - throw new EvalException(location, "Must pass at least one artifact"); - } - - Artifact resolvedSymlinkDynamicLibrary = null; - Artifact resolvedSymlinkInterfaceLibrary = null; - if (!featureConfiguration.isEnabled(CppRuleClasses.TARGETS_WINDOWS)) { - if (dynamicLibrary != null) { - resolvedSymlinkDynamicLibrary = dynamicLibrary; - dynamicLibrary = - SolibSymlinkAction.getDynamicLibrarySymlink( - /* actionRegistry= */ skylarkActionFactory.asActionRegistry( - location, skylarkActionFactory), - /* actionConstructionContext= */ skylarkActionFactory - .getActionConstructionContext(), - ccToolchainProvider.getSolibDirectory(), - dynamicLibrary, - /* preserveName= */ true, - /* prefixConsumer= */ true, - /* configuration= */ null); + String parameters = + "actions*, feature_configuration*, " + + "cc_toolchain*, static_library, pic_static_library, dynamic_library, " + + "interface_library and alwayslink. Those with * are required."; + String oldAndNewApiMixError = + "Do not mix parameter of old and new API. Old API parameters are: ctx*, library* and " + + "artifact_category*. New API parameters are: " + + parameters; + + if (skylarkRuleContext != null || library != null || skylarkArtifactCategory != null) { + CcCommon.checkLocationWhitelisted( + environment.getSemantics(), + location, + environment.getGlobals().getLabel().getPackageIdentifier().toString()); + if (skylarkRuleContext == null + || library == null + || skylarkArtifactCategory == null + || skylarkActionFactory != null + || featureConfiguration != null + || ccToolchainProvider != null + || staticLibrary != null + || picStaticLibrary != null + || dynamicLibrary != null + || interfaceLibrary != null) { + throw new EvalException(location, oldAndNewApiMixError); } - if (interfaceLibrary != null) { - resolvedSymlinkInterfaceLibrary = interfaceLibrary; - interfaceLibrary = - SolibSymlinkAction.getDynamicLibrarySymlink( - /* actionRegistry= */ skylarkActionFactory.asActionRegistry( - location, skylarkActionFactory), - /* actionConstructionContext= */ skylarkActionFactory - .getActionConstructionContext(), - ccToolchainProvider.getSolibDirectory(), - interfaceLibrary, - /* preserveName= */ true, - /* prefixConsumer= */ true, - /* configuration= */ null); + CcCommon.checkRuleWhitelisted(skylarkRuleContext); + ArtifactCategory artifactCategory = + ArtifactCategory.fromString( + skylarkArtifactCategory, + skylarkRuleContext.getRuleContext().getRule().getLocation(), + "artifact_category"); + return LinkerInputs.opaqueLibraryToLink( + library, artifactCategory, CcLinkingOutputs.libraryIdentifierOf(library)); + } + + if (skylarkActionFactory != null + || featureConfiguration != null + || ccToolchainProvider != null + || staticLibrary != null + || picStaticLibrary != null + || dynamicLibrary != null + || interfaceLibrary != null) { + if (skylarkActionFactory == null + || featureConfiguration == null + || ccToolchainProvider == null + || skylarkRuleContext != null + || library != null + || skylarkArtifactCategory != null) { + throw new EvalException(location, oldAndNewApiMixError); + } + Artifact notNullArtifactForIdentifier = null; + if (staticLibrary != null) { + notNullArtifactForIdentifier = staticLibrary; + } else if (picStaticLibrary != null) { + notNullArtifactForIdentifier = picStaticLibrary; + } else if (dynamicLibrary != null) { + notNullArtifactForIdentifier = dynamicLibrary; + } else if (interfaceLibrary != null) { + notNullArtifactForIdentifier = interfaceLibrary; + } else { + throw new EvalException(location, "Must pass at least one artifact"); + } + + Artifact resolvedSymlinkDynamicLibrary = null; + Artifact resolvedSymlinkInterfaceLibrary = null; + if (!featureConfiguration.isEnabled(CppRuleClasses.TARGETS_WINDOWS)) { + if (dynamicLibrary != null) { + resolvedSymlinkDynamicLibrary = dynamicLibrary; + dynamicLibrary = + SolibSymlinkAction.getDynamicLibrarySymlink( + /* actionRegistry= */ skylarkActionFactory.asActionRegistry( + location, skylarkActionFactory), + /* actionConstructionContext= */ skylarkActionFactory + .getActionConstructionContext(), + ccToolchainProvider.getSolibDirectory(), + dynamicLibrary, + /* preserveName= */ true, + /* prefixConsumer= */ true, + /* configuration= */ null); + } + if (interfaceLibrary != null) { + resolvedSymlinkInterfaceLibrary = interfaceLibrary; + interfaceLibrary = + SolibSymlinkAction.getDynamicLibrarySymlink( + /* actionRegistry= */ skylarkActionFactory.asActionRegistry( + location, skylarkActionFactory), + /* actionConstructionContext= */ skylarkActionFactory + .getActionConstructionContext(), + ccToolchainProvider.getSolibDirectory(), + interfaceLibrary, + /* preserveName= */ true, + /* prefixConsumer= */ true, + /* configuration= */ null); + } } return LibraryToLinkWrapper.builder() @@ -456,10 +524,7 @@ public Object createLibraryLinkerInput( .setAlwayslink(alwayslink) .build(); } - throw new EvalException( - location, - "Must pass parameters: static_library, pic_static_library, dynamic_library, " - + "interface_library and alwayslink."); + throw new EvalException(location, "Must pass parameters: " + parameters); } @Override @@ -641,18 +706,73 @@ private static SkylarkNestedSet toNestedSetOfStrings(Object obj, String fieldNam @Override public Object createCcLinkingInfo( + Object skylarkRuleContextObject, + Object staticModeParamsForDynamicLibraryObject, + Object staticModeParamsForExecutableObject, + Object dynamicModeParamsForDynamicLibraryObject, + Object dynamicModeParamsForExecutableObject, Object librariesToLinkObject, Object userLinkFlagsObject, Location location, Environment environment) throws EvalException, InterruptedException { + SkylarkRuleContext skylarkRuleContext = + nullIfNone(skylarkRuleContextObject, SkylarkRuleContext.class); + CcLinkParams staticModeParamsForDynamicLibrary = + nullIfNone(staticModeParamsForDynamicLibraryObject, CcLinkParams.class); + CcLinkParams staticModeParamsForExecutable = + nullIfNone(staticModeParamsForExecutableObject, CcLinkParams.class); + CcLinkParams dynamicModeParamsForDynamicLibrary = + nullIfNone(dynamicModeParamsForDynamicLibraryObject, CcLinkParams.class); + CcLinkParams dynamicModeParamsForExecutable = + nullIfNone(dynamicModeParamsForExecutableObject, CcLinkParams.class); @SuppressWarnings("unchecked") SkylarkList librariesToLink = nullIfNone(librariesToLinkObject, SkylarkList.class); @SuppressWarnings("unchecked") SkylarkList userLinkFlags = nullIfNone(userLinkFlagsObject, SkylarkList.class); + String oldAndNewApiMixError = + "Do not mix parameter of old and new API. Old API parameters are: ctx, " + + "static_mode_params_for_dynamic_library, " + + "static_mode_params_for_executable, " + + "dynamic_mode_params_for_dynamic_library and dynamic_mode_params_for_executable." + + " New API parameters are: libraries_to_link and user_link_flags."; + + if (skylarkRuleContext != null + || staticModeParamsForDynamicLibrary != null + || staticModeParamsForExecutable != null + || dynamicModeParamsForDynamicLibrary != null + || dynamicModeParamsForExecutable != null) { + CcCommon.checkLocationWhitelisted( + environment.getSemantics(), + location, + environment.getGlobals().getLabel().getPackageIdentifier().toString()); + if (skylarkRuleContext == null + || staticModeParamsForDynamicLibrary == null + || staticModeParamsForExecutable == null + || dynamicModeParamsForDynamicLibrary == null + || dynamicModeParamsForExecutable == null + || librariesToLink != null + || userLinkFlags != null) { + throw new EvalException(location, oldAndNewApiMixError); + } + CcLinkingInfo.Builder ccLinkingInfoBuilder = CcLinkingInfo.Builder.create(); + ccLinkingInfoBuilder + .setStaticModeParamsForDynamicLibrary(staticModeParamsForDynamicLibrary) + .setStaticModeParamsForExecutable(staticModeParamsForExecutable) + .setDynamicModeParamsForDynamicLibrary(dynamicModeParamsForDynamicLibrary) + .setDynamicModeParamsForExecutable(dynamicModeParamsForExecutable); + return ccLinkingInfoBuilder.build(); + } if (librariesToLink != null || userLinkFlags != null) { + if (staticModeParamsForDynamicLibrary != null + || staticModeParamsForExecutable != null + || dynamicModeParamsForDynamicLibrary != null + || dynamicModeParamsForExecutable != null + || dynamicModeParamsForExecutable != null) { + throw new EvalException(location, oldAndNewApiMixError); + } CcLinkingContext.Builder ccLinkingContextBuilder = CcLinkingContext.builder(); if (librariesToLink != null) { ccLinkingContextBuilder.addLibraries( diff --git a/dataset/GitHub_Java/bazelbuild.bazel/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java b/dataset/GitHub_Java/bazelbuild.bazel/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java index b72840ff866..8dbb42fe50a 100644 --- a/dataset/GitHub_Java/bazelbuild.bazel/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java +++ b/dataset/GitHub_Java/bazelbuild.bazel/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java @@ -43,6 +43,7 @@ import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.VariableWithValue; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.WithFeatureSet; import com.google.devtools.build.lib.rules.cpp.CcToolchainVariables.StringValueParser; +import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; import com.google.devtools.build.lib.skylarkbuildapi.cpp.LibraryToLinkApi; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.SkylarkDict; @@ -1055,7 +1056,8 @@ public void testCcCompilationProvider() throws Exception { List mergedHeaders = ((SkylarkNestedSet) r.get("merged_headers")).getSet(Artifact.class).toList(); assertThat( - mergedHeaders.stream() + mergedHeaders + .stream() .map(Artifact::getFilename) .collect(ImmutableList.toImmutableList())) .containsAllOf("header.h", "dep1.h", "dep2.h"); @@ -1121,6 +1123,92 @@ public void testCcCompilationProviderInvalidValues() throws Exception { assertContainsEvent("'headers' argument must be a depset"); } + @Test + @Deprecated + // TODO(118663806): Libraries won't be created this way from Skylark after removing CcLinkParams. + public void testLibraryLinkerInputs() throws Exception { + scratch.file("a/BUILD", "load('//tools/build_defs/cc:rule.bzl', 'crule')", "crule(name='r')"); + scratch.file("a/lib.a", ""); + scratch.file("a/lib.lo", ""); + scratch.file("a/lib.so", ""); + scratch.file("a/lib.ifso", ""); + scratch.file("tools/build_defs/cc/BUILD", ""); + scratch.file( + "tools/build_defs/cc/rule.bzl", + "def _create(ctx, lib, c):", + " return cc_common.create_library_to_link(ctx=ctx, library=lib, artifact_category=c)", + "def _impl(ctx):", + " static_library = _create(ctx, ctx.file.liba, 'static_library')", + " alwayslink_static_library = _create(ctx, ctx.file.liblo, 'alwayslink_static_library')", + " dynamic_library = _create(ctx, ctx.file.libso, 'dynamic_library')", + " interface_library = _create(ctx, ctx.file.libifso, 'interface_library')", + " toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]", + " symlink_library = cc_common.create_symlink_library_to_link(", + " ctx=ctx, cc_toolchain=toolchain, library=ctx.file.libso)", + " return struct(", + " static_library = static_library,", + " alwayslink_static_library = alwayslink_static_library,", + " dynamic_library = dynamic_library,", + " interface_library = interface_library,", + " symlink_library = symlink_library", + " )", + "crule = rule(", + " _impl,", + " attrs = { ", + " 'liba': attr.label(default='//a:lib.a', allow_single_file=True),", + " 'liblo': attr.label(default='//a:lib.lo', allow_single_file=True),", + " 'libso': attr.label(default='//a:lib.so', allow_single_file=True),", + " 'libifso': attr.label(default='//a:lib.ifso', allow_single_file=True),", + " '_cc_toolchain': attr.label(default =", + " configuration_field(fragment = 'cpp', name = 'cc_toolchain'))", + " },", + " fragments = ['cpp'],", + ");"); + ConfiguredTarget r = getConfiguredTarget("//a:r"); + @SuppressWarnings("unchecked") + LibraryToLink staticLibrary = (LibraryToLink) r.get("static_library"); + assertThat(staticLibrary.getArtifact().getFilename()).isEqualTo("lib.a"); + LibraryToLink alwaysLinkStaticLibrary = (LibraryToLink) r.get("alwayslink_static_library"); + assertThat(alwaysLinkStaticLibrary.getArtifact().getFilename()).isEqualTo("lib.lo"); + LibraryToLink dynamicLibrary = (LibraryToLink) r.get("dynamic_library"); + assertThat(dynamicLibrary.getArtifact().getFilename()).isEqualTo("lib.so"); + LibraryToLink interfaceLibrary = (LibraryToLink) r.get("interface_library"); + assertThat(interfaceLibrary.getArtifact().getFilename()).isEqualTo("lib.ifso"); + LibraryToLink symlinkLibrary = (LibraryToLink) r.get("symlink_library"); + assertThat(symlinkLibrary.getArtifact().getFilename()).isEqualTo("lib.so"); + assertThat(symlinkLibrary.getArtifact().getPath()) + .isNotEqualTo(symlinkLibrary.getOriginalLibraryArtifact().getPath()); + } + + @Test + @Deprecated + // TODO(118663806): Artifact category won't be part of API. + public void testLibraryLinkerInputArtifactCategoryError() throws Exception { + scratch.file("a/BUILD", "load('//tools/build_defs/cc:rule.bzl', 'crule')", "crule(name='r')"); + scratch.file("a/lib.a", ""); + scratch.file("tools/build_defs/cc/BUILD", ""); + scratch.file( + "tools/build_defs/cc/rule.bzl", + "def _impl(ctx):", + " executable = cc_common.create_library_to_link(", + " ctx=ctx, library=ctx.file.lib, artifact_category='executable')", + " return struct(", + " executable = executable,", + " )", + "crule = rule(", + " _impl,", + " attrs = { ", + " 'lib': attr.label(default='//a:lib.a', allow_single_file=True),", + " },", + " fragments = ['cpp'],", + ");"); + reporter.removeHandler(failFastHandler); + assertThat(getConfiguredTarget("//a:r")).isNull(); + assertContainsEvent( + "Possible values for artifact_category: static_library, " + + "alwayslink_static_library, dynamic_library, interface_library"); + } + @Test public void testFlagWhitelist() throws Exception { setSkylarkSemanticsOptions("--experimental_cc_skylark_api_enabled_packages=\"\""); @@ -1133,6 +1221,174 @@ public void testFlagWhitelist() throws Exception { + "will be making breaking changes to this API without prior warning."); } + @Test + public void testOldCcLinkingProvider() throws Exception { + AnalysisMock.get() + .ccSupport() + .setupCrosstool( + mockToolsConfig, + "supports_interface_shared_objects: false"); + useConfiguration(); + setUpOldCcLinkingProviderParamsTest(); + ConfiguredTarget r = getConfiguredTarget("//a:r"); + + List staticSharedLinkopts = + ((SkylarkNestedSet) r.get("sd_linkopts")).getSet(String.class).toList(); + List staticNoSharedLinkopts = + ((SkylarkNestedSet) r.get("se_linkopts")).getSet(String.class).toList(); + List noStaticSharedLinkopts = + ((SkylarkNestedSet) r.get("dd_linkopts")).getSet(String.class).toList(); + List noStaticNoSharedLinkopts = + ((SkylarkNestedSet) r.get("de_linkopts")).getSet(String.class).toList(); + assertThat(staticSharedLinkopts) + .containsAllOf("-static_for_dynamic", "-DEP1_LINKOPT", "-DEP2_LINKOPT"); + assertThat(staticNoSharedLinkopts) + .containsAllOf("-static_for_executable", "-DEP1_LINKOPT", "-DEP2_LINKOPT"); + assertThat(noStaticSharedLinkopts) + .containsAllOf("-dynamic_for_dynamic", "-DEP1_LINKOPT", "-DEP2_LINKOPT"); + assertThat(noStaticNoSharedLinkopts) + .containsAllOf("-dynamic_for_executable", "-DEP1_LINKOPT", "-DEP2_LINKOPT"); + + List staticSharedLibs = + ((SkylarkNestedSet) r.get("sd_libs")).getSet(LibraryToLink.class).toList(); + List staticNoSharedLibs = + ((SkylarkNestedSet) r.get("se_libs")).getSet(LibraryToLink.class).toList(); + List noStaticSharedLibs = + ((SkylarkNestedSet) r.get("dd_libs")).getSet(LibraryToLink.class).toList(); + List noStaticNoSharedLibs = + ((SkylarkNestedSet) r.get("de_libs")).getSet(LibraryToLink.class).toList(); + assertThat( + staticSharedLibs + .stream() + .map(x -> x.getOriginalLibraryArtifact().getFilename()) + .collect(ImmutableList.toImmutableList())) + .containsAllOf("lib.a", "libdep1.a", "libdep2.a"); + assertThat( + staticNoSharedLibs + .stream() + .map(x -> x.getOriginalLibraryArtifact().getFilename()) + .collect(ImmutableList.toImmutableList())) + .containsAllOf("lib.a", "libdep1.a", "libdep2.a"); + + assertThat( + noStaticSharedLibs + .stream() + .map(x -> x.getOriginalLibraryArtifact().getFilename()) + .collect(ImmutableList.toImmutableList())) + .containsAllOf("lib.so", "libdep1.so", "libdep2.so"); + assertThat( + noStaticNoSharedLibs + .stream() + .map(x -> x.getOriginalLibraryArtifact().getFilename()) + .collect(ImmutableList.toImmutableList())) + .containsAllOf("lib.so", "libdep1.so", "libdep2.so"); + + List staticSharedRunLibs = + ((SkylarkNestedSet) r.get("sd_runlibs")).getSet(Artifact.class).toList(); + List staticNoSharedRunLibs = + ((SkylarkNestedSet) r.get("se_runlibs")).getSet(Artifact.class).toList(); + List noStaticSharedRunLibs = + ((SkylarkNestedSet) r.get("dd_runlibs")).getSet(Artifact.class).toList(); + List noStaticNoSharedRunLibs = + ((SkylarkNestedSet) r.get("de_runlibs")).getSet(Artifact.class).toList(); + assertThat( + staticSharedRunLibs + .stream() + .map(Artifact::getFilename) + .collect(ImmutableList.toImmutableList())) + .isEmpty(); + assertThat( + staticNoSharedRunLibs + .stream() + .map(Artifact::getFilename) + .collect(ImmutableList.toImmutableList())) + .isEmpty(); + assertThat( + noStaticSharedRunLibs + .stream() + .map(Artifact::getFilename) + .collect(ImmutableList.toImmutableList())) + .containsAllOf("lib.so", "liba_Slibdep1.so", "liba_Slibdep2.so"); + assertThat( + noStaticNoSharedRunLibs + .stream() + .map(Artifact::getFilename) + .collect(ImmutableList.toImmutableList())) + .containsAllOf("lib.so", "liba_Slibdep1.so", "liba_Slibdep2.so"); + } + + private void setUpOldCcLinkingProviderParamsTest() throws Exception { + scratch.file( + "a/BUILD", + "load('//tools/build_defs/cc:rule.bzl', 'crule')", + "crule(name='r')", + "cc_library(", + " name = 'dep1',", + " srcs = ['dep1.cc'],", + " hdrs = ['dep1.h'],", + " linkopts = ['-DEP1_LINKOPT'],", + ")", + "cc_library(", + " name = 'dep2',", + " srcs = ['dep2.cc'],", + " hdrs = ['dep2.h'],", + " linkopts = ['-DEP2_LINKOPT'],", + ")"); + scratch.file("a/lib.a", ""); + scratch.file("a/lib.so", ""); + scratch.file("tools/build_defs/cc/BUILD", ""); + scratch.file( + "tools/build_defs/cc/rule.bzl", + "def _create(ctx, l, r, f):", + " return cc_common.create_cc_link_params(", + " ctx=ctx, libraries_to_link=depset(l), dynamic_libraries_for_runtime=depset(r),", + " user_link_flags=depset(f))", + "def _impl(ctx):", + " liba = cc_common.create_library_to_link(ctx=ctx, library=ctx.file.liba,", + " artifact_category='static_library')", + " libso = cc_common.create_library_to_link(ctx=ctx, library=ctx.file.libso,", + " artifact_category='dynamic_library')", + " sd = _create(ctx, [liba], [], ['-static_for_dynamic'])", + " se = _create(ctx, [liba], [], ['-static_for_executable'])", + " dd = _create(ctx, [libso], [ctx.file.libso], ['-dynamic_for_dynamic'])", + " de = _create(ctx, [libso], [ctx.file.libso], ['-dynamic_for_executable'])", + " linking_context = cc_common.create_linking_context(ctx=ctx,", + " static_mode_params_for_dynamic_library=sd, static_mode_params_for_executable=se,", + " dynamic_mode_params_for_dynamic_library=dd, dynamic_mode_params_for_executable=de)", + " cc_infos = [CcInfo(linking_context=linking_context)]", + " for dep in ctx.attr._deps:", + " cc_infos.append(dep[CcInfo])", + " merged_cc_info = cc_common.merge_cc_infos(cc_infos=cc_infos)", + " sd = merged_cc_info.linking_context.static_mode_params_for_dynamic_library", + " se = merged_cc_info.linking_context.static_mode_params_for_executable", + " dd = merged_cc_info.linking_context.dynamic_mode_params_for_dynamic_library", + " de = merged_cc_info.linking_context.dynamic_mode_params_for_executable", + " return struct(", + " cc_info = merged_cc_info,", + " sd_linkopts = sd.user_link_flags,", + " se_linkopts = se.user_link_flags,", + " dd_linkopts = dd.user_link_flags,", + " de_linkopts = de.user_link_flags,", + " sd_libs = sd.libraries_to_link,", + " se_libs = se.libraries_to_link,", + " dd_libs = dd.libraries_to_link,", + " de_libs = de.libraries_to_link,", + " sd_runlibs = sd.dynamic_libraries_for_runtime,", + " se_runlibs = se.dynamic_libraries_for_runtime,", + " dd_runlibs = dd.dynamic_libraries_for_runtime,", + " de_runlibs = de.dynamic_libraries_for_runtime,", + " )", + "crule = rule(", + " _impl,", + " attrs = { ", + " 'liba': attr.label(default='//a:lib.a', allow_single_file=True),", + " 'libso': attr.label(default='//a:lib.so', allow_single_file=True),", + " '_deps': attr.label_list(default=['//a:dep1', '//a:dep2']),", + " },", + " fragments = ['cpp'],", + ");"); + } + @Test public void testCcLinkingContext() throws Exception { AnalysisMock.get() @@ -1329,7 +1585,8 @@ public void testLinkingOutputs() throws Exception { SkylarkList libraries = (SkylarkList) target.get("libraries"); assertThat( - libraries.stream() + libraries + .stream() .map(x -> x.getOriginalLibraryArtifact().getFilename()) .collect(ImmutableList.toImmutableList())) .contains("libskylark_lib.so"); @@ -1355,7 +1612,9 @@ public void testSettingDynamicLibraryArtifact() throws Exception { assertThat(getConfiguredTarget("//foo:skylark_lib")).isNotNull(); ConfiguredTarget target = getConfiguredTarget("//foo:skylark_lib"); assertThat( - getFilesToBuild(target).toCollection().stream() + getFilesToBuild(target) + .toCollection() + .stream() .map(x -> x.getFilename()) .collect(ImmutableList.toImmutableList())) .contains("dynamic_lib_artifact.so");