Search in sources :

Example 1 with ToolPath

use of com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath in project bazel by bazelbuild.

the class NdkPaths method createToolpaths.

public ImmutableList<ToolPath> createToolpaths(String toolchainName, String targetPlatform, CppConfiguration.Tool... excludedTools) {
    ImmutableList.Builder<ToolPath> toolPaths = ImmutableList.builder();
    for (Tool tool : CppConfiguration.Tool.values()) {
        // Some toolchains don't have particular tools.
        if (!Arrays.asList(excludedTools).contains(tool)) {
            String toolPath = createToolPath(toolchainName, targetPlatform + "-" + tool.getNamePart());
            toolPaths.add(ToolPath.newBuilder().setName(tool.getNamePart()).setPath(toolPath).build());
        }
    }
    return toolPaths.build();
}
Also used : ToolPath(com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath) ImmutableList(com.google.common.collect.ImmutableList) Tool(com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool)

Example 2 with ToolPath

use of com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath in project bazel by bazelbuild.

the class AndroidNdkRepositoryFunction method createCcToolchainRule.

private static String createCcToolchainRule(String ccToolchainTemplate, CToolchain toolchain) {
    // TODO(bazel-team): It's unfortunate to have to extract data from a CToolchain proto like this.
    // It would be better to have a higher-level construction (like an AndroidToolchain class)
    // from which the CToolchain proto and rule information needed here can be created.
    // Alternatively it would be nicer to just be able to glob the entire NDK and add that one glob
    // to each cc_toolchain rule, and then the complexities in the method and the templates can
    // go away, but globbing the entire NDK takes ~60 seconds, mostly because of MD5ing all the
    // binary files in the NDK (eg the .so / .a / .o files).
    // This also includes the files captured with cxx_builtin_include_directory.
    // Use gcc specifically because clang toolchains will have both gcc and llvm toolchain paths,
    // but the gcc tool will actually be clang.
    ToolPath gcc = null;
    for (ToolPath toolPath : toolchain.getToolPathList()) {
        if ("gcc".equals(toolPath.getName())) {
            gcc = toolPath;
        }
    }
    checkNotNull(gcc, "gcc not found in crosstool toolpaths");
    String toolchainDirectory = NdkPaths.getToolchainDirectoryFromToolPath(gcc.getPath());
    // Create file glob patterns for the various files that the toolchain references.
    String androidPlatformIncludes = NdkPaths.stripRepositoryPrefix(toolchain.getBuiltinSysroot()) + "/**/*";
    List<String> toolchainFileGlobPatterns = new ArrayList<>();
    toolchainFileGlobPatterns.add(androidPlatformIncludes);
    for (String cxxFlag : toolchain.getUnfilteredCxxFlagList()) {
        if (!cxxFlag.startsWith("-")) {
            // Skip flag names
            toolchainFileGlobPatterns.add(NdkPaths.stripRepositoryPrefix(cxxFlag) + "/**/*");
        }
    }
    // If this is a clang toolchain, also add the corresponding gcc toolchain to the globs.
    int gccToolchainIndex = toolchain.getCompilerFlagList().indexOf("-gcc-toolchain");
    if (gccToolchainIndex > -1) {
        String gccToolchain = toolchain.getCompilerFlagList().get(gccToolchainIndex + 1);
        toolchainFileGlobPatterns.add(NdkPaths.stripRepositoryPrefix(gccToolchain) + "/**/*");
    }
    StringBuilder toolchainFileGlobs = new StringBuilder();
    for (String toolchainFileGlobPattern : toolchainFileGlobPatterns) {
        toolchainFileGlobs.append(String.format("        \"%s\",\n", toolchainFileGlobPattern));
    }
    return ccToolchainTemplate.replace("%toolchainName%", toolchain.getToolchainIdentifier()).replace("%cpu%", toolchain.getTargetCpu()).replace("%dynamicRuntimeLibs%", toolchain.getDynamicRuntimesFilegroup()).replace("%staticRuntimeLibs%", toolchain.getStaticRuntimesFilegroup()).replace("%toolchainDirectory%", toolchainDirectory).replace("%toolchainFileGlobs%", toolchainFileGlobs.toString().trim());
}
Also used : ToolPath(com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath) ArrayList(java.util.ArrayList)

