From 38916d025875540d19392bb03468c3bbfee5073f Mon Sep 17 00:00:00 2001 From: jingwen Date: Fri, 2 Mar 2018 11:46:33 -0800 Subject: Add Android NDK r15 support for Bazel. NDK15 changelog: https://android.googlesource.com/platform/ndk/+/ndk-r15-release/CHANGELOG.md Notable changes for this CL: - Clang has been updated to v5.0.300080. - android-9 is not supported anymore. Anything lower than android-14 will default to android-14. - NDK sysroot has been changed to %ndk%/sysroot - Requires additional compilation flags because the headers are now unified in a single location across archs and API levels Also removed NDK 10 checks in integration tests because it is old and we don't test against that anymore. Fixes https://github.com/bazelbuild/bazel/issues/3137 Paves the way for r16: https://github.com/bazelbuild/bazel/issues/4068 RELNOTES[NEW]: Added Android NDK r15 support, including compatibility with Unified Headers. PiperOrigin-RevId: 187648715 --- .../android/AndroidNdkRepositoryFunction.java | 3 + .../rules/android/AndroidNdkRepositoryRule.java | 2 +- .../ndkcrosstools/AndroidNdkCrosstools.java | 16 +- .../rules/android/ndkcrosstools/NdkPaths.java | 31 +++- .../ndkcrosstools/r15/AndroidNdkCrosstoolsR15.java | 116 ++++++++++++ .../android/ndkcrosstools/r15/ApiLevelR15.java | 65 +++++++ .../android/ndkcrosstools/r15/ArmCrosstools.java | 196 +++++++++++++++++++++ .../android/ndkcrosstools/r15/MipsCrosstools.java | 143 +++++++++++++++ .../ndkcrosstools/r15/NdkMajorRevisionR15.java | 42 +++++ .../android/ndkcrosstools/r15/X86Crosstools.java | 121 +++++++++++++ 10 files changed, 725 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/AndroidNdkCrosstoolsR15.java create mode 100644 src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/ApiLevelR15.java create mode 100644 src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/ArmCrosstools.java create mode 100644 src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/MipsCrosstools.java create mode 100644 src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/NdkMajorRevisionR15.java create mode 100644 src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/X86Crosstools.java (limited to 'src/main/java/com/google/devtools/build') diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java index faae014e40..bbdefada8a 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java @@ -332,6 +332,9 @@ public class AndroidNdkRepositoryFunction extends AndroidRepositoryFunction { } } + // For NDK 15 and up. Unfortunately, the toolchain does not encode the NDK revision number. + toolchainFileGlobPatterns.add("ndk/sysroot/**/*"); + // 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) { diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryRule.java index 1c29539bfb..c2a5be5f92 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryRule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryRule.java @@ -85,7 +85,7 @@ public class AndroidNdkRepositoryRule implements RuleDefinition { /*

Configures Bazel to use an Android NDK to support building Android targets with native -code. NDK versions 10, 11, 12, 13 and 14 are currently supported. +code. NDK versions 10 up to 16 are currently supported.

