You can generate the gradle project with running cmake the first time (using configure_file to create the needed bits and pieces), then the same cmake can be invoked by android studio and controlled by a flag (so you know if you are generating the gradle files or actually running from within android studio). This works nicely for us.
Invoke cmake normally (not really important the generator):
cmake -G "Unix Makefiles" \
-DJUCE_ANDROID_APPLICATION_ID=com.your.app \
-DJUCE_ANDROID_COMPILE_SDK_VERSION=25 \
-DJUCE_ANDROID_MIN_SDK_VERSION=14 \
-DJUCE_ANDROID_TARGET_SDK_VERSION=25 \
-DJUCE_ANDROID_ABI="armeabi-v7a" \
-DJUCE_ANDROID_ARM_NEON=TRUE \
-DJUCE_ANDROID_TOOLCHAIN=clang \
-DJUCE_ANDROID_PLATFORM=android-14 \
-DJUCE_ANDROID_STL=c++_static
../
In the juce cmake CMakeLists.txt:
if(ANDROID AND NOT JUCE_COMPILE_GRADLE)
juce_prepare_gradle_android()
else()
# normal juce stuff
endif()
The juce_prepare_gradle_android
is more or less:
function(juce_prepare_gradle_android)
# Eventually set defaults here
# Then generate gradle
configure_file(${ROOT_CMAKE_DIR}/files/android/build.gradle.in ${CMAKE_CURRENT_LIST_DIR}/build.gradle)
configure_file(${ROOT_CMAKE_DIR}/files/android/settings.gradle.in ${CMAKE_CURRENT_LIST_DIR}/settings.gradle)
configure_file(${ROOT_CMAKE_DIR}/files/android/module.build.gradle.in ${CMAKE_CURRENT_LIST_DIR}/android/build.gradle)
configure_file(${ROOT_CMAKE_DIR}/files/android/gradlew.in ${CMAKE_CURRENT_LIST_DIR}/gradlew COPYONLY)
configure_file(${ROOT_CMAKE_DIR}/files/android/gradlew.bat.in ${CMAKE_CURRENT_LIST_DIR}/gradlew.bat COPYONLY)
configure_file(${ROOT_CMAKE_DIR}/files/android/gradle.properties.in ${CMAKE_CURRENT_LIST_DIR}/gradle.properties COPYONLY)
endfunction()
The interesting part is the module.build.gradle.in
:
apply plugin: 'com.android.application'
android {
compileSdkVersion @JUCE_ANDROID_COMPILE_SDK_VERSION@
defaultConfig {
applicationId "@JUCE_ANDROID_APPLICATION_ID@"
minSdkVersion @JUCE_ANDROID_MIN_SDK_VERSION@
targetSdkVersion @JUCE_ANDROID_TARGET_SDK_VERSION@
versionCode @JUCE_ANDROID_VERSION_CODE@
versionName "@JUCE_ANDROID_VERSION_NAME@"
ndk {
abiFilters @JUCE_ANDROID_ABI@
}
externalNativeBuild {
cmake {
arguments "-DANDROID_TOOLCHAIN=@JUCE_ANDROID_TOOLCHAIN@",
"-DANDROID_ARM_NEON=@JUCE_ANDROID_ARM_NEON@",
"-DANDROID_PLATFORM=@JUCE_ANDROID_PLATFORM@",
"-DANDROID_STL=@JUCE_ANDROID_STL@",
"-DANDROID_CPP_FEATURES=@JUCE_ANDROID_CPP_FEATURES@",
"-DANDROID_ALLOW_UNDEFINED_SYMBOLS=FALSE",
"-DANDROID_PIE=ON",
"-DCPP_STD_VERSION=@JUCE_CPP_STD_VERSION@",
"-DENABLE_ADDRESS_SANITIZER=@JUCE_ENABLE_ADDRESS_SANITIZER@",
"-DENABLE_THREAD_SANITIZER=@JUCE_ENABLE_THREAD_SANITIZER@",
"-DJUCE_COMPILE_GRADLE:BOOL=ON"
}
}
}
externalNativeBuild {
cmake {
buildStagingDirectory "../build/android"
path "../CMakeLists.txt"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:25.4.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}
Eventually juce can allow subclass your own .in
files in case you want to do special configs.