Skip to content

Commit

Permalink
Merge pull request #4252 from degasus/android
Browse files Browse the repository at this point in the history
Android: Update the gradle file to use android studio 2.2 cmake.
  • Loading branch information
degasus committed Oct 6, 2016
2 parents 3c822f2 + 05eff01 commit f028b70
Show file tree
Hide file tree
Showing 14 changed files with 59 additions and 332 deletions.
28 changes: 5 additions & 23 deletions AndroidSetup.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,10 @@ If you'd like to contribute to the Android project, but do not currently have a

## Prerequisites

* A Linux VM or host, or a Mac.
* JDK 7 for your platform.
* CMake
* [Android NDK](https://developer.android.com/tools/sdk/ndk/index.html)
* [Android Studio](http://developer.android.com/tools/studio/index.html) **OR**
* [Android SDK Tools](http://developer.android.com/sdk/index.html#Other) (for command-line usage)
* [Android Studio](http://developer.android.com/tools/studio/index.html)

If you downloaded Android Studio, extract it and then see [Setting up Android Studio](#setting-up-android-studio).

If you instead chose to download the commoand-line SDK tools, see [Setting up the SDK Tools](#setting-up-the-sdk-tools).

## Setting up Android Studio

1. Launch Android Studio, which will start a first-launch wizard.
Expand All @@ -26,12 +19,6 @@ If you instead chose to download the commoand-line SDK tools, see [Setting up th
7. Use the SDK Manager to get necessary dependencies, as described in [Getting Dependencies](#getting-dependencies).
8. When done, follow the steps in [Readme.md](Readme.md#installation-on-android) to compile and deploy the application.

## Setting up the SDK Tools

1. In `Source/Android`, create a file called `local.properties`.
2. Add a single line: `sdk.dir=<sdk-path>`, where `<sdk-path>` is the path where you extracted the SDK Tools package.
3. Follow the steps in [Readme.md](Readme.md#installation-on-android) to compile and deploy the application.

## Executing Gradle Tasks

In Android Studio, you can find a list of possible Gradle tasks in a tray at the top right of the screen:
Expand All @@ -50,19 +37,14 @@ For command-line users, any task may be executed with `Source/Android/gradlew <t

Most dependencies for the Android project are supplied by Gradle automatically. However, Android platform libraries (and a few Google-supplied supplementary libraries) must be downloaded through the Android package manager.

1. Launch the Android SDK Manager from the commandline by executing `<sdk-path>/tools/android`, or by clicking on its icon in Android Studio's main toolbar:
1. Launch the Android SDK Manager by clicking on its icon in Android Studio's main toolbar:
![Android Studio Package Icon][package-icon]
2. At the bottom of the window, click "Deselect All", and then "Updates".
3. Install or update the following packages:

* SDK Platform, under "Android 5.0.1 (API 21)". This will allow compiling apps that target Lollipop.
* Android Support Repository
* Android Support Library
* Google Repository
2. Install or update the SDK Platform. Choose the API level selected as [compileSdkVersion](Source/Android/app/build.gradle#L5).
3. Install or update the SDK Tools. CMake, LLDB and NDK. If you don't use android-studio, please check out https://github.com/Commit451/android-cmake-installer.

In the future, if the project targets a newer version of Android, or use newer versions of the tools/build-tools packages, it will be necessary to use this tool to download updates.

[components]: http://i.imgur.com/Oo1Fs93.png
[package-icon]: http://i.imgur.com/NUpkAH8.png
[gradle]: http://i.imgur.com/dXIH6o3.png
[shortcut]: http://i.imgur.com/eCWP4Yy.png
[shortcut]: http://i.imgur.com/eCWP4Yy.png
44 changes: 19 additions & 25 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -188,36 +188,28 @@ else()
add_definitions(-D_ARCH_32=1)
endif()

if(NOT ENABLE_GENERIC)
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^x86" OR
${CMAKE_SYSTEM_PROCESSOR} MATCHES "i.86" OR
${CMAKE_SYSTEM_PROCESSOR} MATCHES "amd64" OR
APPLE)
if(_ARCH_64)
set(_M_X86 1)
set(_M_X86_64 1)
add_definitions(-D_M_X86=1 -D_M_X86_64=1 -msse2)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-pie")
else()
message(FATAL_ERROR "x86_32 is an unsupported platform. Enable generic build if you really want a JIT-less binary.")
endif()
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm")
message(FATAL_ERROR "ARMv7 is an unsupported platform. Enable generic build if you really want a JIT-less binary.")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
# This option only applies to 64bit ARM
set(_M_ARM 1)
set(_M_ARM_64 1)
add_definitions(-D_M_ARM=1 -D_M_ARM_64=1)
add_definitions(-march=armv8-a+crc)
else()
set(ENABLE_GENERIC 1)
endif()
endif()

if(ENABLE_GENERIC)
message("Warning! Building generic build!")
set(_M_GENERIC 1)
add_definitions(-D_M_GENERIC=1)
elseif(_ARCH_64 AND (
${CMAKE_SYSTEM_PROCESSOR} MATCHES "^x86" OR
${CMAKE_SYSTEM_PROCESSOR} MATCHES "i.86" OR
${CMAKE_SYSTEM_PROCESSOR} MATCHES "amd64" OR
APPLE
))
set(_M_X86 1)
set(_M_X86_64 1)
add_definitions(-D_M_X86=1 -D_M_X86_64=1 -msse2)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-pie")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
set(_M_ARM 1)
set(_M_ARM_64 1)
add_definitions(-D_M_ARM=1 -D_M_ARM_64=1)
add_definitions(-march=armv8-a+crc)
else()
message(FATAL_ERROR "You're building on an unsupported platform. Enable generic build if you really want a JIT-less binary.")
endif()

include(CheckCXXCompilerFlag)
Expand Down Expand Up @@ -423,6 +415,8 @@ if(ANDROID)
# We are cross compiling, search only the toolchain for libraries and includes
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
elseif(NOT APPLE AND NOT CMAKE_SYSTEM_NAME MATCHES OpenBSD)
list(APPEND LIBS rt)
endif()
Expand Down
24 changes: 1 addition & 23 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,29 +99,7 @@ If using Android Studio, import the Gradle project located in `./Source/Android`

Android apps are compiled using a build system called Gradle. Dolphin's native component,
however, is compiled using CMake. The Gradle script will attempt to run a CMake build
automatically while building the Java code, if you create the file `Source/Android/build.properties`,
and place the following inside:

```
# Specifies arguments for the 'make' command. Can be blank.
makeArgs=
# The path to your machine's Git executable. Will autodetect if blank (on Linux only).
gitPath=
# The path to the CMake executable. Will autodetect if blank (on Linux only).
cmakePath=
# The path to the extracted NDK package. Will autodetect if blank (on Linux only).
ndkPath=
```

If you prefer, you can run the CMake step manually, and it will copy the resulting
binary into the correct location for inclusion in the Android APK.

Execute the Gradle task `assembleArm_64Debug` to build, or `installArm_64Debug` to
install the application onto a connected device. If other ABIs are eventually supported,
execute the tasks corresponding to the desired ABI.
automatically while building the Java code.

## Uninstalling
When Dolphin has been installed with the NSIS installer, you can uninstall
Expand Down
1 change: 1 addition & 0 deletions Source/Android/app/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/build
/.externalNativeBuild
209 changes: 18 additions & 191 deletions Source/Android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apply plugin: 'com.android.application'

android {
// Leanback support requires >22
compileSdkVersion 23
buildToolsVersion '23.0.2'
compileSdkVersion 24
buildToolsVersion '24.0.3'

lintOptions {
// This is important as it will run lint but not abort on error
Expand Down Expand Up @@ -53,213 +53,40 @@ android {
applicationIdSuffix ".debug"
versionNameSuffix '-debug'
jniDebuggable true

tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn(compileNative)
}
}
}

// Define product flavors, which can be split into categories. Common examples
// of product flavors are paid vs. free, ARM vs. x86, etc.
productFlavors {
arm_64 {
dimension "abi"
ndk {
abiFilter "arm64-v8a"
}
externalNativeBuild {
cmake {
path "../../../CMakeLists.txt"
}
}

x86_64 {
dimension "abi"
ndk {
abiFilter "x86_64"
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_static", "-DCMAKE_BUILD_TYPE=RelWithDebInfo", "-DENABLE_PCH=OFF" // , "-DENABLE_GENERIC=ON"
abiFilters "arm64-v8a" //, "armeabi-v7a", "x86_64", "x86"
}
}
}
}

dependencies {
compile 'com.android.support:support-v13:23.1.1'
compile 'com.android.support:cardview-v7:23.1.1'
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:support-v13:24.2.1'
compile 'com.android.support:cardview-v7:24.2.1'
compile 'com.android.support:recyclerview-v7:24.2.1'
compile 'com.android.support:design:24.2.1'

// Android TV UI libraries.
compile 'com.android.support:leanback-v17:23.1.1'
compile 'com.android.support:leanback-v17:24.2.1'

// For showing the banner as a circle a-la Material Design Guidelines
compile 'de.hdodenhof:circleimageview:1.2.2'
compile 'de.hdodenhof:circleimageview:2.1.0'

// For loading huge screenshots from the disk.
compile 'com.squareup.picasso:picasso:2.5.2'

// Allows FRP-style asynchronous operations in Android.
compile 'io.reactivex:rxandroid:1.1.0'
}

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))

String abi = getAbi()

mkdir('build/' + abi)
workingDir 'build/' + abi

executable getExecutablePath("cmake")

args "-DANDROID=true",
"-DANDROID_NATIVE_API_LEVEL=android-18",
"-DCMAKE_TOOLCHAIN_FILE=../../../android.toolchain.cmake",
"../../../../..",
"-DGIT_EXECUTABLE=" + getExecutablePath("git"),
"-DANDROID_NDK=" + getNdkPath(),
"-DANDROID_TOOLCHAIN_NAME=" + getToolchainName(),
"-DANDROID_ABI=" + abi
} else {
executable 'echo'
args 'No build.properties found; skipping CMake.'
}
compile 'io.reactivex:rxandroid:1.2.1'
}

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))

String abi = getAbi()

workingDir 'build/' + abi

executable 'make'

if (buildProperties.makeArgs == null || buildProperties.makeArgs.isEmpty()) {
// TODO
} else {
args buildProperties.makeArgs
}
} else {
executable 'echo'
args 'No build.properties found; skipping native build.'
}
}

String getExecutablePath(String command) {
def propsFile = rootProject.file("build.properties")
def path = null

if (propsFile.canRead()) {
def buildProperties = new Properties()
buildProperties.load(new FileInputStream(propsFile))
println buildProperties
path = buildProperties[command + "Path"]
}

if (path == null || path.isEmpty()) {
try {
def stdout = new ByteArrayOutputStream()

exec {
commandLine 'which', command
standardOutput = stdout
}

path = stdout.toString().trim()
} catch (ignored) {
project.logger.error("Gradle error: Couldn't find " + command + " executable.")
}
}

if (path != null) {
project.logger.quiet("Gradle: Found " + command + " executuable:" + path)
}

return path
}

String getNdkPath() {
def propsFile = rootProject.file("build.properties")
def ndkPath = null

if (propsFile.canRead()) {
def buildProperties = new Properties()
buildProperties.load(new FileInputStream(propsFile))
ndkPath = buildProperties.ndkPath
}

if (ndkPath == null || ndkPath.isEmpty()) {
try {
def stdout = new ByteArrayOutputStream()

exec {
// ndk-build.cmd is a file unique to the root directory of android-ndk-r10e.
commandLine 'locate', 'ndk-build.cmd'
standardOutput = stdout
}

def ndkCmdPath = stdout.toString()
ndkPath = ndkCmdPath.substring(0, ndkCmdPath.lastIndexOf('/'))
} catch (ignored) {
project.logger.error("Gradle error: Couldn't find NDK.")
}
}

if (ndkPath != null) {
project.logger.quiet("Gradle: Found Android NDK: " + ndkPath)
}
return ndkPath
}

String getAbi() {
String taskName = getGradle().startParameter.taskNames[0]
String abi;

if (taskName == null) {
return ""
}

project.logger.quiet("Gradle: Build = " + taskName)

if (taskName.contains("Arm_64")) {
abi = "arm64-v8a"
} else if (taskName.contains("Arm")) {
abi = "armeabi-v7a"
} else if (taskName.contains("X86_64")) {
abi = "x86_64"
}

project.logger.quiet("Gradle: ABI name: " + abi)
return abi;
}

String getToolchainName() {
String taskName = getGradle().startParameter.taskNames[0]
String toolchain;

if (taskName == null) {
return ""
}

if (taskName.contains("Arm_64")) {
toolchain = "aarch64-linux-android-4.9"
} else if (taskName.contains("Arm")) {
toolchain = "arm-linux-androideabi-4.9"
} else if (taskName.contains("X86_64")) {
toolchain = "x86_64-4.9"
}

project.logger.quiet("Gradle: ABI name: " + toolchain)
return toolchain;
}
Loading

0 comments on commit f028b70

Please sign in to comment.