Search in sources :

Example 1 with SymlinkAction

use of com.google.devtools.build.lib.analysis.actions.SymlinkAction in project bazel by bazelbuild.

the class NativeDepsHelper method createNativeDepsAction.

public static NativeDepsRunfiles createNativeDepsAction(final RuleContext ruleContext, CcLinkParams linkParams, Collection<String> extraLinkOpts, BuildConfiguration configuration, CcToolchainProvider toolchain, Artifact nativeDeps, String libraryIdentifier, Root bindirIfShared, boolean useDynamicRuntime) throws InterruptedException {
    Preconditions.checkState(ruleContext.isLegalFragment(CppConfiguration.class), "%s does not have access to CppConfiguration", ruleContext.getRule().getRuleClass());
    List<String> linkopts = new ArrayList<>(extraLinkOpts);
    linkopts.addAll(linkParams.flattenedLinkopts());
    Map<Artifact, NestedSet<Artifact>> linkstamps = CppHelper.resolveLinkstamps(ruleContext, linkParams);
    List<Artifact> buildInfoArtifacts = linkstamps.isEmpty() ? ImmutableList.<Artifact>of() : ruleContext.getAnalysisEnvironment().getBuildInfo(ruleContext, CppBuildInfo.KEY, configuration);
    boolean shareNativeDeps = configuration.getFragment(CppConfiguration.class).shareNativeDeps();
    NestedSet<LibraryToLink> linkerInputs = linkParams.getLibraries();
    Artifact sharedLibrary;
    if (shareNativeDeps) {
        PathFragment sharedPath = getSharedNativeDepsPath(LinkerInputs.toLibraryArtifacts(linkerInputs), linkopts, linkstamps.keySet(), buildInfoArtifacts, ruleContext.getFeatures());
        libraryIdentifier = sharedPath.getPathString();
        sharedLibrary = ruleContext.getShareableArtifact(sharedPath.replaceName(sharedPath.getBaseName() + ".so"), configuration.getBinDirectory(ruleContext.getRule().getRepository()));
    } else {
        sharedLibrary = nativeDeps;
    }
    FdoSupportProvider fdoSupport = CppHelper.getFdoSupport(ruleContext, ":cc_toolchain");
    CppLinkActionBuilder builder = new CppLinkActionBuilder(ruleContext, sharedLibrary, configuration, toolchain, fdoSupport);
    if (useDynamicRuntime) {
        builder.setRuntimeInputs(ArtifactCategory.DYNAMIC_LIBRARY, toolchain.getDynamicRuntimeLinkMiddleman(), toolchain.getDynamicRuntimeLinkInputs());
    } else {
        builder.setRuntimeInputs(ArtifactCategory.STATIC_LIBRARY, toolchain.getStaticRuntimeLinkMiddleman(), toolchain.getStaticRuntimeLinkInputs());
    }
    CppLinkAction linkAction = builder.setLinkArtifactFactory(SHAREABLE_LINK_ARTIFACT_FACTORY).setCrosstoolInputs(toolchain.getLink()).addLibraries(linkerInputs).setLinkType(LinkTargetType.DYNAMIC_LIBRARY).setLinkStaticness(LinkStaticness.MOSTLY_STATIC).setLibraryIdentifier(libraryIdentifier).addLinkopts(linkopts).setNativeDeps(true).addLinkstamps(linkstamps).build();
    ruleContext.registerAction(linkAction);
    Artifact linkerOutput = linkAction.getPrimaryOutput();
    if (shareNativeDeps) {
        // Collect dynamic-linker-resolvable symlinks for C++ runtime library dependencies.
        // Note we only need these symlinks when --share_native_deps is on, as shared native deps
        // mangle path names such that the library's conventional _solib RPATH entry
        // no longer resolves (because the target directory's relative depth gets lost).
        List<Artifact> runtimeSymlinks;
        if (useDynamicRuntime) {
            runtimeSymlinks = new LinkedList<>();
            for (final Artifact runtimeInput : toolchain.getDynamicRuntimeLinkInputs()) {
                final Artifact runtimeSymlink = ruleContext.getPackageRelativeArtifact(getRuntimeLibraryPath(ruleContext, runtimeInput), bindirIfShared);
                // Since runtime library symlinks are underneath the target's output directory and
                // multiple targets may share the same output directory, we need to make sure this
                // symlink's generating action is only set once.
                ruleContext.registerAction(new SymlinkAction(ruleContext.getActionOwner(), runtimeInput, runtimeSymlink, null));
                runtimeSymlinks.add(runtimeSymlink);
            }
        } else {
            runtimeSymlinks = ImmutableList.of();
        }
        ruleContext.registerAction(new SymlinkAction(ruleContext.getActionOwner(), linkerOutput, nativeDeps, null));
        return new NativeDepsRunfiles(nativeDeps, runtimeSymlinks);
    }
    return new NativeDepsRunfiles(linkerOutput, ImmutableList.<Artifact>of());
}
Also used : NestedSet(com.google.devtools.build.lib.collect.nestedset.NestedSet) FdoSupportProvider(com.google.devtools.build.lib.rules.cpp.FdoSupportProvider) SymlinkAction(com.google.devtools.build.lib.analysis.actions.SymlinkAction) ArrayList(java.util.ArrayList) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) Artifact(com.google.devtools.build.lib.actions.Artifact) LibraryToLink(com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink) CppLinkAction(com.google.devtools.build.lib.rules.cpp.CppLinkAction) CppConfiguration(com.google.devtools.build.lib.rules.cpp.CppConfiguration) CppLinkActionBuilder(com.google.devtools.build.lib.rules.cpp.CppLinkActionBuilder)

