Merge pull request #2420 from sigmabeta/android-native-gradle-build

Android: Allow building of native code inside Android Studio / Gradle
This commit is contained in:
Lioncash 2015-05-20 19:31:30 -04:00
commit 12493c332c
3 changed files with 109 additions and 11 deletions

View File

@ -55,19 +55,20 @@ the Android UI. Import the Gradle project located in `./Source/Android`, and the
Gradle task `assembleDebug` to build, or `installDebug` to install the UI onto a connected device. Gradle task `assembleDebug` to build, or `installDebug` to install the UI onto a connected device.
In order to launch the app, you must build and include the native Dolphin libraries into the UI project. In order to launch the app, you must build and include the native Dolphin libraries into the UI project.
Building native code requires the [Android NDK](https://developer.android.com/tools/sdk/ndk/index.html). (Building native code requires the [Android NDK](https://developer.android.com/tools/sdk/ndk/index.html).)
Android Studio will do this for you if you create `Source/Android/build.properties`, and place the
following inside:
### Build Steps: ```
1. `mkdir Build-Android-<abi>` toolchain=<toolchain>
2. `cd Build-Android-<abi>` abi=<abi>
3. `cmake -DANDROID=True -DANDROID_NDK=<ndk-path> -DANDROID_NATIVE_API_LEVEL=android-18 -DANDROID_TOOLCHAIN_NAME=<toolchain> -DANDROID_ABI=<abi> -DCMAKE_TOOLCHAIN_FILE=../Source/Android/android.toolchain.cmake -DGIT_EXECUTABLE=<git-path> ..` makeArgs=<make-args>
4. `make` ```
Replace `<git-path>` with the absolute path to your machine's Git executable, <ndk-path> with the absolute Replace `<make-args>` with any arguments you want to pass to `make`, and the rest depending on which
path to where you installed your NDK, and the rest depending on which platform the Android device you are platform the Android device you are targeting uses:
targeting uses:
|Platform | abi | toolchain | |Platform | `<abi>` | `<toolchain>` |
|-------------------------|-------------|---------------------------| |-------------------------|-------------|---------------------------|
|ARM 32-bit (most devices)| armeabi-v7a | arm-linux-androideabi-4.9 | |ARM 32-bit (most devices)| armeabi-v7a | arm-linux-androideabi-4.9 |
|ARM 64-bit (i.e. Nexus 9)| arm64-v8a | aarch64-linux-android-4.9 | |ARM 64-bit (i.e. Nexus 9)| arm64-v8a | aarch64-linux-android-4.9 |

View File

@ -39,4 +39,5 @@ tasks.xml
gradle/ gradle/
build/ build/
*.so *.so
*.iml *.iml
build.properties

View File

@ -42,6 +42,10 @@ android {
applicationIdSuffix ".debug" applicationIdSuffix ".debug"
versionNameSuffix '-debug' versionNameSuffix '-debug'
jniDebuggable true jniDebuggable true
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn(compileNative)
}
} }
} }
@ -88,3 +92,95 @@ dependencies {
// For loading huge screenshots from the disk. // For loading huge screenshots from the disk.
compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.squareup.picasso:picasso:2.5.2'
} }
task setupCMake(type: Exec) {
// Check if a build properties file exists.
def propsFile = rootProject.file("build.properties")
// If it does, call CMake.
if (propsFile.canRead()) {
// Read the properties file's contents.
def buildProperties = new Properties()
buildProperties.load(new FileInputStream(propsFile))
mkdir('build/' + buildProperties.abi)
workingDir 'build/' + buildProperties.abi
executable 'cmake'
args "-DANDROID=true",
"-DANDROID_NATIVE_API_LEVEL=android-18",
"-DCMAKE_TOOLCHAIN_FILE=../../../android.toolchain.cmake",
"../../../../..",
"-DGIT_EXECUTABLE=" + getGitPath(),
"-DANDROID_NDK=" + getNdkPath(),
"-DANDROID_TOOLCHAIN_NAME=" + buildProperties.toolchain,
"-DANDROID_ABI=" + buildProperties.abi
} else {
executable 'echo'
args 'No build.properties found; skipping CMake.'
}
}
task compileNative(type: Exec, dependsOn: 'setupCMake') {
// Check if a build properties file exists.
def propsFile = rootProject.file("build.properties")
// If it does, call make.
if (propsFile.canRead()) {
// Read the properties file's contents.
def buildProperties = new Properties()
buildProperties.load(new FileInputStream(propsFile))
workingDir 'build/' + buildProperties.abi
executable 'make'
args buildProperties.makeArgs
} else {
executable 'echo'
args 'No build.properties found; skipping native build.'
}
}
String getGitPath() {
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'which', 'git'
standardOutput = stdout
}
def gitPath = stdout.toString().trim()
project.logger.quiet("Gradle: Found git executuable:" + gitPath)
return gitPath
} catch (ignored) {
// Shouldn't happen. How did the user get this file without git?
project.logger.error("Gradle error: Couldn't find git executable.")
return null;
}
}
String getNdkPath() {
try {
def stdout = new ByteArrayOutputStream()
exec {
// ndk-build.cmd is a file unique to the root directory of android-ndk-r10d.
commandLine 'locate', 'ndk-build.cmd'
standardOutput = stdout
}
def ndkCmdPath = stdout.toString()
def ndkPath = ndkCmdPath.substring(0, ndkCmdPath.lastIndexOf('/'))
project.logger.quiet("Gradle: Found Android NDK:" + ndkPath)
return ndkPath
} catch (ignored) {
project.logger.error("Gradle error: Couldn't find NDK.")
return null;
}
}