Example 3 with ToolPath

use of com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath in project bazel by bazelbuild.

the class CppConfiguration method addLegacyFeatures.

// TODO(bazel-team): Remove this once bazel supports all crosstool flags through
// feature configuration, and all crosstools have been converted.
private CToolchain addLegacyFeatures(CToolchain toolchain) {
    CToolchain.Builder toolchainBuilder = CToolchain.newBuilder();
    Set<ArtifactCategory> definedCategories = new HashSet<>();
    for (ArtifactNamePattern pattern : toolchainBuilder.getArtifactNamePatternList()) {
        try {
            definedCategories.add(ArtifactCategory.valueOf(pattern.getCategoryName().toUpperCase()));
        } catch (IllegalArgumentException e) {
            // Invalid category name, will be detected later.
            continue;
        }
    }
    for (ArtifactCategory category : ArtifactCategory.values()) {
        if (!definedCategories.contains(category) && category.getDefaultPattern() != null) {
            toolchainBuilder.addArtifactNamePattern(ArtifactNamePattern.newBuilder().setCategoryName(category.toString().toLowerCase()).setPattern(category.getDefaultPattern()).build());
        }
    }
    ImmutableSet.Builder<String> featuresBuilder = ImmutableSet.builder();
    for (CToolchain.Feature feature : toolchain.getFeatureList()) {
        featuresBuilder.add(feature.getName());
    }
    Set<String> features = featuresBuilder.build();
    if (!features.contains(CppRuleClasses.NO_LEGACY_FEATURES)) {
        try {
            if (!linkActionsAreConfigured(toolchain)) {
                String linkerToolPath = "DUMMY_LINKER_TOOL";
                for (ToolPath tool : toolchain.getToolPathList()) {
                    if (tool.getName().equals(Tool.GCC.getNamePart())) {
                        linkerToolPath = crosstoolTopPathFragment.getRelative(new PathFragment(tool.getPath())).getPathString();
                    }
                }
                if (getTargetLibc().equals("macosx")) {
                    TextFormat.merge(CppLinkActionConfigs.getCppLinkActionConfigs(CppLinkPlatform.MAC, features, linkerToolPath, supportsEmbeddedRuntimes), toolchainBuilder);
                } else {
                    TextFormat.merge(CppLinkActionConfigs.getCppLinkActionConfigs(CppLinkPlatform.LINUX, features, linkerToolPath, supportsEmbeddedRuntimes), toolchainBuilder);
                }
            }
            if (!features.contains("dependency_file")) {
                // Gcc options:
                //  -MD turns on .d file output as a side-effect (doesn't imply -E)
                //  -MM[D] enables user includes only, not system includes
                //  -MF <name> specifies the dotd file name
                // Issues:
                //  -M[M] alone subverts actual .o output (implies -E)
                //  -M[M]D alone breaks some of the .d naming assumptions
                // This combination gets user and system includes with specified name:
                //  -MD -MF <name>
                TextFormat.merge("" + "feature {" + "  name: 'dependency_file'" + "  flag_set {" + "    action: 'assemble'" + "    action: 'preprocess-assemble'" + "    action: 'c-compile'" + "    action: 'c++-compile'" + "    action: 'c++-module-compile'" + "    action: 'objc-compile'" + "    action: 'objc++-compile'" + "    action: 'c++-header-preprocessing'" + "    action: 'c++-header-parsing'" + "    expand_if_all_available: 'dependency_file'" + "    flag_group {" + "      flag: '-MD'" + "      flag: '-MF'" + "      flag: '%{dependency_file}'" + "    }" + "  }" + "}", toolchainBuilder);
            }
            if (!features.contains("random_seed")) {
                // GCC and Clang give randomized names to symbols which are defined in
                // an anonymous namespace but have external linkage.  To make
                // computation of these deterministic, we want to override the
                // default seed for the random number generator.  It's safe to use
                // any value which differs for all translation units; we use the
                // path to the object file.
                TextFormat.merge("" + "feature {" + "  name: 'random_seed'" + "  flag_set {" + "    action: 'c++-compile'" + "    action: 'c++-module-codegen'" + "    action: 'c++-module-compile'" + "    flag_group {" + "      flag: '-frandom-seed=%{output_file}'" + "    }" + "  }" + "}", toolchainBuilder);
            }
            if (!features.contains("pic")) {
                TextFormat.merge("" + "feature {" + "  name: 'pic'" + "  flag_set {" + "    action: 'c-compile'" + "    action: 'c++-compile'" + "    action: 'c++-module-codegen'" + "    action: 'c++-module-compile'" + "    action: 'preprocess-assemble'" + "    expand_if_all_available: 'pic'" + "    flag_group {" + "      flag: '-fPIC'" + "    }" + "  }" + "}", toolchainBuilder);
            }
            if (!features.contains("per_object_debug_info")) {
                TextFormat.merge("" + "feature {" + "  name: 'per_object_debug_info'" + "  flag_set {" + "    action: 'c-compile'" + "    action: 'c++-compile'" + "    action: 'assemble'" + "    action: 'preprocess-assemble'" + "    action: 'lto-backend'" + "    expand_if_all_available: 'per_object_debug_info_file'" + "    flag_group {" + "      flag: '-gsplit-dwarf'" + "    }" + "  }" + "}", toolchainBuilder);
            }
            if (!features.contains("preprocessor_defines")) {
                TextFormat.merge("" + "feature {" + "  name: 'preprocessor_defines'" + "  flag_set {" + "    action: 'preprocess-assemble'" + "    action: 'c-compile'" + "    action: 'c++-compile'" + "    action: 'c++-header-parsing'" + "    action: 'c++-header-preprocessing'" + "    action: 'c++-module-compile'" + "    action: 'clif-match'" + "    flag_group {" + "      flag: '-D%{preprocessor_defines}'" + "    }" + "  }" + "}", toolchainBuilder);
            }
            if (!features.contains("include_paths")) {
                TextFormat.merge("" + "feature {" + "  name: 'include_paths'" + "  flag_set {" + "    action: 'preprocess-assemble'" + "    action: 'c-compile'" + "    action: 'c++-compile'" + "    action: 'c++-header-parsing'" + "    action: 'c++-header-preprocessing'" + "    action: 'c++-module-compile'" + "    action: 'clif-match'" + "    action: 'objc-compile'" + "    action: 'objc++-compile'" + "    flag_group {" + "      flag: '-iquote'" + "      flag: '%{quote_include_paths}'" + "    }" + "    flag_group {" + "      flag: '-I%{include_paths}'" + "    }" + "    flag_group {" + "      flag: '-isystem'" + "      flag: '%{system_include_paths}'" + "    }" + "  }" + "}", toolchainBuilder);
            }
            if (!features.contains("fdo_instrument")) {
                TextFormat.merge("" + "feature {" + "  name: 'fdo_instrument'" + "  provides: 'profile'" + "  flag_set {" + "    action: 'c-compile'" + "    action: 'c++-compile'" + "    action: 'c++-link-interface-dynamic-library'" + "    action: 'c++-link-dynamic-library'" + "    action: 'c++-link-executable'" + "    flag_group {" + "      flag: '-fprofile-generate=%{fdo_instrument_path}'" + "      flag: '-fno-data-sections'" + "    }" + "  }" + "}", toolchainBuilder);
            }
            if (!features.contains("fdo_optimize")) {
                TextFormat.merge("" + "feature {" + "  name: 'fdo_optimize'" + "  provides: 'profile'" + "  flag_set {" + "    action: 'c-compile'" + "    action: 'c++-compile'" + "    expand_if_all_available: 'fdo_profile_path'" + "    flag_group {" + "      flag: '-fprofile-use=%{fdo_profile_path}'" + "      flag: '-Xclang-only=-Wno-profile-instr-unprofiled'" + "      flag: '-Xclang-only=-Wno-profile-instr-out-of-date'" + "      flag: '-fprofile-correction'" + "    }" + "  }" + "}", toolchainBuilder);
            }
            if (!features.contains("autofdo")) {
                TextFormat.merge("" + "feature {" + "  name: 'autofdo'" + "  provides: 'profile'" + "  flag_set {" + "    action: 'c-compile'" + "    action: 'c++-compile'" + "    expand_if_all_available: 'fdo_profile_path'" + "    flag_group {" + "      flag: '-fauto-profile=%{fdo_profile_path}'" + "      flag: '-fprofile-correction'" + "    }" + "  }" + "}", toolchainBuilder);
            }
            if (!features.contains("lipo")) {
                TextFormat.merge("" + "feature {" + "  name: 'lipo'" + "  requires { feature: 'autofdo' }" + "  requires { feature: 'fdo_optimize' }" + "  requires { feature: 'fdo_instrument' }" + "  flag_set {" + "    action: 'c-compile'" + "    action: 'c++-compile'" + "    flag_group {" + "      flag: '-fripa'" + "    }" + "  }" + "}", toolchainBuilder);
            }
            if (!features.contains("coverage")) {
                String compileFlags;
                String linkerFlags;
                if (useLLVMCoverageMap) {
                    compileFlags = "flag_group {" + " flag: '-fprofile-instr-generate'" + " flag: '-fcoverage-mapping'" + "}";
                    linkerFlags = "  flag_group {" + "  flag: '-fprofile-instr-generate'" + "}";
                } else {
                    compileFlags = "  expand_if_all_available: 'gcov_gcno_file'" + "flag_group {" + "  flag: '-fprofile-arcs'" + "  flag: '-ftest-coverage'" + "}";
                    linkerFlags = "  flag_group {" + "  flag: '-lgcov'" + "}";
                }
                TextFormat.merge("" + "feature {" + "  name: 'coverage'" + "  provides: 'profile'" + "  flag_set {" + "    action: 'preprocess-assemble'" + "    action: 'c-compile'" + "    action: 'c++-compile'" + "    action: 'c++-header-parsing'" + "    action: 'c++-header-preprocessing'" + "    action: 'c++-module-compile'" + compileFlags + "  }" + "  flag_set {" + "    action: 'c++-link-interface-dynamic-library'" + "    action: 'c++-link-dynamic-library'" + "    action: 'c++-link-executable'" + linkerFlags + "  }" + "}", toolchainBuilder);
            }
        } catch (ParseException e) {
            // configuration above.
            throw new RuntimeException(e);
        }
    }
    toolchainBuilder.mergeFrom(toolchain);
    return toolchainBuilder.build();
}
Also used : ToolPath(com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath) ArtifactNamePattern(com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain.ArtifactNamePattern) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) CToolchain(com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain) ImmutableSet(com.google.common.collect.ImmutableSet) ParseException(com.google.protobuf.TextFormat.ParseException) HashSet(java.util.HashSet)

Example 4 with ToolPath

use of com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath in project bazel by bazelbuild.

the class AndroidNdkCrosstoolsTest method testPathsExist.

@Test
public void testPathsExist() throws Exception {
    for (CrosstoolRelease crosstool : crosstoolReleases) {
        for (CToolchain toolchain : crosstool.getToolchainList()) {
            // Test that all tool paths exist.
            for (ToolPath toolpath : toolchain.getToolPathList()) {
                assertThat(ndkFiles).contains(toolpath.getPath());
            }
            // Test that all cxx_builtin_include_directory paths exist.
            for (String includeDirectory : toolchain.getCxxBuiltinIncludeDirectoryList()) {
                // Special case for builtin_sysroot.
                if (!includeDirectory.equals("%sysroot%/usr/include")) {
                    String path = NdkPaths.stripRepositoryPrefix(includeDirectory);
                    assertThat(ndkDirectories).contains(path);
                }
            }
            // Test that the builtin_sysroot path exists.
            {
                String builtinSysroot = NdkPaths.stripRepositoryPrefix(toolchain.getBuiltinSysroot());
                assertThat(ndkDirectories).contains(builtinSysroot);
            }
            // Test that all include directories added through unfiltered_cxx_flag exist.
            for (String flag : toolchain.getUnfilteredCxxFlagList()) {
                if (!flag.equals("-isystem")) {
                    flag = NdkPaths.stripRepositoryPrefix(flag);
                    assertThat(ndkDirectories).contains(flag);
                }
            }
        }
    }
}
Also used : CToolchain(com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain) ToolPath(com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath) CrosstoolRelease(com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease) Test(org.junit.Test)

Aggregations

ToolPath (com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath)4 CToolchain (com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain)2 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Tool (com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool)1 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)1 ArtifactNamePattern (com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain.ArtifactNamePattern)1 CrosstoolRelease (com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease)1 ParseException (com.google.protobuf.TextFormat.ParseException)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 Test (org.junit.Test)1