Example 2 with SymlinkAction

use of com.google.devtools.build.lib.analysis.actions.SymlinkAction in project bazel by bazelbuild.

the class CcLibraryHelper method computePublicHeaders.

private PublicHeaders computePublicHeaders() {
    if (!ruleContext.attributes().has("strip_include_prefix", Type.STRING) || !ruleContext.attributes().has("include_prefix", Type.STRING)) {
        return new PublicHeaders(ImmutableList.copyOf(Iterables.concat(publicHeaders, nonModuleMapHeaders)), ImmutableList.copyOf(publicHeaders), null);
    }
    PathFragment prefix = ruleContext.attributes().isAttributeValueExplicitlySpecified("include_prefix") ? new PathFragment(ruleContext.attributes().get("include_prefix", Type.STRING)) : null;
    PathFragment stripPrefix;
    if (ruleContext.attributes().isAttributeValueExplicitlySpecified("strip_include_prefix")) {
        stripPrefix = new PathFragment(ruleContext.attributes().get("strip_include_prefix", Type.STRING));
        if (stripPrefix.isAbsolute()) {
            stripPrefix = ruleContext.getLabel().getPackageIdentifier().getRepository().getSourceRoot().getRelative(stripPrefix.toRelative());
        } else {
            stripPrefix = ruleContext.getPackageDirectory().getRelative(stripPrefix);
        }
    } else if (prefix != null) {
        stripPrefix = ruleContext.getPackageDirectory();
    } else {
        stripPrefix = null;
    }
    if (stripPrefix == null && prefix == null) {
        // Simple case, no magic needed
        return new PublicHeaders(ImmutableList.copyOf(Iterables.concat(publicHeaders, nonModuleMapHeaders)), ImmutableList.copyOf(publicHeaders), null);
    }
    if (stripPrefix.containsUplevelReferences()) {
        ruleContext.attributeError("strip_include_prefix", "should not contain uplevel references");
    }
    if (prefix != null && prefix.containsUplevelReferences()) {
        ruleContext.attributeError("include_prefix", "should not contain uplevel references");
    }
    if (prefix != null && prefix.isAbsolute()) {
        ruleContext.attributeError("include_prefix", "should be a relative path");
    }
    if (ruleContext.hasErrors()) {
        return new PublicHeaders(ImmutableList.<Artifact>of(), ImmutableList.<Artifact>of(), null);
    }
    ImmutableList.Builder<Artifact> moduleHeadersBuilder = ImmutableList.builder();
    for (Artifact originalHeader : publicHeaders) {
        if (!originalHeader.getRootRelativePath().startsWith(stripPrefix)) {
            ruleContext.ruleError(String.format("header '%s' is not under the specified strip prefix '%s'", originalHeader.getExecPathString(), stripPrefix.getPathString()));
            continue;
        }
        PathFragment includePath = originalHeader.getRootRelativePath().relativeTo(stripPrefix);
        if (prefix != null) {
            includePath = prefix.getRelative(includePath);
        }
        if (!originalHeader.getExecPath().equals(includePath)) {
            Artifact virtualHeader = ruleContext.getUniqueDirectoryArtifact("_virtual_includes", includePath, ruleContext.getBinOrGenfilesDirectory());
            ruleContext.registerAction(new SymlinkAction(ruleContext.getActionOwner(), originalHeader, virtualHeader, "Symlinking virtual headers for " + ruleContext.getLabel()));
            moduleHeadersBuilder.add(virtualHeader);
        } else {
            moduleHeadersBuilder.add(originalHeader);
        }
    }
    ImmutableList<Artifact> moduleMapHeaders = moduleHeadersBuilder.build();
    ImmutableList<Artifact> virtualHeaders = ImmutableList.<Artifact>builder().addAll(moduleMapHeaders).addAll(nonModuleMapHeaders).build();
    return new PublicHeaders(virtualHeaders, moduleMapHeaders, ruleContext.getBinOrGenfilesDirectory().getExecPath().getRelative(ruleContext.getUniqueDirectory("_virtual_includes")));
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) SymlinkAction(com.google.devtools.build.lib.analysis.actions.SymlinkAction) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) Artifact(com.google.devtools.build.lib.actions.Artifact)

