[android][sdk] Move cpp code into sdk lib

Signed-off-by: Andrei Shkrob <github@shkrob.dev>
This commit is contained in:
Andrei Shkrob
2025-06-25 21:00:47 +02:00
committed by Konstantin Pastbin
parent 0c8648d1e3
commit dd023b65c7
86 changed files with 137 additions and 108 deletions

View File

@@ -269,5 +269,5 @@ endif()
omim_add_test_subdirectory(qt_tstfrm) omim_add_test_subdirectory(qt_tstfrm)
if (PLATFORM_ANDROID) if (PLATFORM_ANDROID)
add_subdirectory(android/app/src/main/cpp) add_subdirectory(android/sdk/src/main/cpp)
endif() endif()

View File

@@ -19,33 +19,13 @@ apply plugin: 'com.android.application'
apply plugin: 'com.github.triplet.play' apply plugin: 'com.github.triplet.play'
apply plugin: 'ru.cian.huawei-publish-gradle-plugin' apply plugin: 'ru.cian.huawei-publish-gradle-plugin'
def run(cmd) {
def stdout = new ByteArrayOutputStream()
exec {
commandLine = cmd
standardOutput = stdout
}
return stdout.toString()
}
import com.github.triplet.gradle.androidpublisher.ReleaseStatus import com.github.triplet.gradle.androidpublisher.ReleaseStatus
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
def getVersion() {
def isWindows = DefaultNativePlatform.getCurrentOperatingSystem().isWindows()
def bash = isWindows ? 'C:\\Program Files\\Git\\bin\\bash.exe' : 'bash'
def versionCode = Integer.parseInt(run([bash, '../../tools/unix/version.sh', 'android_code']).trim())
def versionName = run([bash, '../../tools/unix/version.sh', 'android_name']).trim()
return new Tuple2(versionCode, versionName)
}
def getCommitMessage() { def getCommitMessage() {
return run(['git', '--no-pager', 'show', '-s', '--format=%s%n%n%b', 'HEAD']).trim() return run(['git', '--no-pager', 'show', '-s', '--format=%s%n%n%b', 'HEAD']).trim()
} }
def osName = System.properties['os.name'].toLowerCase()
project.ext.appId = 'app.comaps' project.ext.appId = 'app.comaps'
project.ext.appName = 'CoMaps' project.ext.appName = 'CoMaps'
@@ -81,13 +61,9 @@ android {
// All properties are read from gradle.properties file // All properties are read from gradle.properties file
compileSdk propCompileSdkVersion.toInteger() compileSdk propCompileSdkVersion.toInteger()
ndkVersion '28.2.13676358'
defaultConfig { defaultConfig {
// Default package name is taken from the manifest and should be app.comaps versionCode = rootProject.ext.versionCode
def ver = getVersion() versionName = rootProject.ext.versionName
versionCode = ver.V1
versionName = ver.V2
println('Version: ' + versionName) println('Version: ' + versionName)
println('VersionCode: ' + versionCode) println('VersionCode: ' + versionCode)
minSdk propMinSdkVersion.toInteger() minSdk propMinSdkVersion.toInteger()
@@ -97,60 +73,6 @@ android {
// Should be customized in flavors. // Should be customized in flavors.
buildConfigField 'String', 'REVIEW_URL', '""' buildConfigField 'String', 'REVIEW_URL', '""'
externalNativeBuild {
def pchFlag = 'OFF'
if (project.hasProperty('pch')) pchFlag = 'ON'
def njobs = ''
if (project.hasProperty('njobs')) njobs = project.getProperty('njobs')
def enableVulkanDiagnostics = 'OFF'
if (project.hasProperty('enableVulkanDiagnostics')) {
enableVulkanDiagnostics = project.getProperty('enableVulkanDiagnostics')
}
def enableTrace = 'OFF'
if (project.hasProperty('enableTrace')) {
enableTrace = project.getProperty('enableTrace')
}
cmake {
cppFlags '-fexceptions', '-frtti'
// There is no sense to enable sections without gcc's --gc-sections flag.
cFlags '-fno-function-sections', '-fno-data-sections',
'-Wno-extern-c-compat'
arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static',
"-DOS=$osName", '-DSKIP_TESTS=ON', '-DSKIP_TOOLS=ON', "-DUSE_PCH=$pchFlag",
"-DNJOBS=$njobs", "-DENABLE_VULKAN_DIAGNOSTICS=$enableVulkanDiagnostics",
"-DENABLE_TRACE=$enableTrace"
targets 'organicmaps'
}
}
// Use, for example, -Parm32 gradle parameter to build only for armeabi-v7a.
ndk {
abiFilters = new HashSet<>()
if (project.hasProperty('arm32') || project.hasProperty('armeabi-v7a')) {
abiFilters.add('armeabi-v7a')
}
if (project.hasProperty('arm64') || project.hasProperty('arm64-v8a')) {
abiFilters.add('arm64-v8a')
}
if (project.hasProperty('x86')) {
abiFilters.add('x86')
}
if (project.hasProperty('x86_64') || project.hasProperty('x64')) {
abiFilters.add('x86_64')
}
if (abiFilters.isEmpty()) {
abiFilters.add('armeabi-v7a')
abiFilters.add('arm64-v8a')
// For the emulator, chromebooks and some Intel Atom devices.
abiFilters.add('x86_64')
}
println('Building for ' + abiFilters + ' archs.')
}
setProperty('archivesBaseName', appName.replaceAll('\\s','') + '-' + defaultConfig.versionCode) setProperty('archivesBaseName', appName.replaceAll('\\s','') + '-' + defaultConfig.versionCode)
} }
@@ -276,12 +198,9 @@ android {
debug { debug {
applicationIdSuffix '.debug' // Allows to install debug and release builds together applicationIdSuffix '.debug' // Allows to install debug and release builds together
versionNameSuffix '-debug' versionNameSuffix '-debug'
jniDebuggable true // Enable jni debug build
zipAlignEnabled true zipAlignEnabled true
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
resValue 'string', 'app_name', 'CoMaps Debug' resValue 'string', 'app_name', 'CoMaps Debug'
// Do not generate separate debug symbols for debug apps, because we don't distribute them.
ndk.debugSymbolLevel = 'none'
} }
release { release {
@@ -301,8 +220,6 @@ android {
// To learn more, go to the documentation section about R8 configuration files. // To learn more, go to the documentation section about R8 configuration files.
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
resValue 'string', 'app_name', project.ext.appName resValue 'string', 'app_name', project.ext.appName
// Full size symbols are too big for Google, 217mb aab vs 95mb.
ndk.debugSymbolLevel = 'symbol_table'
} }
beta { beta {
@@ -325,16 +242,6 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
matchingFallbacks = ['release'] // use dependencies of "release" build type matchingFallbacks = ['release'] // use dependencies of "release" build type
resValue 'string', 'app_name', 'CoMaps Test' resValue 'string', 'app_name', 'CoMaps Test'
// Full size symbols are too big for Google, 217mb aab vs 95mb.
ndk.debugSymbolLevel = 'symbol_table'
}
}
externalNativeBuild {
cmake {
version '3.22.1+'
buildStagingDirectory './nativeOutputs'
path '../../CMakeLists.txt'
} }
} }
@@ -453,10 +360,6 @@ dependencies {
testImplementation libs.mockito.core testImplementation libs.mockito.core
} }
tasks.withType(JavaCompile) {
options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation'
}
android.applicationVariants.all { variant -> android.applicationVariants.all { variant ->
def authorityValue = variant.applicationId + ".provider" def authorityValue = variant.applicationId + ".provider"
def authority = "\"" + authorityValue + "\"" def authority = "\"" + authorityValue + "\""

View File

@@ -1,5 +1,34 @@
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins { plugins {
alias libs.plugins.android.application apply false alias libs.plugins.android.application apply false
alias libs.plugins.android.library apply false alias libs.plugins.android.library apply false
} }
def run(cmd) {
def stdout = new ByteArrayOutputStream()
exec {
commandLine = cmd
standardOutput = stdout
}
return stdout.toString()
}
def getVersion() {
def isWindows = DefaultNativePlatform.getCurrentOperatingSystem().isWindows()
def bash = isWindows ? 'C:\\Program Files\\Git\\bin\\bash.exe' : 'bash'
def versionCode = Integer.parseInt(run([bash, '../tools/unix/version.sh', 'android_code']).trim())
def versionName = run([bash, '../tools/unix/version.sh', 'android_name']).trim()
return new Tuple2(versionCode, versionName)
}
rootProject.ext {
def ver = getVersion()
versionCode = ver.V1
versionName = ver.V2
}
tasks.withType(JavaCompile).configureEach {
options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation'
}

3
android/sdk/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
.cxx
build
nativeOutputs

View File

@@ -6,17 +6,96 @@ android {
namespace 'app.organicmaps.sdk' namespace 'app.organicmaps.sdk'
compileSdk propCompileSdkVersion.toInteger() compileSdk propCompileSdkVersion.toInteger()
ndkVersion '28.2.13676358'
defaultConfig { defaultConfig {
versionCode = rootProject.ext.versionCode
versionName = rootProject.ext.versionName
minSdk propMinSdkVersion.toInteger() minSdk propMinSdkVersion.toInteger()
targetSdk propTargetSdkVersion.toInteger() targetSdk propTargetSdkVersion.toInteger()
ndk.debugSymbolLevel = 'symbol_table'
externalNativeBuild {
def pchFlag = 'OFF'
if (project.hasProperty('pch')) pchFlag = 'ON'
def njobs = ''
if (project.hasProperty('njobs')) njobs = project.getProperty('njobs')
def enableVulkanDiagnostics = 'OFF'
if (project.hasProperty('enableVulkanDiagnostics')) {
enableVulkanDiagnostics = project.getProperty('enableVulkanDiagnostics')
}
def enableTrace = 'OFF'
if (project.hasProperty('enableTrace')) {
enableTrace = project.getProperty('enableTrace')
}
cmake {
cppFlags '-fexceptions', '-frtti'
// There is no sense to enable sections without gcc's --gc-sections flag.
cFlags '-fno-function-sections', '-fno-data-sections',
'-Wno-extern-c-compat'
arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static',
'-DSKIP_TESTS=ON', '-DSKIP_TOOLS=ON', "-DUSE_PCH=$pchFlag",
"-DNJOBS=$njobs", "-DENABLE_VULKAN_DIAGNOSTICS=$enableVulkanDiagnostics",
"-DENABLE_TRACE=$enableTrace"
targets 'organicmaps'
}
}
// Use, for example, -Parm32 gradle parameter to build only for armeabi-v7a.
ndk {
abiFilters = new HashSet<>()
if (project.hasProperty('arm32') || project.hasProperty('armeabi-v7a')) {
abiFilters.add('armeabi-v7a')
}
if (project.hasProperty('arm64') || project.hasProperty('arm64-v8a')) {
abiFilters.add('arm64-v8a')
}
if (project.hasProperty('x86')) {
abiFilters.add('x86')
}
if (project.hasProperty('x86_64') || project.hasProperty('x64')) {
abiFilters.add('x86_64')
}
if (abiFilters.isEmpty()) {
abiFilters.add('armeabi-v7a')
abiFilters.add('arm64-v8a')
// For the emulator, chromebooks and some Intel Atom devices.
abiFilters.add('x86_64')
}
println('Building for ' + abiFilters + ' archs.')
}
} }
buildTypes { buildTypes {
debug {
versionNameSuffix '-debug'
jniDebuggable true // Enable jni debug build
}
release { release {
minifyEnabled false minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
} }
beta {
versionNameSuffix '-test'
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
matchingFallbacks = ['release']
}
} }
externalNativeBuild {
cmake {
version '3.22.1+'
buildStagingDirectory './nativeOutputs'
path '../../CMakeLists.txt'
}
}
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_17 sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17
@@ -26,3 +105,18 @@ android {
dependencies { dependencies {
} }
// TODO: Running lint task triggers native build. Find a better solution.
project.afterEvaluate {
boolean isLintRun = project.gradle.startParameter.taskNames.any { it.toLowerCase().contains('lint') }
if (isLintRun) {
tasks.findAll { task ->
(task.name.startsWith('Native') || task.name.contains('CMake')) &&
task.project == project
}.each { nativeTask ->
logger.warn("Disabling task ${nativeTask.path} because lint is running.")
nativeTask.onlyIf { false }
}
}
}

View File

@@ -1,5 +1,5 @@
#include "android/app/src/main/cpp/app/organicmaps/sdk/core/jni_helper.hpp" #include "android/sdk/src/main/cpp/app/organicmaps/sdk/core/jni_helper.hpp"
#include "android/app/src/main/cpp/app/organicmaps/sdk/core/ScopedLocalRef.hpp" #include "android/sdk/src/main/cpp/app/organicmaps/sdk/core/ScopedLocalRef.hpp"
#include "platform/locale.hpp" #include "platform/locale.hpp"

View File

@@ -1,4 +1,4 @@
#include "android/app/src/main/cpp/app/organicmaps/sdk/core/jni_helper.hpp" #include "android/sdk/src/main/cpp/app/organicmaps/sdk/core/jni_helper.hpp"
#include "geometry/mercator.hpp" #include "geometry/mercator.hpp"

View File

@@ -1,4 +1,4 @@
#include "android/app/src/main/cpp/app/organicmaps/sdk/core/jni_helper.hpp" #include "android/sdk/src/main/cpp/app/organicmaps/sdk/core/jni_helper.hpp"
#include "platform/preferred_languages.hpp" #include "platform/preferred_languages.hpp"
extern "C" extern "C"

View File

@@ -19,7 +19,7 @@
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h>
#include "android/app/src/main/cpp/app/organicmaps/sdk/opengl/gl3stub.h" #include "android/sdk/src/main/cpp/app/organicmaps/sdk/opengl/gl3stub.h"
#include <EGL/egl.h> #include <EGL/egl.h>
#elif defined(OMIM_OS_LINUX) #elif defined(OMIM_OS_LINUX)
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES

View File

@@ -22,7 +22,7 @@ using namespace std;
Platform::Platform() Platform::Platform()
{ {
/// @see initialization routine in android/app/src/main/cpp/com/.../Platform.hpp /// @see initialization routine in android/sdk/src/main/cpp/com/.../Platform.hpp
} }
#ifdef DEBUG #ifdef DEBUG

View File

@@ -23,7 +23,7 @@
#elif defined(OMIM_OS_LINUX) #elif defined(OMIM_OS_LINUX)
#include <cstdlib> #include <cstdlib>
#elif defined(OMIM_OS_ANDROID) #elif defined(OMIM_OS_ANDROID)
/// Body for this function is inside android/app/src/main/cpp sources /// Body for this function is inside android/sdk/src/main/cpp sources
std::string GetAndroidSystemLanguage(); std::string GetAndroidSystemLanguage();
#else #else
#error "Define language preferences for your platform" #error "Define language preferences for your platform"