Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8c00f39

Browse files
aj-michaelhermione521
authored andcommitted
Improve handling of unknown NDK revisions in android_ndk_repository.
-- PiperOrigin-RevId: 148816635 MOS_MIGRATED_REVID=148816635
1 parent 2f11192 commit 8c00f39

5 files changed

Lines changed: 137 additions & 63 deletions

File tree

src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.AndroidNdkCrosstools;
2323
import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.AndroidNdkCrosstools.NdkCrosstoolsException;
2424
import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.ApiLevel;
25+
import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkMajorRevision;
2526
import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkPaths;
2627
import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkRelease;
2728
import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.StlImpl;
@@ -63,7 +64,7 @@ public class AndroidNdkRepositoryFunction extends RepositoryFunction {
6364
private static final PathFragment PLATFORMS_DIR = new PathFragment("platforms");
6465

6566
private static final Iterable<String> PATH_ENV_VAR_AS_LIST = ImmutableList.of(PATH_ENV_VAR);
66-
67+
6768
private static final class CrosstoolStlPair {
6869

6970
private final CrosstoolRelease crosstoolRelease;
@@ -165,26 +166,36 @@ public RepositoryDirectoryValue.Builder fetch(Rule rule, Path outputDirectory,
165166
apiLevelString = apiLevels.first().toString();
166167
}
167168

168-
ApiLevel apiLevel;
169-
apiLevel =
170-
AndroidNdkCrosstools.KNOWN_NDK_MAJOR_REVISIONS
171-
.get(ndkRelease.majorRevision)
172-
.apiLevel(env.getListener(), ruleName, apiLevelString);
173-
169+
// NDK minor revisions should be backwards compatible within a major revision, the crosstools
170+
// we generate don't care about the minor revision.
171+
NdkMajorRevision ndkMajorRevision;
174172
if (!ndkRelease.isValid) {
175-
env.getListener().handle(Event.warn(String.format(
176-
"The revision of the Android NDK given in android_ndk_repository rule '%s' could not be "
177-
+ "determined (the revision string found is '%s'). "
178-
+ "Defaulting to Android NDK revision %s", ruleName, ndkRelease.rawRelease,
179-
AndroidNdkCrosstools.LATEST_KNOWN_REVISION)));
173+
String warningMessage =
174+
String.format(
175+
"The revision of the Android NDK referenced by android_ndk_repository rule '%s' "
176+
+ "could not be determined (the revision string found is '%s'). Defaulting to "
177+
+ "revision %s.",
178+
ruleName, ndkRelease.rawRelease, AndroidNdkCrosstools.LATEST_KNOWN_REVISION.getKey());
179+
env.getListener().handle(Event.warn(warningMessage));
180+
ndkMajorRevision = AndroidNdkCrosstools.LATEST_KNOWN_REVISION.getValue();
181+
} else if (!AndroidNdkCrosstools.isKnownNDKRevision(ndkRelease)) {
182+
String warningMessage =
183+
String.format(
184+
"The major revision of the Android NDK referenced by android_ndk_repository rule "
185+
+ "'%s' is %s. The major revisions supported by Bazel are %s. Defaulting to "
186+
+ "revision %s.",
187+
ruleName,
188+
ndkRelease.majorRevision,
189+
AndroidNdkCrosstools.KNOWN_NDK_MAJOR_REVISIONS.keySet(),
190+
AndroidNdkCrosstools.LATEST_KNOWN_REVISION.getKey());
191+
env.getListener().handle(Event.warn(warningMessage));
192+
ndkMajorRevision = AndroidNdkCrosstools.LATEST_KNOWN_REVISION.getValue();
193+
} else {
194+
ndkMajorRevision =
195+
AndroidNdkCrosstools.KNOWN_NDK_MAJOR_REVISIONS.get(ndkRelease.majorRevision);
180196
}
181197

182-
if (!AndroidNdkCrosstools.isKnownNDKRevision(ndkRelease)) {
183-
env.getListener().handle(Event.warn(String.format(
184-
"Bazel Android NDK crosstools are based on Android NDK revision %s. "
185-
+ "The revision of the Android NDK given in android_ndk_repository rule '%s' is '%s'",
186-
AndroidNdkCrosstools.LATEST_KNOWN_REVISION, ruleName, ndkRelease.rawRelease)));
187-
}
198+
ApiLevel apiLevel = ndkMajorRevision.apiLevel(env.getListener(), ruleName, apiLevelString);
188199

189200
ImmutableList.Builder<CrosstoolStlPair> crosstoolsAndStls = ImmutableList.builder();
190201
try {
@@ -193,13 +204,8 @@ public RepositoryDirectoryValue.Builder fetch(Rule rule, Path outputDirectory,
193204
NdkPaths ndkPaths = new NdkPaths(ruleName, hostPlatform, apiLevel);
194205

195206
for (StlImpl stlImpl : StlImpls.get(ndkPaths)) {
196-
197-
CrosstoolRelease crosstoolRelease = AndroidNdkCrosstools.create(
198-
ndkRelease,
199-
ndkPaths,
200-
stlImpl,
201-
hostPlatform);
202-
207+
CrosstoolRelease crosstoolRelease =
208+
ndkMajorRevision.crosstoolRelease(ndkPaths, stlImpl, hostPlatform);
203209
crosstoolsAndStls.add(new CrosstoolStlPair(crosstoolRelease, stlImpl));
204210
}
205211

@@ -246,7 +252,7 @@ private static String createBuildFile(String ruleName, List<CrosstoolStlPair> cr
246252
}
247253

248254
String toolchainName = createToolchainName(crosstoolStlPair.stlImpl.getName());
249-
255+
250256
ccToolchainSuites.append(ccToolchainSuiteTemplate
251257
.replace("%toolchainName%", toolchainName)
252258
.replace("%toolchainMap%", toolchainMap.toString().trim())
@@ -277,7 +283,7 @@ private static String createBuildFile(String ruleName, List<CrosstoolStlPair> cr
277283
static String createToolchainName(String stlName) {
278284
return TOOLCHAIN_NAME_PREFIX + stlName;
279285
}
280-
286+
281287
private static String createCcToolchainRule(String ccToolchainTemplate, CToolchain toolchain) {
282288

283289
// TODO(bazel-team): It's unfortunate to have to extract data from a CToolchain proto like this.
@@ -345,7 +351,7 @@ private static NdkRelease getNdkRelease(Path directory, Environment env)
345351
// For NDK r10e
346352
releaseFilePath = directory.getRelative("RELEASE.TXT");
347353
}
348-
354+
349355
SkyKey releaseFileKey = FileValue.key(RootedPath.toRootedPath(directory, releaseFilePath));
350356

351357
String releaseFileContent;

src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/AndroidNdkCrosstools.java

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r12.NdkMajorRevisionR12;
2222
import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.r13.NdkMajorRevisionR13;
2323
import com.google.devtools.build.lib.util.OS;
24-
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease;
24+
import java.util.Map;
2525

2626
/**
2727
* Helper methods for generating a CrosstoolRelease proto for the Android NDK based on a particular
@@ -38,8 +38,8 @@ private AndroidNdkCrosstools() {}
3838
"11", new NdkMajorRevisionR11(),
3939
"12", new NdkMajorRevisionR12(),
4040
"13", new NdkMajorRevisionR13());
41-
public static final String LATEST_KNOWN_REVISION =
42-
Iterables.getLast(KNOWN_NDK_MAJOR_REVISIONS.keySet());
41+
public static final Map.Entry<String, NdkMajorRevision> LATEST_KNOWN_REVISION =
42+
Iterables.getLast(KNOWN_NDK_MAJOR_REVISIONS.entrySet());
4343

4444
/**
4545
* Exception thrown when there is an error creating the crosstools file.
@@ -50,23 +50,6 @@ private NdkCrosstoolsException(String msg) {
5050
}
5151
}
5252

53-
public static CrosstoolRelease create(
54-
NdkRelease ndkRelease,
55-
NdkPaths ndkPaths,
56-
StlImpl stlImpl,
57-
String hostPlatform) {
58-
NdkMajorRevision ndkMajorRevision;
59-
if (ndkRelease.isValid) {
60-
// NDK minor revisions should be backwards compatible within a major revision, so it should be
61-
// enough to check the major revision of the release.
62-
ndkMajorRevision = KNOWN_NDK_MAJOR_REVISIONS.get(ndkRelease.majorRevision);
63-
} else {
64-
// If the NDK revision isn't valid, try using the latest one we know about.
65-
ndkMajorRevision = KNOWN_NDK_MAJOR_REVISIONS.get(LATEST_KNOWN_REVISION);
66-
}
67-
return ndkMajorRevision.crosstoolRelease(ndkPaths, stlImpl, hostPlatform);
68-
}
69-
7053
public static String getHostPlatform(NdkRelease ndkRelease) throws NdkCrosstoolsException {
7154
String hostOs;
7255
switch (OS.getCurrent()) {
@@ -99,5 +82,5 @@ public static String getHostPlatform(NdkRelease ndkRelease) throws NdkCrosstools
9982

10083
public static boolean isKnownNDKRevision(NdkRelease ndkRelease) {
10184
return KNOWN_NDK_MAJOR_REVISIONS.containsKey(ndkRelease.majorRevision);
102-
}
85+
}
10386
}

src/main/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/NdkRelease.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,19 @@ private static NdkRelease createFromSourceProperties(String releaseString) {
5151
}
5252
String revision = properties.getProperty(REVISION_PROPERTY);
5353
String[] revisionParsed = revision.split("\\.");
54-
return new NdkRelease(
55-
revision, // raw revision
56-
true, // isValid
57-
revisionParsed[0], // major revision
58-
revisionParsed[1], // minor revision
59-
null, // release candidate
60-
true // is64 bit. 32-bit NDKs are provided for only windows.
61-
);
54+
if (revisionParsed.length < 2) {
55+
// Unable to parse Pkg.Revision. Return invalid NdkRelease.
56+
return new NdkRelease(revision, false, null, null, null, false);
57+
} else {
58+
return new NdkRelease(
59+
revision, // raw revision
60+
true, // isValid
61+
revisionParsed[0], // major revision
62+
revisionParsed[1], // minor revision
63+
null, // release candidate
64+
true // is64 bit. 32-bit NDKs are provided for only windows.
65+
);
66+
}
6267
}
6368

6469
/**

src/test/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryTest.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
2121
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
2222
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
23+
import com.google.devtools.build.lib.testutil.MoreAsserts;
2324
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
2425
import com.google.devtools.build.lib.vfs.FileSystemUtils;
2526
import org.junit.Before;
@@ -74,4 +75,79 @@ public void testApiLevelHighestVersionDetection() throws Exception {
7475
.doesNotContain(
7576
"src external/androidndk/ndk/platforms/android-22/arch-x86/usr/lib/libandroid.so");
7677
}
78+
79+
@Test
80+
public void testInvalidNdkReleaseTxt() throws Exception {
81+
scratchPlatformsDirectories("arch-x86", 24);
82+
FileSystemUtils.appendIsoLatin1(
83+
scratch.resolve("WORKSPACE"),
84+
"android_ndk_repository(",
85+
" name = 'androidndk',",
86+
" path = '/ndk',",
87+
" api_level = 24,",
88+
")");
89+
90+
scratch.deleteFile("/ndk/source.properties");
91+
scratch.file("/ndk/RELEASE.TXT", "not a valid release string");
92+
93+
invalidatePackages();
94+
95+
assertThat(getConfiguredTarget("@androidndk//:files")).isNotNull();
96+
MoreAsserts.assertContainsEvent(
97+
eventCollector,
98+
"The revision of the Android NDK referenced by android_ndk_repository rule 'androidndk' "
99+
+ "could not be determined (the revision string found is 'not a valid release string')."
100+
+ " Defaulting to revision 13.");
101+
}
102+
103+
@Test
104+
public void testInvalidNdkSourceProperties() throws Exception {
105+
scratchPlatformsDirectories("arch-x86", 24);
106+
FileSystemUtils.appendIsoLatin1(
107+
scratch.resolve("WORKSPACE"),
108+
"android_ndk_repository(",
109+
" name = 'androidndk',",
110+
" path = '/ndk',",
111+
" api_level = 24,",
112+
")");
113+
114+
scratch.overwriteFile(
115+
"/ndk/source.properties",
116+
"Pkg.Desc = Android NDK",
117+
"Pkg.Revision = invalid package revision");
118+
119+
invalidatePackages();
120+
121+
assertThat(getConfiguredTarget("@androidndk//:files")).isNotNull();
122+
MoreAsserts.assertContainsEvent(
123+
eventCollector,
124+
"The revision of the Android NDK referenced by android_ndk_repository rule 'androidndk' "
125+
+ "could not be determined (the revision string found is 'invalid package revision'). "
126+
+ "Defaulting to revision 13.");
127+
}
128+
129+
@Test
130+
public void testUnsupportedNdkVersion() throws Exception {
131+
scratchPlatformsDirectories("arch-x86", 24);
132+
FileSystemUtils.appendIsoLatin1(
133+
scratch.resolve("WORKSPACE"),
134+
"android_ndk_repository(",
135+
" name = 'androidndk',",
136+
" path = '/ndk',",
137+
" api_level = 24,",
138+
")");
139+
140+
scratch.overwriteFile(
141+
"/ndk/source.properties",
142+
"Pkg.Desc = Android NDK",
143+
"Pkg.Revision = 14.0.3675639-beta2");
144+
invalidatePackages();
145+
146+
assertThat(getConfiguredTarget("@androidndk//:files")).isNotNull();
147+
MoreAsserts.assertContainsEvent(
148+
eventCollector,
149+
"The major revision of the Android NDK referenced by android_ndk_repository rule "
150+
+ "'androidndk' is 14. The major revisions supported by Bazel are [10, 11, 12, 13]. "
151+
+ "Defaulting to revision 13.");
152+
}
77153
}

src/test/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/AndroidNdkCrosstoolsTest.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ private static class AndroidNdkCrosstoolsTestParams {
7373
this.ndkDirectoriesFilename = ndkDirectoriesFilename;
7474
}
7575

76+
NdkMajorRevision getNdkMajorRevision() {
77+
return AndroidNdkCrosstools.KNOWN_NDK_MAJOR_REVISIONS.get(ndkRelease.majorRevision);
78+
}
79+
7680
ImmutableSet<String> getNdkFiles() throws IOException {
7781
String ndkFilesFileContent =
7882
ResourceFileLoader.loadResource(AndroidNdkCrosstoolsTest.class, ndkFilesFilename);
@@ -134,7 +138,7 @@ public AndroidNdkCrosstoolsTest(AndroidNdkCrosstoolsTestParams params) throws IO
134138
for (StlImpl ndkStlImpl : StlImpls.get(ndkPaths)) {
135139
// Protos are immutable, so this can be shared between tests.
136140
CrosstoolRelease crosstool =
137-
AndroidNdkCrosstools.create(params.ndkRelease, ndkPaths, ndkStlImpl, HOST_PLATFORM);
141+
params.getNdkMajorRevision().crosstoolRelease(ndkPaths, ndkStlImpl, HOST_PLATFORM);
138142
crosstools.add(crosstool);
139143
stlFilegroupsBuilder.putAll(ndkStlImpl.getFilegroupNamesAndFilegroupFileGlobPatterns());
140144
}
@@ -144,18 +148,18 @@ public AndroidNdkCrosstoolsTest(AndroidNdkCrosstoolsTestParams params) throws IO
144148
ndkFiles = params.getNdkFiles();
145149
ndkDirectories = params.getNdkDirectories();
146150
}
147-
151+
148152
@Test
149153
public void testPathsExist() throws Exception {
150154

151155
for (CrosstoolRelease crosstool : crosstoolReleases) {
152156
for (CToolchain toolchain : crosstool.getToolchainList()) {
153-
157+
154158
// Test that all tool paths exist.
155159
for (ToolPath toolpath : toolchain.getToolPathList()) {
156160
assertThat(ndkFiles).contains(toolpath.getPath());
157161
}
158-
162+
159163
// Test that all cxx_builtin_include_directory paths exist.
160164
for (String includeDirectory : toolchain.getCxxBuiltinIncludeDirectoryList()) {
161165
// Special case for builtin_sysroot.
@@ -164,13 +168,13 @@ public void testPathsExist() throws Exception {
164168
assertThat(ndkDirectories).contains(path);
165169
}
166170
}
167-
171+
168172
// Test that the builtin_sysroot path exists.
169173
{
170174
String builtinSysroot = NdkPaths.stripRepositoryPrefix(toolchain.getBuiltinSysroot());
171175
assertThat(ndkDirectories).contains(builtinSysroot);
172176
}
173-
177+
174178
// Test that all include directories added through unfiltered_cxx_flag exist.
175179
for (String flag : toolchain.getUnfilteredCxxFlagList()) {
176180
if (!flag.equals("-isystem")) {

0 commit comments

Comments
 (0)