aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java
diff options
context:
space:
mode:
authorGravatar Alex Humesky <ahumesky@google.com>2016-05-12 18:53:43 +0000
committerGravatar Klaus Aehlig <aehlig@google.com>2016-05-13 08:27:59 +0000
commitabdaff492440b373bacd016d772ef73611a27901 (patch)
treeb9147a1503dbc38b15b57a86c06dd621c7decb33 /src/main/java
parent3ae058d0fea53dd629d639ec8007c8c443ab47f2 (diff)
Support NDK r11 in bazel
RELNOTES: Added supported for Android NDK revision 11 -- MOS_MIGRATED_REVID=122181286
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java80
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryRule.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/AndroidNdkCrosstools.java99
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/ApiLevel.java104
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/NdkPaths.java (renamed from src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/NdkPaths.java)16
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/NdkRelease.java84
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/StlImpl.java (renamed from src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/StlImpl.java)2
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/StlImpls.java (renamed from src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/StlImpls.java)2
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/AndroidNdkCrosstoolsR10e.java73
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/ApiLevelR10e.java (renamed from src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/ApiLevel.java)59
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/ArmCrosstools.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/MipsCrosstools.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/X86Crosstools.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/AndroidNdkCrosstoolsR11.java120
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/ApiLevelR11.java114
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/ArmCrosstools.java426
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/MipsCrosstools.java222
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/X86Crosstools.java205
18 files changed, 1434 insertions, 180 deletions
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 77fd1e6f41..b30dae6afb 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
@@ -13,16 +13,19 @@
// limitations under the License.
package com.google.devtools.build.lib.bazel.rules.android;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.RuleDefinition;
+import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.AndroidNdkCrosstools;
+import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.AndroidNdkCrosstools.NdkCrosstoolsException;
+import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.ApiLevel;
+import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkPaths;
import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkRelease;
-import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r10e.AndroidNdkCrosstoolsR10e;
-import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r10e.AndroidNdkCrosstoolsR10e.NdkCrosstoolsException;
-import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r10e.ApiLevel;
-import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r10e.NdkPaths;
-import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r10e.StlImpl;
-import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r10e.StlImpls;
+import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.StlImpl;
+import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.StlImpls;
+import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
@@ -39,6 +42,7 @@ import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.RootedPath;
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.ToolPath;
import com.google.devtools.build.skyframe.SkyFunction.Environment;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyFunctionException.Transience;
@@ -94,26 +98,40 @@ public class AndroidNdkRepositoryFunction extends RepositoryFunction {
AttributeMap attributes = NonconfigurableAttributeMapper.of(rule);
String ruleName = rule.getName();
String apiLevelAttr = attributes.get("api_level", Type.INTEGER).toString();
- ApiLevel apiLevel = new ApiLevel(env.getListener(), ruleName, apiLevelAttr);
NdkRelease ndkRelease = getNdkRelease(outputDirectory, env);
if (env.valuesMissing()) {
return null;
}
+
+ ApiLevel apiLevel = ApiLevel.getApiLevel(ndkRelease, env.getListener(), ruleName, apiLevelAttr);
+
+ if (!ndkRelease.isValid) {
+ env.getListener().handle(Event.warn(String.format(
+ "The revision of the Android NDK given in android_ndk_repository rule '%s' could not be "
+ + "determined (the revision string found is '%s'). "
+ + "Defaulting to Android NDK revision %s", ruleName, ndkRelease.rawRelease,
+ AndroidNdkCrosstools.LATEST_KNOWN_REVISION)));
+ }
+ if (!AndroidNdkCrosstools.isKnownNDKRevision(ndkRelease)) {
+ env.getListener().handle(Event.warn(String.format(
+ "Bazel Android NDK crosstools are based on Android NDK revision %s. "
+ + "The revision of the Android NDK given in android_ndk_repository rule '%s' is '%s'",
+ AndroidNdkCrosstools.LATEST_KNOWN_REVISION, ruleName, ndkRelease.rawRelease)));
+ }
+
ImmutableList.Builder<CrosstoolStlPair> crosstoolsAndStls = ImmutableList.builder();
try {
- String hostPlatform = AndroidNdkCrosstoolsR10e.getHostPlatform(ndkRelease);
+ String hostPlatform = AndroidNdkCrosstools.getHostPlatform(ndkRelease);
NdkPaths ndkPaths = new NdkPaths(ruleName, hostPlatform, apiLevel);
for (StlImpl stlImpl : StlImpls.get(ndkPaths)) {
- CrosstoolRelease crosstoolRelease = AndroidNdkCrosstoolsR10e.create(
- env.getListener(),
- ndkPaths,
- ruleName,
+ CrosstoolRelease crosstoolRelease = AndroidNdkCrosstools.create(
ndkRelease,
+ ndkPaths,
stlImpl,
hostPlatform);
@@ -200,9 +218,17 @@ public class AndroidNdkRepositoryFunction extends RepositoryFunction {
// 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
- String toolchainDirectory = NdkPaths.getToolchainDirectoryFromToolPath(
- toolchain.getToolPathList().get(0).getPath());
+ // 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.
@@ -218,6 +244,13 @@ public class AndroidNdkRepositoryFunction extends RepositoryFunction {
}
}
+ // 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(
@@ -236,11 +269,16 @@ public class AndroidNdkRepositoryFunction extends RepositoryFunction {
private static NdkRelease getNdkRelease(Path directory, Environment env)
throws RepositoryFunctionException {
- Path releaseFilePath = directory.getRelative("ndk/RELEASE.TXT");
+ // For NDK r11+
+ Path releaseFilePath = directory.getRelative("ndk/source.properties");
+ if (!releaseFilePath.exists()) {
+ // For NDK r10e
+ releaseFilePath = directory.getRelative("ndk/RELEASE.TXT");
+ }
+
+ SkyKey releaseFileKey = FileValue.key(
+ RootedPath.toRootedPath(directory, releaseFilePath));
- SkyKey releaseFileKey = FileValue.key(RootedPath.toRootedPath(
- releaseFilePath, PathFragment.EMPTY_FRAGMENT));
-
String releaseFileContent;
try {
env.getValueOrThrow(releaseFileKey,
@@ -251,8 +289,8 @@ public class AndroidNdkRepositoryFunction extends RepositoryFunction {
releaseFileContent = new String(FileSystemUtils.readContent(releaseFilePath));
} catch (IOException | FileSymlinkException | InconsistentFilesystemException e) {
throw new RepositoryFunctionException(
- new IOException("Could not read RELEASE.TXT in Android NDK: " + e.getMessage()),
- Transience.PERSISTENT);
+ new IOException("Could not read " + releaseFilePath.getBaseName() + " in Android NDK: "
+ + e.getMessage()), Transience.PERSISTENT);
}
return NdkRelease.create(releaseFileContent.trim());
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 0a91e21ce3..2afc5b52a8 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
@@ -21,7 +21,7 @@ import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
-import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r10e.StlImpls;
+import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.StlImpls;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
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
new file mode 100644
index 0000000000..1962da1b87
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/AndroidNdkCrosstools.java
@@ -0,0 +1,99 @@
+// Copyright 2016 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.devtools.build.lib.bazel.rules.android.ndkcrosstools.r10e.AndroidNdkCrosstoolsR10e;
+import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r11.AndroidNdkCrosstoolsR11;
+import com.google.devtools.build.lib.util.OS;
+import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease;
+
+/**
+ * Generates a CrosstoolRelease proto for the Android NDK based on a particular NDK release.
+ */
+public 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.
+ private static final String NDK_REVISION_10 = "10";
+ private static final String NDK_REVISION_11 = "11";
+ public static final String LATEST_KNOWN_REVISION = NDK_REVISION_11;
+
+ /**
+ * Exception thrown when there is an error creating the crosstools file.
+ */
+ public static class NdkCrosstoolsException extends Exception {
+ private NdkCrosstoolsException(String msg) {
+ super(msg);
+ }
+ }
+
+ public static CrosstoolRelease create(
+ NdkRelease ndkRelease,
+ NdkPaths ndkPaths,
+ StlImpl stlImpl,
+ String hostPlatform) {
+
+ // If the NDK revision isn't valid, try using the latest one we know about.
+ String majorRevision;
+ if (ndkRelease.isValid) {
+ majorRevision = ndkRelease.majorRevision;
+ } else {
+ majorRevision = LATEST_KNOWN_REVISION;
+ }
+
+ // NDK minor revisions should be backwards compatible within a major revision, so it should be
+ // enough to check the major revision of the release.
+ if (NDK_REVISION_10.equals(majorRevision)) {
+ return AndroidNdkCrosstoolsR10e.create(ndkPaths, stlImpl, hostPlatform);
+ } else {
+ return AndroidNdkCrosstoolsR11.create(ndkPaths, stlImpl, hostPlatform);
+ }
+ }
+
+ public static String getHostPlatform(NdkRelease ndkRelease) throws NdkCrosstoolsException {
+ String hostOs;
+ switch (OS.getCurrent()) {
+ case DARWIN:
+ hostOs = "darwin";
+ break;
+ case LINUX:
+ hostOs = "linux";
+ break;
+ case WINDOWS:
+ hostOs = "windows";
+ if (!ndkRelease.is64Bit) {
+ // 32-bit windows paths don't have the "-x86" suffix in the NDK (added below), but
+ // 64-bit windows does have the "-x86_64" suffix.
+ return hostOs;
+ }
+ break;
+ case UNKNOWN:
+ default:
+ throw new NdkCrosstoolsException(
+ String.format("NDK does not support the host platform \"%s\"", OS.getCurrent()));
+ }
+
+ // Use the arch from the NDK rather than detecting the actual platform, since it's possible
+ // to use the 32-bit NDK on a 64-bit machine.
+ String hostArch = ndkRelease.is64Bit ? "x86_64" : "x86";
+
+ return hostOs + "-" + hostArch;
+ }
+
+ public static boolean isKnownNDKRevision(NdkRelease ndkRelease) {
+ return NDK_REVISION_10.equals(ndkRelease.majorRevision)
+ || NDK_REVISION_11.equals(ndkRelease.majorRevision);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/ApiLevel.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/ApiLevel.java
new file mode 100644
index 0000000000..fbc8559f4e
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/ApiLevel.java
@@ -0,0 +1,104 @@
+// Copyright 2016 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.ImmutableListMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r10e.ApiLevelR10e;
+import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r11.ApiLevelR11;
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventHandler;
+
+/**
+ * Base class for ApiLevels, which provides a factory function to create an ApiLevel based on an
+ * NDK release.
+ */
+public abstract class ApiLevel {
+
+ public static ApiLevel getApiLevel(
+ NdkRelease release, EventHandler eventHandler, String repositoryName, String apiLevel) {
+ if ("10".equals(release.majorRevision)) {
+ return new ApiLevelR10e(eventHandler, repositoryName, apiLevel);
+ } else {
+ return new ApiLevelR11(eventHandler, repositoryName, apiLevel);
+ }
+ }
+
+ /**
+ * Maps an Android API level to the architectures that that level supports.
+ * Based on the directories in the "platforms" directory in the NDK.
+ */
+ private final ImmutableListMultimap<String, String> apiLevelToArchitectures;
+
+ /**
+ * Maps an API level to its equivalent API level in the NDK.
+ */
+ private final ImmutableMap<String, String> apiEquivalencies;
+
+ private final String correctedApiLevel;
+
+ protected ApiLevel(
+ ImmutableListMultimap<String, String> apiLevelToArchitectures,
+ ImmutableMap<String, String> apiEquivalencies,
+ EventHandler eventHandler,
+ String repositoryName,
+ String apiLevel) {
+
+ this.apiLevelToArchitectures = apiLevelToArchitectures;
+ this.apiEquivalencies = apiEquivalencies;
+ this.correctedApiLevel = getCorrectedApiLevel(eventHandler, repositoryName, apiLevel);
+ }
+
+ /**
+ * Translates the given API level to the equivalent API level in the NDK.
+ */
+ private String getCorrectedApiLevel(
+ EventHandler eventHandler, String repositoryName, String apiLevel) {
+
+ String correctedApiLevel = apiEquivalencies.get(apiLevel);
+ if (correctedApiLevel == null) {
+ // The user specified an API level we don't know about. Default to the most recent API level.
+ // This relies on the entries being added in sorted order.
+ String latestApiLevel = Iterables.getLast(apiEquivalencies.keySet());
+ correctedApiLevel = apiEquivalencies.get(latestApiLevel);
+
+ eventHandler.handle(Event.warn(String.format(
+ "API level %s specified by android_ndk_repository '%s' is not available. "
+ + "Using latest known API level %s",
+ apiLevel, repositoryName, latestApiLevel)));
+ }
+ return correctedApiLevel;
+ }
+
+ public String getCpuCorrectedApiLevel(String targetCpu) {
+
+ // Check that this API level supports the given cpu architecture (eg 64 bit is supported on only
+ // 21+).
+ if (!apiLevelToArchitectures.containsEntry(correctedApiLevel, targetCpu)) {
+ // If the given API level does not support the given architecture, find an API level that
+ // does support this architecture. A warning isn't printed because the crosstools for
+ // architectures that aren't supported by this API level are generated anyway, even if the
+ // user doesn't intend to use them (eg, if they're building for only 32 bit archs, the
+ // crosstools for the 64 bit toolchains are generated regardless).
+ // API_LEVEL_TO_ARCHITECTURES.inverse() returns a map of architectures to the APIs that
+ // support that architecture.
+ return Iterables.getLast(apiLevelToArchitectures.inverse().get(targetCpu));
+ }
+
+ return correctedApiLevel;
+ }
+}
+
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/NdkPaths.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/NdkPaths.java
index 084601e75b..3016a95af6 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/NdkPaths.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/NdkPaths.java
@@ -12,7 +12,7 @@
// 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;
+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;
@@ -46,7 +46,7 @@ public class NdkPaths {
this.apiLevel = apiLevel;
}
- ImmutableList<ToolPath> createToolpaths(String toolchainName, String targetPlatform,
+ public ImmutableList<ToolPath> createToolpaths(String toolchainName, String targetPlatform,
CppConfiguration.Tool... excludedTools) {
ImmutableList.Builder<ToolPath> toolPaths = ImmutableList.builder();
@@ -68,7 +68,7 @@ public class NdkPaths {
return toolPaths.build();
}
- ImmutableList<ToolPath> createClangToolpaths(String toolchainName, String targetPlatform,
+ public ImmutableList<ToolPath> createClangToolpaths(String toolchainName, String targetPlatform,
String llvmVersion, CppConfiguration.Tool... excludedTools) {
// Add GCC to the list of excluded tools. It will be replaced by clang below.
@@ -84,7 +84,7 @@ public class NdkPaths {
.add(ToolPath.newBuilder()
.setName("gcc")
- .setPath(createToolPath("llvm-" + llvmVersion, "clang"))
+ .setPath(createToolPath(llvmVersion == null ? "llvm" : "llvm-" + llvmVersion, "clang"))
.build())
.build();
}
@@ -105,7 +105,7 @@ public class NdkPaths {
return toolPath.split("/")[2];
}
- String createGccToolchainPath(String toolchainName) {
+ public String createGccToolchainPath(String toolchainName) {
String gccToolchainPathTemplate =
"external/%repositoryName%/ndk/toolchains/%toolchainName%/prebuilt/%hostPlatform%";
@@ -116,7 +116,7 @@ public class NdkPaths {
.replace("%hostPlatform%", hostPlatform);
}
- void addToolchainIncludePaths(
+ public void addToolchainIncludePaths(
List<CToolchain.Builder> toolchains,
String toolchainName,
String targetPlatform,
@@ -127,7 +127,7 @@ public class NdkPaths {
}
}
- void addToolchainIncludePaths(
+ public void addToolchainIncludePaths(
CToolchain.Builder toolchain,
String toolchainName,
String targetPlatform,
@@ -172,7 +172,7 @@ public class NdkPaths {
.replace("%includeFolderName%", includeFolderName);
}
- String createBuiltinSysroot(String targetCpu) {
+ public String createBuiltinSysroot(String targetCpu) {
String correctedApiLevel = apiLevel.getCpuCorrectedApiLevel(targetCpu);
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/NdkRelease.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/NdkRelease.java
index 16d9b671ad..ec39fdc0da 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/NdkRelease.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/NdkRelease.java
@@ -14,8 +14,9 @@
package com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools;
-import com.google.devtools.build.lib.util.CPU;
-
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -24,7 +25,46 @@ import java.util.regex.Pattern;
*/
public class NdkRelease {
+ /** Key name for the revision in the source.properties file. */
+ private static final String REVISION_PROPERTY = "Pkg.Revision";
+
public static NdkRelease create(String releaseString) {
+ if (releaseString.contains(REVISION_PROPERTY)) {
+ // For NDK r11+
+ return createFromSourceProperties(releaseString);
+ } else {
+ // For NDK r10e
+ return createFromReleaseTxt(releaseString);
+ }
+ }
+
+ /**
+ * Creates an NdkRelease for r11+ (uses source.properties)
+ */
+ private static NdkRelease createFromSourceProperties(String releaseString) {
+ Properties properties = new Properties();
+ try {
+ properties.load(new StringReader(releaseString));
+ } catch (IOException e) {
+ // This shouldn't happen from a StringReader.
+ throw new IllegalStateException(e);
+ }
+ String revision = properties.getProperty(REVISION_PROPERTY);
+ String[] revisionParsed = revision.split("\\.");
+ return new NdkRelease(
+ revision, // raw revision
+ true, // isValid
+ revisionParsed[0], // major revision
+ revisionParsed[1], // minor revision
+ null, // release candidate
+ true // is64 bit. 32-bit NDKs are provided for only windows.
+ );
+ }
+
+ /**
+ * Creates an NdkRelease pre-r11 (used RELEASE.TXT)
+ */
+ private static NdkRelease createFromReleaseTxt(String revisionString) {
// NDK release should be of the format "r\d+\w?(-rc\d+)?( \(64-bit\))?", eg:
// r8
// r10
@@ -32,49 +72,43 @@ public class NdkRelease {
// r10e
// r10e-rc4
// r10e-rc4 (64-bit)
- Pattern releaseRegex = Pattern.compile(
- "(?<rel>r\\d+\\w?)(-(?<rc>rc\\d+))?(?<s4> \\(64-bit\\))?");
- Matcher matcher = releaseRegex.matcher(releaseString);
+ Pattern revisionRegex = Pattern.compile(
+ "r(?<Mrev>\\d+)(?<mrev>\\w)?(-(?<rc>rc\\d+))?(?<s4> \\(64-bit\\))?");
+ Matcher matcher = revisionRegex.matcher(revisionString);
boolean isValid = matcher.matches();
if (isValid) {
return new NdkRelease(
- releaseString,
+ revisionString,
isValid,
- matcher.group("rel"), /* release */
+ matcher.group("Mrev"), /* major revision */
+ matcher.group("mrev"), /* minor revision */
matcher.group("rc"), /* releaseCandidate */
matcher.group("s4") != null /* is64Bit */);
} else {
- return new NdkRelease(releaseString, false, null, null, false);
+ return new NdkRelease(revisionString, false, null, null, null, false);
}
}
- /**
- * Guesses the bit-ness of the NDK based on the current platform.
- */
- public static NdkRelease guessBitness(String baseReleaseString) {
- NdkRelease baseRelease = create(baseReleaseString);
- boolean is64Bit = (CPU.getCurrent() == CPU.X86_64);
- return new NdkRelease(
- baseRelease.rawRelease + (is64Bit ? " (64-bit)" : ""),
- baseRelease.isValid,
- baseRelease.release,
- baseRelease.releaseCandidate,
- is64Bit);
- }
-
public final String rawRelease;
public final boolean isValid;
- public final String release;
+ public final String majorRevision;
+ public final String minorRevision;
public final String releaseCandidate;
public final boolean is64Bit;
- private NdkRelease(String rawRelease, boolean isValid, String release, String releaseCandidate,
+ private NdkRelease(
+ String rawRelease,
+ boolean isValid,
+ String majorRevision,
+ String minorRevision,
+ String releaseCandidate,
boolean is64Bit) {
this.rawRelease = rawRelease;
this.isValid = isValid;
- this.release = release;
+ this.majorRevision = majorRevision;
+ this.minorRevision = minorRevision;
this.releaseCandidate = releaseCandidate;
this.is64Bit = is64Bit;
}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/StlImpl.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/StlImpl.java
index e763ba314a..d8e793df78 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/StlImpl.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/StlImpl.java
@@ -12,7 +12,7 @@
// 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;
+package com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools;
import com.google.common.base.Verify;
import com.google.common.collect.ImmutableList;
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/StlImpls.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/StlImpls.java
index dc5d13695e..90cb21f793 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/StlImpls.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/StlImpls.java
@@ -12,7 +12,7 @@
// 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;
+package com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain.Builder;
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/AndroidNdkCrosstoolsR10e.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/AndroidNdkCrosstoolsR10e.java
index 23fe66b2ac..7dc4b1ff76 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/AndroidNdkCrosstoolsR10e.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/AndroidNdkCrosstoolsR10e.java
@@ -16,10 +16,8 @@ package com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r10e;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkRelease;
-import com.google.devtools.build.lib.events.Event;
-import com.google.devtools.build.lib.events.EventHandler;
-import com.google.devtools.build.lib.util.OS;
+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;
@@ -33,17 +31,6 @@ import java.util.Map.Entry;
*/
public class AndroidNdkCrosstoolsR10e {
- private static final String KNOWN_NDK_REVISION = "r10e";
-
- /**
- * Exception thrown when there is an error creating the crosstools file.
- */
- public static class NdkCrosstoolsException extends Exception {
- private NdkCrosstoolsException(String msg) {
- super(msg);
- }
- }
-
private AndroidNdkCrosstoolsR10e() {}
/**
@@ -54,39 +41,13 @@ public class AndroidNdkCrosstoolsR10e {
* NDK. TODO(bazel-team): Eventually we should move this into Skylark so the crosstools can be
* updated independently of Bazel itself.
*
- * @param eventHandler The event handler for sending warning messages.
- * @param repositoryName The name of the repository, which should correspond to the name of the
- * android_ndk_repository rule.
- * @param ndkRelease The NDK release
* @return A CrosstoolRelease for the Android NDK.
*/
public static CrosstoolRelease create(
- EventHandler eventHandler,
NdkPaths ndkPaths,
- String repositoryName,
- NdkRelease ndkRelease,
StlImpl stlImpl,
String hostPlatform) {
- // Check that the Android NDK revision is both valid and one we know about.
- if (!ndkRelease.isValid) {
-
- // Try using the NDK revision we know about.
- ndkRelease = NdkRelease.guessBitness(KNOWN_NDK_REVISION);
-
- eventHandler.handle(Event.warn(String.format(
- "The revision of the Andorid NDK given in android_ndk_repository rule '%s' could not be "
- + "determined (the revision string found is '%s'). "
- + "Defaulting to Android NDK revision %s", repositoryName, ndkRelease.rawRelease,
- ndkRelease)));
-
- } else if (!KNOWN_NDK_REVISION.equals(ndkRelease.release)) {
- eventHandler.handle(Event.warn(String.format(
- "Bazel Android NDK crosstools are based on Android NDK revision %s. "
- + "The revision of the Android NDK given in android_ndk_repository rule '%s' is '%s'",
- KNOWN_NDK_REVISION, repositoryName, ndkRelease.release)));
- }
-
CrosstoolRelease crosstoolRelease = CrosstoolRelease.newBuilder()
.setMajorVersion("android")
.setMinorVersion("")
@@ -156,34 +117,4 @@ public class AndroidNdkCrosstoolsR10e {
}
return defaultCpuToolchains.build();
}
-
- public static String getHostPlatform(NdkRelease ndkRelease) throws NdkCrosstoolsException {
- String hostOs;
- switch (OS.getCurrent()) {
- case DARWIN:
- hostOs = "darwin";
- break;
- case LINUX:
- hostOs = "linux";
- break;
- case WINDOWS:
- hostOs = "windows";
- if (!ndkRelease.is64Bit) {
- // 32-bit windows paths don't have the "-x86" suffix in the NDK (added below), but
- // 64-bit windows does have the "-x86_64" suffix.
- return hostOs;
- }
- break;
- case UNKNOWN:
- default:
- throw new NdkCrosstoolsException(
- String.format("NDK does not support the host platform \"%s\"", OS.getCurrent()));
- }
-
- // Use the arch from the NDK rather than detecting the actual platform, since it's possible
- // to use the 32-bit NDK on a 64-bit machine.
- String hostArch = ndkRelease.is64Bit ? "x86_64" : "x86";
-
- return hostOs + "-" + hostArch;
- }
}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/ApiLevel.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/ApiLevelR10e.java
index d5f44265b4..743025fa3f 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/ApiLevel.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/ApiLevelR10e.java
@@ -16,19 +16,14 @@ package com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r10e;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.devtools.build.lib.events.Event;
+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.
*/
-public class ApiLevel {
+public class ApiLevelR10e extends ApiLevel {
- /**
- * Maps an Android API level to the architectures that that level supports.
- * Based on the directories in the "platforms" directory in the NDK.
- */
private static final ImmutableListMultimap<String, String> API_LEVEL_TO_ARCHITECTURES =
ImmutableListMultimap.<String, String>builder()
.putAll("3", "arm")
@@ -48,8 +43,6 @@ public class ApiLevel {
.build();
/**
- * Maps an API level to it's equivalent API level in the NDK.
- *
* <p>Per the "special cases" listed in build/core/add-application.mk:
*
* <pre>
@@ -105,50 +98,12 @@ public class ApiLevel {
.build();
- private final String correctedApiLevel;
-
- public ApiLevel(EventHandler eventHandler, String repositoryName, String apiLevel) {
- this.correctedApiLevel = getCorrectedApiLevel(eventHandler, repositoryName, apiLevel);
- }
-
- /**
- * Translates the given API level to the equivalent API level in the NDK.
- */
- private static String getCorrectedApiLevel(
- EventHandler eventHandler, String repositoryName, String apiLevel) {
-
- String correctedApiLevel = API_EQUIVALENCIES.get(apiLevel);
- if (correctedApiLevel == null) {
- // The user specified an API level we don't know about. Default to the most recent API level.
- // This relies on the entries being added in sorted order.
- String latestApiLevel = Iterables.getLast(API_EQUIVALENCIES.keySet());
- correctedApiLevel = API_EQUIVALENCIES.get(latestApiLevel);
+ public ApiLevelR10e(
+ EventHandler eventHandler,
+ String repositoryName,
+ String apiLevel) {
- eventHandler.handle(Event.warn(String.format(
- "API level %s specified by android_ndk_repository '%s' is not available. "
- + "Using latest known API level %s",
- apiLevel, repositoryName, latestApiLevel)));
- }
- return correctedApiLevel;
+ super(API_LEVEL_TO_ARCHITECTURES, API_EQUIVALENCIES, eventHandler, repositoryName, apiLevel);
}
-
- String getCpuCorrectedApiLevel(String targetCpu) {
-
- // Check that this API level supports the given cpu architecture (eg 64 bit is supported on only
- // 21+).
- if (!API_LEVEL_TO_ARCHITECTURES.containsEntry(correctedApiLevel, targetCpu)) {
- // If the given API level does not support the given architecture, find an API level that
- // does support this architecture. A warning isn't printed because the crosstools for
- // architectures that aren't supported by this API level are generated anyway, even if the
- // user doesn't intend to use them (eg, if they're building for only 32 bit archs, the
- // crosstools for the 64 bit toolchains are generated regardless).
- // API_LEVEL_TO_ARCHITECTURES.inverse() returns a map of architectures to the APIs that
- // support that architecture.
- return Iterables.getLast(API_LEVEL_TO_ARCHITECTURES.inverse().get(targetCpu));
- }
-
- return correctedApiLevel;
- }
-
}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/ArmCrosstools.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/ArmCrosstools.java
index c2b6a4954b..d07f4ef2f1 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/ArmCrosstools.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/ArmCrosstools.java
@@ -15,6 +15,8 @@
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;
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/MipsCrosstools.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/MipsCrosstools.java
index e9ef3cb23a..9b7ad74a4a 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/MipsCrosstools.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/MipsCrosstools.java
@@ -15,6 +15,8 @@
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;
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/X86Crosstools.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/X86Crosstools.java
index 3583d0519a..7bacf16b3d 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/X86Crosstools.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r10e/X86Crosstools.java
@@ -15,6 +15,8 @@
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;
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/AndroidNdkCrosstoolsR11.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/AndroidNdkCrosstoolsR11.java
new file mode 100644
index 0000000000..5b5218fcb8
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/AndroidNdkCrosstoolsR11.java
@@ -0,0 +1,120 @@
+// Copyright 2016 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.r11;
+
+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.
+ */
+public class AndroidNdkCrosstoolsR11 {
+
+ private AndroidNdkCrosstoolsR11() {}
+
+ /**
+ * 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.
+ */
+ public static CrosstoolRelease create(
+ NdkPaths ndkPaths,
+ StlImpl stlImpl,
+ String hostPlatform) {
+
+ CrosstoolRelease crosstoolRelease = CrosstoolRelease.newBuilder()
+ .setMajorVersion("android")
+ .setMinorVersion("")
+ .setDefaultTargetCpu("armeabi")
+ .addAllDefaultToolchain(getDefaultCpuToolchains(stlImpl))
+ .addAllToolchain(createToolchains(ndkPaths, stlImpl, hostPlatform))
+ .build();
+
+ return crosstoolRelease;
+ }
+
+ private static ImmutableList<CToolchain> createToolchains(
+ NdkPaths ndkPaths, StlImpl stlImpl, String hostPlatform) {
+
+ List<CToolchain.Builder> toolchainBuilders = new ArrayList<>();
+ toolchainBuilders.addAll(new ArmCrosstools(ndkPaths, stlImpl).createCrosstools());
+ toolchainBuilders.addAll(new MipsCrosstools(ndkPaths, stlImpl).createCrosstools());
+ toolchainBuilders.addAll(new X86Crosstools(ndkPaths, stlImpl).createCrosstools());
+
+ ImmutableList.Builder<CToolchain> 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.
+ toolchainBuilder.addCxxBuiltinIncludeDirectory("%sysroot%/usr/include");
+
+ toolchains.add(toolchainBuilder.build());
+ }
+
+ return toolchains.build();
+ }
+
+ private static ImmutableList<DefaultCpuToolchain> getDefaultCpuToolchains(StlImpl stlImpl) {
+ // TODO(bazel-team): It would be better to auto-generate this somehow.
+
+ ImmutableMap<String, String> defaultCpus = ImmutableMap.<String, String>builder()
+ // arm
+ .put("armeabi", "arm-linux-androideabi-4.9")
+ .put("armeabi-v7a", "arm-linux-androideabi-4.9-v7a")
+ .put("armeabi-v7a-hard", "arm-linux-androideabi-4.9-v7a-hard")
+ .put("armeabi-thumb", "arm-linux-androideabi-4.9-thumb")
+ .put("armeabi-v7a-thumb", "arm-linux-androideabi-4.9-v7a-thumb")
+ .put("armeabi-v7a-hard-thumb", "arm-linux-androideabi-4.9-v7a-hard-thumb")
+ .put("arm64-v8a", "aarch64-linux-android-4.9")
+
+ // mips
+ .put("mips", "mipsel-linux-android-4.9")
+ .put("mips64", "mips64el-linux-android-4.9")
+
+ // x86
+ .put("x86", "x86-4.9")
+ .put("x86_64", "x86_64-4.9")
+ .build();
+
+ ImmutableList.Builder<DefaultCpuToolchain> defaultCpuToolchains = ImmutableList.builder();
+ for (Entry<String, String> 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/r11/ApiLevelR11.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/ApiLevelR11.java
new file mode 100644
index 0000000000..59d98caf81
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/ApiLevelR11.java
@@ -0,0 +1,114 @@
+// Copyright 2016 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.r11;
+
+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.
+ */
+public class ApiLevelR11 extends ApiLevel {
+
+ private static final ImmutableListMultimap<String, String> API_LEVEL_TO_ARCHITECTURES =
+ ImmutableListMultimap.<String, String>builder()
+ .putAll("3", "arm")
+ .putAll("4", "arm")
+ .putAll("5", "arm")
+ .putAll("8", "arm")
+ .putAll("9", "arm", "mips", "x86")
+ .putAll("12", "arm", "mips", "x86")
+ .putAll("13", "arm", "mips", "x86")
+ .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("23", "arm", "mips", "x86", "arm64", "mips64", "x86_64")
+ .putAll("24", "arm", "mips", "x86", "arm64", "mips64", "x86_64")
+ .build();
+
+ /**
+ * <p>Per the "special cases" listed in build/core/add-application.mk:
+ *
+ * <pre>
+ * SPECIAL CASES:
+ * 1) android-6 and android-7 are the same thing as android-5
+ * 2) android-10 and android-11 are the same thing as android-9
+ * 3) android-20 is the same thing as android-19
+ * 4) android-21 and up are the same thing as android-21
+ * ADDITIONAL CASES for remote server where total number of files is limited
+ * 5) android-13 is the same thing as android-12
+ * 6) android-15 is the same thing as android-14
+ * 7) android-17 is the same thing as android-16
+ * </pre>
+ */
+ private static final ImmutableMap<String, String> API_EQUIVALENCIES =
+ ImmutableMap.<String, String>builder()
+ .put("3", "3")
+ .put("4", "4")
+
+ // Case 1
+ .put("5", "5")
+ .put("6", "5")
+ .put("7", "5")
+
+ .put("8", "8")
+
+ // Case 2
+ .put("9", "9")
+ .put("10", "9")
+ .put("11", "9")
+
+ // Case 5
+ .put("12", "12")
+ .put("13", "12")
+
+ // Case 6
+ .put("14", "14")
+ .put("15", "14")
+
+ // Case 7
+ .put("16", "16")
+ .put("17", "16")
+
+ .put("18", "18")
+
+ // Case 3
+ .put("19", "19")
+ .put("20", "19")
+
+ // Case 4
+ .put("21", "21")
+ .put("22", "21")
+
+ .put("23", "23")
+ .put("24", "24")
+
+ .build();
+
+ public ApiLevelR11(
+ 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/r11/ArmCrosstools.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/ArmCrosstools.java
new file mode 100644
index 0000000000..724f87352d
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/ArmCrosstools.java
@@ -0,0 +1,426 @@
+// Copyright 2016 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.r11;
+
+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());
+ toolchains.add(createAarch64ClangToolchain());
+
+ // 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,
+ // resulting in:
+ // 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.
+
+ toolchains.addAll(createArmeabiToolchains(false));
+ toolchains.addAll(createArmeabiToolchains(true));
+
+ toolchains.addAll(createArmeabiClangToolchain(false));
+ toolchains.addAll(createArmeabiClangToolchain(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 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-clang3.8")
+ .setTargetSystemName("aarch64-linux-android")
+ .setTargetCpu("arm64-v8a")
+ .setCompiler("clang3.8")
+
+ .addAllToolPath(ndkPaths.createClangToolpaths(toolchainName, targetPlatform, null))
+
+ .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")
+
+ // 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(boolean thumb,
+ CppConfiguration.Tool... excludedTools) {
+
+ ImmutableList<CToolchain.Builder> toolchains = ImmutableList.of(
+ createBaseArmeabiToolchain(thumb, excludedTools)
+ .setToolchainIdentifier(
+ createArmeabiName("arm-linux-androideabi-4.9", thumb))
+ .setTargetCpu(createArmeabiCpuName("armeabi", thumb))
+
+ .addCompilerFlag("-march=armv5te")
+ .addCompilerFlag("-mtune=xscale")
+ .addCompilerFlag("-msoft-float"),
+
+ createBaseArmeabiToolchain(thumb, excludedTools)
+ .setToolchainIdentifier(
+ createArmeabiName("arm-linux-androideabi-4.9-v7a", 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"),
+
+ createBaseArmeabiToolchain(thumb, excludedTools)
+ .setToolchainIdentifier(
+ createArmeabiName("arm-linux-androideabi-4.9-v7a-hard", 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"));
+
+ stlImpl.addStlImpl(toolchains, "4.9");
+ return toolchains;
+ }
+
+ /**
+ * Flags common to arm-linux-androideabi*
+ */
+ private CToolchain.Builder createBaseArmeabiToolchain(
+ boolean thumb, CppConfiguration.Tool... excludedTools) {
+
+ String toolchainName = "arm-linux-androideabi-4.9";
+ String targetPlatform = "arm-linux-androideabi";
+
+ CToolchain.Builder toolchain = CToolchain.newBuilder()
+ .setTargetSystemName(targetPlatform)
+ .setCompiler("gcc-4.9")
+
+ .addAllToolPath(ndkPaths.createToolpaths(toolchainName, targetPlatform, excludedTools))
+ .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("arm"))
+
+ // Compiler flags
+ .addCompilerFlag("-fstack-protector-strong")
+ .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, "4.9");
+ return toolchain;
+ }
+
+ private List<CToolchain.Builder> createArmeabiClangToolchain(boolean thumb) {
+
+ ImmutableList<CToolchain.Builder> toolchains = ImmutableList.of(
+ createBaseArmeabiClangToolchain(thumb)
+ .setToolchainIdentifier(createArmeabiName("arm-linux-androideabi-clang3.8", 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"),
+
+ createBaseArmeabiClangToolchain(thumb)
+ .setToolchainIdentifier(createArmeabiName("arm-linux-androideabi-clang3.8-v7a", 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"),
+
+ createBaseArmeabiClangToolchain(thumb)
+ .setToolchainIdentifier(
+ createArmeabiName("arm-linux-androideabi-clang3.8-v7a-hard", 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"));
+
+ stlImpl.addStlImpl(toolchains, "4.9");
+ return toolchains;
+ }
+
+ private CToolchain.Builder createBaseArmeabiClangToolchain(boolean thumb) {
+
+ 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("clang3.8")
+
+ .addAllToolPath(ndkPaths.createClangToolpaths(toolchainName, targetPlatform, null))
+
+ .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");
+
+ 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, boolean thumb) {
+ return base + (thumb ? "-thumb" : "");
+ }
+
+ private static String createArmeabiCpuName(String base, boolean thumb) {
+ return base + (thumb ? "-thumb" : "");
+ }
+} \ No newline at end of file
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/MipsCrosstools.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/MipsCrosstools.java
new file mode 100644
index 0000000000..7084c93096
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/MipsCrosstools.java
@@ -0,0 +1,222 @@
+// Copyright 2016 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.r11;
+
+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 MIPS. These values are based on the setup.mk files in the Android NDK
+ * toolchain directories.
+ */
+class MipsCrosstools {
+
+ private final NdkPaths ndkPaths;
+ private final StlImpl stlImpl;
+
+ MipsCrosstools(NdkPaths ndkPaths, StlImpl stlImpl) {
+ this.ndkPaths = ndkPaths;
+ this.stlImpl = stlImpl;
+ }
+
+ ImmutableList<CToolchain.Builder> createCrosstools() {
+
+ ImmutableList.Builder<CToolchain.Builder> toolchains = ImmutableList.builder();
+
+ toolchains.addAll(createMips64Toolchains());
+ toolchains.addAll(createMipsToolchains());
+
+ return toolchains.build();
+ }
+
+ private List<CToolchain.Builder> createMips64Toolchains() {
+
+ ImmutableList.Builder<CToolchain.Builder> toolchainsListBuilder = ImmutableList.builder();
+
+ toolchainsListBuilder.add(createBaseMipsToolchain()
+ .setToolchainIdentifier("mips64el-linux-android-4.9")
+ .setTargetSystemName("mips64el-linux-android")
+ .setTargetCpu("mips64")
+ .setCompiler("gcc-4.9")
+
+ .addAllToolPath(ndkPaths.createToolpaths(
+ "mips64el-linux-android-4.9", "mips64el-linux-android",
+ // mips64 toolchain doesn't have the dwp tool.
+ CppConfiguration.Tool.DWP))
+
+ .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("mips64")));
+
+ toolchainsListBuilder.add(createBaseMipsClangToolchain("mips64el")
+ .setToolchainIdentifier("mips64el-linux-android-clang3.8")
+ .setTargetSystemName("mips64el-linux-android")
+ .setTargetCpu("mips64")
+
+ .addAllToolPath(ndkPaths.createClangToolpaths(
+ "mips64el-linux-android-4.9",
+ "mips64el-linux-android",
+ null,
+ CppConfiguration.Tool.DWP))
+
+ .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("mips64")));
+
+ List<CToolchain.Builder> toolchains = toolchainsListBuilder.build();
+ ndkPaths.addToolchainIncludePaths(
+ toolchains, "mips64el-linux-android-4.9", "mips64el-linux-android", "4.9");
+ stlImpl.addStlImpl(toolchains, "4.9");
+ return toolchains;
+ }
+
+ private List<CToolchain.Builder> createMipsToolchains() {
+
+ ImmutableList.Builder<CToolchain.Builder> toolchainsListBuilder = ImmutableList.builder();
+
+ // The gcc-4.9 mips toolchain doesn't have the dwp tool.
+ toolchainsListBuilder.add(createMipsToolchain());
+
+ CToolchain.Builder mipsClang = createBaseMipsClangToolchain("mipsel")
+ // Purposefully no hyphen between "clang" and clang version.
+ .setToolchainIdentifier("mipsel-linux-android-clang3.8")
+ .setTargetSystemName("mipsel-linux-android")
+ .setTargetCpu("mips")
+
+ .addAllToolPath(ndkPaths.createClangToolpaths(
+ "mipsel-linux-android-4.9",
+ "mipsel-linux-android",
+ null,
+ CppConfiguration.Tool.DWP, CppConfiguration.Tool.GCOVTOOL))
+
+ .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("mips"));
+
+ ndkPaths.addToolchainIncludePaths(
+ mipsClang, "mipsel-linux-android-4.9", "mipsel-linux-android", "4.9");
+ stlImpl.addStlImpl(mipsClang, "4.9");
+ toolchainsListBuilder.add(mipsClang);
+
+ return toolchainsListBuilder.build();
+ }
+
+ private CToolchain.Builder createMipsToolchain() {
+
+ CToolchain.Builder toolchain = createBaseMipsToolchain()
+ .setToolchainIdentifier("mipsel-linux-android-4.9")
+ .setTargetSystemName("mipsel-linux-android")
+ .setTargetCpu("mips")
+ .setCompiler("gcc-4.9")
+
+ .addAllToolPath(ndkPaths.createToolpaths(
+ "mipsel-linux-android-4.9", "mipsel-linux-android",
+ CppConfiguration.Tool.DWP))
+
+ .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("mips"));
+
+ ndkPaths.addToolchainIncludePaths(
+ toolchain, "mipsel-linux-android-4.9", "mipsel-linux-android", "4.9");
+ stlImpl.addStlImpl(toolchain, "4.9");
+ return toolchain;
+ }
+
+ private CToolchain.Builder createBaseMipsToolchain() {
+ return CToolchain.newBuilder()
+ // Compiler flags
+ .addCompilerFlag("-fpic")
+ .addCompilerFlag("-fno-strict-aliasing")
+ .addCompilerFlag("-finline-functions")
+ .addCompilerFlag("-ffunction-sections")
+ .addCompilerFlag("-funwind-tables")
+ .addCompilerFlag("-fmessage-length=0")
+ .addCompilerFlag("-fno-inline-functions-called-once")
+ .addCompilerFlag("-fgcse-after-reload")
+ .addCompilerFlag("-frerun-cse-after-loop")
+ .addCompilerFlag("-frename-registers")
+ .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("-funswitch-loops")
+ .addCompilerFlag("-finline-limit=300"))
+
+ // Additional debug flags
+ .addCompilationModeFlags(CompilationModeFlags.newBuilder()
+ .setMode(CompilationMode.DBG)
+ .addCompilerFlag("-O0")
+ .addCompilerFlag("-g")
+ .addCompilerFlag("-fno-omit-frame-pointer"));
+ }
+
+ 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("clang3.8")
+
+ // 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")
+ .addCompilerFlag("-fomit-frame-pointer"))
+
+ // Additional debug flags
+ .addCompilationModeFlags(CompilationModeFlags.newBuilder()
+ .setMode(CompilationMode.DBG)
+ .addCompilerFlag("-O0")
+ .addCompilerFlag("-g")
+ .addCompilerFlag("-fno-omit-frame-pointer"));
+ }
+}
+
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/X86Crosstools.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/X86Crosstools.java
new file mode 100644
index 0000000000..e249278265
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/r11/X86Crosstools.java
@@ -0,0 +1,205 @@
+// Copyright 2016 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.r11;
+
+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.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.
+ */
+class X86Crosstools {
+
+ private final NdkPaths ndkPaths;
+ private final StlImpl stlImpl;
+
+ X86Crosstools(NdkPaths ndkPaths, StlImpl stlImpl) {
+ this.ndkPaths = ndkPaths;
+ this.stlImpl = stlImpl;
+ }
+
+ ImmutableList<CToolchain.Builder> createCrosstools() {
+
+ ImmutableList.Builder<CToolchain.Builder> toolchains = ImmutableList.builder();
+
+ /**
+ * x86
+ */
+
+ // gcc 4.9
+ toolchains.add(createX86Toolchain());
+
+ // clang
+ CToolchain.Builder x86Clang = createBaseX86ClangToolchain("x86", "i686")
+ .setToolchainIdentifier("x86-clang3.8")
+ .setTargetCpu("x86")
+
+ .addAllToolPath(ndkPaths.createClangToolpaths(
+ "x86-4.9", "i686-linux-android", null))
+
+ .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("x86"));
+
+ ndkPaths.addToolchainIncludePaths(x86Clang, "x86-4.9", "i686-linux-android", "4.9");
+ stlImpl.addStlImpl(x86Clang, "4.9");
+ toolchains.add(x86Clang);
+
+ /**
+ * x86_64
+ */
+
+ CToolchain.Builder x8664 = createBaseX86Toolchain()
+ .setToolchainIdentifier("x86_64-4.9")
+ .setTargetCpu("x86_64")
+ .setCompiler("gcc-4.9")
+
+ .addAllToolPath(ndkPaths.createToolpaths(
+ "x86_64-4.9", "x86_64-linux-android"))
+
+ .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("x86_64"))
+
+ .addCompilerFlag("-fstack-protector-strong");
+
+ ndkPaths.addToolchainIncludePaths(x8664, "x86_64-4.9", "x86_64-linux-android", "4.9");
+ stlImpl.addStlImpl(x8664, "4.9");
+ toolchains.add(x8664);
+
+ CToolchain.Builder x8664Clang =
+ createBaseX86ClangToolchain("x86_64", "x86_64")
+ .setToolchainIdentifier("x86_64-clang3.8")
+ .setTargetCpu("x86_64")
+
+ .addAllToolPath(ndkPaths.createClangToolpaths(
+ "x86_64-4.9", "x86_64-linux-android", null))
+
+ .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("x86_64"));
+
+ ndkPaths.addToolchainIncludePaths(x8664Clang, "x86_64-4.9", "x86_64-linux-android", "4.9");
+ stlImpl.addStlImpl(x8664Clang, "4.9");
+ toolchains.add(x8664Clang);
+
+ ImmutableList<CToolchain.Builder> toolchainBuilders = toolchains.build();
+
+ // x86_64 also sets "x86-linux-android"
+ for (CToolchain.Builder toolchainBuilder : toolchainBuilders) {
+ toolchainBuilder.setTargetSystemName("x86-linux-android");
+ }
+
+ return toolchainBuilders;
+ }
+
+ private CToolchain.Builder createX86Toolchain() {
+
+ CToolchain.Builder toolchain = createBaseX86Toolchain()
+ .setToolchainIdentifier("x86-4.9")
+ .setTargetCpu("x86")
+ .setCompiler("gcc-4.9")
+
+ .addAllToolPath(ndkPaths.createToolpaths("x86-4.9", "i686-linux-android"))
+
+ .setBuiltinSysroot(ndkPaths.createBuiltinSysroot("x86"))
+
+ .addCompilerFlag("-fstack-protector-strong");
+
+ ndkPaths.addToolchainIncludePaths(
+ toolchain, "x86-4.9", "i686-linux-android", "4.9");
+ stlImpl.addStlImpl(toolchain, "4.9");
+ return toolchain;
+ }
+
+ private CToolchain.Builder createBaseX86Toolchain() {
+ return CToolchain.newBuilder()
+ // Compiler flags
+ .addCompilerFlag("-ffunction-sections")
+ .addCompilerFlag("-funwind-tables")
+ .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("-g")
+ .addCompilerFlag("-fno-omit-frame-pointer")
+ .addCompilerFlag("-fno-strict-aliasing"));
+ }
+
+ private CToolchain.Builder createBaseX86ClangToolchain(String x86Arch, String llvmArch) {
+
+ String gccToolchain = ndkPaths.createGccToolchainPath(x86Arch + "-4.9");
+
+ String llvmTriple = llvmArch + "-none-linux-android";
+
+ return CToolchain.newBuilder()
+ .setCompiler("clang3.8")
+
+ // 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")
+
+ // 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("-g")
+ .addCompilerFlag("-fno-omit-frame-pointer")
+ .addCompilerFlag("-fnostrict-aliasing"));
+ }
+}