diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java index 244c202f298206..eb89d3d04e2f5e 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java @@ -20,7 +20,6 @@ import com.google.devtools.build.lib.rules.cpp.CcCompilationHelper.CompilationInfo; import com.google.devtools.build.lib.rules.cpp.CcCompilationOutputs; import com.google.devtools.build.lib.rules.cpp.CcLinkingHelper.LinkingInfo; -import com.google.devtools.build.lib.rules.cpp.CcLinkingInfo; import com.google.devtools.build.lib.rules.cpp.CcModule; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration; import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider; @@ -46,7 +45,6 @@ public class BazelCcModule extends CcModule CcCompilationContext, CcCompilationOutputs, LinkingInfo, - CcLinkingInfo, CcLinkingContext, LibraryToLinkWrapper, CcToolchainVariables> { @@ -87,7 +85,7 @@ public LinkingInfo link( CcCompilationOutputs ccCompilationOutputs, Object skylarkLinkopts, Object dynamicLibrary, - SkylarkList skylarkCcLinkingInfos, + SkylarkList skylarkCcLinkingContexts, boolean neverLink) throws InterruptedException, EvalException { return BazelCcModule.link( @@ -99,7 +97,7 @@ public LinkingInfo link( skylarkLinkopts, /* shouldCreateStaticLibraries= */ true, dynamicLibrary, - skylarkCcLinkingInfos, + skylarkCcLinkingContexts, neverLink); } } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java index f960b25a773414..d7480568a92481 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java @@ -369,7 +369,7 @@ public CcInfo buildCcInfoProvider(Iterable d .collect(ImmutableList.toImmutableList())) .build(); - // TODO(plf): return empty CcLinkingInfo. + // TODO(plf): return empty CcInfo. return CcInfo.merge(ccInfos); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCcLinkParamsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCcLinkParamsProvider.java index 89aa62996b1693..6c9cb871fae263 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCcLinkParamsProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCcLinkParamsProvider.java @@ -32,7 +32,7 @@ public final class AndroidCcLinkParamsProvider extends NativeInfo public AndroidCcLinkParamsProvider(CcInfo ccInfo) { super(PROVIDER); - this.ccInfo = CcInfo.builder().setCcLinkingInfo(ccInfo.getCcLinkingInfo()).build(); + this.ccInfo = CcInfo.builder().setCcLinkingContext(ccInfo.getCcLinkingContext()).build(); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java index 9cd9c921587f78..365d114f9d0455 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java @@ -48,8 +48,8 @@ import com.google.devtools.build.lib.rules.android.ZipFilterBuilder.CheckHashMismatchMode; import com.google.devtools.build.lib.rules.android.databinding.DataBindingContext; import com.google.devtools.build.lib.rules.cpp.CcInfo; -import com.google.devtools.build.lib.rules.cpp.CcLinkParams; -import com.google.devtools.build.lib.rules.cpp.CcLinkingInfo; +import com.google.devtools.build.lib.rules.cpp.CcLinkParams.LinkOptions; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper.CcLinkingContext; import com.google.devtools.build.lib.rules.java.ClasspathConfiguredFragment; import com.google.devtools.build.lib.rules.java.JavaCcLinkParamsProvider; import com.google.devtools.build.lib.rules.java.JavaCommon; @@ -825,16 +825,13 @@ public CcInfo getCcInfo() { public static CcInfo getCcInfo( final Iterable deps, final Collection linkOpts) { - CcLinkParams linkOptsParams = CcLinkParams.builder().addLinkOpts(linkOpts).build(); - CcLinkingInfo linkOptsCcLinkingInfo = - CcLinkingInfo.Builder.create() - .setStaticModeParamsForDynamicLibrary(linkOptsParams) - .setStaticModeParamsForExecutable(linkOptsParams) - .setDynamicModeParamsForDynamicLibrary(linkOptsParams) - .setDynamicModeParamsForExecutable(linkOptsParams) + CcLinkingContext ccLinkingContext = + CcLinkingContext.builder() + .addUserLinkFlags( + NestedSetBuilder.linkOrder().add(LinkOptions.of(linkOpts)).build()) .build(); - CcInfo linkoptsCcInfo = CcInfo.builder().setCcLinkingInfo(linkOptsCcLinkingInfo).build(); + CcInfo linkoptsCcInfo = CcInfo.builder().setCcLinkingContext(ccLinkingContext).build(); ImmutableList ccInfos = ImmutableList.builder() diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java b/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java index 9f0628c6acfca9..5f2e958639cf93 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.rules.android; import com.google.common.base.Optional; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -33,12 +34,11 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; -import com.google.devtools.build.lib.rules.cpp.CcLinkParams; +import com.google.devtools.build.lib.rules.cpp.CcInfo; import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider; -import com.google.devtools.build.lib.rules.cpp.CppFileTypes; import com.google.devtools.build.lib.rules.cpp.CppHelper; import com.google.devtools.build.lib.rules.cpp.CppSemantics; -import com.google.devtools.build.lib.rules.cpp.LinkerInput; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper; import com.google.devtools.build.lib.rules.nativedeps.NativeDepsHelper; import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData; import com.google.devtools.build.lib.vfs.PathFragment; @@ -68,17 +68,15 @@ public static NativeLibs fromLinkedNativeDeps( String nativeDepsLibraryBasename = null; for (Map.Entry> entry : getSplitDepsByArchitecture(ruleContext, depsAttributes).asMap().entrySet()) { - CcLinkParams linkParams = + CcInfo ccInfo = AndroidCommon.getCcInfo( - entry.getValue(), - ImmutableList.of("-Wl,-soname=lib" + ruleContext.getLabel().getName())) - .getCcLinkingInfo() - .getStaticModeParamsForDynamicLibrary(); + entry.getValue(), + ImmutableList.of("-Wl,-soname=lib" + ruleContext.getLabel().getName())); Artifact nativeDepsLibrary = NativeDepsHelper.linkAndroidNativeDepsIfPresent( ruleContext, - linkParams, + ccInfo, configurationMap.get(entry.getKey()), toolchainsByCpu.get(entry.getKey()), cppSemantics); @@ -89,7 +87,8 @@ public static NativeLibs fromLinkedNativeDeps( nativeDepsLibraryBasename = nativeDepsLibrary.getExecPath().getBaseName(); } librariesBuilder.addAll( - filterUniqueSharedLibraries(ruleContext, nativeDepsLibrary, linkParams.getLibraries())); + filterUniqueSharedLibraries( + ruleContext, nativeDepsLibrary, ccInfo.getCcLinkingContext().getLibraries())); NestedSet libraries = librariesBuilder.build(); if (!libraries.isEmpty()) { @@ -246,20 +245,33 @@ private static Map getToolchainsByCpu(RuleContext r } private static Iterable filterUniqueSharedLibraries( - RuleContext ruleContext, Artifact linkedLibrary, NestedSet libraries) { + RuleContext ruleContext, Artifact linkedLibrary, NestedSet libraries) { Map basenames = new HashMap<>(); Set artifacts = new HashSet<>(); if (linkedLibrary != null) { basenames.put(linkedLibrary.getExecPath().getBaseName(), linkedLibrary); } - for (LinkerInput linkerInput : libraries) { - String name = linkerInput.getArtifact().getFilename(); - if (!(CppFileTypes.SHARED_LIBRARY.matches(name) - || CppFileTypes.VERSIONED_SHARED_LIBRARY.matches(name))) { + for (LibraryToLinkWrapper linkerInput : libraries) { + if (linkerInput.getPicStaticLibrary() != null || linkerInput.getStaticLibrary() != null) { // This is not a shared library and will not be loaded by Android, so skip it. continue; } - Artifact artifact = linkerInput.getOriginalLibraryArtifact(); + Artifact artifact = null; + if (linkerInput.getInterfaceLibrary() != null) { + if (linkerInput.getResolvedSymlinkInterfaceLibrary() != null) { + artifact = linkerInput.getResolvedSymlinkInterfaceLibrary(); + } else { + artifact = linkerInput.getInterfaceLibrary(); + } + } else { + if (linkerInput.getResolvedSymlinkDynamicLibrary() != null) { + artifact = linkerInput.getResolvedSymlinkDynamicLibrary(); + } else { + artifact = linkerInput.getDynamicLibrary(); + } + } + Preconditions.checkNotNull(artifact); + if (!artifacts.add(artifact)) { // We have already reached this library, e.g., through a different solib symlink. continue; diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java index 4cae09a35da54d..597999088b8ee5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java @@ -56,9 +56,11 @@ import com.google.devtools.build.lib.rules.apple.ApplePlatform; import com.google.devtools.build.lib.rules.cpp.CcCommon.CcFlagsSupplier; import com.google.devtools.build.lib.rules.cpp.CcCompilationHelper.CompilationInfo; +import com.google.devtools.build.lib.rules.cpp.CcLinkParams.LinkOptions; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration; import com.google.devtools.build.lib.rules.cpp.CppConfiguration.DynamicMode; import com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper.CcLinkingContext; import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType; import com.google.devtools.build.lib.rules.cpp.Link.LinkingMode; import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; @@ -112,12 +114,11 @@ public static class CcLauncherInfo extends NativeInfo { public static final Provider PROVIDER = new Provider(); private final CcCompilationOutputs ccCompilationOutputs; - private final CcLinkingInfo staticModeParamsForExecutable; + private final CcInfo ccInfo; - public CcLauncherInfo( - CcLinkingInfo staticModeParamsForExecutable, CcCompilationOutputs ccCompilationOutputs) { + public CcLauncherInfo(CcInfo ccInfo, CcCompilationOutputs ccCompilationOutputs) { super(PROVIDER); - this.staticModeParamsForExecutable = staticModeParamsForExecutable; + this.ccInfo = ccInfo; this.ccCompilationOutputs = ccCompilationOutputs; } @@ -126,9 +127,9 @@ public CcCompilationOutputs getCcCompilationOutputs(RuleContext ruleContext) { return ccCompilationOutputs; } - public CcLinkingInfo getStaticModeParamsForExecutable(RuleContext ruleContext) { + public CcInfo getCcInfo(RuleContext ruleContext) { checkRestrictedUsage(ruleContext); - return staticModeParamsForExecutable; + return ccInfo; } private void checkRestrictedUsage(RuleContext ruleContext) { @@ -357,9 +358,8 @@ public static ConfiguredTarget init(CppSemantics semantics, RuleContext ruleCont } boolean isStaticMode = linkingMode != LinkingMode.DYNAMIC; - boolean forDynamicLibrary = isLinkShared(ruleContext); - CcLinkingInfo depsCcLinkingInfo = collectCcLinkingInfo(ruleContext); + CcLinkingContext depsCcLinkingContext = collectCcLinkingContext(ruleContext); Artifact generatedDefFile = null; Artifact customDefFile = null; @@ -367,14 +367,22 @@ public static ConfiguredTarget init(CppSemantics semantics, RuleContext ruleCont if (featureConfiguration.isEnabled(CppRuleClasses.TARGETS_WINDOWS)) { ImmutableList.Builder objectFiles = ImmutableList.builder(); objectFiles.addAll(ccCompilationOutputs.getObjectFiles(false)); - for (LibraryToLink library : - depsCcLinkingInfo.getCcLinkParams(isStaticMode, forDynamicLibrary).getLibraries()) { - if (library.containsObjectFiles() - && library.getArtifactCategory() != ArtifactCategory.DYNAMIC_LIBRARY - && library.getArtifactCategory() != ArtifactCategory.INTERFACE_LIBRARY) { - objectFiles.addAll(library.getObjectFiles()); + + for (LibraryToLinkWrapper library : depsCcLinkingContext.getLibraries()) { + if (isStaticMode + || (library.getDynamicLibrary() == null && library.getInterfaceLibrary() == null)) { + if (library.getPicStaticLibrary() != null) { + if (library.getPicObjectFiles() != null) { + objectFiles.addAll(library.getPicObjectFiles()); + } + } else if (library.getStaticLibrary() != null) { + if (library.getObjectFiles() != null) { + objectFiles.addAll(library.getObjectFiles()); + } + } } } + generatedDefFile = CppHelper.createDefFileActions( ruleContext, @@ -394,13 +402,12 @@ public static ConfiguredTarget init(CppSemantics semantics, RuleContext ruleCont pdbFile = ruleContext.getRelatedArtifact(binary.getRootRelativePath(), ".pdb"); } - NestedSetBuilder extraLinkTimeLibrariesNestedSet = NestedSetBuilder.linkOrder(); + NestedSetBuilder extraLinkTimeLibrariesNestedSet = + NestedSetBuilder.linkOrder(); NestedSetBuilder extraLinkTimeRuntimeLibraries = NestedSetBuilder.linkOrder(); ExtraLinkTimeLibraries extraLinkTimeLibraries = - depsCcLinkingInfo - .getCcLinkParams(isStaticMode, forDynamicLibrary) - .getExtraLinkTimeLibraries(); + depsCcLinkingContext.getExtraLinkTimeLibraries(); if (extraLinkTimeLibraries != null) { ExtraLinkTimeLibrary.BuildLibraryOutput extraLinkBuildLibraryOutput = extraLinkTimeLibraries.buildLibraries( @@ -424,7 +431,7 @@ public static ConfiguredTarget init(CppSemantics semantics, RuleContext ruleCont ccCompilationContext, fake, binary, - depsCcLinkingInfo, + depsCcLinkingContext, extraLinkTimeLibrariesNestedSet.build(), linkCompileOutputSeparately, semantics, @@ -500,14 +507,23 @@ public static ConfiguredTarget init(CppSemantics semantics, RuleContext ruleCont // If the binary is linked dynamically and COPY_DYNAMIC_LIBRARIES_TO_BINARY is enabled, collect // all the dynamic libraries we need at runtime. Then copy these libraries next to the binary. if (featureConfiguration.isEnabled(CppRuleClasses.COPY_DYNAMIC_LIBRARIES_TO_BINARY)) { + ImmutableList.Builder runtimeLibraries = ImmutableList.builder(); + for (LibraryToLinkWrapper libraryToLinkWrapper : depsCcLinkingContext.getLibraries()) { + Artifact library = + libraryToLinkWrapper.getDynamicLibraryForRuntimeOrNull( + /* linkingStatically= */ isStaticMode); + if (library != null) { + runtimeLibraries.add(library); + } + } filesToBuild = NestedSetBuilder.fromNestedSet(filesToBuild) .addAll( createDynamicLibrariesCopyActions( ruleContext, - depsCcLinkingInfo - .getCcLinkParams(isStaticMode, forDynamicLibrary) - .getDynamicLibrariesForRuntime())) + NestedSetBuilder.linkOrder() + .addAll(runtimeLibraries.build()) + .build())) .build(); } @@ -597,8 +613,8 @@ public static Pair createTransitiveLinkingActi CcCompilationContext ccCompilationContext, boolean fake, Artifact binary, - CcLinkingInfo depsCcLinkingInfo, - NestedSet extraLinkTimeLibraries, + CcLinkingContext depsCcLinkingContext, + NestedSet extraLinkTimeLibraries, boolean linkCompileOutputSeparately, CppSemantics cppSemantics, LinkingMode linkingMode, @@ -623,15 +639,26 @@ public static Pair createTransitiveLinkingActi fdoContext, ruleContext.getConfiguration()); - CcLinkParams.Builder ccLinkParamsBuilder = CcLinkParams.builder(); - ccLinkParamsBuilder.addTransitiveArgs( - depsCcLinkingInfo.getCcLinkParams( - linkingMode != LinkingMode.DYNAMIC, isLinkShared(ruleContext))); + CcInfo depsCcInfo = CcInfo.builder().setCcLinkingContext(depsCcLinkingContext).build(); + + CcLinkingContext.Builder currentCcLinkingContextBuilder = CcLinkingContext.builder(); if (linkCompileOutputSeparately) { + ImmutableList.Builder localLibraries = ImmutableList.builder(); for (LibraryToLink library : ccLinkingOutputs.getDynamicLibrariesForLinking()) { - ccLinkParamsBuilder.addLibrary(library); + LibraryToLinkWrapper.Builder libraryToLinkWrapperBuilder = LibraryToLinkWrapper.builder(); + libraryToLinkWrapperBuilder.setLibraryIdentifier( + LibraryToLinkWrapper.setDynamicArtifactsAndReturnIdentifier( + libraryToLinkWrapperBuilder, + library, + library, + /* runtimeLibraryIterator= */ ImmutableList.of().listIterator())); + localLibraries.add(libraryToLinkWrapperBuilder.build()); } + currentCcLinkingContextBuilder.addLibraries( + NestedSetBuilder.linkOrder() + .addAll(localLibraries.build()) + .build()); ccCompilationOutputsWithOnlyObjects = new CcCompilationOutputs.Builder().build(); } @@ -639,62 +666,81 @@ public static Pair createTransitiveLinkingActi // First libraries from srcs. Shared library artifacts here are substituted with mangled symlink // artifacts generated by getDynamicLibraryLink(). This is done to minimize number of -rpath // entries during linking process. + ImmutableList.Builder precompiledLibraries = ImmutableList.builder(); for (Artifact library : precompiledFiles.getLibraries()) { if (Link.SHARED_LIBRARY_FILETYPES.matches(library.getFilename())) { - ccLinkParamsBuilder.addLibrary( - LinkerInputs.solibLibraryToLink( - common.getDynamicLibrarySymlink(library, true), - library, - CcLinkingOutputs.libraryIdentifierOf(library))); + LibraryToLinkWrapper libraryToLinkWrapper = + LibraryToLinkWrapper.builder() + .setLibraryIdentifier(CcLinkingOutputs.libraryIdentifierOf(library)) + .setDynamicLibrary( + common.getDynamicLibrarySymlink(library, /* preserveName= */ true)) + .setResolvedSymlinkDynamicLibrary(library) + .build(); + precompiledLibraries.add(libraryToLinkWrapper); } else if (Link.LINK_LIBRARY_FILETYPES.matches(library.getFilename())) { - ccLinkParamsBuilder.addLibrary( - LinkerInputs.precompiledLibraryToLink( - library, ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY)); + LibraryToLinkWrapper libraryToLinkWrapper = + LibraryToLinkWrapper.builder() + .setLibraryIdentifier(CcLinkingOutputs.libraryIdentifierOf(library)) + .setStaticLibrary(library) + .setAlwayslink(true) + .build(); + precompiledLibraries.add(libraryToLinkWrapper); } else if (Link.ARCHIVE_FILETYPES.matches(library.getFilename())) { - ccLinkParamsBuilder.addLibrary( - LinkerInputs.precompiledLibraryToLink(library, ArtifactCategory.STATIC_LIBRARY)); + LibraryToLinkWrapper libraryToLinkWrapper = + LibraryToLinkWrapper.builder() + .setLibraryIdentifier(CcLinkingOutputs.libraryIdentifierOf(library)) + .setStaticLibrary(library) + .build(); + precompiledLibraries.add(libraryToLinkWrapper); } else { throw new IllegalStateException(); } } + currentCcLinkingContextBuilder.addLibraries( + NestedSetBuilder.wrap(Order.LINK_ORDER, precompiledLibraries.build())); + ImmutableList.Builder userLinkflags = ImmutableList.builder(); if (linkingMode != Link.LinkingMode.DYNAMIC && !cppConfiguration.disableEmittingStaticLibgcc()) { // Only force a static link of libgcc if static runtime linking is enabled (which // can't be true if runtimeInputs is empty). // TODO(bazel-team): Move this to CcToolchain. if (!ccToolchain.getStaticRuntimeLinkInputs(ruleContext, featureConfiguration).isEmpty()) { - ccLinkParamsBuilder.addLinkOpts(ImmutableList.of("-static-libgcc")); + userLinkflags.add("-static-libgcc"); } } - ccLinkParamsBuilder - .addNonCodeInputs(ccCompilationContext.getTransitiveCompilationPrerequisites()) - .addNonCodeInputs(common.getLinkerScripts()) - .addLinkOpts(common.getLinkopts()); - - CcLinkParams ccLinkParamsForLauncher = ccLinkParamsBuilder.build(); - CcLinkParams ccLinkParams = - CcLinkParams.builder() - .addTransitiveArgs(ccLinkParamsForLauncher) - .addLibraries(extraLinkTimeLibraries) - .addTransitiveArgs(CcLinkParams.builder().addLibraries(extraLinkTimeLibraries).build()) + userLinkflags.addAll(common.getLinkopts()); + currentCcLinkingContextBuilder + .addNonCodeInputs( + NestedSetBuilder.linkOrder() + .addAll(ccCompilationContext.getTransitiveCompilationPrerequisites()) + .addAll(common.getLinkerScripts()) + .build()) + .addUserLinkFlags( + NestedSetBuilder.linkOrder() + .add(new LinkOptions(userLinkflags.build())) + .build()); + + CcInfo ccInfoWithoutExtraLinkTimeLibraries = + CcInfo.merge( + ImmutableList.of( + CcInfo.builder() + .setCcLinkingContext(currentCcLinkingContextBuilder.build()) + .build(), + depsCcInfo)); + + CcInfo extraLinkTimeLibrariesCcInfo = + CcInfo.builder() + .setCcLinkingContext( + CcLinkingContext.builder().addLibraries(extraLinkTimeLibraries).build()) .build(); - - CcLinkingInfo.Builder ccLinkingInfo = CcLinkingInfo.Builder.create(); - ccLinkingInfo.setStaticModeParamsForDynamicLibrary(ccLinkParams); - ccLinkingInfo.setStaticModeParamsForExecutable(ccLinkParams); - ccLinkingInfo.setDynamicModeParamsForDynamicLibrary(ccLinkParams); - ccLinkingInfo.setDynamicModeParamsForExecutable(ccLinkParams); - - CcLinkingInfo.Builder ccLinkingInfoForLauncher = CcLinkingInfo.Builder.create(); - ccLinkingInfoForLauncher.setStaticModeParamsForDynamicLibrary(ccLinkParamsForLauncher); - ccLinkingInfoForLauncher.setStaticModeParamsForExecutable(ccLinkParamsForLauncher); - ccLinkingInfoForLauncher.setDynamicModeParamsForDynamicLibrary(ccLinkParamsForLauncher); - ccLinkingInfoForLauncher.setDynamicModeParamsForExecutable(ccLinkParamsForLauncher); + CcInfo ccInfo = + CcInfo.merge( + ImmutableList.of(ccInfoWithoutExtraLinkTimeLibraries, extraLinkTimeLibrariesCcInfo)); ccLinkingHelper - .addCcLinkingInfos(ImmutableList.of(ccLinkingInfo.build())) + .addCcLinkingContexts(ImmutableList.of(ccInfo.getCcLinkingContext())) .setUseTestOnlyFlags(ruleContext.isTestTarget()) .setShouldCreateStaticLibraries(false) .setLinkingMode(linkingMode) @@ -717,7 +763,8 @@ public static Pair createTransitiveLinkingActi return Pair.of( ccLinkingHelper.link(ccCompilationOutputsWithOnlyObjects), - new CcLauncherInfo(ccLinkingInfoForLauncher.build(), ccCompilationOutputsWithOnlyObjects)); + new CcLauncherInfo( + ccInfoWithoutExtraLinkTimeLibraries, ccCompilationOutputsWithOnlyObjects)); } /** @@ -937,7 +984,7 @@ private static Artifact getIntermediateDwpFile(RuleContext ruleContext, Artifact } /** Collect link parameters from the transitive closure. */ - private static CcLinkingInfo collectCcLinkingInfo(RuleContext context) { + private static CcLinkingContext collectCcLinkingContext(RuleContext context) { ImmutableList.Builder ccInfoListBuilder = ImmutableList.builder(); ccInfoListBuilder.addAll(context.getPrerequisites("deps", Mode.TARGET, CcInfo.PROVIDER)); @@ -947,7 +994,7 @@ private static CcLinkingInfo collectCcLinkingInfo(RuleContext context) { ccInfoListBuilder.add(ccInfo); } } - return CcInfo.merge(ccInfoListBuilder.build()).getCcLinkingInfo(); + return CcInfo.merge(ccInfoListBuilder.build()).getCcLinkingContext(); } private static void addTransitiveInfoProviders( diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcInfo.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcInfo.java index f8064fb2fb7d89..8d69a01468d30c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcInfo.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcInfo.java @@ -36,13 +36,12 @@ public final class CcInfo extends NativeInfo implements CcInfoApi { public static final CcInfo EMPTY = CcInfo.builder().build(); private final CcCompilationContext ccCompilationContext; - // TODO(b/117875295): Rename CcLinkingInfo to CcLinkingContext - private final CcLinkingInfo ccLinkingInfo; + private final CcLinkingContext ccLinkingContext; - public CcInfo(CcCompilationContext ccCompilationContext, CcLinkingInfo ccLinkingInfo) { + public CcInfo(CcCompilationContext ccCompilationContext, CcLinkingContext ccLinkingContext) { super(PROVIDER); this.ccCompilationContext = ccCompilationContext; - this.ccLinkingInfo = ccLinkingInfo; + this.ccLinkingContext = ccLinkingContext; } @Override @@ -51,27 +50,23 @@ public CcCompilationContext getCcCompilationContext() { } @Override - public CcLinkingInfo getCcLinkingInfo() { - return ccLinkingInfo; - } - public CcLinkingContext getCcLinkingContext() { - return LibraryToLinkWrapper.fromCcLinkingInfo(ccLinkingInfo); + return ccLinkingContext; } public static CcInfo merge(Collection ccInfos) { ImmutableList.Builder ccCompilationContexts = ImmutableList.builder(); - ImmutableList.Builder ccLinkingInfos = ImmutableList.builder(); + ImmutableList.Builder ccLinkingContexts = ImmutableList.builder(); for (CcInfo ccInfo : ccInfos) { ccCompilationContexts.add(ccInfo.getCcCompilationContext()); - ccLinkingInfos.add(ccInfo.getCcLinkingInfo()); + ccLinkingContexts.add(ccInfo.getCcLinkingContext()); } CcCompilationContext.Builder builder = new CcCompilationContext.Builder(/* ruleContext= */ null); return new CcInfo( builder.mergeDependentCcCompilationContexts(ccCompilationContexts.build()).build(), - CcLinkingInfo.merge(ccLinkingInfos.build())); + CcLinkingContext.merge(ccLinkingContexts.build())); } @Override @@ -84,7 +79,7 @@ public boolean equals(Object otherObject) { return true; } if (!this.ccCompilationContext.equals(other.ccCompilationContext) - || !this.ccLinkingInfo.equals(other.ccLinkingInfo)) { + || !this.getCcLinkingContext().equals(other.getCcLinkingContext())) { return false; } return true; @@ -92,7 +87,7 @@ public boolean equals(Object otherObject) { @Override public int hashCode() { - return Objects.hashCode(ccCompilationContext, ccLinkingInfo); + return Objects.hashCode(ccCompilationContext, ccLinkingContext); } public static Builder builder() { @@ -102,7 +97,7 @@ public static Builder builder() { /** A Builder for {@link CcInfo}. */ public static class Builder { private CcCompilationContext ccCompilationContext; - private CcLinkingInfo ccLinkingInfo; + private CcLinkingContext ccLinkingContext; public CcInfo.Builder setCcCompilationContext(CcCompilationContext ccCompilationContext) { Preconditions.checkState(this.ccCompilationContext == null); @@ -110,15 +105,9 @@ public CcInfo.Builder setCcCompilationContext(CcCompilationContext ccCompilation return this; } - public CcInfo.Builder setCcLinkingInfo(CcLinkingInfo ccLinkingInfo) { - Preconditions.checkState(this.ccLinkingInfo == null); - this.ccLinkingInfo = ccLinkingInfo; - return this; - } - public CcInfo.Builder setCcLinkingContext(CcLinkingContext ccLinkingContext) { - Preconditions.checkState(this.ccLinkingInfo == null); - this.ccLinkingInfo = ccLinkingContext.toCcLinkingInfo(); + Preconditions.checkState(this.ccLinkingContext == null); + this.ccLinkingContext = ccLinkingContext; return this; } @@ -126,10 +115,10 @@ public CcInfo build() { if (ccCompilationContext == null) { ccCompilationContext = CcCompilationContext.EMPTY; } - if (ccLinkingInfo == null) { - ccLinkingInfo = CcLinkingInfo.EMPTY; + if (ccLinkingContext == null) { + ccLinkingContext = CcLinkingContext.EMPTY; } - return new CcInfo(ccCompilationContext, ccLinkingInfo); + return new CcInfo(ccCompilationContext, ccLinkingContext); } } @@ -148,24 +137,15 @@ public CcInfoApi createInfo( throws EvalException { CcCompilationContext ccCompilationContext = nullIfNone(skylarkCcCompilationContext, CcCompilationContext.class); - CcLinkingInfo ccLinkingInfo = null; - try { - ccLinkingInfo = nullIfNone(skylarkCcLinkingInfo, CcLinkingInfo.class); - } catch (ClassCastException e) { - // TODO(b/118663806): Eventually only CcLinkingContext will be allowed, this is for - // backwards compatibility. - CcLinkingContext ccLinkingContext = - nullIfNone(skylarkCcLinkingInfo, CcLinkingContext.class); - if (ccLinkingContext != null) { - ccLinkingInfo = ccLinkingContext.toCcLinkingInfo(); - } - } + // TODO(b/118663806): Eventually only CcLinkingContext will be allowed, this is for + // backwards compatibility. + CcLinkingContext ccLinkingContext = nullIfNone(skylarkCcLinkingInfo, CcLinkingContext.class); CcInfo.Builder ccInfoBuilder = CcInfo.builder(); if (ccCompilationContext != null) { ccInfoBuilder.setCcCompilationContext(ccCompilationContext); } - if (ccLinkingInfo != null) { - ccInfoBuilder.setCcLinkingInfo(ccLinkingInfo); + if (ccLinkingContext != null) { + ccInfoBuilder.setCcLinkingContext(ccLinkingContext); } return ccInfoBuilder.build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java index 05edc0560dcfe6..9ce22cc2225a33 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java @@ -50,6 +50,7 @@ import com.google.devtools.build.lib.rules.cpp.CcCommon.CcFlagsSupplier; import com.google.devtools.build.lib.rules.cpp.CcCompilationHelper.CompilationInfo; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper.CcLinkingContext; import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType; import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; import com.google.devtools.build.lib.rules.cpp.LinkerInputs.SolibLibraryToLink; @@ -375,8 +376,8 @@ public static void init( ccCompilationOutputs); } - CcLinkingInfo ccLinkingInfo = - linkingHelper.buildCcLinkingInfoFromLibraryToLinkWrappers( + CcLinkingContext ccLinkingContext = + linkingHelper.buildCcLinkingContextFromLibraryToLinkWrappers( libraryToLinkWrappers, compilationInfo.getCcCompilationContext()); CcNativeLibraryProvider ccNativeLibraryProvider = CppHelper.collectNativeCcLibraries( @@ -445,7 +446,7 @@ public static void init( .addNativeDeclaredProvider( CcInfo.builder() .setCcCompilationContext(compilationInfo.getCcCompilationContext()) - .setCcLinkingInfo(ccLinkingInfo) + .setCcLinkingContext(ccLinkingContext) .build()) .addOutputGroups( CcCommon.mergeOutputGroups( @@ -658,7 +659,10 @@ private static ImmutableList createLibraryToLinkWrappersLi // files if they exist. libraryToLinkWrappers.addAll( convertPrecompiledLibrariesToLibraryToLinkWrapper( - staticLibraries, picStaticLibraries, dynamicLibrariesForRuntime)); + ruleContext.getFragment(CppConfiguration.class).forcePic(), + staticLibraries, + picStaticLibraries, + dynamicLibrariesForRuntime)); if (!ccCompilationOutputs.isEmpty() || (staticLibraries.isEmpty() && picStaticLibraries.isEmpty() @@ -681,6 +685,7 @@ private static boolean isContentsOfCcLinkingOutputsImplicitlyCreated( } private static List convertPrecompiledLibrariesToLibraryToLinkWrapper( + boolean forcePic, List staticLibraries, List picStaticLibraries, List dynamicLibrariesForRuntime) { @@ -691,17 +696,21 @@ private static List convertPrecompiledLibrariesToLibraryTo // here with the local libraries, none of the libraries of the transitive closure. for (LibraryToLink staticLibrary : staticLibraries) { LibraryToLinkWrapper.Builder libraryToLinkWrapperBuilder = LibraryToLinkWrapper.builder(); - libraryToLinkWrapperBuilder.setStaticLibrary(staticLibrary.getArtifact()); String identifier = staticLibrary.getLibraryIdentifier(); libraryToLinkWrapperBuilder.setLibraryIdentifier(identifier); List sameIdentifierPicStaticLibraries = picStaticLibraries.stream() .filter(x -> x.getLibraryIdentifier().equals(identifier)) .collect(ImmutableList.toImmutableList()); + boolean hadPic = false; if (!sameIdentifierPicStaticLibraries.isEmpty()) { + hadPic = true; libraryToLinkWrapperBuilder.setPicStaticLibrary( sameIdentifierPicStaticLibraries.get(0).getArtifact()); } + if (!forcePic || !hadPic) { + libraryToLinkWrapperBuilder.setStaticLibrary(staticLibrary.getArtifact()); + } List sameIdentifierDynamicLibraries = dynamicLibrariesForRuntime.stream() .filter(x -> x.getLibraryIdentifier().equals(identifier)) diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParams.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParams.java index 4c858bda9b069a..06d1c50313a065 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParams.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParams.java @@ -14,22 +14,15 @@ package com.google.devtools.build.lib.rules.cpp; -import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.collect.nestedset.NestedSet; -import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; -import java.util.Collection; import java.util.Objects; -import javax.annotation.Nullable; /** * Parameters to be passed to the linker. @@ -73,349 +66,6 @@ public String toString() { } } - private final NestedSet linkOpts; - private final NestedSet linkstamps; - private final NestedSet libraries; - private final NestedSet dynamicLibrariesForRuntime; - private final ExtraLinkTimeLibraries extraLinkTimeLibraries; - private final NestedSet nonCodeInputs; - - @AutoCodec.Instantiator - @VisibleForSerialization - CcLinkParams( - NestedSet linkOpts, - NestedSet linkstamps, - NestedSet libraries, - NestedSet dynamicLibrariesForRuntime, - ExtraLinkTimeLibraries extraLinkTimeLibraries, - NestedSet nonCodeInputs) { - this.linkOpts = linkOpts; - this.linkstamps = linkstamps; - this.libraries = libraries; - this.dynamicLibrariesForRuntime = dynamicLibrariesForRuntime; - this.extraLinkTimeLibraries = extraLinkTimeLibraries; - this.nonCodeInputs = nonCodeInputs; - } - - /** - * Returns the linkopts - */ - public NestedSet getLinkopts() { - return linkOpts; - } - - public ImmutableList flattenedLinkopts() { - return linkOpts.toList().stream() - .map(LinkOptions::get) - .flatMap(Collection::stream) - .collect(ImmutableList.toImmutableList()); - } - - /** - * Returns the linkstamps - */ - public NestedSet getLinkstamps() { - return linkstamps; - } - - /** - * Returns the libraries - */ - public NestedSet getLibraries() { - return libraries; - } - - /** Returns the dynamicLibrariesForRuntime. */ - public NestedSet getDynamicLibrariesForRuntime() { - return dynamicLibrariesForRuntime; - } - - /** - * The extra link time libraries; will be null if there are no such libraries. - */ - public @Nullable ExtraLinkTimeLibraries getExtraLinkTimeLibraries() { - return extraLinkTimeLibraries; - } - - /** - * Returns the non-code inputs, e.g. linker scripts; will be null if none. - */ - public @Nullable NestedSet getNonCodeInputs() { - return nonCodeInputs; - } - - public static final Builder builder(boolean linkingStatically, boolean linkShared) { - return new Builder(linkingStatically, linkShared); - } - - public static final Builder builder() { - return new Builder(); - } - - /** - * Builder for {@link CcLinkParams}. - */ - public static final class Builder { - - /** - * linkingStatically is true when we're linking this target in either FULLY STATIC mode - * (linkopts=["-static"]) or MOSTLY STATIC mode (linkstatic=1). When this is true, we want to - * use static versions of any libraries that this target depends on (except possibly system - * libraries, which are not handled by CcLinkParams). When this is false, we want to use dynamic - * versions of any libraries that this target depends on. - */ - private boolean linkingStatically; - - /** linkShared is true when we're linking with "-shared" (linkshared=1). */ - private boolean linkShared; - - // TODO(plf): Ideally the two booleans above are removed from this Builder. We would pass the - // specific instances of CcLinkParams that are needed from transitive dependencies instead of - // calling the convenience methods that dig them out from the CcLinkingInfo using these - // booleans. - private boolean linkingStaticallyLinkSharedSet; - - private final ImmutableList.Builder localLinkoptsBuilder = ImmutableList.builder(); - private final NestedSetBuilder localLinkOptions = NestedSetBuilder.linkOrder(); - - private final NestedSetBuilder linkOptsBuilder = - NestedSetBuilder.linkOrder(); - private final NestedSetBuilder linkstampsBuilder = - NestedSetBuilder.compileOrder(); - private final NestedSetBuilder librariesBuilder = - NestedSetBuilder.linkOrder(); - private final NestedSetBuilder dynamicLibrariesForRuntimeBuilder = - NestedSetBuilder.linkOrder(); - - /** - * A builder for the list of link time libraries. Most builds - * won't have any such libraries, so save space by leaving the - * default as null. - */ - private ExtraLinkTimeLibraries.Builder extraLinkTimeLibrariesBuilder = null; - - private NestedSetBuilder nonCodeInputsBuilder = null; - - private boolean built = false; - - /** The static builder methods of {@link CcLinkParams} should be used for instantiation. */ - private Builder(boolean linkingStatically, boolean linkShared) { - this.linkingStatically = linkingStatically; - this.linkShared = linkShared; - this.linkingStaticallyLinkSharedSet = true; - } - - private Builder() {} - - /** - * Builds a {@link CcLinkParams} object. - */ - public CcLinkParams build() { - Preconditions.checkState(!built); - // Not thread-safe, but builders should not be shared across threads. - built = true; - - ImmutableList localLinkopts = localLinkoptsBuilder.build(); - if (!localLinkopts.isEmpty()) { - linkOptsBuilder.add(LinkOptions.of(localLinkopts)); - } - if (!localLinkOptions.isEmpty()) { - linkOptsBuilder.addTransitive(localLinkOptions.build()); - } - ExtraLinkTimeLibraries extraLinkTimeLibraries = null; - if (extraLinkTimeLibrariesBuilder != null) { - extraLinkTimeLibraries = extraLinkTimeLibrariesBuilder.build(); - } - NestedSet nonCodeInputs = null; - if (nonCodeInputsBuilder != null) { - nonCodeInputs = nonCodeInputsBuilder.build(); - } - return new CcLinkParams( - linkOptsBuilder.build(), - linkstampsBuilder.build(), - librariesBuilder.build(), - dynamicLibrariesForRuntimeBuilder.build(), - extraLinkTimeLibraries, - nonCodeInputs); - } - - public NestedSet getLinkOptsBuilder() { - return linkOptsBuilder.build(); - } - - public boolean add(CcLinkingInfo ccLinkingInfo) { - Preconditions.checkState(linkingStaticallyLinkSharedSet); - if (ccLinkingInfo != null) { - CcLinkParams args = ccLinkingInfo.getCcLinkParams(linkingStatically, linkShared); - addTransitiveArgs(args); - } - return ccLinkingInfo != null; - } - - /** - * Includes link parameters from a collection of dependency targets. - */ - public Builder addTransitiveTargets(Iterable targets) { - for (TransitiveInfoCollection target : targets) { - addTransitiveTarget(target); - } - return this; - } - - /** - * Includes link parameters from the given targets. Each target is checked for the given - * mappings in the order specified, and the first mapping that returns a non-null result is - * added. - */ - @SafeVarargs - public final Builder addTransitiveTargets( - Iterable targets, - Function firstMapping, - @SuppressWarnings("unchecked") // Java arrays don't preserve generic arguments. - Function... remainingMappings) { - for (TransitiveInfoCollection target : targets) { - addTransitiveTarget(target, firstMapping, remainingMappings); - } - return this; - } - - /** - * Includes link parameters from a dependency target. - * - *

The target should implement {@link CcLinkingInfo}. If it does not, the method does not do - * anything. - */ - public Builder addTransitiveTarget(TransitiveInfoCollection target) { - CcInfo ccInfo = target.get(CcInfo.PROVIDER); - if (ccInfo != null) { - add(ccInfo.getCcLinkingInfo()); - } - return this; - } - - /** - * Includes link parameters from a dependency target. The target is checked for the given - * mappings in the order specified, and the first mapping that returns a non-null result is - * added. - */ - @SafeVarargs - public final Builder addTransitiveTarget( - TransitiveInfoCollection target, - Function firstMapping, - @SuppressWarnings("unchecked") // Java arrays don't preserve generic arguments. - Function... remainingMappings) { - if (add(firstMapping.apply(target))) { - return this; - } - for (Function mapping : remainingMappings) { - if (add(mapping.apply(target))) { - return this; - } - } - return this; - } - - /** - * Merges the other {@link CcLinkParams} object into this one. - */ - public Builder addTransitiveArgs(CcLinkParams args) { - linkOptsBuilder.addTransitive(args.getLinkopts()); - linkstampsBuilder.addTransitive(args.getLinkstamps()); - librariesBuilder.addTransitive(args.getLibraries()); - dynamicLibrariesForRuntimeBuilder.addTransitive(args.getDynamicLibrariesForRuntime()); - if (args.getExtraLinkTimeLibraries() != null) { - if (extraLinkTimeLibrariesBuilder == null) { - extraLinkTimeLibrariesBuilder = ExtraLinkTimeLibraries.builder(); - } - extraLinkTimeLibrariesBuilder.addTransitive(args.getExtraLinkTimeLibraries()); - } - if (args.getNonCodeInputs() != null) { - if (nonCodeInputsBuilder == null) { - nonCodeInputsBuilder = NestedSetBuilder.linkOrder(); - } - nonCodeInputsBuilder.addTransitive(args.getNonCodeInputs()); - } - return this; - } - - /** - * Adds a collection of link options. This is deprecated, use {@link #addLinkOpts} version which - * takes a {@link NestedSet}.The reason for that is that this version of the method would force - * flattening of nested sets in some cases. - */ - @Deprecated - public Builder addLinkOpts(Collection linkOpts) { - localLinkoptsBuilder.addAll(linkOpts); - return this; - } - - public Builder addLinkOpts(NestedSet linkOpts) { - this.localLinkOptions.addTransitive(linkOpts); - return this; - } - - public Builder addLinkstamps(NestedSet linkstamps) { - for (Linkstamp linkstamp : linkstamps) { - linkstampsBuilder.add(linkstamp); - } - return this; - } - - /** - * Adds a library artifact. - */ - public Builder addLibrary(LibraryToLink library) { - librariesBuilder.add(library); - return this; - } - - /** - * Adds a collection of library artifacts. - */ - public Builder addLibraries(Iterable libraries) { - librariesBuilder.addAll(libraries); - return this; - } - - /** Adds a collection of library artifacts. */ - public Builder addDynamicLibrariesForRuntime(Iterable libraries) { - dynamicLibrariesForRuntimeBuilder.addAll(libraries); - return this; - } - - /** - * Adds an extra link time library, a library that is actually - * built at link time. - */ - public Builder addExtraLinkTimeLibrary(ExtraLinkTimeLibrary e) { - if (extraLinkTimeLibrariesBuilder == null) { - extraLinkTimeLibrariesBuilder = ExtraLinkTimeLibraries.builder(); - } - extraLinkTimeLibrariesBuilder.add(e); - return this; - } - - public Builder addTransitiveExtraLinkTimeLibrary(ExtraLinkTimeLibraries e) { - Preconditions.checkNotNull(e); - if (extraLinkTimeLibrariesBuilder == null) { - extraLinkTimeLibrariesBuilder = ExtraLinkTimeLibraries.builder(); - } - extraLinkTimeLibrariesBuilder.addTransitive(e); - return this; - } - - /** - * Adds a collection of non-code inputs. - */ - public Builder addNonCodeInputs(Iterable nonCodeInputs) { - if (nonCodeInputsBuilder == null) { - nonCodeInputsBuilder = NestedSetBuilder.linkOrder(); - } - nonCodeInputsBuilder.addAll(nonCodeInputs); - return this; - } - } - /** * A linkstamp that also knows about its declared includes. * @@ -465,14 +115,4 @@ public boolean equals(Object obj) { && declaredIncludeSrcs.equals(other.declaredIncludeSrcs); } } - - /** Empty CcLinkParams. */ - public static final CcLinkParams EMPTY = - new CcLinkParams( - NestedSetBuilder.emptySet(Order.LINK_ORDER), - NestedSetBuilder.emptySet(Order.COMPILE_ORDER), - NestedSetBuilder.emptySet(Order.LINK_ORDER), - NestedSetBuilder.emptySet(Order.STABLE_ORDER), - null, - NestedSetBuilder.linkOrder().build()); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingHelper.java index ed7e921f4861e8..94e4e4f9986d33 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingHelper.java @@ -66,17 +66,17 @@ public final class CcLinkingHelper { // TODO(plf): Only used by Skylark API. Remove after migrating. @Deprecated public static final class LinkingInfo implements LinkingInfoApi { - private final CcLinkingInfo ccLinkingInfo; + private final CcLinkingContext ccLinkingContext; private final CcLinkingOutputs linkingOutputs; - public LinkingInfo(CcLinkingInfo ccLinkingInfo, CcLinkingOutputs linkingOutputs) { - this.ccLinkingInfo = ccLinkingInfo; + public LinkingInfo(CcLinkingContext ccLinkingContext, CcLinkingOutputs linkingOutputs) { + this.ccLinkingContext = ccLinkingContext; this.linkingOutputs = linkingOutputs; } @Override - public CcLinkingInfo getCcLinkingInfo() { - return ccLinkingInfo; + public CcLinkingContext getCcLinkingContext() { + return ccLinkingContext; } @Override @@ -93,7 +93,7 @@ public CcLinkingOutputs getCcLinkingOutputs() { private final List nonCodeLinkerInputs = new ArrayList<>(); private final List linkopts = new ArrayList<>(); private final List deps = new ArrayList<>(); - private final List ccLinkingInfos = new ArrayList<>(); + private final List ccLinkingContexts = new ArrayList<>(); private final NestedSetBuilder linkstamps = NestedSetBuilder.stableOrder(); private final List linkActionInputs = new ArrayList<>(); @@ -194,20 +194,20 @@ public CcLinkingHelper addLinkopts(Iterable linkopts) { * (like from a "deps" attribute) and also implicit dependencies on runtime libraries. */ public CcLinkingHelper addDeps(Iterable deps) { - this.ccLinkingInfos.addAll( + this.ccLinkingContexts.addAll( Streams.stream(AnalysisUtils.getProviders(deps, CcInfo.PROVIDER)) - .map(CcInfo::getCcLinkingInfo) + .map(CcInfo::getCcLinkingContext) .collect(ImmutableList.toImmutableList())); Iterables.addAll(this.deps, deps); return this; } /** - * Adds additional {@link CcLinkingInfo} that will be used everywhere where CcLinkingInfos were + * Adds additional {@link CcLinkingContext} that will be used everywhere where CcLinkingInfos were * obtained from deps. */ - public CcLinkingHelper addCcLinkingInfos(Iterable ccLinkingInfos) { - Iterables.addAll(this.ccLinkingInfos, ccLinkingInfos); + public CcLinkingHelper addCcLinkingContexts(Iterable ccLinkingContexts) { + Iterables.addAll(this.ccLinkingContexts, ccLinkingContexts); return this; } @@ -359,32 +359,36 @@ public CcLinkingOutputs link(CcCompilationOutputs ccOutputs) return ccLinkingOutputs; } - public CcLinkingInfo buildCcLinkingInfoFromLibraryToLinkWrappers( + public CcLinkingContext buildCcLinkingContextFromLibraryToLinkWrappers( ImmutableCollection libraryToLinkWrappers, CcCompilationContext ccCompilationContext) { NestedSetBuilder linkstampBuilder = NestedSetBuilder.stableOrder(); for (Artifact linkstamp : linkstamps.build()) { linkstampBuilder.add(new Linkstamp(linkstamp, ccCompilationContext.getDeclaredIncludeSrcs())); } - CcLinkingInfo ccLinkingInfo = CcLinkingInfo.EMPTY; + CcLinkingContext ccLinkingContext = CcLinkingContext.EMPTY; if (!neverlink) { - ccLinkingInfo = - LibraryToLinkWrapper.toCcLinkingInfo( - cppConfiguration.forcePic(), - libraryToLinkWrappers, - // We want an empty set if there are no link options. We have to make sure we don't - // create a LinkOptions instance that contains an empty list. - linkopts.isEmpty() - ? NestedSetBuilder.emptySet(Order.LINK_ORDER) - : NestedSetBuilder.create(Order.LINK_ORDER, LinkOptions.of(linkopts)), - linkstampBuilder.build(), - nonCodeLinkerInputs, - /* extraLinkTimeLibraries= */ null); + // We want an empty set if there are no link options. We have to make sure we don't + // create a LinkOptions instance that contains an empty list. + ccLinkingContext = + CcLinkingContext.builder() + .addUserLinkFlags( + linkopts.isEmpty() + ? NestedSetBuilder.emptySet(Order.LINK_ORDER) + : NestedSetBuilder.create(Order.LINK_ORDER, LinkOptions.of(linkopts))) + .addLibraries( + NestedSetBuilder.linkOrder() + .addAll(libraryToLinkWrappers) + .build()) + .addNonCodeInputs( + NestedSetBuilder.linkOrder().addAll(nonCodeLinkerInputs).build()) + .addLinkstamps(linkstampBuilder.build()) + .build(); } - ImmutableList.Builder mergedCcLinkingInfos = ImmutableList.builder(); - mergedCcLinkingInfos.add(ccLinkingInfo); - mergedCcLinkingInfos.addAll(ccLinkingInfos); - return CcLinkingInfo.merge(mergedCcLinkingInfos.build()); + ImmutableList.Builder mergedCcLinkingContexts = ImmutableList.builder(); + mergedCcLinkingContexts.add(ccLinkingContext); + mergedCcLinkingContexts.addAll(ccLinkingContexts); + return CcLinkingContext.merge(mergedCcLinkingContexts.build()); } /** @@ -664,16 +668,12 @@ private void createDynamicLibrary( || dynamicLinkType != LinkTargetType.NODEPS_DYNAMIC_LIBRARY; if (shouldLinkTransitively) { - CcLinkingInfo mergedCcLinkingInfo = CcLinkingInfo.merge(ccLinkingInfos); - CcLinkingContext ccLinkingContext = - LibraryToLinkWrapper.fromCcLinkingInfo(mergedCcLinkingInfo); + CcLinkingContext ccLinkingContext = CcLinkingContext.merge(ccLinkingContexts); List libraries = - ccLinkingContext - .toCcLinkingInfo() - .getCcLinkParams( - linkingMode != LinkingMode.DYNAMIC, dynamicLinkType.isDynamicLibrary()) - .getLibraries() - .toList(); + LibraryToLinkWrapper.convertLibraryToLinkWrapperListToLibraryToLinkList( + ccLinkingContext.getLibraries(), + linkingMode != LinkingMode.DYNAMIC, + dynamicLinkType.isDynamicLibrary()); dynamicLinkActionBuilder.addLinkParams( libraries, ccLinkingContext.getFlattenedUserLinkFlags(), diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingInfo.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingInfo.java deleted file mode 100644 index e53543a9088ec8..00000000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingInfo.java +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.lib.rules.cpp; - -import com.google.common.base.Objects; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Streams; -import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.rules.cpp.CcLinkParams.LinkOptions; -import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper.CcLinkingContext; -import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; -import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; -import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcLinkingInfoApi; -import com.google.devtools.build.lib.skylarkbuildapi.cpp.LibraryToLinkWrapperApi; -import com.google.devtools.build.lib.syntax.SkylarkList; -import java.util.Collection; - -/** Wrapper for every C++ linking provider. */ -@Immutable -@AutoCodec -public final class CcLinkingInfo implements CcLinkingInfoApi { - - public static final CcLinkingInfo EMPTY = - CcLinkingInfo.Builder.create() - .setStaticModeParamsForDynamicLibrary(CcLinkParams.EMPTY) - .setStaticModeParamsForExecutable(CcLinkParams.EMPTY) - .setDynamicModeParamsForDynamicLibrary(CcLinkParams.EMPTY) - .setDynamicModeParamsForExecutable(CcLinkParams.EMPTY) - .build(); - - private final CcLinkParams staticModeParamsForExecutable; - private final CcLinkParams staticModeParamsForDynamicLibrary; - private final CcLinkParams dynamicModeParamsForExecutable; - private final CcLinkParams dynamicModeParamsForDynamicLibrary; - - @AutoCodec.Instantiator - @VisibleForSerialization - CcLinkingInfo( - CcLinkParams staticModeParamsForExecutable, - CcLinkParams staticModeParamsForDynamicLibrary, - CcLinkParams dynamicModeParamsForExecutable, - CcLinkParams dynamicModeParamsForDynamicLibrary) { - this.staticModeParamsForExecutable = staticModeParamsForExecutable; - this.staticModeParamsForDynamicLibrary = staticModeParamsForDynamicLibrary; - this.dynamicModeParamsForExecutable = dynamicModeParamsForExecutable; - this.dynamicModeParamsForDynamicLibrary = dynamicModeParamsForDynamicLibrary; - } - - public CcLinkParams getStaticModeParamsForExecutable() { - return staticModeParamsForExecutable; - } - - public CcLinkParams getStaticModeParamsForDynamicLibrary() { - return staticModeParamsForDynamicLibrary; - } - - public CcLinkParams getDynamicModeParamsForExecutable() { - return dynamicModeParamsForExecutable; - } - - public CcLinkParams getDynamicModeParamsForDynamicLibrary() { - return dynamicModeParamsForDynamicLibrary; - } - - @Override - public SkylarkList getSkylarkUserLinkFlags() { - CcLinkingContext ccLinkingContext = LibraryToLinkWrapper.fromCcLinkingInfo(this); - return SkylarkList.createImmutable( - Streams.stream(ccLinkingContext.getUserLinkFlags()) - .map(LinkOptions::get) - .flatMap(Collection::stream) - .collect(ImmutableList.toImmutableList())); - } - - @Override - public SkylarkList getSkylarkLibrariesToLink() { - CcLinkingContext ccLinkingContext = LibraryToLinkWrapper.fromCcLinkingInfo(this); - return SkylarkList.createImmutable(ccLinkingContext.getLibraries().toList()); - } - - public static CcLinkingInfo merge(Collection ccLinkingInfos) { - CcLinkParams.Builder staticModeParamsForDynamicLibraryBuilder = CcLinkParams.builder(); - CcLinkParams.Builder staticModeParamsForExecutableBuilder = CcLinkParams.builder(); - CcLinkParams.Builder dynamicModeParamsForDynamicLibraryBuilder = CcLinkParams.builder(); - CcLinkParams.Builder dynamicModeParamsForExecutableBuilder = CcLinkParams.builder(); - for (CcLinkingInfo ccLinkingInfo : ccLinkingInfos) { - staticModeParamsForDynamicLibraryBuilder.addTransitiveArgs( - ccLinkingInfo.getStaticModeParamsForDynamicLibrary()); - staticModeParamsForExecutableBuilder.addTransitiveArgs( - ccLinkingInfo.getStaticModeParamsForExecutable()); - dynamicModeParamsForDynamicLibraryBuilder.addTransitiveArgs( - ccLinkingInfo.getDynamicModeParamsForDynamicLibrary()); - dynamicModeParamsForExecutableBuilder.addTransitiveArgs( - ccLinkingInfo.getDynamicModeParamsForExecutable()); - } - return new CcLinkingInfo.Builder() - .setStaticModeParamsForDynamicLibrary(staticModeParamsForDynamicLibraryBuilder.build()) - .setStaticModeParamsForExecutable(staticModeParamsForExecutableBuilder.build()) - .setDynamicModeParamsForDynamicLibrary(dynamicModeParamsForDynamicLibraryBuilder.build()) - .setDynamicModeParamsForExecutable(dynamicModeParamsForExecutableBuilder.build()) - .build(); - } - - public CcLinkParams getCcLinkParams(boolean staticMode, boolean forDynamicLibrary) { - if (staticMode) { - if (forDynamicLibrary) { - return getStaticModeParamsForDynamicLibrary(); - } else { - return getStaticModeParamsForExecutable(); - } - } else { - if (forDynamicLibrary) { - return getDynamicModeParamsForDynamicLibrary(); - } else { - return getDynamicModeParamsForExecutable(); - } - } - } - - /** A Builder for {@link CcLinkingInfo}. */ - public static class Builder { - CcLinkParams staticModeParamsForDynamicLibrary; - CcLinkParams staticModeParamsForExecutable; - CcLinkParams dynamicModeParamsForDynamicLibrary; - CcLinkParams dynamicModeParamsForExecutable; - - public static CcLinkingInfo.Builder create() { - return new CcLinkingInfo.Builder(); - } - - public Builder setStaticModeParamsForDynamicLibrary(CcLinkParams ccLinkParams) { - Preconditions.checkState(this.staticModeParamsForDynamicLibrary == null); - this.staticModeParamsForDynamicLibrary = ccLinkParams; - return this; - } - - public Builder setStaticModeParamsForExecutable(CcLinkParams ccLinkParams) { - Preconditions.checkState(this.staticModeParamsForExecutable == null); - this.staticModeParamsForExecutable = ccLinkParams; - return this; - } - - public Builder setDynamicModeParamsForDynamicLibrary(CcLinkParams ccLinkParams) { - Preconditions.checkState(this.dynamicModeParamsForDynamicLibrary == null); - this.dynamicModeParamsForDynamicLibrary = ccLinkParams; - return this; - } - - public Builder setDynamicModeParamsForExecutable(CcLinkParams ccLinkParams) { - Preconditions.checkState(this.dynamicModeParamsForExecutable == null); - this.dynamicModeParamsForExecutable = ccLinkParams; - return this; - } - - public CcLinkingInfo build() { - Preconditions.checkNotNull(staticModeParamsForExecutable); - Preconditions.checkNotNull(staticModeParamsForDynamicLibrary); - Preconditions.checkNotNull(dynamicModeParamsForExecutable); - Preconditions.checkNotNull(dynamicModeParamsForDynamicLibrary); - return new CcLinkingInfo( - staticModeParamsForExecutable, - staticModeParamsForDynamicLibrary, - dynamicModeParamsForExecutable, - dynamicModeParamsForDynamicLibrary); - } - } - - @Override - public boolean equals(Object otherObject) { - if (!(otherObject instanceof CcLinkingInfo)) { - return false; - } - CcLinkingInfo other = (CcLinkingInfo) otherObject; - if (this == other) { - return true; - } - if (!this.staticModeParamsForExecutable.equals(other.staticModeParamsForExecutable) - || !this.staticModeParamsForDynamicLibrary.equals(other.staticModeParamsForDynamicLibrary) - || !this.dynamicModeParamsForExecutable.equals(other.dynamicModeParamsForExecutable) - || !this.dynamicModeParamsForDynamicLibrary.equals( - other.dynamicModeParamsForDynamicLibrary)) { - return false; - } - return true; - } - - @Override - public int hashCode() { - return Objects.hashCode( - staticModeParamsForExecutable, - staticModeParamsForDynamicLibrary, - dynamicModeParamsForExecutable, - dynamicModeParamsForDynamicLibrary); - } -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java index 301d3d79294f97..1eb9a6dcbdf4e5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java @@ -606,7 +606,7 @@ protected static LinkingInfo link( Object skylarkLinkopts, boolean shouldCreateStaticLibraries, Object dynamicLibrary, - SkylarkList skylarkCcLinkingInfos, + SkylarkList skylarkCcLinkingContexts, boolean neverLink) throws InterruptedException, EvalException, InterruptedException { CcCommon.checkRuleWhitelisted(skylarkRuleContext); @@ -628,7 +628,7 @@ protected static LinkingInfo link( .addLinkopts(linkopts) .setShouldCreateStaticLibraries(shouldCreateStaticLibraries) .setLinkerOutputArtifact(convertFromNoneable(dynamicLibrary, null)) - .addCcLinkingInfos(skylarkCcLinkingInfos) + .addCcLinkingContexts(skylarkCcLinkingContexts) .setNeverLink(neverLink); try { CcLinkingOutputs ccLinkingOutputs = CcLinkingOutputs.EMPTY; @@ -641,10 +641,10 @@ protected static LinkingInfo link( LibraryToLinkWrapper.convertLinkOutputsToLibraryToLinkWrapper(ccLinkingOutputs)); } } - CcLinkingInfo ccLinkingInfo = - helper.buildCcLinkingInfoFromLibraryToLinkWrappers( + CcLinkingContext ccLinkingContext = + helper.buildCcLinkingContextFromLibraryToLinkWrappers( libraryToLinkWrapperBuilder.build(), CcCompilationContext.EMPTY); - return new LinkingInfo(ccLinkingInfo, ccLinkingOutputs); + return new LinkingInfo(ccLinkingContext, ccLinkingOutputs); } catch (RuleErrorException e) { throw new EvalException(ruleContext.getRule().getLocation(), e); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProvider.java index d54a2b4c9720fc..e7eb2fb1a85591 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProvider.java @@ -55,9 +55,8 @@ public NestedSet getLibraries() { if (ccInfo == null) { return libs.build(); } - for (LinkerInput lib : - ccInfo.getCcLinkingInfo().getStaticModeParamsForExecutable().getLibraries()) { - libs.add(lib.getArtifact()); + for (Artifact lib : ccInfo.getCcLinkingContext().getStaticModeParamsForExecutableLibraries()) { + libs.add(lib); } return libs.build(); } @@ -68,7 +67,7 @@ public ImmutableList getLinkopts() { if (ccInfo == null) { return ImmutableList.of(); } - return ccInfo.getCcLinkingInfo().getStaticModeParamsForExecutable().flattenedLinkopts(); + return ccInfo.getCcLinkingContext().getFlattenedUserLinkFlags(); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java index 51c470ab8339a8..c785c20cb913fe 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java @@ -34,6 +34,7 @@ import com.google.devtools.build.lib.packages.RuleErrorConsumer; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration; import com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper.CcLinkingContext; import com.google.devtools.build.lib.rules.cpp.Link.LinkingMode; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcToolchainProviderApi; @@ -196,7 +197,7 @@ public CcToolchainProvider( this.ccInfo = CcInfo.builder() .setCcCompilationContext(Preconditions.checkNotNull(ccCompilationContext)) - .setCcLinkingInfo(CcLinkingInfo.EMPTY) + .setCcLinkingContext(CcLinkingContext.EMPTY) .build(); this.supportsParamFiles = supportsParamFiles; this.supportsHeaderParsing = supportsHeaderParsing; diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java index 9cf696e5dbce29..bd0ac8a9272c43 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java @@ -399,11 +399,10 @@ public static final Function runfilesFunctio // Cannot add libraries directly because the nested set has link order. NestedSet dynamicLibrariesForRuntime = NestedSetBuilder.stableOrder() - .addTransitive( + .addAll( provider - .getCcLinkingInfo() - .getDynamicModeParamsForExecutable() - .getDynamicLibrariesForRuntime()) + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ false)) .build(); return new Runfiles.Builder(ruleContext.getWorkspaceName()) .addTransitiveArtifacts(dynamicLibrariesForRuntime) @@ -420,11 +419,10 @@ public static final Function runfilesFunctio // Cannot add libraries directly because the nested set has link order. NestedSet dynamicLibrariesForRuntime = NestedSetBuilder.stableOrder() - .addTransitive( + .addAll( provider - .getCcLinkingInfo() - .getStaticModeParamsForExecutable() - .getDynamicLibrariesForRuntime()) + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ true)) .build(); return new Runfiles.Builder(ruleContext.getWorkspaceName()) .addTransitiveArtifacts(dynamicLibrariesForRuntime) diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java index 73a48b29780774..0a5a3a92fa95e4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java @@ -112,6 +112,8 @@ public Artifact create( private final Set objectFiles = new LinkedHashSet<>(); private final Set nonCodeInputs = new LinkedHashSet<>(); private final NestedSetBuilder libraries = NestedSetBuilder.linkOrder(); + private final NestedSetBuilder libraryToLinkWrappers = + NestedSetBuilder.linkOrder(); private NestedSet linkerFiles = NestedSetBuilder.emptySet(Order.STABLE_ORDER); private Artifact runtimeMiddleman; private ArtifactCategory toolchainLibrariesType = null; @@ -576,8 +578,63 @@ boolean canSplitCommandLine() { } } + private List convertLibraryToLinkWrapperListToLibraryToLinkList( + NestedSet libraryToLinkWrappers) { + ImmutableList.Builder librariesToLink = ImmutableList.builder(); + for (LibraryToLinkWrapper libraryToLinkWrapper : libraryToLinkWrappers) { + LibraryToLink staticLibraryToLink = + libraryToLinkWrapper.getStaticLibrary() == null + ? null + : libraryToLinkWrapper.getStaticLibraryToLink(); + LibraryToLink picStaticLibraryToLink = + libraryToLinkWrapper.getPicStaticLibrary() == null + ? null + : libraryToLinkWrapper.getPicStaticLibraryToLink(); + LibraryToLink libraryToLinkToUse = null; + if (linkingMode == LinkingMode.STATIC) { + if (linkType.isDynamicLibrary()) { + if (picStaticLibraryToLink != null) { + libraryToLinkToUse = picStaticLibraryToLink; + } else if (staticLibraryToLink != null) { + libraryToLinkToUse = staticLibraryToLink; + } + } else { + if (staticLibraryToLink != null) { + libraryToLinkToUse = staticLibraryToLink; + } else if (picStaticLibraryToLink != null) { + libraryToLinkToUse = picStaticLibraryToLink; + } + } + } + if (libraryToLinkToUse == null) { + if (libraryToLinkWrapper.getInterfaceLibrary() != null) { + libraryToLinkToUse = libraryToLinkWrapper.getInterfaceLibraryToLink(); + } else if (libraryToLinkWrapper.getDynamicLibrary() != null) { + libraryToLinkToUse = libraryToLinkWrapper.getDynamicLibraryToLink(); + } + } + Preconditions.checkNotNull(libraryToLinkToUse); + checkLibrary(libraryToLinkToUse); + librariesToLink.add(libraryToLinkToUse); + } + return librariesToLink.build(); + } + /** Builds the Action as configured and returns it. */ public CppLinkAction build() throws InterruptedException { + NestedSet originalUniqueLibraries = null; + + if (libraryToLinkWrappers.isEmpty()) { + originalUniqueLibraries = libraries.build(); + } else { + Preconditions.checkState(libraries.isEmpty()); + originalUniqueLibraries = + NestedSetBuilder.linkOrder() + .addAll( + convertLibraryToLinkWrapperListToLibraryToLinkList(libraryToLinkWrappers.build())) + .build(); + } + // Executable links do not have library identifiers. boolean hasIdentifier = (libraryIdentifier != null); boolean isExecutable = linkType.isExecutable(); @@ -630,8 +687,6 @@ public CppLinkAction build() throws InterruptedException { includeLinkStaticInLtoIndexing || (linkingMode == Link.LinkingMode.DYNAMIC && !ltoCompilationContext.isEmpty()); - NestedSet originalUniqueLibraries = libraries.build(); - PathFragment ltoOutputRootPrefix = null; if (isLtoIndexing) { Preconditions.checkState(allLtoArtifacts == null); @@ -1316,6 +1371,7 @@ public CppLinkActionBuilder addLibrary(LibraryToLink input) { * libraries. */ public CppLinkActionBuilder addLibraries(Iterable inputs) { + Preconditions.checkState(libraryToLinkWrappers.isEmpty()); for (LibraryToLink input : inputs) { checkLibrary(input); if (input.isMustKeepDebug()) { @@ -1326,6 +1382,17 @@ public CppLinkActionBuilder addLibraries(Iterable inputs) { return this; } + public CppLinkActionBuilder addLibraryToLinkWrappers(Iterable inputs) { + Preconditions.checkState(libraries.isEmpty()); + for (LibraryToLinkWrapper input : inputs) { + if (input.getMustKeepDebug()) { + mustKeepDebug = true; + } + } + this.libraryToLinkWrappers.addAll(inputs); + return this; + } + /** * Sets the type of ELF file to be created (.a, .so, .lo, executable). The default is {@link * LinkTargetType#STATIC_LIBRARY}. diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/ExtraLinkTimeLibraries.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/ExtraLinkTimeLibraries.java index 997ef10a8acdf9..9f53944b6eb8d5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/ExtraLinkTimeLibraries.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/ExtraLinkTimeLibraries.java @@ -20,7 +20,6 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; import com.google.devtools.build.lib.rules.cpp.ExtraLinkTimeLibrary.BuildLibraryOutput; -import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; import java.util.Collection; @@ -107,7 +106,7 @@ public final Builder add(ExtraLinkTimeLibrary b) { public BuildLibraryOutput buildLibraries( RuleContext ruleContext, boolean staticMode, boolean forDynamicLibrary) throws InterruptedException, RuleErrorException { - NestedSetBuilder librariesToLink = NestedSetBuilder.linkOrder(); + NestedSetBuilder librariesToLink = NestedSetBuilder.linkOrder(); NestedSetBuilder runtimeLibraries = NestedSetBuilder.linkOrder(); for (ExtraLinkTimeLibrary extraLibrary : getExtraLibraries()) { BuildLibraryOutput buildLibraryOutput = diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/ExtraLinkTimeLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/ExtraLinkTimeLibrary.java index fab76f856af2f9..28722fb0334cf0 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/ExtraLinkTimeLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/ExtraLinkTimeLibrary.java @@ -18,7 +18,6 @@ import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; -import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; /** * An extra library to include in a link. The actual library is built at link time. @@ -34,16 +33,16 @@ public interface ExtraLinkTimeLibrary { /** Output of {@link #buildLibraries}. Pair of libraries to link and runtime libraries. */ class BuildLibraryOutput { - public NestedSet librariesToLink; + public NestedSet librariesToLink; public NestedSet runtimeLibraries; public BuildLibraryOutput( - NestedSet librariesToLink, NestedSet runtimeLibraries) { + NestedSet librariesToLink, NestedSet runtimeLibraries) { this.librariesToLink = librariesToLink; this.runtimeLibraries = runtimeLibraries; } - public NestedSet getLibrariesToLink() { + public NestedSet getLibrariesToLink() { return librariesToLink; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/LibraryToLinkWrapper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/LibraryToLinkWrapper.java index 0d1057bc42d06f..b585b6999de1ee 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/LibraryToLinkWrapper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/LibraryToLinkWrapper.java @@ -13,12 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +import com.google.common.base.Objects; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import com.google.common.collect.Streams; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.collect.nestedset.NestedSet; @@ -32,7 +31,6 @@ import com.google.devtools.build.lib.syntax.SkylarkList; import com.google.devtools.build.lib.vfs.FileSystemUtils; import java.util.Collection; -import java.util.Iterator; import java.util.List; import java.util.ListIterator; import javax.annotation.Nullable; @@ -118,11 +116,78 @@ public static LibraryToLinkWrapper convertLinkOutputsToLibraryToLinkWrapper( return libraryToLinkWrapperBuilder.build(); } - public Artifact getDynamicLibraryForRuntimeOrNull() { - if (staticLibrary == null && picStaticLibrary == null && dynamicLibrary != null) { - return dynamicLibrary; + public static List convertLibraryToLinkWrapperListToLibraryToLinkList( + NestedSet libraryToLinkWrappers, + boolean staticMode, + boolean forDynamicLibrary) { + ImmutableList.Builder librariesToLink = ImmutableList.builder(); + for (LibraryToLinkWrapper libraryToLinkWrapper : libraryToLinkWrappers) { + LibraryToLink staticLibraryToLink = + libraryToLinkWrapper.getStaticLibrary() == null + ? null + : libraryToLinkWrapper.getStaticLibraryToLink(); + LibraryToLink picStaticLibraryToLink = + libraryToLinkWrapper.getPicStaticLibrary() == null + ? null + : libraryToLinkWrapper.getPicStaticLibraryToLink(); + LibraryToLink libraryToLinkToUse = null; + if (staticMode) { + if (forDynamicLibrary) { + if (picStaticLibraryToLink != null) { + libraryToLinkToUse = picStaticLibraryToLink; + } else if (staticLibraryToLink != null) { + libraryToLinkToUse = staticLibraryToLink; + } + } else { + if (staticLibraryToLink != null) { + libraryToLinkToUse = staticLibraryToLink; + } else if (picStaticLibraryToLink != null) { + libraryToLinkToUse = picStaticLibraryToLink; + } + } + if (libraryToLinkToUse == null) { + if (libraryToLinkWrapper.getInterfaceLibrary() != null) { + libraryToLinkToUse = libraryToLinkWrapper.getInterfaceLibraryToLink(); + } else if (libraryToLinkWrapper.getDynamicLibrary() != null) { + libraryToLinkToUse = libraryToLinkWrapper.getDynamicLibraryToLink(); + } + } + } else { + if (libraryToLinkWrapper.getInterfaceLibrary() != null) { + libraryToLinkToUse = libraryToLinkWrapper.getInterfaceLibraryToLink(); + } else if (libraryToLinkWrapper.getDynamicLibrary() != null) { + libraryToLinkToUse = libraryToLinkWrapper.getDynamicLibraryToLink(); + } + if (libraryToLinkToUse == null) { + if (forDynamicLibrary) { + if (picStaticLibraryToLink != null) { + libraryToLinkToUse = picStaticLibraryToLink; + } else if (staticLibraryToLink != null) { + libraryToLinkToUse = staticLibraryToLink; + } + } else { + if (staticLibraryToLink != null) { + libraryToLinkToUse = staticLibraryToLink; + } else if (picStaticLibraryToLink != null) { + libraryToLinkToUse = picStaticLibraryToLink; + } + } + } + } + Preconditions.checkNotNull(libraryToLinkToUse); + librariesToLink.add(libraryToLinkToUse); } - return null; + return librariesToLink.build(); + } + + public Artifact getDynamicLibraryForRuntimeOrNull(boolean linkingStatically) { + if (dynamicLibrary == null) { + return null; + } + if (linkingStatically && (staticLibrary != null || picStaticLibrary != null)) { + return null; + } + return dynamicLibrary; } /** Structure of the new CcLinkingContext. This will replace {@link CcLinkingInfo}. */ @@ -148,10 +213,27 @@ public CcLinkingContext( this.extraLinkTimeLibraries = extraLinkTimeLibraries; } - private static List getStaticModeParamsForExecutableLibraries( - CcLinkingContext ccLinkingContext) { + public static CcLinkingContext merge(List ccLinkingContexts) { + CcLinkingContext.Builder mergedCcLinkingContext = CcLinkingContext.builder(); + ExtraLinkTimeLibraries.Builder mergedExtraLinkTimeLibraries = + ExtraLinkTimeLibraries.builder(); + for (CcLinkingContext ccLinkingContext : ccLinkingContexts) { + mergedCcLinkingContext + .addLibraries(ccLinkingContext.getLibraries()) + .addUserLinkFlags(ccLinkingContext.getUserLinkFlags()) + .addLinkstamps(ccLinkingContext.getLinkstamps()) + .addNonCodeInputs(ccLinkingContext.getNonCodeInputs()); + if (ccLinkingContext.getExtraLinkTimeLibraries() != null) { + mergedExtraLinkTimeLibraries.addTransitive(ccLinkingContext.getExtraLinkTimeLibraries()); + } + } + mergedCcLinkingContext.setExtraLinkTimeLibraries(mergedExtraLinkTimeLibraries.build()); + return mergedCcLinkingContext.build(); + } + + public List getStaticModeParamsForExecutableLibraries() { ImmutableList.Builder libraryListBuilder = ImmutableList.builder(); - for (LibraryToLinkWrapper libraryToLinkWrapper : ccLinkingContext.getLibraries()) { + for (LibraryToLinkWrapper libraryToLinkWrapper : getLibraries()) { if (libraryToLinkWrapper.getStaticLibrary() != null) { libraryListBuilder.add(libraryToLinkWrapper.getStaticLibrary()); } else if (libraryToLinkWrapper.getPicStaticLibrary() != null) { @@ -165,13 +247,64 @@ private static List getStaticModeParamsForExecutableLibraries( return libraryListBuilder.build(); } - public static List getStaticModeParamsForExecutableLibraries(CcInfo ccInfo) { - return getStaticModeParamsForExecutableLibraries(ccInfo.getCcLinkingContext()); + public List getStaticModeParamsForDynamicLibraryLibraries() { + ImmutableList.Builder artifactListBuilder = ImmutableList.builder(); + for (LibraryToLinkWrapper library : getLibraries()) { + if (library.getPicStaticLibrary() != null) { + artifactListBuilder.add(library.getPicStaticLibrary()); + } else if (library.getStaticLibrary() != null) { + artifactListBuilder.add(library.getStaticLibrary()); + } else if (library.getInterfaceLibrary() != null) { + artifactListBuilder.add(library.getInterfaceLibrary()); + } else { + artifactListBuilder.add(library.getDynamicLibrary()); + } + } + return artifactListBuilder.build(); + } + + public List getDynamicModeParamsForExecutableLibraries() { + ImmutableList.Builder artifactListBuilder = ImmutableList.builder(); + for (LibraryToLinkWrapper library : getLibraries()) { + if (library.getInterfaceLibrary() != null) { + artifactListBuilder.add(library.getInterfaceLibrary()); + } else if (library.getDynamicLibrary() != null) { + artifactListBuilder.add(library.getDynamicLibrary()); + } else if (library.getStaticLibrary() != null) { + artifactListBuilder.add(library.getStaticLibrary()); + } else if (library.getPicStaticLibrary() != null) { + artifactListBuilder.add(library.getPicStaticLibrary()); + } + } + return artifactListBuilder.build(); + } + + public List getDynamicModeParamsForDynamicLibraryLibraries() { + ImmutableList.Builder artifactListBuilder = ImmutableList.builder(); + for (LibraryToLinkWrapper library : getLibraries()) { + if (library.getInterfaceLibrary() != null) { + artifactListBuilder.add(library.getInterfaceLibrary()); + } else if (library.getDynamicLibrary() != null) { + artifactListBuilder.add(library.getDynamicLibrary()); + } else if (library.getPicStaticLibrary() != null) { + artifactListBuilder.add(library.getPicStaticLibrary()); + } else if (library.getStaticLibrary() != null) { + artifactListBuilder.add(library.getStaticLibrary()); + } + } + return artifactListBuilder.build(); } - public static List getStaticModeParamsForExecutableLibraries( - CcLinkingInfo ccLinkingInfo) { - return getStaticModeParamsForExecutableLibraries(fromCcLinkingInfo(ccLinkingInfo)); + public List getDynamicLibrariesForRuntime(boolean linkingStatically) { + ImmutableList.Builder dynamicLibrariesForRuntimeBuilder = ImmutableList.builder(); + for (LibraryToLinkWrapper libraryToLinkWrapper : libraries) { + Artifact artifact = + libraryToLinkWrapper.getDynamicLibraryForRuntimeOrNull(linkingStatically); + if (artifact != null) { + dynamicLibrariesForRuntimeBuilder.add(artifact); + } + } + return dynamicLibrariesForRuntimeBuilder.build(); } public NestedSet getLibraries() { @@ -211,16 +344,6 @@ public ExtraLinkTimeLibraries getExtraLinkTimeLibraries() { return extraLinkTimeLibraries; } - public CcLinkingInfo toCcLinkingInfo() { - return LibraryToLinkWrapper.toCcLinkingInfo( - /* forcePic= */ false, - ImmutableList.copyOf(libraries), - userLinkFlags, - linkstamps, - nonCodeInputs, - extraLinkTimeLibraries); - } - public static Builder builder() { return new Builder(); } @@ -268,6 +391,33 @@ public CcLinkingContext build() { extraLinkTimeLibraries); } } + + @Override + public boolean equals(Object otherObject) { + if (!(otherObject instanceof CcLinkingContext)) { + return false; + } + CcLinkingContext other = (CcLinkingContext) otherObject; + if (this == other) { + return true; + } + if (!this.libraries.shallowEquals(other.libraries) + || !this.userLinkFlags.shallowEquals(other.userLinkFlags) + || !this.linkstamps.shallowEquals(other.linkstamps) + || !this.nonCodeInputs.shallowEquals(other.nonCodeInputs)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return Objects.hashCode( + libraries.shallowHashCode(), + userLinkFlags.shallowHashCode(), + linkstamps.shallowHashCode(), + nonCodeInputs.shallowHashCode()); + } } private final String libraryIdentifier; @@ -378,269 +528,40 @@ public Artifact getDynamicLibrary() { return dynamicLibrary; } + public Artifact getResolvedSymlinkDynamicLibrary() { + return resolvedSymlinkDynamicLibrary; + } + @Override public Artifact getInterfaceLibrary() { return interfaceLibrary; } + public Artifact getResolvedSymlinkInterfaceLibrary() { + return resolvedSymlinkInterfaceLibrary; + } + @Override public boolean getAlwayslink() { return alwayslink; } - public static Builder builder() { - return new Builder(); - } - - public static CcLinkingInfo toCcLinkingInfo( - boolean forcePic, - ImmutableCollection libraryToLinkWrappers, - NestedSet linkOpts, - NestedSet linkstamps, - Iterable nonCodeInputs, - ExtraLinkTimeLibraries extraLinkTimeLibraries) { - CcLinkParams staticModeParamsForDynamicLibrary = - buildStaticModeParamsForDynamicLibraryCcLinkParams( - libraryToLinkWrappers, linkOpts, linkstamps, nonCodeInputs, extraLinkTimeLibraries); - - CcLinkParams staticModeParamsForExecutable; - if (forcePic) { - staticModeParamsForExecutable = staticModeParamsForDynamicLibrary; - } else { - staticModeParamsForExecutable = - buildStaticModeParamsForExecutableCcLinkParams( - libraryToLinkWrappers, linkOpts, linkstamps, nonCodeInputs, extraLinkTimeLibraries); - } - - CcLinkParams dynamicModeParamsForDynamicLibrary = - buildDynamicModeParamsForDynamicLibraryCcLinkParams( - libraryToLinkWrappers, linkOpts, linkstamps, nonCodeInputs, extraLinkTimeLibraries); - CcLinkParams dynamicModeParamsForExecutable; - if (forcePic) { - dynamicModeParamsForExecutable = dynamicModeParamsForDynamicLibrary; - } else { - dynamicModeParamsForExecutable = - buildDynamicModeParamsForExecutableCcLinkParams( - libraryToLinkWrappers, linkOpts, linkstamps, nonCodeInputs, extraLinkTimeLibraries); - } - - CcLinkingInfo.Builder ccLinkingInfoBuilder = - new CcLinkingInfo.Builder() - .setStaticModeParamsForExecutable(staticModeParamsForExecutable) - .setStaticModeParamsForDynamicLibrary(staticModeParamsForDynamicLibrary) - .setDynamicModeParamsForExecutable(dynamicModeParamsForExecutable) - .setDynamicModeParamsForDynamicLibrary(dynamicModeParamsForDynamicLibrary); - return ccLinkingInfoBuilder.build(); - } - - /** - * WARNING: If CcLinkingInfo contains linking parameters from transitive closure, this method will - * be very expensive to execute because of nested set flattening. Should only be called by top - * level targets that do transitive linking when the nested sets have to be flattened anyway. - */ - public static CcLinkingContext fromCcLinkingInfo(CcLinkingInfo ccLinkingInfo) { - CcLinkingContext.Builder ccLinkingContextBuilder = CcLinkingContext.builder(); - CcLinkParams staticModeParamsForExecutable = ccLinkingInfo.getStaticModeParamsForExecutable(); - CcLinkParams staticModeParamsForDynamicLibrary = - ccLinkingInfo.getStaticModeParamsForDynamicLibrary(); - CcLinkParams dynamicModeParamsForExecutable = ccLinkingInfo.getDynamicModeParamsForExecutable(); - CcLinkParams dynamicModeParamsForDynamicLibrary = - ccLinkingInfo.getDynamicModeParamsForDynamicLibrary(); - - ccLinkingContextBuilder.addUserLinkFlags( - getUserLinkFlags( - staticModeParamsForExecutable, - staticModeParamsForDynamicLibrary, - dynamicModeParamsForExecutable, - dynamicModeParamsForDynamicLibrary)); - - ccLinkingContextBuilder.addLinkstamps( - getLinkstamps( - staticModeParamsForExecutable, - staticModeParamsForDynamicLibrary, - dynamicModeParamsForExecutable, - dynamicModeParamsForDynamicLibrary)); - - ccLinkingContextBuilder.addNonCodeInputs( - getNonCodeInputs( - staticModeParamsForExecutable, - staticModeParamsForDynamicLibrary, - dynamicModeParamsForExecutable, - dynamicModeParamsForDynamicLibrary)); - - ccLinkingContextBuilder.setExtraLinkTimeLibraries( - getExtraLinkTimeLibraries( - staticModeParamsForExecutable, - staticModeParamsForDynamicLibrary, - dynamicModeParamsForExecutable, - dynamicModeParamsForDynamicLibrary)); - - ccLinkingContextBuilder.addLibraries( - getLibraries( - staticModeParamsForExecutable, - staticModeParamsForDynamicLibrary, - dynamicModeParamsForExecutable, - dynamicModeParamsForDynamicLibrary)); - return ccLinkingContextBuilder.build(); - } - - private static void checkAllSizesMatch( - int staticModeForExecutable, - int staticModeForDynamicLibrary, - int dynamicModeForExecutable, - int dynamicModeForDynamicLibrary) { - Preconditions.checkState( - staticModeForExecutable == staticModeForDynamicLibrary - && staticModeForDynamicLibrary == dynamicModeForExecutable - && dynamicModeForExecutable == dynamicModeForDynamicLibrary); - } - - private static ExtraLinkTimeLibraries getExtraLinkTimeLibraries( - CcLinkParams staticModeParamsForExecutable, - CcLinkParams staticModeParamsForDynamicLibrary, - CcLinkParams dynamicModeParamsForExecutable, - CcLinkParams dynamicModeParamsForDynamicLibrary) { - Preconditions.checkState( - (staticModeParamsForExecutable.getExtraLinkTimeLibraries() == null - && staticModeParamsForDynamicLibrary.getExtraLinkTimeLibraries() == null) - || (staticModeParamsForExecutable.getExtraLinkTimeLibraries().getExtraLibraries().size() - == staticModeParamsForDynamicLibrary - .getExtraLinkTimeLibraries() - .getExtraLibraries() - .size())); - - Preconditions.checkState( - (staticModeParamsForDynamicLibrary.getExtraLinkTimeLibraries() == null - && dynamicModeParamsForExecutable.getExtraLinkTimeLibraries() == null) - || (staticModeParamsForDynamicLibrary - .getExtraLinkTimeLibraries() - .getExtraLibraries() - .size() - == dynamicModeParamsForExecutable - .getExtraLinkTimeLibraries() - .getExtraLibraries() - .size())); - Preconditions.checkState( - (dynamicModeParamsForExecutable.getExtraLinkTimeLibraries() == null - && dynamicModeParamsForDynamicLibrary.getExtraLinkTimeLibraries() == null) - || (dynamicModeParamsForExecutable - .getExtraLinkTimeLibraries() - .getExtraLibraries() - .size() - == dynamicModeParamsForDynamicLibrary - .getExtraLinkTimeLibraries() - .getExtraLibraries() - .size())); - return staticModeParamsForExecutable.getExtraLinkTimeLibraries(); - } - - private static NestedSet getUserLinkFlags( - CcLinkParams staticModeParamsForExecutable, - CcLinkParams staticModeParamsForDynamicLibrary, - CcLinkParams dynamicModeParamsForExecutable, - CcLinkParams dynamicModeParamsForDynamicLibrary) { - checkAllSizesMatch( - staticModeParamsForExecutable.flattenedLinkopts().size(), - staticModeParamsForDynamicLibrary.flattenedLinkopts().size(), - dynamicModeParamsForExecutable.flattenedLinkopts().size(), - dynamicModeParamsForDynamicLibrary.flattenedLinkopts().size()); - return staticModeParamsForExecutable.getLinkopts(); + public boolean getMustKeepDebug() { + return mustKeepDebug; } - private static NestedSet getLinkstamps( - CcLinkParams staticModeParamsForExecutable, - CcLinkParams staticModeParamsForDynamicLibrary, - CcLinkParams dynamicModeParamsForExecutable, - CcLinkParams dynamicModeParamsForDynamicLibrary) { - checkAllSizesMatch( - staticModeParamsForExecutable.getLinkstamps().toList().size(), - staticModeParamsForDynamicLibrary.getLinkstamps().toList().size(), - dynamicModeParamsForExecutable.getLinkstamps().toList().size(), - dynamicModeParamsForDynamicLibrary.getLinkstamps().toList().size()); - return staticModeParamsForExecutable.getLinkstamps(); - } - - private static NestedSet getNonCodeInputs( - CcLinkParams staticModeParamsForExecutable, - CcLinkParams staticModeParamsForDynamicLibrary, - CcLinkParams dynamicModeParamsForExecutable, - CcLinkParams dynamicModeParamsForDynamicLibrary) { - NestedSet seNonCodeInputs = staticModeParamsForExecutable.getNonCodeInputs(); - NestedSet sdNonCodeInputs = staticModeParamsForDynamicLibrary.getNonCodeInputs(); - NestedSet deNonCodeInputs = dynamicModeParamsForExecutable.getNonCodeInputs(); - NestedSet ddNonCodeInputs = dynamicModeParamsForDynamicLibrary.getNonCodeInputs(); - Preconditions.checkState( - !(seNonCodeInputs == null - || sdNonCodeInputs == null - || deNonCodeInputs == null - || ddNonCodeInputs == null) - || (seNonCodeInputs == null - && sdNonCodeInputs == null - && deNonCodeInputs == null - && ddNonCodeInputs == null)); - if (sdNonCodeInputs == null) { - return NestedSetBuilder.linkOrder().build(); - } - checkAllSizesMatch( - sdNonCodeInputs.toList().size(), - deNonCodeInputs.toList().size(), - deNonCodeInputs.toList().size(), - ddNonCodeInputs.toList().size()); - return staticModeParamsForExecutable.getNonCodeInputs(); - } - - @Nullable - private static String setStaticArtifactsAndReturnIdentifier( - LibraryToLinkWrapper.Builder libraryToLinkWrapperBuilder, - LibraryToLink staticModeParamsForExecutableEntry, - LibraryToLink staticModeParamsForDynamicLibraryEntry) { - LibraryToLinkByPicness noPicAndPicStaticLibraryToLink = - returnNoPicAndPicStaticLibraryToLink( - staticModeParamsForExecutableEntry, staticModeParamsForDynamicLibraryEntry); - String libraryIdentifier = null; - LibraryToLink noPicStaticLibrary = noPicAndPicStaticLibraryToLink.getNoPicLibrary(); - if (noPicStaticLibrary != null) { - libraryToLinkWrapperBuilder.setStaticLibrary(noPicStaticLibrary.getArtifact()); - libraryIdentifier = noPicStaticLibrary.getLibraryIdentifier(); - if (noPicStaticLibrary.containsObjectFiles()) { - libraryToLinkWrapperBuilder.setObjectFiles(noPicStaticLibrary.getObjectFiles()); - } - libraryToLinkWrapperBuilder.setLtoCompilationContext( - noPicStaticLibrary.getLtoCompilationContext()); - libraryToLinkWrapperBuilder.setSharedNonLtoBackends( - noPicStaticLibrary.getSharedNonLtoBackends()); - libraryToLinkWrapperBuilder.setAlwayslink( - noPicStaticLibrary.getArtifactCategory() == ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY); - } - LibraryToLink picStaticLibrary = noPicAndPicStaticLibraryToLink.getPicLibrary(); - if (picStaticLibrary != null) { - libraryToLinkWrapperBuilder.setPicStaticLibrary(picStaticLibrary.getArtifact()); - if (libraryIdentifier == null) { - libraryIdentifier = picStaticLibrary.getLibraryIdentifier(); - } else { - Preconditions.checkState(libraryIdentifier.equals(picStaticLibrary.getLibraryIdentifier())); - } - if (picStaticLibrary.containsObjectFiles()) { - libraryToLinkWrapperBuilder.setPicObjectFiles(picStaticLibrary.getObjectFiles()); - } - libraryToLinkWrapperBuilder.setPicLtoCompilationContext( - picStaticLibrary.getLtoCompilationContext()); - libraryToLinkWrapperBuilder.setPicSharedNonLtoBackends( - picStaticLibrary.getSharedNonLtoBackends()); - libraryToLinkWrapperBuilder.setAlwayslink( - picStaticLibrary.getArtifactCategory() == ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY); - } - - return libraryIdentifier; + public static Builder builder() { + return new Builder(); } @Nullable @SuppressWarnings("ReferenceEquality") - private static String setDynamicArtifactsAndReturnIdentifier( + public static String setDynamicArtifactsAndReturnIdentifier( LibraryToLinkWrapper.Builder libraryToLinkWrapperBuilder, LibraryToLink dynamicModeParamsForExecutableEntry, LibraryToLink dynamicModeParamsForDynamicLibraryEntry, ListIterator runtimeLibraryIterator) { + Preconditions.checkNotNull(runtimeLibraryIterator); Artifact artifact = dynamicModeParamsForExecutableEntry.getArtifact(); String libraryIdentifier = null; Artifact runtimeArtifact = null; @@ -711,166 +632,6 @@ private static String setDynamicArtifactsAndReturnIdentifier( return libraryIdentifier; } - private static NestedSet getLibraries( - CcLinkParams staticModeParamsForExecutable, - CcLinkParams staticModeParamsForDynamicLibrary, - CcLinkParams dynamicModeParamsForExecutable, - CcLinkParams dynamicModeParamsForDynamicLibrary) { - Iterator staticModeParamsForExecutableIterator = - staticModeParamsForExecutable.getLibraries().iterator(); - Iterator staticModeParamsForDynamicLibraryIterator = - staticModeParamsForDynamicLibrary.getLibraries().iterator(); - Iterator dynamicModeParamsForExecutableIterator = - dynamicModeParamsForExecutable.getLibraries().iterator(); - Iterator dynamicModeParamsForDynamicLibraryIterator = - dynamicModeParamsForDynamicLibrary.getLibraries().iterator(); - - ListIterator runtimeLibraryIterator = - dynamicModeParamsForExecutable.getDynamicLibrariesForRuntime().toList().listIterator(); - - NestedSetBuilder libraryToLinkWrappers = NestedSetBuilder.linkOrder(); - while (staticModeParamsForExecutableIterator.hasNext() - && staticModeParamsForDynamicLibraryIterator.hasNext() - && dynamicModeParamsForExecutableIterator.hasNext() - && dynamicModeParamsForDynamicLibraryIterator.hasNext()) { - LibraryToLinkWrapper.Builder libraryToLinkWrapperBuilder = LibraryToLinkWrapper.builder(); - LibraryToLink staticModeParamsForExecutableEntry = - staticModeParamsForExecutableIterator.next(); - LibraryToLink staticModeParamsForDynamicLibraryEntry = - staticModeParamsForDynamicLibraryIterator.next(); - - String identifier = - setStaticArtifactsAndReturnIdentifier( - libraryToLinkWrapperBuilder, - staticModeParamsForExecutableEntry, - staticModeParamsForDynamicLibraryEntry); - - LibraryToLink dynamicModeParamsForExecutableEntry = - dynamicModeParamsForExecutableIterator.next(); - LibraryToLink dynamicModeParamsForDynamicLibraryEntry = - dynamicModeParamsForDynamicLibraryIterator.next(); - - String dynamicLibraryIdentifier = - setDynamicArtifactsAndReturnIdentifier( - libraryToLinkWrapperBuilder, - dynamicModeParamsForExecutableEntry, - dynamicModeParamsForDynamicLibraryEntry, - runtimeLibraryIterator); - - if (identifier == null) { - identifier = dynamicLibraryIdentifier; - } else { - Preconditions.checkState( - dynamicLibraryIdentifier == null || identifier.equals(dynamicLibraryIdentifier)); - } - - libraryToLinkWrapperBuilder.setLibraryIdentifier(identifier); - - Preconditions.checkState( - staticModeParamsForExecutableEntry.isMustKeepDebug() - == staticModeParamsForDynamicLibraryEntry.isMustKeepDebug() - && staticModeParamsForDynamicLibraryEntry.isMustKeepDebug() - == dynamicModeParamsForExecutableEntry.isMustKeepDebug() - && dynamicModeParamsForExecutableEntry.isMustKeepDebug() - == dynamicModeParamsForDynamicLibraryEntry.isMustKeepDebug()); - libraryToLinkWrapperBuilder.setMustKeepDebug( - staticModeParamsForExecutableEntry.isMustKeepDebug()); - - libraryToLinkWrappers.add(libraryToLinkWrapperBuilder.build()); - } - Preconditions.checkState( - !(staticModeParamsForExecutableIterator.hasNext() - || staticModeParamsForDynamicLibraryIterator.hasNext() - || dynamicModeParamsForExecutableIterator.hasNext() - || dynamicModeParamsForDynamicLibraryIterator.hasNext())); - return libraryToLinkWrappers.build(); - } - - private static class LibraryToLinkByPicness { - private final LibraryToLink noPicLibrary; - private final LibraryToLink picLibrary; - - private LibraryToLinkByPicness(LibraryToLink noPicLibrary, LibraryToLink picLibrary) { - this.noPicLibrary = noPicLibrary; - this.picLibrary = picLibrary; - } - - private LibraryToLink getNoPicLibrary() { - return noPicLibrary; - } - - private LibraryToLink getPicLibrary() { - return picLibrary; - } - } - - /** - * In the two static mode params objects of {@link CcLinkingInfo} we may have {@link - * LibraryToLink} objects that are static libraries. This method grabs two instances, each coming - * from one of the static mode params objects and returns a pair with a no-pic static - * LibraryToLink as the first element and a pic static LibraryToLink in the second element. - * - *

We know that for dynamic libraries we will always prefer the pic variant, so if the - * artifacts are different for the executable and for the dynamic library, then we know the former - * is the no-pic static library and the latter is the pic static library. - * - *

If the artifacts are the same, then we check if they have the extension .pic. If they do, - * then we know that there isn't a no-pic static library, so we return null for the first element. - * - *

If the artifacts are the same and they don't have the extension .pic. Then two of the - * following things could be happening: 1. The static library is no-pic and the pic static library - * wasn't generated. 2. The static library is pic and the no-pic static library wasn't generated. - * This can only be happening if we created the static library from {@link CcCompilationHelper}. - * When we create a static library from this class, the {@link LibraryToLink} will have the object - * files used to create the library. We can look at the extension of these objects file to decide - * if the library is pic or no-pic. If there are no object files, then the library must be no-pic. - */ - private static LibraryToLinkByPicness returnNoPicAndPicStaticLibraryToLink( - LibraryToLink fromStaticModeParamsForExecutable, - LibraryToLink fromStaticModeParamsForDynamicLibrary) { - if (fromStaticModeParamsForExecutable.getArtifactCategory() != ArtifactCategory.STATIC_LIBRARY - && fromStaticModeParamsForExecutable.getArtifactCategory() - != ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY) { - return new LibraryToLinkByPicness(/* noPicLibrary= */ null, /* picLibrary= */ null); - } - Preconditions.checkState( - fromStaticModeParamsForExecutable.getArtifactCategory() - == fromStaticModeParamsForDynamicLibrary.getArtifactCategory()); - Artifact artifactFromStaticModeParamsForExecutable = - fromStaticModeParamsForExecutable.getArtifact(); - Artifact artifactFromStaticModeParamsForDynamicLibrary = - fromStaticModeParamsForDynamicLibrary.getArtifact(); - if (artifactFromStaticModeParamsForExecutable - != artifactFromStaticModeParamsForDynamicLibrary) { - Preconditions.checkState( - !FileSystemUtils.removeExtension(artifactFromStaticModeParamsForExecutable.getFilename()) - .endsWith(".pic")); - Preconditions.checkState( - FileSystemUtils.removeExtension( - artifactFromStaticModeParamsForDynamicLibrary.getFilename()) - .endsWith(".pic")); - return new LibraryToLinkByPicness( - fromStaticModeParamsForExecutable, fromStaticModeParamsForDynamicLibrary); - } else if (FileSystemUtils.removeExtension( - artifactFromStaticModeParamsForExecutable.getFilename()) - .endsWith(".pic")) { - return new LibraryToLinkByPicness( - /* noPicLibrary= */ null, fromStaticModeParamsForDynamicLibrary); - } else if (fromStaticModeParamsForExecutable.containsObjectFiles() - && !Iterables.isEmpty(fromStaticModeParamsForExecutable.getObjectFiles()) - && FileSystemUtils.removeExtension( - Iterables.getFirst( - fromStaticModeParamsForExecutable.getObjectFiles(), - /* defaultValue= */ null) - .getFilename()) - .endsWith(".pic")) { - return new LibraryToLinkByPicness( - /* noPicLibrary= */ null, fromStaticModeParamsForDynamicLibrary); - } - return new LibraryToLinkByPicness( - fromStaticModeParamsForDynamicLibrary, /* picLibrary= */ null); - } - private static boolean doArtifactsHaveSameBasename(Artifact first, Artifact second) { String nameFirst = removeAllExtensions(first.getRootRelativePath().getPathString()); String nameSecond = removeAllExtensions(second.getRootRelativePath().getPathString()); @@ -887,138 +648,6 @@ private static String removeAllExtensions(String name) { return currentWithoutExtension; } - /** - * In this method and {@link #buildStaticModeParamsForDynamicLibraryCcLinkParams}, {@link - * #buildDynamicModeParamsForExecutableCcLinkParams} and {@link - * #buildDynamicModeParamsForDynamicLibraryCcLinkParams}, we add the ".a", ".pic.a" and/or ".so" - * files in appropriate order of preference depending on the link preferences. - * - *

For static libraries, first choice is the PIC or no-PIC static variable, depending on - * whether we prefer PIC or not. Even if we are using PIC, we still prefer the no PIC static - * variant than using a dynamic library, although this may be an error later. Best performance is - * obtained with no-PIC static libraries. If we don't have that we use the PIC variant, we can - * live with the extra overhead. - */ - private static CcLinkParams buildStaticModeParamsForExecutableCcLinkParams( - ImmutableCollection libraryToLinkWrappers, - NestedSet linkOpts, - NestedSet linkstamps, - Iterable nonCodeInputs, - ExtraLinkTimeLibraries extraLinkTimeLibraries) { - CcLinkParams.Builder ccLinkParamsBuilder = - initializeCcLinkParams(linkOpts, linkstamps, nonCodeInputs, extraLinkTimeLibraries); - for (LibraryToLinkWrapper libraryToLinkWrapper : libraryToLinkWrappers) { - boolean usedDynamic = false; - if (libraryToLinkWrapper.getStaticLibrary() != null) { - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getStaticLibraryToLink()); - } else if (libraryToLinkWrapper.getPicStaticLibrary() != null) { - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getPicStaticLibraryToLink()); - } else if (libraryToLinkWrapper.getInterfaceLibrary() != null) { - usedDynamic = true; - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getInterfaceLibraryToLink()); - } else if (libraryToLinkWrapper.getDynamicLibrary() != null) { - usedDynamic = true; - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getDynamicLibraryToLink()); - } - - if (usedDynamic && libraryToLinkWrapper.getDynamicLibrary() != null) { - ccLinkParamsBuilder.addDynamicLibrariesForRuntime( - ImmutableList.of(libraryToLinkWrapper.getDynamicLibrary())); - } - } - return ccLinkParamsBuilder.build(); - } - - private static CcLinkParams buildStaticModeParamsForDynamicLibraryCcLinkParams( - ImmutableCollection libraryToLinkWrappers, - NestedSet linkOpts, - NestedSet linkstamps, - Iterable nonCodeInputs, - ExtraLinkTimeLibraries extraLinkTimeLibraries) { - CcLinkParams.Builder ccLinkParamsBuilder = - initializeCcLinkParams(linkOpts, linkstamps, nonCodeInputs, extraLinkTimeLibraries); - for (LibraryToLinkWrapper libraryToLinkWrapper : libraryToLinkWrappers) { - boolean usedDynamic = false; - if (libraryToLinkWrapper.getPicStaticLibrary() != null) { - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getPicStaticLibraryToLink()); - } else if (libraryToLinkWrapper.getStaticLibrary() != null) { - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getStaticLibraryToLink()); - } else if (libraryToLinkWrapper.getInterfaceLibrary() != null) { - usedDynamic = true; - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getInterfaceLibraryToLink()); - } else if (libraryToLinkWrapper.getDynamicLibrary() != null) { - usedDynamic = true; - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getDynamicLibraryToLink()); - } - - if (usedDynamic && libraryToLinkWrapper.getDynamicLibrary() != null) { - ccLinkParamsBuilder.addDynamicLibrariesForRuntime( - ImmutableList.of(libraryToLinkWrapper.getDynamicLibrary())); - } - } - return ccLinkParamsBuilder.build(); - } - - private static CcLinkParams buildDynamicModeParamsForExecutableCcLinkParams( - ImmutableCollection libraryToLinkWrappers, - NestedSet linkOpts, - NestedSet linkstamps, - Iterable nonCodeInputs, - ExtraLinkTimeLibraries extraLinkTimeLibraries) { - CcLinkParams.Builder ccLinkParamsBuilder = - initializeCcLinkParams(linkOpts, linkstamps, nonCodeInputs, extraLinkTimeLibraries); - for (LibraryToLinkWrapper libraryToLinkWrapper : libraryToLinkWrappers) { - boolean usedDynamic = false; - if (libraryToLinkWrapper.getInterfaceLibrary() != null) { - usedDynamic = true; - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getInterfaceLibraryToLink()); - } else if (libraryToLinkWrapper.getDynamicLibrary() != null) { - usedDynamic = true; - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getDynamicLibraryToLink()); - } else if (libraryToLinkWrapper.getStaticLibrary() != null) { - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getStaticLibraryToLink()); - } else if (libraryToLinkWrapper.getPicStaticLibrary() != null) { - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getPicStaticLibraryToLink()); - } - - if (usedDynamic && libraryToLinkWrapper.getDynamicLibrary() != null) { - ccLinkParamsBuilder.addDynamicLibrariesForRuntime( - ImmutableList.of(libraryToLinkWrapper.getDynamicLibrary())); - } - } - return ccLinkParamsBuilder.build(); - } - - private static CcLinkParams buildDynamicModeParamsForDynamicLibraryCcLinkParams( - ImmutableCollection libraryToLinkWrappers, - NestedSet linkOpts, - NestedSet linkstamps, - Iterable nonCodeInputs, - ExtraLinkTimeLibraries extraLinkTimeLibraries) { - CcLinkParams.Builder ccLinkParamsBuilder = - initializeCcLinkParams(linkOpts, linkstamps, nonCodeInputs, extraLinkTimeLibraries); - for (LibraryToLinkWrapper libraryToLinkWrapper : libraryToLinkWrappers) { - boolean usedDynamic = false; - if (libraryToLinkWrapper.getInterfaceLibrary() != null) { - usedDynamic = true; - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getInterfaceLibraryToLink()); - } else if (libraryToLinkWrapper.getDynamicLibrary() != null) { - usedDynamic = true; - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getDynamicLibraryToLink()); - } else if (libraryToLinkWrapper.getPicStaticLibrary() != null) { - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getPicStaticLibraryToLink()); - } else if (libraryToLinkWrapper.getStaticLibrary() != null) { - ccLinkParamsBuilder.addLibrary(libraryToLinkWrapper.getStaticLibraryToLink()); - } - - if (usedDynamic && libraryToLinkWrapper.getDynamicLibrary() != null) { - ccLinkParamsBuilder.addDynamicLibrariesForRuntime( - ImmutableList.of(libraryToLinkWrapper.getDynamicLibrary())); - } - } - return ccLinkParamsBuilder.build(); - } - public LibraryToLink getStaticLibraryToLink() { Preconditions.checkNotNull(staticLibrary); if (staticLibraryToLink != null) { @@ -1103,23 +732,6 @@ public LibraryToLink getInterfaceLibraryToLink() { return interfaceLibraryToLink; } - private static CcLinkParams.Builder initializeCcLinkParams( - NestedSet linkOpts, - NestedSet linkstamps, - Iterable nonCodeInputs, - ExtraLinkTimeLibraries extraLinkTimeLibraries) { - CcLinkParams.Builder ccLinkParamsBuilder = CcLinkParams.builder(); - if (!linkOpts.isEmpty()) { - ccLinkParamsBuilder.addLinkOpts(linkOpts); - } - ccLinkParamsBuilder.addLinkstamps(linkstamps); - ccLinkParamsBuilder.addNonCodeInputs(nonCodeInputs); - if (extraLinkTimeLibraries != null) { - ccLinkParamsBuilder.addTransitiveExtraLinkTimeLibrary(extraLinkTimeLibraries); - } - return ccLinkParamsBuilder; - } - /** Builder for LibraryToLinkWrapper. */ public static class Builder { private String libraryIdentifier; diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java index 33290cb333c20c..f280aef5e2ab56 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java @@ -47,7 +47,6 @@ import com.google.devtools.build.lib.rules.cpp.CcCompilationOutputs; import com.google.devtools.build.lib.rules.cpp.CcInfo; import com.google.devtools.build.lib.rules.cpp.CcLinkingHelper; -import com.google.devtools.build.lib.rules.cpp.CcLinkingInfo; import com.google.devtools.build.lib.rules.cpp.CcLinkingOutputs; import com.google.devtools.build.lib.rules.cpp.CcNativeLibraryProvider; import com.google.devtools.build.lib.rules.cpp.CcToolchain; @@ -58,6 +57,7 @@ import com.google.devtools.build.lib.rules.cpp.CppRuleClasses; import com.google.devtools.build.lib.rules.cpp.CppSemantics; import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper.CcLinkingContext; import com.google.devtools.build.lib.rules.cpp.LinkerInputs; import com.google.devtools.build.lib.rules.proto.ProtoCommon; import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder; @@ -219,8 +219,8 @@ private static class Impl { } CcNativeLibraryProvider ccNativeLibraryProvider = CppHelper.collectNativeCcLibraries(deps, ccLinkingOutputs); - CcLinkingInfo ccLinkingInfo = - ccLinkingHelper.buildCcLinkingInfoFromLibraryToLinkWrappers( + CcLinkingContext ccLinkingContext = + ccLinkingHelper.buildCcLinkingContextFromLibraryToLinkWrappers( libraryToLinkWrapperBuilder.build(), compilationInfo.getCcCompilationContext()); ccLibraryProviders = @@ -229,7 +229,7 @@ private static class Impl { .put( CcInfo.builder() .setCcCompilationContext(compilationInfo.getCcCompilationContext()) - .setCcLinkingInfo(ccLinkingInfo) + .setCcLinkingContext(ccLinkingContext) .build()) .add(ccNativeLibraryProvider) .build(); diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCcLinkParamsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCcLinkParamsProvider.java index 6ad8f60c756f87..83b69441bca8e4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCcLinkParamsProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCcLinkParamsProvider.java @@ -33,7 +33,7 @@ public final class JavaCcLinkParamsProvider extends Info public JavaCcLinkParamsProvider(CcInfo ccInfo) { super(PROVIDER, Location.BUILTIN); - this.ccInfo = CcInfo.builder().setCcLinkingInfo(ccInfo.getCcLinkingInfo()).build(); + this.ccInfo = CcInfo.builder().setCcLinkingContext(ccInfo.getCcLinkingContext()).build(); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/rules/nativedeps/NativeDepsHelper.java b/src/main/java/com/google/devtools/build/lib/rules/nativedeps/NativeDepsHelper.java index 6681889c2c8420..a525ae00ef274f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/nativedeps/NativeDepsHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/nativedeps/NativeDepsHelper.java @@ -30,7 +30,7 @@ import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; import com.google.devtools.build.lib.rules.cpp.ArtifactCategory; import com.google.devtools.build.lib.rules.cpp.CcCommon; -import com.google.devtools.build.lib.rules.cpp.CcLinkParams; +import com.google.devtools.build.lib.rules.cpp.CcInfo; import com.google.devtools.build.lib.rules.cpp.CcLinkParams.Linkstamp; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration; import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider; @@ -42,11 +42,11 @@ import com.google.devtools.build.lib.rules.cpp.CppRuleClasses; import com.google.devtools.build.lib.rules.cpp.CppSemantics; import com.google.devtools.build.lib.rules.cpp.FdoContext; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper.CcLinkingContext; import com.google.devtools.build.lib.rules.cpp.Link; import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType; import com.google.devtools.build.lib.rules.cpp.Link.LinkingMode; -import com.google.devtools.build.lib.rules.cpp.LinkerInputs; -import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; import com.google.devtools.build.lib.rules.cpp.LtoCompilationContext; import com.google.devtools.build.lib.util.Fingerprint; import com.google.devtools.build.lib.vfs.PathFragment; @@ -104,20 +104,19 @@ private NativeDepsHelper() {} * shared libraries. In this case, this function returns {@code null}. * * @param ruleContext the rule context to determine the native deps library - * @param linkParams the {@link CcLinkParams} for the rule, collected with linkstatic = 1 and - * linkshared = 1 + * @param ccInfo the {@link CcInfo} for the rule, collected with linkstatic = 1 and linkshared = 1 * @param cppSemantics to use for linkstamp compiles * @return the native deps library, or null if there was no code which needed to be linked in the * transitive closure. */ public static Artifact linkAndroidNativeDepsIfPresent( final RuleContext ruleContext, - CcLinkParams linkParams, + CcInfo ccInfo, final BuildConfiguration configuration, CcToolchainProvider toolchain, CppSemantics cppSemantics) throws InterruptedException, RuleErrorException { - if (!containsCodeToLink(linkParams.getLibraries())) { + if (!containsCodeToLink(ccInfo.getCcLinkingContext().getLibraries())) { return null; } @@ -131,7 +130,7 @@ public static Artifact linkAndroidNativeDepsIfPresent( return createNativeDepsAction( ruleContext, - linkParams, + ccInfo, /* extraLinkOpts= */ ImmutableList.of(), configuration, toolchain, @@ -144,8 +143,8 @@ public static Artifact linkAndroidNativeDepsIfPresent( } /** Determines if there is any code to be linked in the input iterable. */ - private static boolean containsCodeToLink(Iterable libraries) { - for (LibraryToLink library : libraries) { + private static boolean containsCodeToLink(Iterable libraries) { + for (LibraryToLinkWrapper library : libraries) { if (containsCodeToLink(library)) { return true; } @@ -154,16 +153,21 @@ private static boolean containsCodeToLink(Iterable libraries) { } /** Determines if the input library is or contains an archive which must be linked. */ - private static boolean containsCodeToLink(LibraryToLink library) { - if (Link.SHARED_LIBRARY_FILETYPES.matches(library.getArtifact().getFilename())) { + private static boolean containsCodeToLink(LibraryToLinkWrapper library) { + if (library.getStaticLibrary() == null && library.getPicStaticLibrary() == null) { // this is a shared library so we're going to have to copy it return false; } - if (!library.containsObjectFiles()) { + Iterable objectFiles; + if (library.getObjectFiles() != null) { + objectFiles = library.getObjectFiles(); + } else if (library.getPicObjectFiles() != null) { + objectFiles = library.getPicObjectFiles(); + } else { // this is an opaque library so we're going to have to link it return true; } - for (Artifact object : library.getObjectFiles()) { + for (Artifact object : objectFiles) { if (!Link.SHARED_LIBRARY_FILETYPES.matches(object.getFilename())) { // this library was built with a non-shared-library object so we should link it return true; @@ -175,7 +179,7 @@ private static boolean containsCodeToLink(LibraryToLink library) { public static NativeDepsRunfiles createNativeDepsAction( final RuleContext ruleContext, - CcLinkParams linkParams, + CcInfo ccInfo, Collection extraLinkOpts, BuildConfiguration configuration, CcToolchainProvider toolchain, @@ -185,30 +189,30 @@ public static NativeDepsRunfiles createNativeDepsAction( boolean useDynamicRuntime, CppSemantics cppSemantics) throws InterruptedException, RuleErrorException { + CcLinkingContext ccLinkingContext = ccInfo.getCcLinkingContext(); Preconditions.checkState( ruleContext.isLegalFragment(CppConfiguration.class), "%s does not have access to CppConfiguration", ruleContext.getRule().getRuleClass()); List linkopts = new ArrayList<>(extraLinkOpts); - linkopts.addAll(linkParams.flattenedLinkopts()); + linkopts.addAll(ccLinkingContext.getFlattenedUserLinkFlags()); - CppHelper.checkLinkstampsUnique(ruleContext, linkParams.getLinkstamps()); - ImmutableSet linkstamps = ImmutableSet.copyOf(linkParams.getLinkstamps()); + CppHelper.checkLinkstampsUnique(ruleContext, ccLinkingContext.getLinkstamps()); + ImmutableSet linkstamps = ImmutableSet.copyOf(ccLinkingContext.getLinkstamps()); List buildInfoArtifacts = linkstamps.isEmpty() ? ImmutableList.of() : ruleContext.getAnalysisEnvironment().getBuildInfo( ruleContext, CppBuildInfo.KEY, configuration); boolean shareNativeDeps = configuration.getFragment(CppConfiguration.class).shareNativeDeps(); - NestedSet linkerInputs = linkParams.getLibraries(); + NestedSet linkerInputs = ccLinkingContext.getLibraries(); Artifact sharedLibrary; if (shareNativeDeps) { PathFragment sharedPath = getSharedNativeDepsPath( - LinkerInputs.toLibraryArtifacts(linkerInputs), + ccLinkingContext.getStaticModeParamsForDynamicLibraryLibraries(), linkopts, - linkstamps - .stream() + linkstamps.stream() .map(Linkstamp::getArtifact) .collect(ImmutableList.toImmutableList()), buildInfoArtifacts, @@ -251,13 +255,17 @@ public static NativeDepsRunfiles createNativeDepsAction( toolchain.getStaticRuntimeLinkInputs(ruleContext, featureConfiguration)); } LtoCompilationContext.Builder ltoCompilationContext = new LtoCompilationContext.Builder(); - for (LibraryToLink lib : linkerInputs) { - if (!lib.getLtoCompilationContext().isEmpty()) { + for (LibraryToLinkWrapper lib : linkerInputs) { + if (lib.getPicLtoCompilationContext() != null + && !lib.getPicLtoCompilationContext().isEmpty()) { + ltoCompilationContext.addAll(lib.getPicLtoCompilationContext()); + } else if (lib.getLtoCompilationContext() != null + && !lib.getLtoCompilationContext().isEmpty()) { ltoCompilationContext.addAll(lib.getLtoCompilationContext()); } } - Iterable nonCodeInputs = linkParams.getNonCodeInputs(); + Iterable nonCodeInputs = ccLinkingContext.getNonCodeInputs(); if (nonCodeInputs == null) { nonCodeInputs = ImmutableList.of(); } @@ -265,7 +273,7 @@ public static NativeDepsRunfiles createNativeDepsAction( builder .setLinkArtifactFactory(SHAREABLE_LINK_ARTIFACT_FACTORY) .setLinkerFiles(toolchain.getLinkerFiles()) - .addLibraries(linkerInputs) + .addLibraryToLinkWrappers(linkerInputs) .setLinkType(LinkTargetType.DYNAMIC_LIBRARY) .setLinkingMode(LinkingMode.STATIC) .setLibraryIdentifier(libraryIdentifier) diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java index 707a45a9a03189..a98c9bb17afbe6 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java @@ -154,7 +154,7 @@ public final ConfiguredTarget create(RuleContext ruleContext) .subtractSubtrees( cpuToObjcAvoidDepsMap.get(childCpu), cpuToCcAvoidDepsMap.get(childCpu).stream() - .map(CcInfo::getCcLinkingInfo) + .map(CcInfo::getCcLinkingContext) .collect(ImmutableList.toImmutableList())); librariesToLipo.add(intermediateArtifacts.strippedSingleArchitectureLibrary()); 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 7ac6d72f8a591b..cb16df2c1dbb56 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 @@ -1384,7 +1384,7 @@ private ImmutableList libraryNames(ObjcProvider objcProvider) { /** Returns libraries that should be passed into the linker with {@code -force_load}. */ private ImmutableSet getForceLoadArtifacts(ObjcProvider objcProvider) { - ImmutableList ccLibraries = objcProvider.getCcLibraries(); + List ccLibraries = objcProvider.getCcLibraries(); Iterable ccLibrariesToForceLoad = Iterables.filter(ccLibraries, ALWAYS_LINKED_CC_LIBRARY); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchBinarySupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchBinarySupport.java index 89c8ec745886cd..2c2d1548e2ed41 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchBinarySupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchBinarySupport.java @@ -37,7 +37,6 @@ import com.google.devtools.build.lib.packages.Info; import com.google.devtools.build.lib.packages.NativeProvider; import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; -import com.google.devtools.build.lib.rules.cpp.CcLinkingInfo; import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider; import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs; import com.google.devtools.build.lib.rules.proto.ProtoInfo; @@ -263,8 +262,7 @@ public ImmutableSet getDependencySpecificConfig additionalDepProviders); ObjcProvider objcProviderWithDylibSymbols = common.getObjcProvider(); ObjcProvider objcProvider = - objcProviderWithDylibSymbols.subtractSubtrees( - dylibObjcProviders, ImmutableList.of()); + objcProviderWithDylibSymbols.subtractSubtrees(dylibObjcProviders, ImmutableList.of()); childInfoBuilder.add( DependencySpecificConfiguration.create( 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 3d72703cc972f8..095eb609b4834b 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 @@ -62,15 +62,16 @@ import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; +import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.BuiltinProvider; import com.google.devtools.build.lib.packages.Info; import com.google.devtools.build.lib.rules.apple.AppleToolchain; import com.google.devtools.build.lib.rules.cpp.CcCompilationContext; import com.google.devtools.build.lib.rules.cpp.CcInfo; -import com.google.devtools.build.lib.rules.cpp.CcLinkParams; -import com.google.devtools.build.lib.rules.cpp.CcLinkingInfo; import com.google.devtools.build.lib.rules.cpp.CppFileTypes; import com.google.devtools.build.lib.rules.cpp.CppModuleMap; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper.CcLinkingContext; import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData; import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.util.FileType; @@ -167,7 +168,7 @@ static class Builder { private Optional linkedBinary = Optional.absent(); private Optional linkmapFile = Optional.absent(); private Iterable depCcHeaderProviders = ImmutableList.of(); - private Iterable depCcLinkProviders = ImmutableList.of(); + private Iterable depCcLinkProviders = ImmutableList.of(); /** * Builder for {@link ObjcCommon} obtaining both attribute data and configuration data from @@ -256,14 +257,14 @@ Builder addDeps(List deps) { ImmutableList.Builder propagatedObjcDeps = ImmutableList.builder(); ImmutableList.Builder cppDeps = ImmutableList.builder(); - ImmutableList.Builder cppDepLinkParams = ImmutableList.builder(); + ImmutableList.Builder cppDepLinkParams = ImmutableList.builder(); for (ConfiguredTargetAndData dep : deps) { ConfiguredTarget depCT = dep.getConfiguredTarget(); addAnyProviders(propagatedObjcDeps, depCT, ObjcProvider.SKYLARK_CONSTRUCTOR); addAnyProviders(cppDeps, depCT, CcInfo.PROVIDER); if (isCcLibrary(dep)) { - cppDepLinkParams.add(depCT.get(CcInfo.PROVIDER).getCcLinkingInfo()); + cppDepLinkParams.add(depCT.get(CcInfo.PROVIDER).getCcLinkingContext()); CcCompilationContext ccCompilationContext = depCT.get(CcInfo.PROVIDER).getCcCompilationContext(); addDefines(ccCompilationContext.getDefines()); @@ -434,9 +435,8 @@ ObjcCommon build() { objcProvider.addAll(DEFINE, headerProvider.getDefines()); textualHeaders.addAll(headerProvider.getTextualHdrs()); } - for (CcLinkingInfo linkProvider : depCcLinkProviders) { - CcLinkParams params = linkProvider.getStaticModeParamsForExecutable(); - ImmutableList linkOpts = params.flattenedLinkopts(); + for (CcLinkingContext linkProvider : depCcLinkProviders) { + ImmutableList linkOpts = linkProvider.getFlattenedUserLinkFlags(); ImmutableSet.Builder frameworkLinkOpts = new ImmutableSet.Builder<>(); ImmutableList.Builder nonFrameworkLinkOpts = new ImmutableList.Builder<>(); // Add any framework flags as frameworks directly, rather than as linkopts. @@ -453,7 +453,11 @@ ObjcCommon build() { objcProvider .addAll(SDK_FRAMEWORK, frameworkLinkOpts.build()) .addAll(LINKOPT, nonFrameworkLinkOpts.build()) - .addTransitiveAndPropagate(CC_LIBRARY, params.getLibraries()); + .addTransitiveAndPropagate( + CC_LIBRARY, + NestedSetBuilder.linkOrder() + .addTransitive(linkProvider.getLibraries()) + .build()); } if (compilationAttributes.isPresent()) { diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java index 76e81f6ccce4f4..99811dcb555a58 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java @@ -24,13 +24,11 @@ import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.rules.cpp.ArtifactCategory; import com.google.devtools.build.lib.rules.cpp.CcCompilationContext; import com.google.devtools.build.lib.rules.cpp.CcInfo; -import com.google.devtools.build.lib.rules.cpp.CcLinkParams; -import com.google.devtools.build.lib.rules.cpp.CcLinkingInfo; -import com.google.devtools.build.lib.rules.cpp.LinkerInputs; -import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; +import com.google.devtools.build.lib.rules.cpp.CcLinkParams.LinkOptions; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper.CcLinkingContext; import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.FileSystemUtils; @@ -106,14 +104,7 @@ public ConfiguredTarget create(RuleContext ruleContext) .addDeclaredIncludeSrcs(common.getTextualHdrs()) .build(); - CcLinkParams ccLinkParams = buildCcLinkParams(common); - CcLinkingInfo ccLinkingInfo = - CcLinkingInfo.Builder.create() - .setStaticModeParamsForDynamicLibrary(ccLinkParams) - .setStaticModeParamsForExecutable(ccLinkParams) - .setDynamicModeParamsForDynamicLibrary(ccLinkParams) - .setDynamicModeParamsForExecutable(ccLinkParams) - .build(); + CcLinkingContext ccLinkingContext = buildCcLinkingContext(common); return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build()) .addNativeDeclaredProvider(common.getObjcProvider()) @@ -124,32 +115,39 @@ public ConfiguredTarget create(RuleContext ruleContext) .addNativeDeclaredProvider( CcInfo.builder() .setCcCompilationContext(ccCompilationContext) - .setCcLinkingInfo(ccLinkingInfo) + .setCcLinkingContext(ccLinkingContext) .build()) .addOutputGroups(outputGroupCollector) .build(); } - public CcLinkParams buildCcLinkParams(ObjcCommon common) { - ImmutableSet.Builder libraries = new ImmutableSet.Builder<>(); + public CcLinkingContext buildCcLinkingContext(ObjcCommon common) { + ImmutableSet.Builder libraries = new ImmutableSet.Builder<>(); ObjcProvider objcProvider = common.getObjcProvider(); for (Artifact library : objcProvider.get(ObjcProvider.LIBRARY)) { libraries.add( - LinkerInputs.opaqueLibraryToLink( - library, - ArtifactCategory.STATIC_LIBRARY, - FileSystemUtils.removeExtension(library.getRootRelativePathString()))); + LibraryToLinkWrapper.builder() + .setStaticLibrary(library) + .setLibraryIdentifier( + FileSystemUtils.removeExtension(library.getRootRelativePathString())) + .build()); } libraries.addAll(objcProvider.get(ObjcProvider.CC_LIBRARY)); - CcLinkParams.Builder builder = CcLinkParams.builder(); - builder.addLibraries(libraries.build()); + CcLinkingContext.Builder ccLinkingContext = + CcLinkingContext.builder() + .addLibraries( + NestedSetBuilder.linkOrder() + .addAll(libraries.build()) + .build()); + NestedSetBuilder userLinkFlags = NestedSetBuilder.linkOrder(); for (SdkFramework sdkFramework : objcProvider.get(ObjcProvider.SDK_FRAMEWORK)) { - builder.addLinkOpts(ImmutableList.of("-framework", sdkFramework.getName())); + userLinkFlags.add(LinkOptions.of(ImmutableList.of("-framework", sdkFramework.getName()))); } + ccLinkingContext.addUserLinkFlags(userLinkFlags.build()); - return builder.build(); + return ccLinkingContext.build(); } /** Throws errors or warnings for bad attribute state. */ diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java index b83a96c3b49f33..923338b28f8d0c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java @@ -34,17 +34,19 @@ import com.google.devtools.build.lib.packages.BuiltinProvider; import com.google.devtools.build.lib.packages.Info; import com.google.devtools.build.lib.packages.NativeProvider.WithLegacySkylarkName; -import com.google.devtools.build.lib.rules.cpp.CcLinkingInfo; import com.google.devtools.build.lib.rules.cpp.CppModuleMap; -import com.google.devtools.build.lib.rules.cpp.LinkerInputs; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper.CcLinkingContext; import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; import com.google.devtools.build.lib.skylarkbuildapi.apple.ObjcProviderApi; import com.google.devtools.build.lib.syntax.EvalUtils; import com.google.devtools.build.lib.syntax.SkylarkNestedSet; import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.vfs.PathFragment; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; /** @@ -290,11 +292,9 @@ public Class getType() { */ public static final Key STRINGS = new Key<>(STABLE_ORDER, "strings", Artifact.class); - /** - * Linking information from cc dependencies. - */ - public static final Key CC_LIBRARY = - new Key<>(LINK_ORDER, "cc_library", LinkerInputs.LibraryToLink.class); + /** Linking information from cc dependencies. */ + public static final Key CC_LIBRARY = + new Key<>(LINK_ORDER, "cc_library", LibraryToLinkWrapper.class); /** * Linking options from dependencies. @@ -747,12 +747,14 @@ ImmutableList getObjcLibraries() { } /** Returns the list of .a files required for linking that arise from cc libraries. */ - ImmutableList getCcLibraries() { - ImmutableList.Builder ccLibraryBuilder = ImmutableList.builder(); - for (LinkerInputs.LibraryToLink libraryToLink : get(CC_LIBRARY)) { - ccLibraryBuilder.add(libraryToLink.getArtifact()); + List getCcLibraries() { + NestedSetBuilder libraryToLinkListBuilder = NestedSetBuilder.linkOrder(); + for (LibraryToLinkWrapper libraryToLinkWrapper : get(CC_LIBRARY)) { + libraryToLinkListBuilder.add(libraryToLinkWrapper); } - return ccLibraryBuilder.build(); + CcLinkingContext ccLinkingContext = + CcLinkingContext.builder().addLibraries(libraryToLinkListBuilder.build()).build(); + return ccLinkingContext.getStaticModeParamsForExecutableLibraries(); } /** @@ -769,19 +771,22 @@ ImmutableList getCcLibraries() { // TODO(b/65156211): Investigate subtraction generalized to NestedSet. @SuppressWarnings("unchecked") // Due to depending on Key types, when the keys map erases type. public ObjcProvider subtractSubtrees( - Iterable avoidObjcProviders, Iterable avoidCcProviders) { + Iterable avoidObjcProviders, Iterable avoidCcProviders) { // LIBRARY and CC_LIBRARY need to be special cased for objc-cc interop. // A library which is a dependency of a cc_library may be present in all or any of // three possible locations (and may be duplicated!): // 1. ObjcProvider.LIBRARY // 2. ObjcProvider.CC_LIBRARY - // 3. CcLinkingInfo->LibraryToLink->getArtifact() + // 3. CcLinkingContext->LibraryToLink->getArtifact() // TODO(cpeyser): Clean up objc-cc interop. HashSet avoidLibrariesSet = new HashSet<>(); - for (CcLinkingInfo linkProvider : avoidCcProviders) { - NestedSet librariesToLink = - linkProvider.getStaticModeParamsForExecutable().getLibraries(); - for (LibraryToLink libraryToLink : librariesToLink.toList()) { + for (CcLinkingContext ccLinkingContext : avoidCcProviders) { + List librariesToLink = + LibraryToLinkWrapper.convertLibraryToLinkWrapperListToLibraryToLinkList( + ccLinkingContext.getLibraries(), + /* staticMode= */ true, + /* forDynamicLibrary= */ false); + for (LibraryToLink libraryToLink : librariesToLink) { avoidLibrariesSet.add(libraryToLink.getArtifact().getRunfilesPath()); } } @@ -825,16 +830,42 @@ private static Predicate notContainedIn( } /** - * Returns a predicate which returns true for a given {@link LibraryToLink} if the library's - * runfiles path is not contained in the given set. + * Returns a predicate which returns true for a given {@link LibraryToLinkWrapper} if the + * library's runfiles path is not contained in the given set. * * @param runfilesPaths if a given library has runfiles path present in this set, the predicate * will return false */ - private static Predicate ccLibraryNotYetLinked( + private static Predicate ccLibraryNotYetLinked( final HashSet runfilesPaths) { - return libraryToLink -> !runfilesPaths.contains( - libraryToLink.getArtifact().getRunfilesPath()); + return libraryToLink -> !checkIfLibraryIsInPaths(libraryToLink, runfilesPaths); + } + + private static boolean checkIfLibraryIsInPaths( + LibraryToLinkWrapper libraryToLinkWrapper, HashSet runfilesPaths) { + ImmutableList.Builder libraryRunfilesPaths = ImmutableList.builder(); + if (libraryToLinkWrapper.getStaticLibrary() != null) { + libraryRunfilesPaths.add(libraryToLinkWrapper.getStaticLibrary().getRunfilesPath()); + } + if (libraryToLinkWrapper.getPicStaticLibrary() != null) { + libraryRunfilesPaths.add(libraryToLinkWrapper.getPicStaticLibrary().getRunfilesPath()); + } + if (libraryToLinkWrapper.getDynamicLibrary() != null) { + libraryRunfilesPaths.add(libraryToLinkWrapper.getDynamicLibrary().getRunfilesPath()); + } + if (libraryToLinkWrapper.getResolvedSymlinkDynamicLibrary() != null) { + libraryRunfilesPaths.add( + libraryToLinkWrapper.getResolvedSymlinkDynamicLibrary().getRunfilesPath()); + } + if (libraryToLinkWrapper.getInterfaceLibrary() != null) { + libraryRunfilesPaths.add(libraryToLinkWrapper.getInterfaceLibrary().getRunfilesPath()); + } + if (libraryToLinkWrapper.getResolvedSymlinkInterfaceLibrary() != null) { + libraryRunfilesPaths.add( + libraryToLinkWrapper.getResolvedSymlinkInterfaceLibrary().getRunfilesPath()); + } + + return !Collections.disjoint(libraryRunfilesPaths.build(), runfilesPaths); } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PyCcLinkParamsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/python/PyCcLinkParamsProvider.java index 561f25f51e6bdd..6b382b46cd8d70 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/python/PyCcLinkParamsProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/python/PyCcLinkParamsProvider.java @@ -39,7 +39,7 @@ public final class PyCcLinkParamsProvider extends NativeInfo { public PyCcLinkParamsProvider(CcInfo ccInfo) { super(PROVIDER); - this.ccInfo = CcInfo.builder().setCcLinkingInfo(ccInfo.getCcLinkingInfo()).build(); + this.ccInfo = CcInfo.builder().setCcLinkingContext(ccInfo.getCcLinkingContext()).build(); } @SkylarkCallable(name = "cc_info", doc = "", structField = true, documented = false) diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java index 1c0e845891d77b..79ecc1ec74941e 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java @@ -38,7 +38,6 @@ public interface BazelCcModuleApi< CcCompilationContextT extends CcCompilationContextApi, CcCompilationOutputsT extends CcCompilationOutputsApi, LinkingInfoT extends LinkingInfoApi, - CcLinkingInfoT extends CcLinkingInfoApi, LinkingContextT extends CcLinkingContextApi, LibraryToLinkWrapperT extends LibraryToLinkWrapperApi, CcToolchainVariablesT extends CcToolchainVariablesApi> @@ -197,7 +196,7 @@ LinkingInfoT link( CcCompilationOutputsT ccCompilationOutputs, Object skylarkLinkopts, Object dynamicLibrary, - SkylarkList skylarkCcLinkingInfos, + SkylarkList skylarkCcLinkingContexts, boolean neverLink) throws InterruptedException, EvalException; } diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcBootstrap.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcBootstrap.java index 29ac74fccb3016..d1679d8d378667 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcBootstrap.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcBootstrap.java @@ -29,7 +29,6 @@ public class CcBootstrap implements Bootstrap { ? extends CcCompilationContextApi, ? extends CcCompilationOutputsApi, ? extends LinkingInfoApi, - ? extends CcLinkingInfoApi, ? extends CcLinkingContextApi, ? extends LibraryToLinkWrapperApi, ? extends CcToolchainVariablesApi> @@ -43,7 +42,6 @@ public CcBootstrap( ? extends CcCompilationContextApi, ? extends CcCompilationOutputsApi, ? extends LinkingInfoApi, - ? extends CcLinkingInfoApi, ? extends CcLinkingContextApi, ? extends LibraryToLinkWrapperApi, ? extends CcToolchainVariablesApi> diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcInfoApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcInfoApi.java index 906b8326902a32..54238d0d827996 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcInfoApi.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcInfoApi.java @@ -45,7 +45,7 @@ public interface CcInfoApi extends StructApi { name = "linking_context", doc = "Returns the LinkingContext", structField = true) - CcLinkingInfoApi getCcLinkingInfo(); + CcLinkingContextApi getCcLinkingContext(); /** The provider implementing this can construct the CcInfo provider. */ @SkylarkModule( @@ -83,7 +83,6 @@ interface Provider extends ProviderApi { defaultValue = "None", allowedTypes = { @ParamType(type = CcLinkingContextApi.class), - @ParamType(type = CcLinkingInfoApi.class), @ParamType(type = NoneType.class) }) }, diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkingInfoApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkingInfoApi.java deleted file mode 100644 index 69d0858d2e4517..00000000000000 --- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkingInfoApi.java +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2018 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.lib.skylarkbuildapi.cpp; - -import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; -import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; -import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; -import com.google.devtools.build.lib.syntax.SkylarkList; - -/** Wrapper for every C++ linking provider. */ -@SkylarkModule( - name = "CcLinkingContext", - documented = false, - category = SkylarkModuleCategory.PROVIDER, - doc = "Wrapper for every C++ linking provider") -public interface CcLinkingInfoApi { - @SkylarkCallable(name = "user_link_flags", documented = false, structField = true) - SkylarkList getSkylarkUserLinkFlags(); - - @SkylarkCallable(name = "libraries_to_link", documented = false, structField = true) - SkylarkList getSkylarkLibrariesToLink(); -} diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/LinkingInfoApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/LinkingInfoApi.java index 61291fa3dda543..31c8247c24032e 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/LinkingInfoApi.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/LinkingInfoApi.java @@ -30,7 +30,7 @@ public interface LinkingInfoApi { @SkylarkCallable(name = "linking_context", structField = true, documented = false) - CcLinkingInfoApi getCcLinkingInfo(); + CcLinkingContextApi getCcLinkingContext(); @SkylarkCallable(name = "cc_linking_outputs", structField = true, documented = false) CcLinkingOutputsApi getCcLinkingOutputs(); diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java index 3da4970af48b30..2ae046b656dff7 100644 --- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java +++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java @@ -23,7 +23,6 @@ import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcCompilationOutputsApi; import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcInfoApi; import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcLinkingContextApi; -import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcLinkingInfoApi; import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcModuleApi; import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcToolchainProviderApi; import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcToolchainVariablesApi; @@ -46,7 +45,6 @@ public class FakeCcModule CcCompilationContextApi, CcCompilationOutputsApi, LinkingInfoApi, - CcLinkingInfoApi, CcLinkingContextApi, LibraryToLinkWrapperApi, CcToolchainVariablesApi> { @@ -177,7 +175,7 @@ public LinkingInfoApi link( CcCompilationOutputsApi ccCompilationOutputs, Object skylarkLinkopts, Object dynamicLibrary, - SkylarkList skylarkCcLinkingInfos, + SkylarkList skylarkCcLinkingContexts, boolean neverLink) { return null; } diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidLibraryTest.java index a22ee6767e65a5..1006d6bbb9da27 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidLibraryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidLibraryTest.java @@ -2472,9 +2472,8 @@ public void testAndroidCcLinkParamsProvider() throws Exception { target .get(AndroidCcLinkParamsProvider.PROVIDER) .getLinkParams() - .getCcLinkingInfo() - .getDynamicModeParamsForDynamicLibrary() - .flattenedLinkopts()) + .getCcLinkingContext() + .getFlattenedUserLinkFlags()) .containsExactly("-CC_DEP") .inOrder(); } diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/BUILD b/src/test/java/com/google/devtools/build/lib/rules/cpp/BUILD index 8aef29564b434a..bf0157359fd743 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/BUILD +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/BUILD @@ -105,6 +105,7 @@ java_library( "//src/test/java/com/google/devtools/build/lib:actions_testutil", "//src/test/java/com/google/devtools/build/lib:analysis_testutil", "//src/test/java/com/google/devtools/build/lib:packages_testutil", + "//third_party:guava", "//third_party:junit4", "//third_party:truth", ], diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcCommonTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcCommonTest.java index 9b76995d817817..4fa1a292aa03d8 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcCommonTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcCommonTest.java @@ -122,9 +122,8 @@ public void testEmptyLibrary() throws Exception { assertThat( emptylib .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getDynamicModeParamsForExecutable() - .getDynamicLibrariesForRuntime() + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ false) .isEmpty()) .isTrue(); } @@ -236,9 +235,8 @@ public void testLinkStaticStatically() throws Exception { assertThat( statically .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getDynamicModeParamsForExecutable() - .getDynamicLibrariesForRuntime() + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ false) .isEmpty()) .isTrue(); Artifact staticallyDotA = getOnlyElement(getFilesToBuild(statically)); diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcImportBaseConfiguredTargetTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcImportBaseConfiguredTargetTest.java index 86c182925c6fa0..f2a891d46824ee 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcImportBaseConfiguredTargetTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcImportBaseConfiguredTargetTest.java @@ -17,12 +17,13 @@ import static com.google.common.truth.Truth.assertThat; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.util.AnalysisMock; import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; import com.google.devtools.build.lib.packages.util.MockCcSupport; -import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -140,41 +141,10 @@ public void testCcImportWithStaticLibrary() throws Exception { "foo", skylarkImplementationLoadStatement, "cc_import(name = 'foo', static_library = 'libfoo.a')"); - Iterable libraries = - LinkerInputs.toNonSolibArtifacts( - target - .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getDynamicModeParamsForExecutable() - .getLibraries()); - assertThat(artifactsToStrings(libraries)).containsExactly("src a/libfoo.a"); - - libraries = - LinkerInputs.toNonSolibArtifacts( - target - .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getDynamicModeParamsForDynamicLibrary() - .getLibraries()); - assertThat(artifactsToStrings(libraries)).containsExactly("src a/libfoo.a"); - - libraries = - LinkerInputs.toNonSolibArtifacts( - target - .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getStaticModeParamsForExecutable() - .getLibraries()); - assertThat(artifactsToStrings(libraries)).containsExactly("src a/libfoo.a"); - - libraries = - LinkerInputs.toNonSolibArtifacts( - target - .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getStaticModeParamsForDynamicLibrary() - .getLibraries()); - assertThat(artifactsToStrings(libraries)).containsExactly("src a/libfoo.a"); + Artifact library = + Iterables.getOnlyElement(target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries()) + .getStaticLibrary(); + assertThat(artifactsToStrings(ImmutableList.of(library))).containsExactly("src a/libfoo.a"); } @Test @@ -186,35 +156,16 @@ public void testCcImportWithSharedLibrary() throws Exception { "foo", skylarkImplementationLoadStatement, "cc_import(name = 'foo', shared_library = 'libfoo.so')"); - CcLinkParams ccLinkParams = - target.get(CcInfo.PROVIDER).getCcLinkingInfo().getDynamicModeParamsForExecutable(); - Iterable libraries = LinkerInputs.toNonSolibArtifacts(ccLinkParams.getLibraries()); - Iterable dynamicLibrariesForRuntime = ccLinkParams.getDynamicLibrariesForRuntime(); - assertThat(artifactsToStrings(libraries)).containsExactly("src a/libfoo.so"); - assertThat(artifactsToStrings(dynamicLibrariesForRuntime)) - .containsExactly("bin _solib_k8/_U_S_Sa_Cfoo___Ua/libfoo.so"); - - ccLinkParams = - target.get(CcInfo.PROVIDER).getCcLinkingInfo().getDynamicModeParamsForDynamicLibrary(); - libraries = LinkerInputs.toNonSolibArtifacts(ccLinkParams.getLibraries()); - dynamicLibrariesForRuntime = ccLinkParams.getDynamicLibrariesForRuntime(); - assertThat(artifactsToStrings(libraries)).containsExactly("src a/libfoo.so"); - assertThat(artifactsToStrings(dynamicLibrariesForRuntime)) - .containsExactly("bin _solib_k8/_U_S_Sa_Cfoo___Ua/libfoo.so"); - - ccLinkParams = - target.get(CcInfo.PROVIDER).getCcLinkingInfo().getStaticModeParamsForExecutable(); - libraries = LinkerInputs.toNonSolibArtifacts(ccLinkParams.getLibraries()); - dynamicLibrariesForRuntime = ccLinkParams.getDynamicLibrariesForRuntime(); - assertThat(artifactsToStrings(libraries)).containsExactly("src a/libfoo.so"); - assertThat(artifactsToStrings(dynamicLibrariesForRuntime)) - .containsExactly("bin _solib_k8/_U_S_Sa_Cfoo___Ua/libfoo.so"); - - ccLinkParams = - target.get(CcInfo.PROVIDER).getCcLinkingInfo().getStaticModeParamsForDynamicLibrary(); - libraries = LinkerInputs.toNonSolibArtifacts(ccLinkParams.getLibraries()); - dynamicLibrariesForRuntime = ccLinkParams.getDynamicLibrariesForRuntime(); - assertThat(artifactsToStrings(libraries)).containsExactly("src a/libfoo.so"); + Artifact dynamicLibrary = + Iterables.getOnlyElement(target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries()) + .getResolvedSymlinkDynamicLibrary(); + Iterable dynamicLibrariesForRuntime = + target + .get(CcInfo.PROVIDER) + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ false); + assertThat(artifactsToStrings(ImmutableList.of(dynamicLibrary))) + .containsExactly("src a/libfoo.so"); assertThat(artifactsToStrings(dynamicLibrariesForRuntime)) .containsExactly("bin _solib_k8/_U_S_Sa_Cfoo___Ua/libfoo.so"); } @@ -229,35 +180,16 @@ public void testCcImportWithInterfaceSharedLibrary() throws Exception { skylarkImplementationLoadStatement, "cc_import(name = 'foo', shared_library = 'libfoo.so'," + " interface_library = 'libfoo.ifso')"); - CcLinkParams ccLinkParams = - target.get(CcInfo.PROVIDER).getCcLinkingInfo().getDynamicModeParamsForExecutable(); - Iterable libraries = LinkerInputs.toNonSolibArtifacts(ccLinkParams.getLibraries()); - Iterable dynamicLibrariesForRuntime = ccLinkParams.getDynamicLibrariesForRuntime(); - assertThat(artifactsToStrings(libraries)).containsExactly("src b/libfoo.ifso"); - assertThat(artifactsToStrings(dynamicLibrariesForRuntime)) - .containsExactly("bin _solib_k8/_U_S_Sb_Cfoo___Ub/libfoo.so"); - - ccLinkParams = - target.get(CcInfo.PROVIDER).getCcLinkingInfo().getDynamicModeParamsForDynamicLibrary(); - libraries = LinkerInputs.toNonSolibArtifacts(ccLinkParams.getLibraries()); - dynamicLibrariesForRuntime = ccLinkParams.getDynamicLibrariesForRuntime(); - assertThat(artifactsToStrings(libraries)).containsExactly("src b/libfoo.ifso"); - assertThat(artifactsToStrings(dynamicLibrariesForRuntime)) - .containsExactly("bin _solib_k8/_U_S_Sb_Cfoo___Ub/libfoo.so"); - - ccLinkParams = - target.get(CcInfo.PROVIDER).getCcLinkingInfo().getStaticModeParamsForExecutable(); - libraries = LinkerInputs.toNonSolibArtifacts(ccLinkParams.getLibraries()); - dynamicLibrariesForRuntime = ccLinkParams.getDynamicLibrariesForRuntime(); - assertThat(artifactsToStrings(libraries)).containsExactly("src b/libfoo.ifso"); - assertThat(artifactsToStrings(dynamicLibrariesForRuntime)) - .containsExactly("bin _solib_k8/_U_S_Sb_Cfoo___Ub/libfoo.so"); - - ccLinkParams = - target.get(CcInfo.PROVIDER).getCcLinkingInfo().getStaticModeParamsForDynamicLibrary(); - libraries = LinkerInputs.toNonSolibArtifacts(ccLinkParams.getLibraries()); - dynamicLibrariesForRuntime = ccLinkParams.getDynamicLibrariesForRuntime(); - assertThat(artifactsToStrings(libraries)).containsExactly("src b/libfoo.ifso"); + ; + Artifact library = + Iterables.getOnlyElement(target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries()) + .getResolvedSymlinkInterfaceLibrary(); + assertThat(artifactsToStrings(ImmutableList.of(library))).containsExactly("src b/libfoo.ifso"); + Iterable dynamicLibrariesForRuntime = + target + .get(CcInfo.PROVIDER) + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ false); assertThat(artifactsToStrings(dynamicLibrariesForRuntime)) .containsExactly("bin _solib_k8/_U_S_Sb_Cfoo___Ub/libfoo.so"); } @@ -271,35 +203,24 @@ public void testCcImportWithBothStaticAndSharedLibraries() throws Exception { "foo", skylarkImplementationLoadStatement, "cc_import(name = 'foo', static_library = 'libfoo.a', shared_library = 'libfoo.so')"); - CcLinkParams ccLinkParams = - target.get(CcInfo.PROVIDER).getCcLinkingInfo().getDynamicModeParamsForExecutable(); - Iterable libraries = LinkerInputs.toNonSolibArtifacts(ccLinkParams.getLibraries()); - Iterable dynamicLibrariesForRuntime = ccLinkParams.getDynamicLibrariesForRuntime(); - assertThat(artifactsToStrings(libraries)).containsExactly("src a/libfoo.so"); - assertThat(artifactsToStrings(dynamicLibrariesForRuntime)) - .containsExactly("bin _solib_k8/_U_S_Sa_Cfoo___Ua/libfoo.so"); - ccLinkParams = - target.get(CcInfo.PROVIDER).getCcLinkingInfo().getDynamicModeParamsForDynamicLibrary(); - libraries = LinkerInputs.toNonSolibArtifacts(ccLinkParams.getLibraries()); - dynamicLibrariesForRuntime = ccLinkParams.getDynamicLibrariesForRuntime(); - assertThat(artifactsToStrings(libraries)).containsExactly("src a/libfoo.so"); + Artifact library = + Iterables.getOnlyElement(target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries()) + .getStaticLibrary(); + assertThat(artifactsToStrings(ImmutableList.of(library))).containsExactly("src a/libfoo.a"); + + Artifact dynamicLibrary = + Iterables.getOnlyElement(target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries()) + .getResolvedSymlinkDynamicLibrary(); + Iterable dynamicLibrariesForRuntime = + target + .get(CcInfo.PROVIDER) + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ false); + assertThat(artifactsToStrings(ImmutableList.of(dynamicLibrary))) + .containsExactly("src a/libfoo.so"); assertThat(artifactsToStrings(dynamicLibrariesForRuntime)) .containsExactly("bin _solib_k8/_U_S_Sa_Cfoo___Ua/libfoo.so"); - - ccLinkParams = - target.get(CcInfo.PROVIDER).getCcLinkingInfo().getStaticModeParamsForExecutable(); - libraries = LinkerInputs.toNonSolibArtifacts(ccLinkParams.getLibraries()); - dynamicLibrariesForRuntime = ccLinkParams.getDynamicLibrariesForRuntime(); - assertThat(artifactsToStrings(libraries)).containsExactly("src a/libfoo.a"); - assertThat(artifactsToStrings(dynamicLibrariesForRuntime)).isEmpty(); - - ccLinkParams = - target.get(CcInfo.PROVIDER).getCcLinkingInfo().getStaticModeParamsForDynamicLibrary(); - libraries = LinkerInputs.toNonSolibArtifacts(ccLinkParams.getLibraries()); - dynamicLibrariesForRuntime = ccLinkParams.getDynamicLibrariesForRuntime(); - assertThat(artifactsToStrings(libraries)).containsExactly("src a/libfoo.a"); - assertThat(artifactsToStrings(dynamicLibrariesForRuntime)).isEmpty(); } @Test @@ -310,16 +231,10 @@ public void testCcImportWithAlwaysLinkStaticLibrary() throws Exception { "foo", skylarkImplementationLoadStatement, "cc_import(name = 'foo', static_library = 'libfoo.a', alwayslink = 1)"); - LibraryToLink libraryToLink = - target - .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getDynamicModeParamsForExecutable() - .getLibraries() - .toList() - .get(0); - assertThat(libraryToLink.getArtifactCategory()) - .isEqualTo(ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY); + boolean alwayslink = + Iterables.getOnlyElement(target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries()) + .getAlwayslink(); + assertThat(alwayslink).isTrue(); } @Test @@ -330,11 +245,15 @@ public void testCcImportSystemProvidedIsTrue() throws Exception { "foo", skylarkImplementationLoadStatement, "cc_import(name = 'foo', interface_library = 'libfoo.ifso', system_provided = 1)"); - CcLinkParams ccLinkParams = - target.get(CcInfo.PROVIDER).getCcLinkingInfo().getDynamicModeParamsForExecutable(); - Iterable libraries = LinkerInputs.toNonSolibArtifacts(ccLinkParams.getLibraries()); - Iterable dynamicLibrariesForRuntime = ccLinkParams.getDynamicLibrariesForRuntime(); - assertThat(artifactsToStrings(libraries)).containsExactly("src a/libfoo.ifso"); + Artifact library = + Iterables.getOnlyElement(target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries()) + .getResolvedSymlinkInterfaceLibrary(); + assertThat(artifactsToStrings(ImmutableList.of(library))).containsExactly("src a/libfoo.ifso"); + Iterable dynamicLibrariesForRuntime = + target + .get(CcInfo.PROVIDER) + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ false); assertThat(artifactsToStrings(dynamicLibrariesForRuntime)).isEmpty(); } diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java index 5f5ccf95a128d1..1392f2a96f1420 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java @@ -212,9 +212,8 @@ public void testFilesToBuild() throws Exception { assertThat( hello .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getDynamicModeParamsForExecutable() - .getDynamicLibrariesForRuntime()) + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ false)) .containsExactly(implSharedObjectLink); } @@ -278,22 +277,15 @@ public void testFilesToBuildWithInterfaceSharedObjects() throws Exception { assertThat( hello .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getDynamicModeParamsForExecutable() - .getDynamicLibrariesForRuntime()) + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ false)) .containsExactly(implSharedObjectLink); } @Test public void testEmptyLinkopts() throws Exception { ConfiguredTarget hello = getConfiguredTarget("//hello:hello"); - assertThat( - hello - .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getDynamicModeParamsForExecutable() - .getLinkopts() - .isEmpty()) + assertThat(hello.get(CcInfo.PROVIDER).getCcLinkingContext().getUserLinkFlags().isEmpty()) .isTrue(); } @@ -1384,14 +1376,15 @@ public void addStaticLibraryToStaticSharedLinkParamsWhenBuilding() throws Except ConfiguredTarget target = scratchConfiguredTarget("a", "foo", "cc_library(name = 'foo', srcs = ['foo.cc'])"); - Iterable libraries = - LinkerInputs.toNonSolibArtifacts( - target - .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getStaticModeParamsForDynamicLibrary() - .getLibraries()); - assertThat(artifactsToStrings(libraries)).contains("bin a/libfoo.a"); + LibraryToLinkWrapper library = + Iterables.getOnlyElement(target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries()); + Artifact libraryToUse = library.getPicStaticLibrary(); + if (libraryToUse == null) { + // We may get either a static library or pic static library depending on platform. + libraryToUse = library.getStaticLibrary(); + } + assertThat(libraryToUse).isNotNull(); + assertThat(artifactsToStrings(ImmutableList.of(libraryToUse))).contains("bin a/libfoo.a"); } @Test @@ -1400,32 +1393,21 @@ public void dontAddStaticLibraryToStaticSharedLinkParamsWhenWrappingSameLibraryI ConfiguredTarget target = scratchConfiguredTarget("a", "foo", "cc_library(name = 'foo', srcs = ['libfoo.so'])"); - Iterable libraries = - LinkerInputs.toNonSolibArtifacts( - target - .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getStaticModeParamsForDynamicLibrary() - .getLibraries()); - assertThat(artifactsToStrings(libraries)).doesNotContain("bin a/libfoo.a"); - assertThat(artifactsToStrings(libraries)).contains("src a/libfoo.so"); + LibraryToLinkWrapper library = + Iterables.getOnlyElement(target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries()); + assertThat(library.getStaticLibrary()).isNull(); + assertThat(artifactsToStrings(ImmutableList.of(library.getResolvedSymlinkDynamicLibrary()))) + .contains("src a/libfoo.so"); } @Test - public void onlyAddOneWrappedLibraryWithSameLibraryIdentifierToLinkParams() throws Exception { + public void onlyAddOneWrappedLibraryWithSameLibraryIdentifierToLibraries() throws Exception { ConfiguredTarget target = scratchConfiguredTarget( "a", "foo", "cc_library(name = 'foo', srcs = ['libfoo.lo', 'libfoo.so'])"); - Iterable libraries = - LinkerInputs.toNonSolibArtifacts( - target - .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getStaticModeParamsForDynamicLibrary() - .getLibraries()); - assertThat(artifactsToStrings(libraries)).doesNotContain("src a/libfoo.so"); - assertThat(artifactsToStrings(libraries)).contains("src a/libfoo.lo"); + assertThat(target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries().toList()) + .hasSize(1); } @Test @@ -1440,9 +1422,8 @@ public void testCcLinkParamsHasDynamicLibrariesForRuntime() throws Exception { Iterable libraries = target .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getDynamicModeParamsForDynamicLibrary() - .getDynamicLibrariesForRuntime(); + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ false); assertThat(artifactsToStrings(libraries)).doesNotContain("bin a/libfoo.ifso"); assertThat(artifactsToStrings(libraries)).contains("bin a/libfoo.so"); } @@ -1455,9 +1436,8 @@ public void testCcLinkParamsHasDynamicLibrariesForRuntimeWithoutCopyFeature() th Iterable libraries = target .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getDynamicModeParamsForDynamicLibrary() - .getDynamicLibrariesForRuntime(); + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ false); assertThat(artifactsToStrings(libraries)).doesNotContain("bin _solib_k8/liba_Slibfoo.ifso"); assertThat(artifactsToStrings(libraries)).contains("bin _solib_k8/liba_Slibfoo.so"); } @@ -1471,9 +1451,8 @@ public void testCcLinkParamsDoNotHaveDynamicLibrariesForRuntime() throws Excepti Iterable libraries = target .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getDynamicModeParamsForDynamicLibrary() - .getDynamicLibrariesForRuntime(); + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ false); assertThat(artifactsToStrings(libraries)).isEmpty(); } diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/LibraryLinkingTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/LibraryLinkingTest.java index 1d4f3c971f7bbe..c6beb9fc7ff2c0 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/LibraryLinkingTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/LibraryLinkingTest.java @@ -21,7 +21,6 @@ import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.FileProvider; import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; -import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper.CcLinkingContext; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; @@ -112,9 +111,8 @@ public boolean apply(Artifact artifact) { Iterables.getOnlyElement( ccLib .get(CcInfo.PROVIDER) - .getCcLinkingInfo() - .getDynamicModeParamsForExecutable() - .getDynamicLibrariesForRuntime()); + .getCcLinkingContext() + .getDynamicLibrariesForRuntime(/* linkingStatically= */ false)); // This artifact is generated by a SolibSymlinkAction, so we need to go back two levels. CppLinkAction solibLink = (CppLinkAction) getGeneratingAction(getGeneratingAction(soLib).getPrimaryInput()); @@ -122,74 +120,4 @@ public boolean apply(Artifact artifact) { assertThat(args).contains(linkOpt1); assertThat(args).contains(linkOpt2); } - - /** - * Tests that the shared library version of a cc_library includes linkopts settings in its link - * command line, but the archive library version doesn't. - */ - @Test - public void testBackAndForthCcLinkingInfoConversion() throws Exception { - scratch.overwriteFile( - "foo/BUILD", - "cc_library(name = 'a',", - " srcs = ['a.cc'],", - " linkopts = ['-La'],", - " deps = [':b', ':c'])", - "cc_library(name = 'b',", - " srcs = ['b.cc'],", - " linkopts = ['-Lb1', '-Lb2', '-La']);", - "cc_library(name = 'c',", - " srcs = ['c.so', 'c.pic.a', 'c1.a'],", - " linkopts = ['-Lb1'],", - " deps = [':d', 'script.lds'])", - "cc_library(name = 'd',", - " srcs = ['d.cc', 'd.so'],", - " deps = [':e', ':f'])", - "cc_library(name = 'e',", - " srcs = ['e.c'],", - " linkopts = ['-Le', '-La'])", - "cc_import(name = 'f',", - " interface_library = 'f.ifso',", - " system_provided = 1)"); - - ConfiguredTarget ccLib = getConfiguredTarget("//foo:a"); - CcLinkingInfo ccLinkingInfo = ccLib.get(CcInfo.PROVIDER).getCcLinkingInfo(); - CcLinkingContext ccLinkingContext = LibraryToLinkWrapper.fromCcLinkingInfo(ccLinkingInfo); - CcLinkingInfo convertedCcLinkingInfo = ccLinkingContext.toCcLinkingInfo(); - assertThat( - ccLinkParamsEquals( - ccLinkingInfo.getStaticModeParamsForExecutable(), - convertedCcLinkingInfo.getStaticModeParamsForExecutable())) - .isTrue(); - } - - /** - * We cannot implement equals() in CcLinkParams differently because that would change behavior. - * However, this test neeeds an equals method that is more thorough. - */ - private boolean ccLinkParamsEquals(CcLinkParams thisObject, CcLinkParams otherObject) { - if (thisObject == otherObject) { - return true; - } - if (!thisObject.flattenedLinkopts().equals(otherObject.flattenedLinkopts())) { - return false; - } - if (!thisObject.getLinkstamps().toList().equals(otherObject.getLinkstamps().toList())) { - return false; - } - if (!thisObject.getLibraries().toList().equals(otherObject.getLibraries().toList())) { - return false; - } - if (!thisObject - .getDynamicLibrariesForRuntime() - .toList() - .equals(otherObject.getDynamicLibrariesForRuntime().toList())) { - return false; - } - - if (!thisObject.getNonCodeInputs().toList().equals(otherObject.getNonCodeInputs().toList())) { - return false; - } - return true; - } } 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 261e090c750474..1a34a4a8d09dd3 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 @@ -54,7 +54,7 @@ import com.google.devtools.build.lib.rules.cpp.CppCompileAction; import com.google.devtools.build.lib.rules.cpp.CppModuleMap; import com.google.devtools.build.lib.rules.cpp.CppModuleMapAction; -import com.google.devtools.build.lib.rules.cpp.LinkerInput; +import com.google.devtools.build.lib.rules.cpp.LibraryToLinkWrapper; import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key; import com.google.devtools.build.lib.testutil.TestConstants; import com.google.devtools.build.lib.vfs.PathFragment; @@ -1475,12 +1475,14 @@ public void checkStoresCcLibsAsCc() throws Exception { ObjcProvider objcProvider = providerForTarget("//objc2:lib"); Iterable linkerInputArtifacts = - Iterables.transform(objcProvider.get(CC_LIBRARY), new Function() { - @Override - public Artifact apply(LinkerInput library) { - return library.getArtifact(); - } - }); + Iterables.transform( + objcProvider.get(CC_LIBRARY), + new Function() { + @Override + public Artifact apply(LibraryToLinkWrapper library) { + return library.getStaticLibrary(); + } + }); assertThat(linkerInputArtifacts) .containsAllOf(