From 8c44bb4792162d2aed34a1bbdbf018bcc9223c09 Mon Sep 17 00:00:00 2001 From: Joshua Quick Date: Fri, 9 Apr 2021 20:22:44 -0700 Subject: [PATCH] refactor(android): remove deprecated usage of ndk.dir Fixes TIMOB-28377, TIMOB-27801 --- Jenkinsfile | 10 +- README.md | 4 +- android/cli/commands/_build.js | 5 +- android/cli/commands/_buildModule.js | 5 +- android/cli/lib/gradle-wrapper.js | 8 +- android/notes.md | 4 - android/package.json | 2 +- .../templates/module/generated/build.gradle | 30 +----- build/lib/android/index.js | 94 +------------------ build/scons-build.js | 1 - build/scons-clean.js | 1 - build/scons-cleanbuild.js | 1 - build/scons-gradlew.js | 1 - 13 files changed, 19 insertions(+), 147 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index d1720368f45..0957df9ecbb 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -243,7 +243,7 @@ def cliUnitTests(nodeVersion, npmVersion) { // Wrap in timestamper timestamps { try { - node('git && android-sdk && android-ndk && ant && gperf && osx && xcode-12 && osx-10.15') { + node('git && android-sdk && ant && gperf && osx && xcode-12 && osx-10.15') { stage('Checkout') { // Update our shared reference repo for all branches/PRs dir('..') { @@ -324,16 +324,16 @@ timestamps { ansiColor('xterm') { timeout(15) { - def buildCommand = "npm run clean -- --android-ndk ${env.ANDROID_NDK_R21D}" + def buildCommand = 'npm run clean' if (isMainlineBranch) { - buildCommand += ' --all' + buildCommand += ' -- --all' } sh label: 'clean', script: buildCommand } // timeout timeout(15) { - def buildCommand = "npm run build -- --android-ndk ${env.ANDROID_NDK_R21D}" + def buildCommand = 'npm run build' if (isMainlineBranch) { - buildCommand += ' --all' + buildCommand += ' -- --all' } try { sh label: 'build', script: buildCommand diff --git a/README.md b/README.md index 82ff327d4ec..5f44bba5cd2 100644 --- a/README.md +++ b/README.md @@ -226,13 +226,13 @@ npm run cleanbuild The build and package commands will default to all target platforms on your host OS unless explicitly specified. (i.e. Android, iOS on macOS; Windows and Android on Windows). It will compile, package and install the locally-built SDK for you as well, so you can test it in your own applications without any further procedures. -The build command will look for Android NDK and SDK using $ANDROID_NDK and $ANDROID_SDK env variables if not explicitly passed using command line arguments. +The build command will look for the Android SDK directory path via the $ANDROID_SDK env variables if not explicitly passed using command line arguments. You can use the `-h` flag to display the full list of comands and options. ```bash npm ci -npm run cleanbuild -- [platform1] [platform2] --android-ndk /opt/android-ndk --android-sdk /opt/android-sdk /Users/build/android-sdk-macosx +npm run cleanbuild -- [platform1] [platform2] --android-sdk /opt/android-sdk /Users/build/android-sdk-macosx ``` ### Unit tests diff --git a/android/cli/commands/_build.js b/android/cli/commands/_build.js index fe8ec7b6826..005ae1bff5b 100644 --- a/android/cli/commands/_build.js +++ b/android/cli/commands/_build.js @@ -2187,9 +2187,8 @@ AndroidBuilder.prototype.generateRootProjectFiles = async function generateRootP + fileContent.toString() + '\n'); } - // Create a "local.properties" file providing a path to the Android SDK/NDK directories. - const androidNdkPath = this.androidInfo.ndk ? this.androidInfo.ndk.path : null; - await gradlew.writeLocalPropertiesFile(this.androidInfo.sdk.path, androidNdkPath); + // Create a "local.properties" file providing a path to the Android SDK directory. + await gradlew.writeLocalPropertiesFile(this.androidInfo.sdk.path); // Copy our root "build.gradle" template script to the root build directory. await fs.copyFile( diff --git a/android/cli/commands/_buildModule.js b/android/cli/commands/_buildModule.js index 7313fe3e9a4..4b5776758bf 100644 --- a/android/cli/commands/_buildModule.js +++ b/android/cli/commands/_buildModule.js @@ -509,9 +509,8 @@ AndroidModuleBuilder.prototype.generateRootProjectFiles = async function generat }); await gradlew.writeGradlePropertiesFile(gradleProperties); - // Create a "local.properties" file providing a path to the Android SDK/NDK directories. - const androidNdkPath = this.androidInfo.ndk ? this.androidInfo.ndk.path : null; - await gradlew.writeLocalPropertiesFile(this.androidInfo.sdk.path, androidNdkPath); + // Create a "local.properties" file providing a path to the Android SDK directory. + await gradlew.writeLocalPropertiesFile(this.androidInfo.sdk.path); // Copy our root "build.gradle" template script to the root build directory. const templatesDir = path.join(this.platformPath, 'templates', 'build'); diff --git a/android/cli/lib/gradle-wrapper.js b/android/cli/lib/gradle-wrapper.js index 5a04e1f8ec7..17e9860904c 100644 --- a/android/cli/lib/gradle-wrapper.js +++ b/android/cli/lib/gradle-wrapper.js @@ -354,19 +354,15 @@ class GradleWrapper { /** * Creates a "local.properties" file at the gradle project's root location, - * providing the given Android SDK/NDK directory paths needed to do an Android build. + * providing the given Android SDK directory path needed to do an Android build. * @param {String} androidSdkDirPath Path to the Android SDK directory. Cannot be null/undefined. - * @param {String} [androidNdkDirPath] Optional path to the Android NDK directory. Can be null/undefined. */ - async writeLocalPropertiesFile(androidSdkDirPath, androidNdkDirPath) { + async writeLocalPropertiesFile(androidSdkDirPath) { const filePath = path.join(this._gradlewDirPath, 'local.properties'); const properties = [ { comment: '# This file was generated by Titanium\'s build tools.' }, { key: 'sdk.dir', value: androidSdkDirPath } ]; - if (androidNdkDirPath) { - properties.push({ key: 'ndk.dir', value: androidNdkDirPath }); - } await writeJavaPropertiesFile(filePath, properties); } } diff --git a/android/notes.md b/android/notes.md index ca6ffe42fc6..a7140dc4a46 100644 --- a/android/notes.md +++ b/android/notes.md @@ -9,8 +9,6 @@ Done: TODOs!!! ===== - Clean up all the debug logging I put in place -- Write up notes on generating debug build of library, using ndk-stack to get line numbers in native crash stack traces - - $ANDROID_SDK/platform-tools/adb logcat | $ANDROID_NDK/ndk-stack -sym ~/repos/titanium_mobile/android/runtime/v8/obj/local/x86 - Use ToSomething(Context) in place of ToSomething(Isolate) - Convert to using all of the MaybeLocal APIs - Look for other deprecated API usage and update @@ -24,8 +22,6 @@ The goal is to be able to debug apps via Chrome Devtools or Studio. We hook up a websocket server in JSDebugger.java to talk to DevTools. This carries the messages back and forth (basically wbesaockets are the "base" protocol that the isnpector protocol travels over) - Use multiple terminal tabs/windows: - - One for logcat with crash symbol conversion to actual stacktraces: - - $ANDROID_SDK/platform-tools/adb logcat | $ANDROID_NDK/ndk-stack -sym ~/repos/titanium_mobile/android/runtime/v8/obj/local/x86 - One for running a test app to debug with: - ti build -p android --log-level trace --target emulator --device-id AVD_for_Nexus_10_by_Google --debug-host /127.0.0.1:51388 - One for building the SDK: diff --git a/android/package.json b/android/package.json index 4485eb7618c..f2649f03ed4 100644 --- a/android/package.json +++ b/android/package.json @@ -30,7 +30,7 @@ "android build tools": ">=30.0.2 <=31.x", "android platform tools": "30.x", "android tools": "<=26.x", - "android ndk": ">=r11c <=r21d", + "android ndk": ">=r21 <=r22b", "java": ">=1.8.x" }, "repository": { diff --git a/android/templates/module/generated/build.gradle b/android/templates/module/generated/build.gradle index f33371ff3fe..9b1eb5350b7 100644 --- a/android/templates/module/generated/build.gradle +++ b/android/templates/module/generated/build.gradle @@ -14,28 +14,6 @@ repositories { // Path to proxy binding JSON file created by "kroll-apt" annotation processor and used to do C/C++ code generation. def tiModuleBindingsJsonPath = "${buildDir}/ti-generated/json/<%- moduleName %>.json".toString() -// Fetch Android NDK version assigned to the "local.properties" file. (Will be missing if NDK not installed.) -def ndkVersionString = null; -try { - def localProperties = new Properties() - localProperties.load(file("${rootDir}/local.properties").newDataInputStream()) - def ndkDir = localProperties.get('ndk.dir') - if (ndkDir != null) { - def ndkSourceProperties = new Properties() - ndkSourceProperties.load(file("${ndkDir}/source.properties").newDataInputStream()) - ndkVersionString = ndkSourceProperties.get('Pkg.Revision') - } -} catch (Throwable) { -} - -// If Titanium failed to set Android NDK path in "local.properties", then assume NDK is not installed. -// Have gradle auto-download NDK by setting the version we want below. (Will fail if a different version is installed.) -// Must be set to a stable release version listed here: https://developer.android.com/ndk/downloads -if (ndkVersionString == null) { - ndkVersionString = '21.2.6472646' - android.ndkVersion ndkVersionString -} - android { compileSdkVersion <%- compileSdkVersion %> defaultConfig { @@ -80,13 +58,9 @@ android { cppFlags '-std=c++14' arguments.addAll([ 'APP_STL:=c++_shared', - "-j${Runtime.runtime.availableProcessors()}".toString() + "-j${Runtime.runtime.availableProcessors()}".toString(), + '--output-sync=none' ]) - if (Integer.parseInt(ndkVersionString.split('\\.')[0]) >= 21) { - // Work-around issue where Google sets "--output-sync=target" by default for NDK v21+ - // which causes "bad file descriptor" errors when using "-j" parallel executions argument. - arguments.add('--output-sync=none') - } } } ndk { diff --git a/build/lib/android/index.js b/build/lib/android/index.js index 098e62c6d20..5e6a731b2ba 100644 --- a/build/lib/android/index.js +++ b/build/lib/android/index.js @@ -25,7 +25,6 @@ class Android { /** * @param {Object} options options object * @param {String} options.androidSdk path to the Android SDK to build with - * @param {String} options.androidNdk path to the Andorid NDK to build with * @param {String} options.sdkVersion version of Titanium SDK * @param {String} options.versionTag version of the Titanium SDK package folder/zip * @param {String} options.gitHash SHA of Titanium SDK HEAD @@ -34,7 +33,6 @@ class Android { */ constructor (options) { this.androidSdk = options.androidSdk; - this.androidNdk = options.androidNdk; this.sdkVersion = options.sdkVersion; this.versionTag = options.versionTag; this.gitHash = options.gitHash; @@ -159,8 +157,8 @@ class Android { } async runGradleTask(task, args) { - // Create "local.properties" file which tells gradle where to find the Android SDK/NDK directories. - await createLocalPropertiesFile(this.androidSdk, this.androidNdk); + // Create "local.properties" file which tells gradle where to find the Android SDK directory. + await createLocalPropertiesFile(this.androidSdk); // Run the given gradle task. const newArgs = [ task ]; @@ -187,7 +185,7 @@ async function gradlew(args) { }); } -async function createLocalPropertiesFile(sdkPath, ndkPath) { +async function createLocalPropertiesFile(sdkPath) { // The "local.properties" file must be in the root gradle project directory. const fileName = 'local.properties'; const filePath = path.join(TITANIUM_ANDROID_PATH, fileName); @@ -253,99 +251,13 @@ async function createLocalPropertiesFile(sdkPath, ndkPath) { } } - // Set up an array of Android NDK directory paths to do an existence check on. - const ndkSideBySidePath = path.join(sdkPath, 'ndk'); - const ndkTestPaths = [ - ndkPath, // Prefer given argument's path 1st if provided and it exists. - process.env.ANDROID_NDK, // Titanium's preferred environment variable for setting the path. - process.env.ANDROID_NDK_HOME, // Google's officially supported environment variable. - ndkSideBySidePath, // Google installs multiple NDK versions under Android SDK folder as of 2019. - path.join(sdkPath, 'ndk-bundle') // Google installed only one NDK version under Android SDK before 2019. - ]; - - // Use the 1st existing NDK path configured in the array above. - ndkPath = null; - for (const nextPath of ndkTestPaths) { - if (nextPath && (await fs.exists(nextPath))) { - if (nextPath === ndkSideBySidePath) { - // We've found an NDK side-by-side directory which contains folders with version names. - // Fetch all folders, sort them by version string, and choose the newest versioned folder. - const fileNames = await fs.readdir(nextPath); - fileNames.sort(versionStringSortComparer); - for (let index = fileNames.length - 1; index >= 0; index--) { - const ndkVersionPath = path.join(nextPath, fileNames[index]); - if ((await fs.stat(ndkVersionPath)).isDirectory()) { - ndkPath = ndkVersionPath; - break; - } - } - } else { - // NDK directory path exists. Select it. - ndkPath = nextPath; - } - if (ndkPath) { - break; - } - } - } - // Create a "local.properties" file under Titanium's root "android" directory. // This is required by the Android gradle plugin or else it will fail to build. const fileLines = [ '# This file was generated by Titanium\'s build tools.', 'sdk.dir=' + sdkPath.replace(/\\/g, '\\\\') ]; - if (ndkPath) { - fileLines.push('ndk.dir=' + ndkPath.replace(/\\/g, '\\\\')); - } await fs.writeFile(filePath, fileLines.join('\n') + '\n'); } -function versionStringSortComparer(element1, element2) { - // Check if the references match. (This is an optimization.) - // eslint-disable-next-line eqeqeq - if (element1 == element2) { - return 0; - } - - // Compare element types. String types are always greater than non-string types. - const isElement1String = (typeof element1 === 'string'); - const isElement2String = (typeof element2 === 'string'); - if (isElement1String && !isElement2String) { - return 1; - } else if (!isElement1String && isElement2String) { - return -1; - } else if (!isElement1String && !isElement2String) { - return 0; - } - - // Split version strings into components. Example: '1.2.3' -> ['1', '2', '3'] - // If there is version component lenght mismatch, then pad the rest with zeros. - const version1Components = element1.split('.'); - const version2Components = element2.split('.'); - const componentLengthDelta = version1Components.length - version2Components.length; - if (componentLengthDelta > 0) { - version2Components.push(...Array(componentLengthDelta).fill('0')); - } else if (componentLengthDelta < 0) { - version1Components.push(...Array(-componentLengthDelta).fill('0')); - } - - // Compare the 2 given version strings by their numeric components. - for (let index = 0; index < version1Components.length; index++) { - let value1 = Number.parseInt(version1Components[index], 10); - if (Number.isNaN(value1)) { - value1 = 0; - } - let value2 = Number.parseInt(version2Components[index], 10); - if (Number.isNaN(value2)) { - value2 = 0; - } - const valueDelta = value1 - value2; - if (valueDelta !== 0) { - return valueDelta; - } - } - return 0; -} - module.exports = Android; diff --git a/build/scons-build.js b/build/scons-build.js index 797f1e70c51..65b74e272ea 100755 --- a/build/scons-build.js +++ b/build/scons-build.js @@ -7,7 +7,6 @@ const version = require('../package.json').version; program .option('-v, --sdk-version [version]', 'Override the SDK version we report', process.env.PRODUCT_VERSION || version) .option('-s, --android-sdk [path]', 'Explicitly set the path to the Android SDK used for building') - .option('-n, --android-ndk [path]', 'Explicitly set the path to the Android NDK used for building') .option('-a, --all', 'Build a ti.main.js file for every target OS') .parse(process.argv); diff --git a/build/scons-clean.js b/build/scons-clean.js index 252810179b0..059f3c9777b 100755 --- a/build/scons-clean.js +++ b/build/scons-clean.js @@ -7,7 +7,6 @@ const program = require('commander'); program.option('-v, --sdk-version [version]', 'Override the SDK version we report', process.env.PRODUCT_VERSION || version) .option('-t, --version-tag [tag]', 'Override the SDK version tag we report') .option('-s, --android-sdk [path]', 'Explicitly set the path to the Android SDK used for building') - .option('-n, --android-ndk [path]', 'Explicitly set the path to the Android NDK used for building') .option('-a, --all', 'Clean every OS/platform') .parse(process.argv); diff --git a/build/scons-cleanbuild.js b/build/scons-cleanbuild.js index eedc20151b8..9730bfe90fe 100644 --- a/build/scons-cleanbuild.js +++ b/build/scons-cleanbuild.js @@ -7,7 +7,6 @@ program .option('-v, --sdk-version [version]', 'Override the SDK version we report', process.env.PRODUCT_VERSION || version) .option('-t, --version-tag [tag]', 'Override the SDK version tag we report') .option('-s, --android-sdk [path]', 'Explicitly set the path to the Android SDK used for building') - .option('-n, --android-ndk [path]', 'Explicitly set the path to the Android NDK used for building') .option('--no-docs', 'Do not produce docs') .option('--symlink', 'If possible, symlink the SDK folder to destination rather than copying') .option('-a, --all', 'Build a zipfile for every OS') diff --git a/build/scons-gradlew.js b/build/scons-gradlew.js index 8b5e306576c..8837f970e12 100755 --- a/build/scons-gradlew.js +++ b/build/scons-gradlew.js @@ -13,7 +13,6 @@ program .option('-v, --sdk-version [version]', 'Override the SDK version we report', process.env.PRODUCT_VERSION || version) .option('-t, --version-tag [tag]', 'Override the SDK version tag we report') .option('-s, --android-sdk [path]', 'Explicitly set the path to the Android SDK used for building') - .option('-n, --android-ndk [path]', 'Explicitly set the path to the Android NDK used for building') .option('--args [arguments...]', 'Arguments to be passed to gradlew tool (Must be set last)') .action((task, options) => { const AndroidBuilder = require('./lib/android');