Note that building for Android also requires an android_sdk_repository rule in your WORKSPACE file. diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/AndroidNdkCrosstools.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/AndroidNdkCrosstools.java index ff1127da5c..0171d41b54 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/AndroidNdkCrosstools.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/AndroidNdkCrosstools.java @@ -20,6 +20,7 @@ import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r10e.NdkM import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r11.NdkMajorRevisionR11; import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r12.NdkMajorRevisionR12; import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r13.NdkMajorRevisionR13; +import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r15.NdkMajorRevisionR15; import com.google.devtools.build.lib.util.OS; import java.util.Map; @@ -33,14 +34,17 @@ public final class AndroidNdkCrosstools { // NDK minor revisions should be backwards compatible within a major revision, so all that needs // to be tracked here are the major revision numbers. public static final ImmutableMap KNOWN_NDK_MAJOR_REVISIONS = - ImmutableMap.of( - 10, new NdkMajorRevisionR10(), - 11, new NdkMajorRevisionR11(), - 12, new NdkMajorRevisionR12(), - 13, new NdkMajorRevisionR13("3.8.256229"), + new ImmutableMap.Builder() + .put(10, new NdkMajorRevisionR10()) + .put(11, new NdkMajorRevisionR11()) + .put(12, new NdkMajorRevisionR12()) + .put(13, new NdkMajorRevisionR13("3.8.256229")) // The only difference between the NDK13 and NDK14 CROSSTOOLs is the version of clang in // built-in includes paths, so we can reuse everything else. - 14, new NdkMajorRevisionR13("3.8.275480")); + .put(14, new NdkMajorRevisionR13("3.8.275480")) + .put(15, new NdkMajorRevisionR15("5.0.300080")) + .build(); + public static final Map.Entry LATEST_KNOWN_REVISION = Iterables.getLast(KNOWN_NDK_MAJOR_REVISIONS.entrySet()); diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/NdkPaths.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/NdkPaths.java index 5d6b72d289..c52d07bbd4 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/NdkPaths.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/NdkPaths.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.devtools.build.lib.rules.cpp.CppConfiguration; @@ -24,7 +25,7 @@ import java.util.List; /** * Class for creating paths that are specific to the structure of the Android NDK, but which are - * common to all crosstool toolchains. + * common to all crosstool toolchains. */ public class NdkPaths { @@ -57,7 +58,7 @@ public class NdkPaths { for (Tool tool : CppConfiguration.Tool.values()) { // Some toolchains don't have particular tools. - if (!Arrays.asList(excludedTools).contains(tool)) { + if (!Arrays.asList(excludedTools).contains(tool)) { String toolPath = createToolPath(toolchainName, targetPlatform + "-" + tool.getNamePart()); @@ -162,6 +163,13 @@ public class NdkPaths { .replace("%includeFolderName%", includeFolderName)); } + /** + * NDK 14 and below. Each API level has its own headers. See + * https://android.googlesource.com/platform/ndk/+/ndk-r15-release/docs/UnifiedHeaders.md#supporting-unified-headers-in-your-build-system + * + * @param targetCpu the target CPU architecture + * @return the path to the compile time sysroot + */ public String createBuiltinSysroot(String targetCpu) { String correctedApiLevel = apiLevel.getCpuCorrectedApiLevel(targetCpu); @@ -175,6 +183,22 @@ public class NdkPaths { .replace("%arch%", targetCpu); } + /** + * NDK 15 and above. The headers have been unified into ndk/sysroot. + * + * @return the sysroot location for NDK 15 and above. + */ + public String createBuiltinSysroot() { + // This location does not exist prior to NDK 15 + Preconditions.checkState(majorRevision >= 15); + + return "external/%repositoryName%/ndk/sysroot".replace("%repositoryName%", repositoryName); + } + + public String getCorrectedApiLevel(String targetCpu) { + return apiLevel.getCpuCorrectedApiLevel(targetCpu); + } + ImmutableList createGnuLibstdcIncludePaths(String gccVersion, String targetCpu) { String cpuNoThumb = targetCpu.replaceAll("-thumb$", ""); @@ -236,7 +260,7 @@ public class NdkPaths { */ static String createStlRuntimeLibsGlob( String stl, String gccVersion, String targetCpu, String fileExtension) { - + if (gccVersion != null) { stl += "/" + gccVersion; } @@ -261,3 +285,4 @@ public class NdkPaths { .replace("%targetCpu%", targetCpu); } } + diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/AndroidNdkCrosstoolsR15.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/AndroidNdkCrosstoolsR15.java new file mode 100644 index 0000000000..7a8c0d45c4 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/AndroidNdkCrosstoolsR15.java @@ -0,0 +1,116 @@ +// Copyright 2018 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.r15; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +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.view.config.crosstool.CrosstoolConfig.CToolchain; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.DefaultCpuToolchain; +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +/** Generates a CrosstoolRelease proto for the Android NDK. */ +final class AndroidNdkCrosstoolsR15 { + + /** + * Creates a CrosstoolRelease proto for the Android NDK, given the API level to use and the + * release revision. The crosstools are generated through code rather than checked in as a flat + * file to reduce the amount of templating needed (for parameters like the release name and + * certain paths), to reduce duplication, and to make it easier to support future versions of the + * NDK. TODO(bazel-team): Eventually we should move this into Skylark so the crosstools can be + * updated independently of Bazel itself. + * + * @return A CrosstoolRelease for the Android NDK. + */ + static CrosstoolRelease create( + NdkPaths ndkPaths, StlImpl stlImpl, String hostPlatform, String clangVersion) { + return CrosstoolRelease.newBuilder() + .setMajorVersion("android") + .setMinorVersion("") + .setDefaultTargetCpu("armeabi") + .addAllDefaultToolchain(getDefaultCpuToolchains(stlImpl, clangVersion)) + .addAllToolchain(createToolchains(ndkPaths, stlImpl, hostPlatform, clangVersion)) + .build(); + } + + private static ImmutableList createToolchains( + NdkPaths ndkPaths, StlImpl stlImpl, String hostPlatform, String clangVersion) { + + List toolchainBuilders = new ArrayList<>(); + toolchainBuilders.addAll(new ArmCrosstools(ndkPaths, stlImpl, clangVersion).createCrosstools()); + toolchainBuilders.addAll( + new MipsCrosstools(ndkPaths, stlImpl, clangVersion).createCrosstools()); + toolchainBuilders.addAll(new X86Crosstools(ndkPaths, stlImpl, clangVersion).createCrosstools()); + + ImmutableList.Builder toolchains = new ImmutableList.Builder<>(); + + // Set attributes common to all toolchains. + for (CToolchain.Builder toolchainBuilder : toolchainBuilders) { + toolchainBuilder + .setHostSystemName(hostPlatform) + .setTargetLibc("local") + .setAbiVersion(toolchainBuilder.getTargetCpu()) + .setAbiLibcVersion("local"); + + // builtin_sysroot is set individually on each toolchain. + // platforms/arch sysroot + toolchainBuilder.addCxxBuiltinIncludeDirectory("%sysroot%/usr/include"); + // unified headers sysroot, from ndk15 and up + toolchainBuilder.addCxxBuiltinIncludeDirectory( + ndkPaths.createBuiltinSysroot() + "/usr/include"); + toolchainBuilder.addCompilerFlag( + "-I%ndk%/usr/include".replace("%ndk%", ndkPaths.createBuiltinSysroot())); + + toolchains.add(toolchainBuilder.build()); + } + + return toolchains.build(); + } + + private static ImmutableList getDefaultCpuToolchains( + StlImpl stlImpl, String clangVersion) { + // TODO(bazel-team): It would be better to auto-generate this somehow. + + ImmutableMap defaultCpus = + ImmutableMap.builder() + // arm + .put("armeabi", "arm-linux-androideabi-clang" + clangVersion) + .put("armeabi-v7a", "arm-linux-androideabi-clang" + clangVersion + "-v7a") + .put("arm64-v8a", "aarch64-linux-android-clang" + clangVersion) + + // mips + .put("mips", "mipsel-linux-android-clang" + clangVersion) + .put("mips64", "mips64el-linux-android-clang" + clangVersion) + + // x86 + .put("x86", "x86-clang" + clangVersion) + .put("x86_64", "x86_64-clang" + clangVersion) + .build(); + + ImmutableList.Builder defaultCpuToolchains = ImmutableList.builder(); + for (Entry defaultCpu : defaultCpus.entrySet()) { + defaultCpuToolchains.add( + DefaultCpuToolchain.newBuilder() + .setCpu(defaultCpu.getKey()) + .setToolchainIdentifier(defaultCpu.getValue() + "-" + stlImpl.getName()) + .build()); + } + return defaultCpuToolchains.build(); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/ApiLevelR15.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/ApiLevelR15.java new file mode 100644 index 0000000000..195c27f65e --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/ApiLevelR15.java @@ -0,0 +1,65 @@ +// Copyright 2018 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.r15; + +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.ApiLevel; +import com.google.devtools.build.lib.events.EventHandler; + +/** Class which encodes information from the Android NDK makefiles about API levels. */ +final class ApiLevelR15 extends ApiLevel { + /** This is the contents of {@code platforms/android-*} */ + private static final ImmutableListMultimap API_LEVEL_TO_ARCHITECTURES = + ImmutableListMultimap.builder() + .putAll("14", "arm", "mips", "x86") + .putAll("15", "arm", "mips", "x86") + .putAll("16", "arm", "mips", "x86") + .putAll("17", "arm", "mips", "x86") + .putAll("18", "arm", "mips", "x86") + .putAll("19", "arm", "mips", "x86") + .putAll("21", "arm", "mips", "x86", "arm64", "mips64", "x86_64") + .putAll("22", "arm", "mips", "x86", "arm64", "mips64", "x86_64") + .putAll("23", "arm", "mips", "x86", "arm64", "mips64", "x86_64") + .putAll("24", "arm", "mips", "x86", "arm64", "mips64", "x86_64") + .putAll("26", "arm", "mips", "x86", "arm64", "mips64", "x86_64") + .build(); + + /** This map fill in the gaps of {@code API_LEVEL_TO_ARCHITECTURES}. */ + private static final ImmutableMap API_EQUIVALENCIES = + ImmutableMap.builder() + .put("10", "14") + .put("11", "14") + .put("12", "14") + .put("13", "14") + .put("14", "14") + .put("15", "14") + .put("16", "16") + .put("17", "16") + .put("18", "18") + .put("19", "19") + .put("20", "19") + .put("21", "21") + .put("22", "22") + .put("23", "23") + .put("24", "24") + .put("25", "24") + .put("26", "26") + .build(); + + ApiLevelR15(EventHandler eventHandler, String repositoryName, String apiLevel) { + super(API_LEVEL_TO_ARCHITECTURES, API_EQUIVALENCIES, eventHandler, repositoryName, apiLevel); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/ArmCrosstools.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/ArmCrosstools.java new file mode 100644 index 0000000000..e9987626d1 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/ArmCrosstools.java @@ -0,0 +1,196 @@ +// Copyright 2018 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.r15; + +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.view.config.crosstool.CrosstoolConfig.CToolchain; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain.Builder; +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. + */ +final class ArmCrosstools { + private final NdkPaths ndkPaths; + private final StlImpl stlImpl; + private final String clangVersion; + + ArmCrosstools(NdkPaths ndkPaths, StlImpl stlImpl, String clangVersion) { + this.ndkPaths = ndkPaths; + this.stlImpl = stlImpl; + this.clangVersion = clangVersion; + } + + ImmutableList createCrosstools() { + return ImmutableList.builder() + .add(createAarch64ClangToolchain()) + .addAll(createArmeabiClangToolchain()) + .build(); + } + + private CToolchain.Builder createAarch64ClangToolchain() { + 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(targetPlatform) + .setTargetCpu("arm64-v8a") + .setCompiler("clang" + clangVersion) + .addAllToolPath(ndkPaths.createClangToolpaths(toolchainName, targetPlatform, null)) + .addCxxBuiltinIncludeDirectory( + ndkPaths.createClangToolchainBuiltinIncludeDirectory(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( + "-I%ndk%/usr/include/%triple%" + .replace("%ndk%", ndkPaths.createBuiltinSysroot()) + .replace("%triple%", targetPlatform)) + .addCompilerFlag("-D__ANDROID_API__=" + ndkPaths.getCorrectedApiLevel("arm")) + + // 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")) + + // Additional debug flags + .addCompilationModeFlags( + CompilationModeFlags.newBuilder() + .setMode(CompilationMode.DBG) + .addCompilerFlag("-O0") + .addCompilerFlag("-UNDEBUG")); + + stlImpl.addStlImpl(toolchain, "4.9"); + return toolchain; + } + + private List createArmeabiClangToolchain() { + String targetPlatform = "arm-linux-androideabi"; + ImmutableList toolchains = + ImmutableList.of( + createBaseArmeabiClangToolchain() + .setToolchainIdentifier("arm-linux-androideabi-clang" + clangVersion) + .setTargetCpu("armeabi") + .addCompilerFlag("-target") + .addCompilerFlag("armv5te-none-linux-androideabi") // LLVM_TRIPLE + .addCompilerFlag("-march=armv5te") + .addCompilerFlag("-mtune=xscale") + .addCompilerFlag("-msoft-float") + .addCompilerFlag( + "-I%ndk%/usr/include/%triple%" + .replace("%ndk%", ndkPaths.createBuiltinSysroot()) + .replace("%triple%", targetPlatform)) + .addCompilerFlag("-D__ANDROID_API__=" + ndkPaths.getCorrectedApiLevel("arm")) + .addLinkerFlag("-target") + // LLVM_TRIPLE + .addLinkerFlag("armv5te-none-linux-androideabi"), + createBaseArmeabiClangToolchain() + .setToolchainIdentifier("arm-linux-androideabi-clang" + clangVersion + "-v7a") + .setTargetCpu("armeabi-v7a") + .addCompilerFlag("-target") + .addCompilerFlag("armv7-none-linux-androideabi") // LLVM_TRIPLE + .addCompilerFlag("-march=armv7-a") + .addCompilerFlag("-mfloat-abi=softfp") + .addCompilerFlag("-mfpu=vfpv3-d16") + .addCompilerFlag( + "-I%ndk%/usr/include/%triple%" + .replace("%ndk%", ndkPaths.createBuiltinSysroot()) + .replace("%triple%", targetPlatform)) + .addCompilerFlag("-D__ANDROID_API__=" + ndkPaths.getCorrectedApiLevel("arm")) + .addLinkerFlag("-target") + .addLinkerFlag("armv7-none-linux-androideabi") // LLVM_TRIPLE + .addLinkerFlag("-Wl,--fix-cortex-a8")); + stlImpl.addStlImpl(toolchains, "4.9"); + return toolchains; + } + + private CToolchain.Builder createBaseArmeabiClangToolchain() { + String toolchainName = "arm-linux-androideabi-4.9"; + String targetPlatform = "arm-linux-androideabi"; + String gccToolchain = ndkPaths.createGccToolchainPath("arm-linux-androideabi-4.9"); + + CToolchain.Builder toolchain = + CToolchain.newBuilder() + .setTargetSystemName("arm-linux-androideabi") + .setCompiler("clang" + clangVersion) + .addAllToolPath(ndkPaths.createClangToolpaths(toolchainName, targetPlatform, null)) + .addCxxBuiltinIncludeDirectory( + ndkPaths.createClangToolchainBuiltinIncludeDirectory(clangVersion)) + .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-integrated-as") + + // Linker flags + .addLinkerFlag("-gcc-toolchain") + .addLinkerFlag(gccToolchain) + .addLinkerFlag("-no-canonical-prefixes"); + + toolchain.addCompilationModeFlags( + CompilationModeFlags.newBuilder() + .setMode(CompilationMode.OPT) + .addCompilerFlag("-mthumb") + .addCompilerFlag("-Os") + .addCompilerFlag("-g") + .addCompilerFlag("-DNDEBUG")); + toolchain.addCompilationModeFlags( + CompilationModeFlags.newBuilder() + .setMode(CompilationMode.DBG) + .addCompilerFlag("-g") + .addCompilerFlag("-fno-strict-aliasing") + .addCompilerFlag("-O0") + .addCompilerFlag("-UNDEBUG")); + return toolchain; + } +} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/MipsCrosstools.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/MipsCrosstools.java new file mode 100644 index 0000000000..8bcaf891d9 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/MipsCrosstools.java @@ -0,0 +1,143 @@ +// Copyright 2018 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.r15; + +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.CToolchain.Builder; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CompilationMode; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CompilationModeFlags; + +/** + * Crosstool definitions for MIPS. These values are based on the setup.mk files in the Android NDK + * toolchain directories. + */ +final class MipsCrosstools { + private final NdkPaths ndkPaths; + private final StlImpl stlImpl; + private final String clangVersion; + + MipsCrosstools(NdkPaths ndkPaths, StlImpl stlImpl, String clangVersion) { + this.ndkPaths = ndkPaths; + this.stlImpl = stlImpl; + this.clangVersion = clangVersion; + } + + ImmutableList createCrosstools() { + return ImmutableList.of(createMips64Toolchain(), createMipsToolchain()); + } + + private CToolchain.Builder createMips64Toolchain() { + String targetPlatform = "mips64el-linux-android"; + String targetCpu = "mips64"; + CToolchain.Builder mips64Clang = + createBaseMipsClangToolchain("mips64el") + .setToolchainIdentifier("mips64el-linux-android-clang" + clangVersion) + .setTargetSystemName(targetPlatform) + .setTargetCpu(targetCpu) + .addAllToolPath( + ndkPaths.createClangToolpaths( + "mips64el-linux-android-4.9", targetPlatform, null, CppConfiguration.Tool.DWP)) + .addCompilerFlag( + "-I%ndk%/usr/include/%triple%" + .replace("%ndk%", ndkPaths.createBuiltinSysroot()) + .replace("%triple%", targetPlatform)) + .addCompilerFlag("-D__ANDROID_API__=" + ndkPaths.getCorrectedApiLevel(targetCpu)) + .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("mips64")); + + stlImpl.addStlImpl(mips64Clang, "4.9"); + return mips64Clang; + } + + private CToolchain.Builder createMipsToolchain() { + String targetPlatform = "mipsel-linux-android"; + String targetCpu = "mips"; + CToolchain.Builder mipsClang = + createBaseMipsClangToolchain("mipsel") + // Purposefully no hyphen between "clang" and clang version. + .setToolchainIdentifier("mipsel-linux-android-clang" + clangVersion) + .setTargetSystemName("mipsel-linux-android") + .setTargetCpu(targetCpu) + .addCompilerFlag( + "-I%ndk%/usr/include/%triple%" + .replace("%ndk%", ndkPaths.createBuiltinSysroot()) + .replace("%triple%", targetPlatform)) + .addCompilerFlag("-D__ANDROID_API__=" + ndkPaths.getCorrectedApiLevel("mips")) + .addAllToolPath( + ndkPaths.createClangToolpaths( + "mipsel-linux-android-4.9", + targetPlatform, + null, + CppConfiguration.Tool.DWP, + CppConfiguration.Tool.GCOVTOOL)) + .setBuiltinSysroot(ndkPaths.createBuiltinSysroot(targetCpu)); + + stlImpl.addStlImpl(mipsClang, "4.9"); + + return mipsClang; + } + + private CToolchain.Builder createBaseMipsClangToolchain(String mipsArch) { + String gccToolchain = + ndkPaths.createGccToolchainPath(String.format("%s-linux-android-4.9", mipsArch)); + + String llvmTriple = mipsArch + "-none-linux-android"; + + return CToolchain.newBuilder() + .setCompiler("clang" + clangVersion) + .addCxxBuiltinIncludeDirectory( + ndkPaths.createClangToolchainBuiltinIncludeDirectory(clangVersion)) + + // Compiler flags + .addCompilerFlag("-gcc-toolchain") + .addCompilerFlag(gccToolchain) + .addCompilerFlag("-target") + .addCompilerFlag(llvmTriple) + .addCompilerFlag("-fpic") + .addCompilerFlag("-fno-strict-aliasing") + .addCompilerFlag("-finline-functions") + .addCompilerFlag("-ffunction-sections") + .addCompilerFlag("-funwind-tables") + .addCompilerFlag("-fmessage-length=0") + .addCompilerFlag("-Wno-invalid-command-line-argument") + .addCompilerFlag("-Wno-unused-command-line-argument") + .addCompilerFlag("-no-canonical-prefixes") + + // 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")) + + // Additional debug flags + .addCompilationModeFlags( + CompilationModeFlags.newBuilder() + .setMode(CompilationMode.DBG) + .addCompilerFlag("-O0") + .addCompilerFlag("-g")); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/NdkMajorRevisionR15.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/NdkMajorRevisionR15.java new file mode 100644 index 0000000000..b0c3212820 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/NdkMajorRevisionR15.java @@ -0,0 +1,42 @@ +// Copyright 2018 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.r15; + +import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.ApiLevel; +import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkMajorRevision; +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.events.EventHandler; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease; + +/** Logic specific to Android NDK R15. */ +public class NdkMajorRevisionR15 implements NdkMajorRevision { + private final String clangVersion; + + public NdkMajorRevisionR15(String clangVersion) { + this.clangVersion = clangVersion; + } + + @Override + public CrosstoolRelease crosstoolRelease( + NdkPaths ndkPaths, StlImpl stlImpl, String hostPlatform) { + return AndroidNdkCrosstoolsR15.create(ndkPaths, stlImpl, hostPlatform, clangVersion); + } + + @Override + public ApiLevel apiLevel(EventHandler eventHandler, String name, String apiLevel) { + return new ApiLevelR15(eventHandler, name, apiLevel); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/X86Crosstools.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/X86Crosstools.java new file mode 100644 index 0000000000..b05aa0fd60 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r15/X86Crosstools.java @@ -0,0 +1,121 @@ +// Copyright 2018 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.r15; + +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.view.config.crosstool.CrosstoolConfig.CToolchain; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain.Builder; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CompilationMode; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CompilationModeFlags; + +/** + * Crosstool definitions for x86. These values are based on the setup.mk files in the Android NDK + * toolchain directories. + */ +final class X86Crosstools { + private final NdkPaths ndkPaths; + private final StlImpl stlImpl; + private final String clangVersion; + + X86Crosstools(NdkPaths ndkPaths, StlImpl stlImpl, String clangVersion) { + this.ndkPaths = ndkPaths; + this.stlImpl = stlImpl; + this.clangVersion = clangVersion; + } + + ImmutableList createCrosstools() { + /** x86 */ + // clang + CToolchain.Builder x86Clang = + createBaseX86ClangToolchain("x86", "i686", "i686-linux-android") + // Workaround for https://code.google.com/p/android/issues/detail?id=220159. + .addCompilerFlag("-mstackrealign") + .setToolchainIdentifier("x86-clang" + clangVersion) + .setTargetCpu("x86") + .addAllToolPath(ndkPaths.createClangToolpaths("x86-4.9", "i686-linux-android", null)) + .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("x86")); + + stlImpl.addStlImpl(x86Clang, "4.9"); + + /** x86_64 */ + CToolchain.Builder x8664Clang = + createBaseX86ClangToolchain("x86_64", "x86_64", "x86_64-linux-android") + .setToolchainIdentifier("x86_64-clang" + clangVersion) + .setTargetCpu("x86_64") + .addAllToolPath( + ndkPaths.createClangToolpaths("x86_64-4.9", "x86_64-linux-android", null)) + .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("x86_64")); + + stlImpl.addStlImpl(x8664Clang, "4.9"); + + return ImmutableList.of(x86Clang, x8664Clang); + } + + private CToolchain.Builder createBaseX86ClangToolchain( + String x86Arch, String llvmArch, String triple) { + String gccToolchain = ndkPaths.createGccToolchainPath(x86Arch + "-4.9"); + String llvmTriple = llvmArch + "-none-linux-android"; + + return CToolchain.newBuilder() + .setCompiler("clang" + clangVersion) + .addCxxBuiltinIncludeDirectory( + ndkPaths.createClangToolchainBuiltinIncludeDirectory(clangVersion)) + + // 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("-isysroot " + ndkPaths.createBuiltinSysroot()) + .addCompilerFlag("-I%ndk%/usr/include".replace("%ndk%", ndkPaths.createBuiltinSysroot())) + .addCompilerFlag( + "-I%ndk%/usr/include/%triple%" + .replace("%ndk%", ndkPaths.createBuiltinSysroot()) + .replace("%triple%", triple)) + .addCompilerFlag("-D__ANDROID_API__=" + ndkPaths.getCorrectedApiLevel(x86Arch)) + + // 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")) + + // Additional debug flags + .addCompilationModeFlags( + CompilationModeFlags.newBuilder() + .setMode(CompilationMode.DBG) + .addCompilerFlag("-O0") + .addCompilerFlag("-g")) + .setTargetSystemName("x86-linux-android"); + } +} -- cgit v1.2.3