// Copyright 2015 The Bazel Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r10e; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkPaths; import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.StlImpl; import com.google.devtools.build.lib.rules.cpp.CppConfiguration; import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain; import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CompilationMode; import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CompilationModeFlags; import java.util.List; /** * Crosstool definitions for ARM. These values are based on the setup.mk files in the Android NDK * toolchain directories. */ class ArmCrosstools { private final NdkPaths ndkPaths; private final StlImpl stlImpl; ArmCrosstools(NdkPaths ndkPaths, StlImpl stlImpl) { this.ndkPaths = ndkPaths; this.stlImpl = stlImpl; } ImmutableList<CToolchain.Builder> createCrosstools() { ImmutableList.Builder<CToolchain.Builder> toolchains = ImmutableList.builder(); toolchains.add(createAarch64Toolchain()); // The flags for aarch64 clang 3.5 and 3.6 are the same, they differ only in the LLVM version // given in their tool paths. toolchains.add(createAarch64ClangToolchain("3.5")); toolchains.add(createAarch64ClangToolchain("3.6")); // The Android NDK Make files create several sets of flags base on // arm vs armeabi-v7a vs armeabi-v7a-hard, and arm vs thumb mode, each for gcc 4.8 and 4.9, // resulting in: // arm-linux-androideabi-4.8 // arm-linux-androideabi-4.8-v7a // arm-linux-androideabi-4.8-v7a-hard // arm-linux-androideabi-4.8-thumb // arm-linux-androideabi-4.8-v7a-thumb // arm-linux-androideabi-4.8-v7a-hard-thumb // arm-linux-androideabi-4.9 // arm-linux-androideabi-4.9-v7a // arm-linux-androideabi-4.9-v7a-hard // arm-linux-androideabi-4.9-thumb // arm-linux-androideabi-4.9-v7a-thumb // arm-linux-androideabi-4.9-v7a-hard-thumb // // and similar for the Clang toolchains. // gcc-4.8 for arm doesn't have the gcov-tool. CppConfiguration.Tool[] excludedTools = { CppConfiguration.Tool.GCOVTOOL }; toolchains.addAll(createArmeabiToolchains("4.8", "-fstack-protector", false, excludedTools)); toolchains.addAll(createArmeabiToolchains("4.8", "-fstack-protector", true, excludedTools)); toolchains.addAll(createArmeabiToolchains("4.9", "-fstack-protector-strong", false)); toolchains.addAll(createArmeabiToolchains("4.9", "-fstack-protector-strong", true)); toolchains.addAll(createArmeabiClangToolchain("3.5", false)); toolchains.addAll(createArmeabiClangToolchain("3.5", true)); toolchains.addAll(createArmeabiClangToolchain("3.6", false)); toolchains.addAll(createArmeabiClangToolchain("3.6", true)); return toolchains.build(); } private CToolchain.Builder createAarch64Toolchain() { String toolchainName = "aarch64-linux-android-4.9"; String targetPlatform = "aarch64-linux-android"; CToolchain.Builder toolchain = CToolchain.newBuilder() .setToolchainIdentifier("aarch64-linux-android-4.9") .setTargetSystemName("aarch64-linux-android") .setTargetCpu("arm64-v8a") .setCompiler("gcc-4.9") .addAllToolPath(ndkPaths.createToolpaths(toolchainName, targetPlatform)) .addAllCxxBuiltinIncludeDirectory( ndkPaths.createGccToolchainBuiltinIncludeDirectories( toolchainName, targetPlatform, "4.9")) .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("arm64")) // Compiler flags .addCompilerFlag("-fpic") .addCompilerFlag("-ffunction-sections") .addCompilerFlag("-funwind-tables") .addCompilerFlag("-fstack-protector-strong") .addCompilerFlag("-no-canonical-prefixes") .addCompilerFlag("-fno-canonical-system-headers") // Linker flags .addLinkerFlag("-no-canonical-prefixes") // Additional release flags .addCompilationModeFlags(CompilationModeFlags.newBuilder() .setMode(CompilationMode.OPT) .addCompilerFlag("-O2") .addCompilerFlag("-g") .addCompilerFlag("-DNDEBUG") .addCompilerFlag("-fomit-frame-pointer") .addCompilerFlag("-fstrict-aliasing") .addCompilerFlag("-funswitch-loops") .addCompilerFlag("-finline-limit=300")) // Additional debug flags .addCompilationModeFlags(CompilationModeFlags.newBuilder() .setMode(CompilationMode.DBG) .addCompilerFlag("-O0") .addCompilerFlag("-UNDEBUG") .addCompilerFlag("-fno-omit-frame-pointer") .addCompilerFlag("-fno-strict-aliasing")); stlImpl.addStlImpl(toolchain, "4.9"); return toolchain; } private CToolchain.Builder createAarch64ClangToolchain(String clangVersion) { String toolchainName = "aarch64-linux-android-4.9"; String targetPlatform = "aarch64-linux-android"; String gccToolchain = ndkPaths.createGccToolchainPath(toolchainName); String llvmTriple = "aarch64-none-linux-android"; CToolchain.Builder toolchain = CToolchain.newBuilder() .setToolchainIdentifier("aarch64-linux-android-clang" + clangVersion) .setTargetSystemName("aarch64-linux-android") .setTargetCpu("arm64-v8a") .setCompiler("clang" + clangVersion) .addAllToolPath(ndkPaths.createClangToolpaths(toolchainName, targetPlatform, clangVersion)) .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("arm64")) // Compiler flags .addCompilerFlag("-gcc-toolchain") .addCompilerFlag(gccToolchain) .addCompilerFlag("-target") .addCompilerFlag(llvmTriple) .addCompilerFlag("-ffunction-sections") .addCompilerFlag("-funwind-tables") .addCompilerFlag("-fstack-protector-strong") .addCompilerFlag("-fpic") .addCompilerFlag("-Wno-invalid-command-line-argument") .addCompilerFlag("-Wno-unused-command-line-argument") .addCompilerFlag("-no-canonical-prefixes") .addCompilerFlag("-fno-canonical-system-headers") // Linker flags .addLinkerFlag("-gcc-toolchain") .addLinkerFlag(gccToolchain) .addLinkerFlag("-target") .addLinkerFlag(llvmTriple) .addLinkerFlag("-no-canonical-prefixes") // Additional release flags .addCompilationModeFlags(CompilationModeFlags.newBuilder() .setMode(CompilationMode.OPT) .addCompilerFlag("-O2") .addCompilerFlag("-g") .addCompilerFlag("-DNDEBUG") .addCompilerFlag("-fomit-frame-pointer") .addCompilerFlag("-fstrict-aliasing")) // Additional debug flags .addCompilationModeFlags(CompilationModeFlags.newBuilder() .setMode(CompilationMode.DBG) .addCompilerFlag("-O0") .addCompilerFlag("-UNDEBUG") .addCompilerFlag("-fno-omit-frame-pointer") .addCompilerFlag("-fno-strict-aliasing")); stlImpl.addStlImpl(toolchain, "4.9"); return toolchain; } private List<CToolchain.Builder> createArmeabiToolchains( String gccVersion, String stackProtectorFlag, boolean thumb, CppConfiguration.Tool... excludedTools) { ImmutableList<CToolchain.Builder> toolchains = ImmutableList.<CToolchain.Builder>builder() .add(createBaseArmeabiToolchain(thumb, gccVersion, stackProtectorFlag, excludedTools) .setToolchainIdentifier( createArmeabiName("arm-linux-androideabi-%s", gccVersion, thumb)) .setTargetCpu(createArmeabiCpuName("armeabi", thumb)) .addCompilerFlag("-march=armv5te") .addCompilerFlag("-mtune=xscale") .addCompilerFlag("-msoft-float")) .add(createBaseArmeabiToolchain(thumb, gccVersion, stackProtectorFlag, excludedTools) .setToolchainIdentifier( createArmeabiName("arm-linux-androideabi-%s-v7a", gccVersion, thumb)) .setTargetCpu(createArmeabiCpuName("armeabi-v7a", thumb)) .addCompilerFlag("-march=armv7-a") .addCompilerFlag("-mfpu=vfpv3-d16") .addCompilerFlag("-mfloat-abi=softfp") .addLinkerFlag("-march=armv7-a") .addLinkerFlag("-Wl,--fix-cortex-a8")) .add(createBaseArmeabiToolchain(thumb, gccVersion, stackProtectorFlag, excludedTools) .setToolchainIdentifier( createArmeabiName("arm-linux-androideabi-%s-v7a-hard", gccVersion, thumb)) .setTargetCpu(createArmeabiCpuName("armeabi-v7a-hard", thumb)) .addCompilerFlag("-march=armv7-a") .addCompilerFlag("-mfpu=vfpv3-d16") .addCompilerFlag("-mhard-float") .addCompilerFlag("-D_NDK_MATH_NO_SOFTFP=1") .addLinkerFlag("-march=armv7-a") .addLinkerFlag("-Wl,--fix-cortex-a8") .addLinkerFlag("-Wl,--no-warn-mismatch") .addLinkerFlag("-lm_hard")) .build(); stlImpl.addStlImpl(toolchains, gccVersion); return toolchains; } /** * Flags common to arm-linux-androideabi* */ private CToolchain.Builder createBaseArmeabiToolchain( boolean thumb, String gccVersion, String stackProtectorFlag, CppConfiguration.Tool... excludedTools) { String toolchainName = "arm-linux-androideabi-" + gccVersion; String targetPlatform = "arm-linux-androideabi"; CToolchain.Builder toolchain = CToolchain.newBuilder() .setTargetSystemName(targetPlatform) .setCompiler("gcc-" + gccVersion) .addAllToolPath(ndkPaths.createToolpaths(toolchainName, targetPlatform, excludedTools)) .addAllCxxBuiltinIncludeDirectory( ndkPaths.createGccToolchainBuiltinIncludeDirectories( toolchainName, targetPlatform, gccVersion)) .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("arm")) .addCompilerFlag(stackProtectorFlag) // Compiler flags .addCompilerFlag("-fpic") .addCompilerFlag("-ffunction-sections") .addCompilerFlag("-funwind-tables") .addCompilerFlag("-no-canonical-prefixes") .addCompilerFlag("-fno-canonical-system-headers") // Linker flags .addLinkerFlag("-no-canonical-prefixes"); if (thumb) { toolchain.addCompilationModeFlags(CompilationModeFlags.newBuilder() .setMode(CompilationMode.OPT) .addCompilerFlag("-mthumb") .addCompilerFlag("-Os") .addCompilerFlag("-g") .addCompilerFlag("-DNDEBUG") .addCompilerFlag("-fomit-frame-pointer") .addCompilerFlag("-fno-strict-aliasing") .addCompilerFlag("-finline-limit=64")); toolchain.addCompilationModeFlags(CompilationModeFlags.newBuilder() .setMode(CompilationMode.DBG) .addCompilerFlag("-g") .addCompilerFlag("-fno-strict-aliasing") .addCompilerFlag("-finline-limit=64") .addCompilerFlag("-O0") .addCompilerFlag("-UNDEBUG") .addCompilerFlag("-marm") .addCompilerFlag("-fno-omit-frame-pointer")); } else { toolchain.addCompilationModeFlags(CompilationModeFlags.newBuilder() .setMode(CompilationMode.OPT) .addCompilerFlag("-O2") .addCompilerFlag("-g") .addCompilerFlag("-DNDEBUG") .addCompilerFlag("-fomit-frame-pointer") .addCompilerFlag("-fstrict-aliasing") .addCompilerFlag("-funswitch-loops") .addCompilerFlag("-finline-limit=300")); toolchain.addCompilationModeFlags(CompilationModeFlags.newBuilder() .setMode(CompilationMode.DBG) .addCompilerFlag("-g") .addCompilerFlag("-funswitch-loops") .addCompilerFlag("-finline-limit=300") .addCompilerFlag("-O0") .addCompilerFlag("-UNDEBUG") .addCompilerFlag("-fno-omit-frame-pointer") .addCompilerFlag("-fno-strict-aliasing")); } return toolchain; } private List<CToolchain.Builder> createArmeabiClangToolchain(String clangVersion, boolean thumb) { ImmutableList<CToolchain.Builder> toolchains = ImmutableList.<CToolchain.Builder>builder() .add(createBaseArmeabiClangToolchain(clangVersion, thumb) .setToolchainIdentifier( createArmeabiName("arm-linux-androideabi-clang%s", clangVersion, thumb)) .setTargetCpu(createArmeabiCpuName("armeabi", thumb)) .addCompilerFlag("-target") .addCompilerFlag("armv5te-none-linux-androideabi") // LLVM_TRIPLE .addCompilerFlag("-march=armv5te") .addCompilerFlag("-mtune=xscale") .addCompilerFlag("-msoft-float") .addLinkerFlag("-target") // LLVM_TRIPLE .addLinkerFlag("armv5te-none-linux-androideabi")) .add(createBaseArmeabiClangToolchain(clangVersion, thumb) .setToolchainIdentifier( createArmeabiName("arm-linux-androideabi-clang%s-v7a", clangVersion, thumb)) .setTargetCpu(createArmeabiCpuName("armeabi-v7a", thumb)) .addCompilerFlag("-target") .addCompilerFlag("armv7-none-linux-androideabi") // LLVM_TRIPLE .addCompilerFlag("-march=armv7-a") .addCompilerFlag("-mfloat-abi=softfp") .addCompilerFlag("-mfpu=vfpv3-d16") .addLinkerFlag("-target") .addLinkerFlag("armv7-none-linux-androideabi") // LLVM_TRIPLE .addLinkerFlag("-Wl,--fix-cortex-a8")) .add(createBaseArmeabiClangToolchain(clangVersion, thumb) .setToolchainIdentifier( createArmeabiName("arm-linux-androideabi-clang%s-v7a-hard", clangVersion, thumb)) .setTargetCpu(createArmeabiCpuName("armeabi-v7a-hard", thumb)) .addCompilerFlag("-target") .addCompilerFlag("armv7-none-linux-androideabi") // LLVM_TRIPLE .addCompilerFlag("-march=armv7-a") .addCompilerFlag("-mfpu=vfpv3-d16") .addCompilerFlag("-mhard-float") .addCompilerFlag("-D_NDK_MATH_NO_SOFTFP=1") .addLinkerFlag("-target") .addLinkerFlag("armv7-none-linux-androideabi") // LLVM_TRIPLE .addLinkerFlag("-Wl,--fix-cortex-a8") .addLinkerFlag("-Wl,--no-warn-mismatch") .addLinkerFlag("-lm_hard")) .build(); stlImpl.addStlImpl(toolchains, "4.9"); return toolchains; } private CToolchain.Builder createBaseArmeabiClangToolchain(String clangVersion, boolean thumb) { String toolchainName = "arm-linux-androideabi-4.8"; String targetPlatform = "arm-linux-androideabi"; String gccToolchain = ndkPaths.createGccToolchainPath("arm-linux-androideabi-4.8"); CToolchain.Builder toolchain = CToolchain.newBuilder() .setTargetSystemName("arm-linux-androideabi") .setCompiler("clang" + clangVersion) .addAllToolPath(ndkPaths.createClangToolpaths( toolchainName, targetPlatform, clangVersion, // gcc-4.8 arm doesn't have gcov-tool CppConfiguration.Tool.GCOVTOOL)) .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("arm")) // Compiler flags .addCompilerFlag("-gcc-toolchain") .addCompilerFlag(gccToolchain) .addCompilerFlag("-fpic") .addCompilerFlag("-ffunction-sections") .addCompilerFlag("-funwind-tables") .addCompilerFlag("-fstack-protector-strong") .addCompilerFlag("-Wno-invalid-command-line-argument") .addCompilerFlag("-Wno-unused-command-line-argument") .addCompilerFlag("-no-canonical-prefixes") .addCompilerFlag("-fno-canonical-system-headers") .addCompilerFlag("-fno-integrated-as") // Linker flags .addLinkerFlag("-gcc-toolchain") .addLinkerFlag(gccToolchain) .addLinkerFlag("-no-canonical-prefixes"); if (thumb) { toolchain.addCompilationModeFlags(CompilationModeFlags.newBuilder() .setMode(CompilationMode.OPT) .addCompilerFlag("-mthumb") .addCompilerFlag("-Os") .addCompilerFlag("-g") .addCompilerFlag("-DNDEBUG") .addCompilerFlag("-fomit-frame-pointer") .addCompilerFlag("-fno-strict-aliasing")); toolchain.addCompilationModeFlags(CompilationModeFlags.newBuilder() .setMode(CompilationMode.DBG) .addCompilerFlag("-g") .addCompilerFlag("-fno-strict-aliasing") .addCompilerFlag("-O0") .addCompilerFlag("-UNDEBUG") .addCompilerFlag("-marm") .addCompilerFlag("-fno-omit-frame-pointer")); } else { toolchain.addCompilationModeFlags(CompilationModeFlags.newBuilder() .setMode(CompilationMode.OPT) .addCompilerFlag("-O2") .addCompilerFlag("-g") .addCompilerFlag("-DNDEBUG") .addCompilerFlag("-fomit-frame-pointer") .addCompilerFlag("-fstrict-aliasing")); toolchain.addCompilationModeFlags(CompilationModeFlags.newBuilder() .setMode(CompilationMode.DBG) .addCompilerFlag("-g") .addCompilerFlag("-O0") .addCompilerFlag("-UNDEBUG") .addCompilerFlag("-fno-omit-frame-pointer") .addCompilerFlag("-fno-strict-aliasing")); } return toolchain; } private static String createArmeabiName(String base, String gccVersion, boolean thumb) { return String.format(base, gccVersion) + (thumb ? "-thumb" : ""); } private static String createArmeabiCpuName(String base, boolean thumb) { return base + (thumb ? "-thumb" : ""); } }