Example 3 with SymlinkAction

use of com.google.devtools.build.lib.analysis.actions.SymlinkAction in project bazel by bazelbuild.

the class XcodeSupport method addDummySource.

/**
   * Adds a dummy source file to the Xcode target. This is needed if the target does not have any
   * source files but Xcode requires one.
   *
   * @return this xcode support
   */
XcodeSupport addDummySource(XcodeProvider.Builder xcodeProviderBuilder) {
    ruleContext.registerAction(new SymlinkAction(ruleContext.getActionOwner(), ruleContext.getPrerequisiteArtifact("$dummy_source", Mode.TARGET), intermediateArtifacts.dummySource(), "Symlinking dummy artifact"));
    xcodeProviderBuilder.addAdditionalSources(intermediateArtifacts.dummySource());
    return this;
}
Also used : SymlinkAction(com.google.devtools.build.lib.analysis.actions.SymlinkAction)

Aggregations

SymlinkAction (com.google.devtools.build.lib.analysis.actions.SymlinkAction)3 Artifact (com.google.devtools.build.lib.actions.Artifact)2 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)2 ImmutableList (com.google.common.collect.ImmutableList)1 NestedSet (com.google.devtools.build.lib.collect.nestedset.NestedSet)1 CppConfiguration (com.google.devtools.build.lib.rules.cpp.CppConfiguration)1 CppLinkAction (com.google.devtools.build.lib.rules.cpp.CppLinkAction)1 CppLinkActionBuilder (com.google.devtools.build.lib.rules.cpp.CppLinkActionBuilder)1 FdoSupportProvider (com.google.devtools.build.lib.rules.cpp.FdoSupportProvider)1 LibraryToLink (com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink)1 ArrayList (java.util.ArrayList)1