Search in sources :

Example 91 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment in project bazel by bazelbuild.

the class NativeDepsHelper method linkAndroidNativeDepsIfPresent.

/**
   * Creates an Action to create a dynamic library for Android by linking all native code (C/C++)
   * libraries in the transitive dependency closure of a rule.
   *
   * <p>We link the native deps in the equivalent of linkstatic=1, linkshared=1 mode.
   *
   * <p>linkstatic=1 means mostly-static mode, i.e. we select the ".a" (or ".pic.a") files, but we
   * don't include "-static" in linkopts.
   *
   * <p>linkshared=1 means we prefer the ".pic.a" files to the ".a" files, and the LinkTargetType is
   * set to DYNAMIC_LIBRARY which causes Link.java to include "-shared" in the linker options.
   *
   * <p>It is possible that this function may have no work to do if there are no native libraries
   * in the transitive closure, or if the only native libraries in the transitive closure are
   * already 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
   * @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, final BuildConfiguration configuration, CcToolchainProvider toolchain) throws InterruptedException {
    if (!containsCodeToLink(linkParams.getLibraries())) {
        return null;
    }
    PathFragment labelName = new PathFragment(ruleContext.getLabel().getName());
    String libraryIdentifier = ruleContext.getUniqueDirectory(ANDROID_UNIQUE_DIR).getRelative(labelName.replaceName("lib" + labelName.getBaseName())).getPathString();
    Artifact nativeDeps = ruleContext.getUniqueDirectoryArtifact(ANDROID_UNIQUE_DIR, labelName.replaceName("lib" + labelName.getBaseName() + ".so"), configuration.getBinDirectory(ruleContext.getRule().getRepository()));
    return createNativeDepsAction(ruleContext, linkParams, /** extraLinkOpts */
    ImmutableList.<String>of(), configuration, toolchain, nativeDeps, libraryIdentifier, configuration.getBinDirectory(ruleContext.getRule().getRepository()), /*useDynamicRuntime*/
    false).getLibrary();
}
Also used : PathFragment(com.google.devtools.build.lib.vfs.PathFragment) Artifact(com.google.devtools.build.lib.actions.Artifact)

Example 92 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment 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 93 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment in project bazel by bazelbuild.

the class FdoSupport method readAutoFdoImports.

/**
   * Reads a .afdo.imports file and stores the imports information.
   */
private static ImmutableMultimap<PathFragment, PathFragment> readAutoFdoImports(Path importsFile) throws IOException, FdoException {
    ImmutableMultimap.Builder<PathFragment, PathFragment> importBuilder = ImmutableMultimap.builder();
    for (String line : FileSystemUtils.iterateLinesAsLatin1(importsFile)) {
        line = line.trim();
        if (line.isEmpty()) {
            continue;
        }
        int colonIndex = line.indexOf(':');
        if (colonIndex < 0) {
            continue;
        }
        PathFragment key = new PathFragment(line.substring(0, colonIndex));
        if (key.isAbsolute()) {
            throw new FdoException("Absolute paths not allowed in afdo imports file " + importsFile + ": " + key);
        }
        for (String auxFile : line.substring(colonIndex + 1).split(" ")) {
            if (auxFile.length() == 0) {
                continue;
            }
            importBuilder.put(key, new PathFragment(auxFile));
        }
    }
    return importBuilder.build();
}
Also used : PathFragment(com.google.devtools.build.lib.vfs.PathFragment) ImmutableMultimap(com.google.common.collect.ImmutableMultimap)

Example 94 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment in project bazel by bazelbuild.

the class FdoSupport method getGcdaArtifactsForObjectFileName.

/**
   * Returns a list of .gcda file artifacts for an object file path.
   *
   * <p>The resulting set is either empty (because no .gcda file exists for the
   * given object file) or contains one or two artifacts (the file itself and a
   * symlink to it).
   */
private ImmutableList<Artifact> getGcdaArtifactsForObjectFileName(RuleContext ruleContext, FdoSupportProvider fdoSupportProvider, PathFragment objectFileName, Label lipoLabel) {
    // We put the .gcda files relative to the location of the .o file in the instrumentation run.
    String gcdaExt = Iterables.getOnlyElement(CppFileTypes.COVERAGE_DATA.getExtensions());
    PathFragment baseName = FileSystemUtils.replaceExtension(objectFileName, gcdaExt);
    PathFragment gcdaFile = getNonLipoObjDir(ruleContext, lipoLabel).getRelative(baseName);
    if (!gcdaFiles.contains(gcdaFile)) {
        // If the object is a .pic.o file and .pic.gcda is not found, we should try finding .gcda too
        String picoExt = Iterables.getOnlyElement(CppFileTypes.PIC_OBJECT_FILE.getExtensions());
        baseName = FileSystemUtils.replaceExtension(objectFileName, gcdaExt, picoExt);
        if (baseName == null) {
            // Object file is not .pic.o
            return ImmutableList.of();
        }
        gcdaFile = getNonLipoObjDir(ruleContext, lipoLabel).getRelative(baseName);
        if (!gcdaFiles.contains(gcdaFile)) {
            // .gcda file not found
            return ImmutableList.of();
        }
    }
    return ImmutableList.of(fdoSupportProvider.getGcdaArtifacts().get(gcdaFile));
}
Also used : PathFragment(com.google.devtools.build.lib.vfs.PathFragment)

