Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android: Update the gradle file to use android studio 2.2 cmake. #4252

Merged
merged 1 commit into from Oct 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 5 additions & 23 deletions AndroidSetup.md
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
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
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
@@ -1 +1,2 @@
/build
/.externalNativeBuild
209 changes: 18 additions & 191 deletions Source/Android/app/build.gradle
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;
}