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