Last active
February 9, 2023 01:24
-
-
Save ppetraki/ca8630cc272edcd6a881ed82aa30b559 to your computer and use it in GitHub Desktop.
gradle plugin to drive conan multi arch android build
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
title |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
apply plugin: 'com.android.application' | |
apply from: "${rootDir}/conan.gradle" | |
android { | |
compileSdkVersion 29 | |
buildToolsVersion "29.0.1" | |
defaultConfig { | |
applicationId "org.libsdl.app" | |
minSdkVersion 26 | |
targetSdkVersion 29 | |
versionCode 1 | |
versionName "1.0" | |
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | |
externalNativeBuild { | |
cmake { | |
cppFlags "-std=c++17" | |
abiFilters 'x86', 'armeabi-v7a', 'x86_64' | |
} | |
} | |
} //defaultConfig | |
// https://stackoverflow.com/questions/36414219/install-failed-no-matching-abis-failed-to-extract-native-libraries-res-113 | |
splits { | |
abi { | |
enable true | |
reset() | |
include 'x86', 'armeabi-v7a', 'x86_64' | |
// include defaultConfig.externalNativeBuild.getCmake().getAbiFilters(). | |
universalApk true | |
} | |
} | |
buildTypes { | |
release { | |
minifyEnabled true | |
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | |
} | |
} | |
externalNativeBuild { | |
cmake { | |
path "src/main/cpp/CMakeLists.txt" | |
version "3.10.2" | |
} | |
} | |
} //android | |
// XXX the plugin should handle this | |
clean.doLast { | |
delete file('conan_build') | |
} | |
dependencies { | |
implementation fileTree(dir: 'libs', include: ['*.jar']) | |
implementation 'androidx.appcompat:appcompat:1.1.0' | |
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' | |
testImplementation 'junit:junit:4.12' | |
androidTestImplementation 'androidx.test:runner:1.2.0' | |
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
project(SDL2CYCLEBLOCKS) | |
# For more information about using CMake with Android Studio, read the | |
# documentation: https://d.android.com/studio/projects/add-native-code.html | |
# Sets the minimum version of CMake required to build the native library. | |
cmake_minimum_required(VERSION 3.4.1) | |
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../conan_build/${CMAKE_BUILD_TYPE}/${ANDROID_ABI}/conanbuildinfo.cmake) | |
conan_basic_setup(TARGETS) | |
# MainActivity will dynamically load this lib | |
add_library(main SHARED main.cpp) | |
include_directories( | |
CONAN_PKG::sdl2 | |
CONAN_PKG::sdl2pp | |
) | |
# get android env | |
add_library(native_app_glue STATIC | |
${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c) | |
target_include_directories(native_app_glue | |
PUBLIC | |
${ANDROID_NDK}/sources/android/native_app_glue | |
) | |
# Searches for a specified prebuilt library and stores the path as a | |
# variable. Because CMake includes system libraries in the search path by | |
# default, you only need to specify the name of the public NDK library | |
# you want to add. CMake verifies that the library exists before | |
# completing its build. | |
find_library( # Sets the name of the path variable. | |
log-lib | |
# Specifies the name of the NDK library that | |
# you want CMake to locate. | |
log) | |
target_link_libraries(main | |
android | |
native_app_glue | |
${log-lib} | |
EGL | |
GLESv2 | |
CONAN_PKG::sdl2 | |
CONAN_PKG::sdl2pp | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ls ~/.conan/profiles/ | |
android-armeabi-v7a android-x86 android-x86_64 | |
The plugin is looking for profiles names in the format "android-${abi}" | |
The contents of these files vary little. They use the cmake_wrapper package so all that's changing | |
is the host. This could be optimized to driven by the conan CLI and managed by the plugin. Ideally, the | |
plugin should provide it's own default profile for the NDK and decorate it from the data provided by the | |
build. | |
#[file: android-armeabi-v7a] | |
[build_requires] | |
android_ndk_installer/r20@bincrafters/stable | |
[settings] | |
os=Android | |
os.api_level=21 | |
os_build=Linux | |
# https://docs.conan.io/en/latest/systems_cross_building/cross_building.html#cross-building-android | |
# Android armbeabi-v7a armv7 | |
# Android armv64-v8a armv8 | |
# Android armeabi armv6 (as a minimal compatible, will be compatible with v7 too) | |
arch=armv7 | |
arch_build=x86_64 | |
compiler=clang | |
compiler.version=8 | |
compiler.libcxx=libc++ | |
[options] | |
*:pic = True | |
#[file: android-x86] | |
[build_requires] | |
android_ndk_installer/r20@bincrafters/stable | |
[settings] | |
os=Android | |
os.api_level=21 | |
os_build=Linux | |
# https://docs.conan.io/en/latest/systems_cross_building/cross_building.html#cross-building-android | |
# target device | |
arch=x86 | |
# builder | |
arch_build=x86_64 | |
compiler=clang | |
compiler.version=8 | |
compiler.libcxx=libc++ | |
[options] | |
*:pic = True | |
#[file: android-x86_64] | |
[build_requires] | |
android_ndk_installer/r20@bincrafters/stable | |
[settings] | |
os=Android | |
os.api_level=21 | |
os_build=Linux | |
# https://docs.conan.io/en/latest/systems_cross_building/cross_building.html#cross-building-android | |
# Android armbeabi-v7a armv7 | |
# Android armv64-v8a armv8 | |
# Android armeabi armv6 (as a minimal compatible, will be compatible with v7 too) | |
arch=x86_64 | |
arch_build=x86_64 | |
compiler=clang | |
compiler.version=8 | |
compiler.libcxx=libc++ | |
[options] | |
*:pic = True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// From https://gist.github.com/CAMOBAP795/ed9aa6a7549787b5eea4b2048b896747 | |
// with some changes | |
// | |
// Originally discovered here: https://github.com/conan-io/docs/issues/1259 | |
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}/conan_build/${buildType}/${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" | |
println "ConanPlugin: conan profile template: ${extension.profile}" | |
println "ConanPlugin: conan dir path template: ${extension.outputDirPath}" | |
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.capitalize()] | |
println """ | |
---------------------------- | |
ConanPlugin( | |
abi: ${params['abi']} | |
flavor: ${params['flavor']} | |
projectDir: ${params['projectDir']} | |
buildType: ${params['buildType']} | |
) | |
---------------------------- | |
""".stripMargin() | |
def conanProfileFileName = engine.createTemplate(conanProfileFileNameTemplate).make(params).toString() | |
def conanOutputDirPath = engine.createTemplate(conanOutputDirPathTemplate).make(params).toString() | |
println """ | |
---------------------------- | |
ConanPlugin( | |
conanProfileFileName: ${conanProfileFileName} | |
conanOutputDirPath: ${conanOutputDirPath} | |
) | |
---------------------------- | |
""".stripMargin() | |
def conanInstallTaskName = "conanInstall${taskSuffix}" | |
println "ConanPlugin: Executing conan install task: ${conanInstallTaskName}" | |
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=${params['buildType']}", | |
'--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) | |
['externalNativeBuildCleanRegularDebug', | |
'externalNativeBuildCleanRegularRelease', | |
'generateRegularDebugSources', | |
'generateRegularReleaseSources', | |
"externalNativeBuild${flavor.capitalize()}", | |
"externalNativeBuildClean${flavor.capitalize()}" ].each { | |
if (project.tasks.findByName("${it}")) { | |
println "ConanPlugin: Adding dependency ${it}->conanInstallTaskName" | |
project.tasks.findByName("${it}").dependsOn(conanInstallTaskName) | |
} | |
} | |
} //void createTasksForAndroidExternalNativeBuild | |
} //class ConanPlugin | |
void apply(Project project) { | |
extension = project.extensions.create('conan', ConanPluginExtension) | |
project.afterEvaluate { | |
validate(project) | |
createTasksForAndroidExternalNativeBuild(project) | |
} | |
} | |
} | |
apply plugin: ConanPlugin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ppetraki@vanguard:~/Sandbox/Games/conansdl2$ tree app/ | |
app/ | |
├── app.iml | |
├── build | |
│ ├── generated | |
│ │ └── source | |
│ │ └── buildConfig | |
│ │ └── debug | |
│ │ └── org | |
│ │ └── libsdl | |
│ │ └── app | |
│ │ └── BuildConfig.java | |
│ └── intermediates | |
│ └── check_manifest_result | |
│ └── debug | |
│ └── checkDebugManifest | |
│ └── out | |
├── build.gradle | |
├── conan_build | |
│ ├── Debug | |
│ │ ├── armeabi-v7a | |
│ │ │ ├── conanbuildinfo.cmake | |
│ │ │ ├── conanbuildinfo.txt | |
│ │ │ ├── conaninfo.txt | |
│ │ │ ├── conan.lock | |
│ │ │ └── graph_info.json | |
│ │ ├── x86 | |
│ │ │ ├── conanbuildinfo.cmake | |
│ │ │ ├── conanbuildinfo.txt | |
│ │ │ ├── conaninfo.txt | |
│ │ │ ├── conan.lock | |
│ │ │ └── graph_info.json | |
│ │ └── x86_64 | |
│ │ ├── conanbuildinfo.cmake | |
│ │ ├── conanbuildinfo.txt | |
│ │ ├── conaninfo.txt | |
│ │ ├── conan.lock | |
│ │ └── graph_info.json | |
│ └── Release | |
│ ├── armeabi-v7a | |
│ │ ├── conanbuildinfo.cmake | |
│ │ ├── conanbuildinfo.txt | |
│ │ ├── conaninfo.txt | |
│ │ ├── conan.lock | |
│ │ └── graph_info.json | |
│ ├── x86 | |
│ │ ├── conanbuildinfo.cmake | |
│ │ ├── conanbuildinfo.txt | |
│ │ ├── conaninfo.txt | |
│ │ ├── conan.lock | |
│ │ └── graph_info.json | |
│ └── x86_64 | |
│ ├── conanbuildinfo.cmake | |
│ ├── conanbuildinfo.txt | |
│ ├── conaninfo.txt | |
│ ├── conan.lock | |
│ └── graph_info.json | |
├── libs | |
├── proguard-rules.pro | |
└── src | |
├── androidTest | |
│ └── java | |
│ └── com | |
│ └── example | |
│ └── conansdl2 | |
│ └── ExampleInstrumentedTest.java | |
├── main | |
│ ├── AndroidManifest.xml | |
│ ├── cpp | |
│ │ ├── CMakeLists.txt | |
│ │ ├── conanfile.txt | |
│ │ └── main.cpp |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment