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();
}
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());
}
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();
}
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);
}
}
}
}
}
Aggregations