use of com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain in project bazel by bazelbuild.
the class AndroidNdkCrosstoolsTest method testAllToolchainsHaveRuntimesFilegroup.
@Test
public void testAllToolchainsHaveRuntimesFilegroup() {
for (CrosstoolRelease crosstool : crosstoolReleases) {
for (CToolchain toolchain : crosstool.getToolchainList()) {
assertThat(toolchain.getDynamicRuntimesFilegroup()).isNotEmpty();
assertThat(toolchain.getStaticRuntimesFilegroup()).isNotEmpty();
}
}
}
use of com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain in project bazel by bazelbuild.
the class AndroidNdkRepositoryFunction method createBuildFile.
private static String createBuildFile(String ruleName, List<CrosstoolStlPair> crosstools) {
String buildFileTemplate = getTemplate("android_ndk_build_file_template.txt");
String ccToolchainSuiteTemplate = getTemplate("android_ndk_cc_toolchain_suite_template.txt");
String ccToolchainTemplate = getTemplate("android_ndk_cc_toolchain_template.txt");
String stlFilegroupTemplate = getTemplate("android_ndk_stl_filegroup_template.txt");
StringBuilder ccToolchainSuites = new StringBuilder();
StringBuilder ccToolchainRules = new StringBuilder();
StringBuilder stlFilegroups = new StringBuilder();
for (CrosstoolStlPair crosstoolStlPair : crosstools) {
// Create the cc_toolchain_suite rule
CrosstoolRelease crosstool = crosstoolStlPair.crosstoolRelease;
StringBuilder toolchainMap = new StringBuilder();
for (CToolchain toolchain : crosstool.getToolchainList()) {
toolchainMap.append(String.format(" \"%s|%s\": \":%s\",\n", toolchain.getTargetCpu(), toolchain.getCompiler(), toolchain.getToolchainIdentifier()));
}
String toolchainName = createToolchainName(crosstoolStlPair.stlImpl.getName());
ccToolchainSuites.append(ccToolchainSuiteTemplate.replace("%toolchainName%", toolchainName).replace("%toolchainMap%", toolchainMap.toString().trim()).replace("%crosstoolReleaseProto%", crosstool.toString()));
// Create the cc_toolchain rules
for (CToolchain toolchain : crosstool.getToolchainList()) {
ccToolchainRules.append(createCcToolchainRule(ccToolchainTemplate, toolchain));
}
// Create the STL file group rules
for (Map.Entry<String, String> entry : crosstoolStlPair.stlImpl.getFilegroupNamesAndFilegroupFileGlobPatterns().entrySet()) {
stlFilegroups.append(stlFilegroupTemplate.replace("%name%", entry.getKey()).replace("%fileGlobPattern%", entry.getValue()));
}
}
return buildFileTemplate.replace("%ruleName%", ruleName).replace("%ccToolchainSuites%", ccToolchainSuites).replace("%ccToolchainRules%", ccToolchainRules).replace("%stlFilegroups%", stlFilegroups);
}
use of com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain 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.CToolchain 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);
}
}
}
}
}
use of com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain in project bazel by bazelbuild.
the class AndroidNdkCrosstoolsTest method testCrosstoolTriples.
/**
* Tests that each (cpu, compiler, glibc) triple in each crosstool is unique in that crosstool.
*/
@Test
public void testCrosstoolTriples() {
StringBuilder errorBuilder = new StringBuilder();
for (CrosstoolRelease crosstool : crosstoolReleases) {
// Create a map of (cpu, compiler, glibc) triples -> toolchain.
ImmutableMultimap.Builder<String, CToolchain> triples = ImmutableMultimap.builder();
for (CToolchain toolchain : crosstool.getToolchainList()) {
String triple = "(" + Joiner.on(", ").join(toolchain.getTargetCpu(), toolchain.getCompiler(), toolchain.getTargetLibc()) + ")";
triples.put(triple, toolchain);
}
// Collect all the duplicate triples.
for (Entry<String, Collection<CToolchain>> entry : triples.build().asMap().entrySet()) {
if (entry.getValue().size() > 1) {
errorBuilder.append(entry.getKey() + ": " + Joiner.on(", ").join(Collections2.transform(entry.getValue(), new Function<CToolchain, String>() {
@Override
public String apply(CToolchain toolchain) {
return toolchain.getToolchainIdentifier();
}
})));
errorBuilder.append("\n");
}
}
errorBuilder.append("\n");
}
// This is a rather awkward condition to test on, but collecting all the duplicates first is
// the only way to make a useful error message rather than finding the errors one by one.
String error = errorBuilder.toString().trim();
if (!error.isEmpty()) {
fail("Toolchains contain duplicate (cpu, compiler, glibc) triples:\n" + error);
}
}
Aggregations