-
-
Save CAMOBAP/ed9aa6a7549787b5eea4b2048b896747 to your computer and use it in GitHub Desktop.
include(default) | |
standalone_toolchain=/opt/android-ndk-toolchains/arm-27 | |
ndk_home=/opt/android-ndk | |
api_level=27 | |
target_host=arm-linux-androideabi | |
cc_compiler=clang | |
cxx_compiler=clang++ | |
target_specific_flags=-mfpu=neon | |
[settings] | |
os=Android | |
os.api_level=$api_level | |
arch=armv7hf | |
compiler=clang | |
compiler.version=7.0 | |
compiler.libcxx=libstdc++ | |
[env] | |
ANDROID_NDK_HOME=$ndk_home | |
CONAN_CMAKE_FIND_ROOT_PATH=$standalone_toolchain/sysroot | |
PATH=[$standalone_toolchain/bin] | |
CHOST=$target_host | |
AR=$target_host-ar | |
AS=$target_host-as | |
RANLIB=$target_host-ranlib | |
CC=$target_host-$cc_compiler | |
CXX=$target_host-$cxx_compiler | |
LD=$target_host-ld | |
STRIP=$target_host-strip | |
CFLAGS= -fPIE -fPIC -I$standalone_toolchain/include/c++/4.9.x -D__ANDROID__ -D__ANDROID_API__=$api_level $target_specific_flags | |
CXXFLAGS= -fPIE -fPIC -I$standalone_toolchain/include/c++/4.9.x -D__ANDROID__ -D__ANDROID_API__=$api_level $target_specific_flags | |
LDFLAGS= -pie -march=armv7-a -Wl,--fix-cortex-a8 |
standalone_toolchain=/opt/android-ndk-toolchains/x86_64-27 | |
ndk_home=/opt/android-ndk | |
api_level=27 | |
target_host=x86_64-linux-android | |
cc_compiler=clang | |
cxx_compiler=clang++ | |
target_specific_flags=-mfpu=neon | |
[settings] | |
os=Android | |
os.api_level=$api_level | |
arch=x86_64 | |
compiler=clang | |
compiler.version=7.0 | |
compiler.libcxx=libstdc++ | |
[env] | |
ANDROID_NDK_HOME=$ndk_home | |
CONAN_CMAKE_FIND_ROOT_PATH=$standalone_toolchain/sysroot | |
PATH=[$standalone_toolchain/bin] | |
CHOST=$target_host | |
AR=$target_host-ar | |
AS=$target_host-as | |
RANLIB=$target_host-ranlib | |
CC=$target_host-$cc_compiler | |
CXX=$target_host-$cxx_compiler | |
LD=$target_host-ld | |
STRIP=$target_host-strip | |
CFLAGS= -fPIE -fPIC -I$standalone_toolchain/include/c++/4.9.x -D__ANDROID__ -D__ANDROID_API__=$api_level $target_specific_flags | |
CXXFLAGS= -fPIE -fPIC -I$standalone_toolchain/include/c++/4.9.x -D__ANDROID__ -D__ANDROID_API__=$api_level $target_specific_flags | |
LDFLAGS= -pie |
apply plugin: 'com.android.application' | |
apply from: "${rootDir}/conan.gradle" | |
conan { | |
conanfile = 'src/main/cpp/conanfile.txt' | |
profile = 'android-${abi}' | |
} | |
android { | |
compileSdkVersion 28 | |
defaultConfig { | |
applicationId "org.camobap.conan.gradle.example" | |
minSdkVersion 27 | |
targetSdkVersion 28 | |
versionCode 1 | |
versionName "1.0" | |
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | |
externalNativeBuild { | |
cmake { | |
abiFilters "armeabi-v7a", "x86_64" | |
arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_STL=c++_shared", | |
} | |
} | |
} | |
buildTypes { | |
release { | |
minifyEnabled true | |
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | |
} | |
} | |
externalNativeBuild { | |
cmake { | |
path "src/main/cpp/CMakeLists.txt" | |
} | |
} | |
} | |
clean.doLast { | |
delete file('.externalNativeBuild') | |
} | |
dependencies { | |
implementation 'com.android.support:appcompat-v7:28.0.0' | |
implementation 'com.android.support:support-annotations:28.0.0' | |
testImplementation 'junit:junit:4.12' | |
androidTestImplementation 'androidx.test:core:1.1.0' | |
androidTestImplementation 'androidx.test.ext:junit:1.1.0' | |
androidTestImplementation 'androidx.test:runner:1.1.1' | |
androidTestImplementation 'androidx.test:rules:1.1.1' | |
} |
import java.nio.file.Paths | |
import groovy.text.SimpleTemplateEngine | |
class ConanPluginExtension { | |
String conanfile = "src/main/cpp/conanfile.txt" | |
String profile = 'android-${abi}' // TODO maybe support map abi->filename | |
String outputDirPath = '${projectDir}/.externalNativeBuild/conan/${flavor}/${abi}' | |
} | |
class ConanPlugin implements Plugin<Project> { | |
def android | |
def extension | |
def conanfilePath | |
def conanProfileFileNameTemplate | |
def conanOutputDirPathTemplate | |
void validate(Project project) { | |
android = project.extensions.android | |
assert android: "Cannot be applied for non android projects" | |
conanfilePath = Paths.get(project.projectDir.absolutePath, extension.conanfile).toString() | |
assert project.file(conanfilePath).exists(): "conan file ${conanfilePath} doesn't exists" | |
conanProfileFileNameTemplate = extension.profile | |
conanOutputDirPathTemplate = extension.outputDirPath | |
} | |
void createTasksForAndroidExternalNativeBuild(Project project) { | |
android.applicationVariants.all { variant -> | |
def engine = new SimpleTemplateEngine() | |
for (def abi in android.defaultConfig.externalNativeBuild.cmake.abiFilters) { | |
def flavor = variant.name | |
def taskSuffix = "${abi.capitalize()}${flavor.capitalize()}" | |
def buildType = flavor.toLowerCase().contains('release') ? 'release' : 'debug' | |
def params = ['abi': abi, 'flavor': flavor, 'projectDir': project.projectDir, 'buildType': buildType] | |
def conanProfileFileName = engine.createTemplate(conanProfileFileNameTemplate).make(params).toString() | |
def conanOutputDirPath = engine.createTemplate(conanOutputDirPathTemplate).make(params).toString() | |
def conanInstallTaskName = "conanInstall${taskSuffix}" | |
def conanInstallTask = project.task(conanInstallTaskName, type: Exec) { | |
group 'Conan tasks' | |
description 'Run conan to get and build missing dependencies' | |
workingDir conanOutputDirPath | |
commandLine 'conan', 'install', conanfilePath, | |
'--profile', conanProfileFileName, | |
'--settings', "build_type=${buildType.capitalize()}", | |
'--install-folder', workingDir, | |
'--build', 'missing' | |
inputs.files conanfilePath | |
outputs.dir workingDir | |
doFirst { | |
workingDir.mkdirs() | |
} | |
} | |
def conanCheckProfileTaskName = "conanCheckProfileFor${taskSuffix}" | |
project.task(conanCheckProfileTaskName) { | |
group 'Conan tasks' | |
description 'Check that conan profile file exists' | |
doFirst { | |
if (!project.file(conanProfileFileName).exists()) { | |
def conanProfilePath = "${System.properties['user.home']}/.conan/profiles/${conanProfileFileName}" | |
assert project.file(conanProfilePath).exists() \ | |
: "Conan profile file \"${conanProfilePath}\" missing please check README.md" | |
} | |
} | |
} | |
def conanCleanTaskName = "conanClean${taskSuffix}" | |
project.task(conanCleanTaskName, type: Delete) { | |
group 'Conan tasks' | |
description 'Delete conan generated files' | |
delete conanOutputDirPath | |
} | |
conanInstallTask.dependsOn(conanCheckProfileTaskName) | |
project.tasks.findByName("externalNativeBuild${flavor.capitalize()}").dependsOn(conanInstallTaskName) | |
project.tasks.findByName("externalNativeBuildClean${flavor.capitalize()}").dependsOn(conanCleanTaskName) | |
} | |
} | |
} | |
void apply(Project project) { | |
extension = project.extensions.create('conan', ConanPluginExtension) | |
project.afterEvaluate { | |
validate(project) | |
createTasksForAndroidExternalNativeBuild(project) | |
} | |
} | |
} | |
apply plugin: ConanPlugin |
Hi @ppetraki
Sorry for log silence
To build the fat APK you need to add this: ...
This not true, android building FAT APK out of the box, moreover split
section used to build separate APK for each ABI, according to official doe https://developer.android.com/studio/build/configure-apk-splits:
universalApk
If true, Gradle generates a universal APK in addition to per-ABI APKs. A universal APK contains code and resources for all ABIs in a single APK. The default value is false. Note that this option is only available in the splits.abi block. When building multiple APKs based on screen density, Gradle always generates a universal APK that contains code and resources for all screen densities.
If flavors don't matter for the NDK build....
Flavors have no relationships with NDK, most close equivalent in CMake
-word is a target
All that has to change in the plugin is ...
You can achieve the same by modifying the 'user' side only, no need to touch plugin for this
conan {
conanfile = 'src/main/cpp/conanfile.txt'
profile = 'android-${abi}'
outputDirPath = '${projectDir}/conan_build/${buildType}/${abi}'
}
So according what I found from your comment there is no reason to modify the plugin by itself,
@ppetraki correct me if I'm wrong
Would it be possible to release this as proper Gradle Plugin?
@janseeger probably not (at least in near future)
@CAMOBAP795
I solved the "distclean" problem. It was a matter of different tasks being invoked by the IDE vs the CLI. I've created my own gist now as the plugin has diverged quite a bit from your original version. Feel free to merge the changes.
https://gist.github.com/ppetraki/ca8630cc272edcd6a881ed82aa30b559
I think this can be done with even less external config. Especially if you use the cmake_wrapper. As all of my profiles vary by just a single config string that could easily be driven to the conan CLI. Then the plugin could provide it's own default NDK profile and decorate it. Making it completely self contained.