blob: 43f61c9659036e4d4efa6e9eb35e8054a65a811b [file] [log] [blame]
// 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;
import com.google.common.collect.ImmutableList;
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))
.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"));
ndkPaths.addToolchainIncludePaths(toolchain, toolchainName, targetPlatform, "4.9");
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"));
ndkPaths.addToolchainIncludePaths(toolchain, toolchainName, targetPlatform, "4.9");
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))
.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"));
}
ndkPaths.addToolchainIncludePaths(toolchain, toolchainName, targetPlatform, gccVersion);
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"));
}
ndkPaths.addToolchainIncludePaths(toolchain, toolchainName, targetPlatform, "4.8");
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" : "");
}
}