Example 95 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment in project bazel by bazelbuild.

the class FdoSupport method extractFdoZip.

/**
   * Extracts the FDO zip file and collects data from it that's needed during analysis.
   *
   * <p>When an {@code --fdo_optimize} compile is requested, unpacks the given
   * FDO gcda zip file into a clean working directory under execRoot.
   *
   * @throws FdoException if the FDO ZIP contains a file of unknown type
   */
private static FdoZipContents extractFdoZip(FdoMode fdoMode, LipoMode lipoMode, Path execRoot, Path fdoProfile, PathFragment fdoRootExecPath, String productName) throws IOException, FdoException {
    // The execRoot != null case is only there for testing. We cannot provide a real ZIP file in
    // tests because ZipFileSystem does not work with a ZIP on an in-memory file system.
    // IMPORTANT: Keep in sync with #declareSkyframeDependencies to avoid incrementality issues.
    ImmutableSet<PathFragment> gcdaFiles = ImmutableSet.of();
    ImmutableMultimap<PathFragment, PathFragment> imports = ImmutableMultimap.of();
    if (fdoProfile != null && execRoot != null) {
        Path fdoDirPath = execRoot.getRelative(fdoRootExecPath);
        FileSystemUtils.deleteTreesBelow(fdoDirPath);
        FileSystemUtils.createDirectoryAndParents(fdoDirPath);
        if (fdoMode == FdoMode.AUTO_FDO) {
            if (lipoMode != LipoMode.OFF) {
                imports = readAutoFdoImports(getAutoFdoImportsPath(fdoProfile));
            }
            FileSystemUtils.ensureSymbolicLink(execRoot.getRelative(getAutoProfilePath(fdoProfile, fdoRootExecPath)), fdoProfile);
        } else if (fdoMode == FdoMode.LLVM_FDO) {
            FileSystemUtils.ensureSymbolicLink(execRoot.getRelative(getLLVMProfilePath(fdoProfile, fdoRootExecPath)), fdoProfile);
        } else {
            Path zipFilePath = new ZipFileSystem(fdoProfile).getRootDirectory();
            String outputSymlinkName = productName + "-out";
            if (!zipFilePath.getRelative(outputSymlinkName).isDirectory()) {
                throw new ZipException("FDO zip files must be zipped directly above '" + outputSymlinkName + "' for the compiler to find the profile");
            }
            ImmutableSet.Builder<PathFragment> gcdaFilesBuilder = ImmutableSet.builder();
            ImmutableMultimap.Builder<PathFragment, PathFragment> importsBuilder = ImmutableMultimap.builder();
            extractFdoZipDirectory(zipFilePath, fdoDirPath, gcdaFilesBuilder, importsBuilder);
            gcdaFiles = gcdaFilesBuilder.build();
            imports = importsBuilder.build();
        }
    }
    return new FdoZipContents(gcdaFiles, imports);
}
Also used : RootedPath(com.google.devtools.build.lib.vfs.RootedPath) Path(com.google.devtools.build.lib.vfs.Path) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) ZipException(java.util.zip.ZipException) ZipFileSystem(com.google.devtools.build.lib.vfs.ZipFileSystem)

Aggregations

PathFragment (com.google.devtools.build.lib.vfs.PathFragment)512 Test (org.junit.Test)208 Artifact (com.google.devtools.build.lib.actions.Artifact)184 Path (com.google.devtools.build.lib.vfs.Path)111 RootedPath (com.google.devtools.build.lib.vfs.RootedPath)65 SkyKey (com.google.devtools.build.skyframe.SkyKey)56 IOException (java.io.IOException)38 ArrayList (java.util.ArrayList)35 ImmutableList (com.google.common.collect.ImmutableList)32 Root (com.google.devtools.build.lib.actions.Root)32 HashMap (java.util.HashMap)27 Label (com.google.devtools.build.lib.cmdline.Label)26 LinkedHashMap (java.util.LinkedHashMap)26 TreeFileArtifact (com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact)23 ImmutableMap (com.google.common.collect.ImmutableMap)22 Map (java.util.Map)21 SpecialArtifact (com.google.devtools.build.lib.actions.Artifact.SpecialArtifact)20 FilesetTraversalParams (com.google.devtools.build.lib.actions.FilesetTraversalParams)16 PackageIdentifier (com.google.devtools.build.lib.cmdline.PackageIdentifier)16 NestedSetBuilder (com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder)16