CMake generates SHARED library but not STATIC library - android

I am trying to generate a static library using CMAKE and Android Studio(2.3.2). Below is what my CMakeLists.txt looks like. I am unable to generate .a file, however when I change the library to SHARED, CMakeTestModule.so file gets generated when I do "Build->Rebuild Project". Is it required for me to add/set any flag for building STATIC libraries.
cmake_minimum_required(VERSION 3.4.1)
project (CMakeTestProject)
include_directories(
src/main/cpp/
)
add_library(
CMakeTestModule
STATIC
src/main/cpp/CMakeTestModule.cpp
)
add_executable(
CMakeTestModule_test
src/main/cpp/CMakeTestModule_test.cpp
)
target_link_libraries(CMakeTestModule_test CMakeTestModule)
This is what my build.gradle looks like:
apply plugin: 'com.android.library'
android {
compileSdkVersion 16
buildToolsVersion "25.0.0"
defaultConfig {
minSdkVersion 8
targetSdkVersion 8
externalNativeBuild {
cmake {
abiFilters 'armeabi'
}
}
}
externalNativeBuild {
cmake {
path 'CMakeLists.txt'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}

I fixed this issue by specifying the target in the build.gradle. Something like below. Since apk only uses .so files, we need to mention the targets for static libraries and executables.
apply plugin: 'com.android.library'
android {
compileSdkVersion 16
buildToolsVersion "25.0.0"
defaultConfig {
minSdkVersion 8
targetSdkVersion 8
externalNativeBuild {
cmake {
abiFilters 'armeabi'
}
targets "CMakeTestModule_test", "CMakeTestModule"
}
}
externalNativeBuild {
cmake {
path 'CMakeLists.txt'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}

Related

How to set cpp folder for a specific build flavor

I have an issue with adding a cpp folder and CMakelist.txt file to a specific flavor in android studio.
I was working on three separate apps with a unique database structure, so I tried to make these three apps as one application using build flavors and other related settings.
For the first two apps, it did so well, but for the last one, I faced an issue that I had no idea how to add cpp folder and CMakelist.txt file to that specific flavor using Gradle. As you may have guessed, the last application is NDK based and uses a CMakelist.txt file and has an activity that works with JNI.
android {
...
defaultConfig {
applicationId "com.example"
...
externalNativeBuild {
cmake {
cppFlags ""
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
flavorDimensions 'program'
productFlavors {
first {
dimension = 'program'
applicationIdSuffix = '.first'
}
second {
dimension = 'program'
applicationIdSuffix = '.second'
}
third {
dimension = 'program'
applicationIdSuffix = '.third'
externalNativeBuild {
cmake {
relativeProjectPath "src/third/cpp/CMakeLists.txt"
version "3.10.2"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
ndk { abiFilters "arm64-v8a" }
}
debug {
ndk { abiFilters "arm64-v8a" }
}
}
}
}
I am using a relativeProjectPath method in gradle, and expect that CMakelist.txt links with my cpp folders but nothing happens.
I have not tried it that way. What worked for me in my previous projects is this.
android {
...
flavorDimensions "program"
productFlavors {
...
third {
dimension "program"
externalNativeBuild.cmake {
arguments "-DFLAVOR=THIRD_PROGRAM"
}
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
...
}
Then in your CMakeList.txt, do this conditional test
if(${FLAVOR} STREQUAL "THIRD_PROGRAM")
// build your cpp codes for flavor THIRD
else()
// nothing to build?
endif()
Note that my CMakeList.txt is in app/ directory.

dlopen cannot find .so library at runtime

Everything compiled well and my apk is built, but at runtime I get this error:
java.lang.UnsatisfiedLinkError: dlopen failed: library "../../../../libs/x86/mylib.so" not found
I tried to extract the apk and check libs/x86 folder and the .so is there.
My android field at app/build.gradle is:
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.example.test"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
}
}
ndk {
abiFilters "x86"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}

External native build issues, build command failed, error while executing 'C:/User/user.../cmake.exe' with arguments {-HF

Recently i have tried to attach cmake with my existing android studio project. I am searching SO since last four day not yet succeeded. Please don't mark this as duplicate. I am running android studio 2.2.1 with gradle version 2.14.1 in windows 8.1pro.
My build.gradle (app level):
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "25.0.2"
defaultConfig {
applicationId = "com.example.user.myproject"
minSdkVersion 17
targetSdkVersion 24
multiDexEnabled true
versionCode 1
versionName "1.0"
vectorDrawables.useSupportLibrary true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
arguments '-DANDROID_TOOLCHAIN=clang'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// proguardFiles.add(file("proguard-rules.txt"))
}
}
externalNativeBuild {
cmake {
path 'src/main/cpp/CMakeLists.txt'
}
}
productFlavors {
arm7 {
// in the future, ndk.abiFilter might also work
ndk {
abiFilter 'armeabi-v7a'
}
}
arm8 {
ndk {
abiFilters 'arm64-v8a'
}
}
arm {
ndk {
abiFilter 'armeabi'
}
}
x86 {
ndk {
abiFilter 'x86'
}
}
x86_64 {
ndk {
abiFilter 'x86_64'
}
}
mips {
ndk {
abiFilters 'mips', 'mips64'
}
}
universal {
ndk {
abiFilters 'mips', 'mips64', 'x86', 'x86_64'
}
}
}
}
dependencies {
My CMakeLists.txt (path: 'app/src/main/cpp')
cmake_minimum_required(VERSION 3.4.1)
add_library(native-lib
SHARED
src/main/cpp/native-lib.cpp)
I am getting this error in message view:
Error while executing 'C:\Users\User\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe' with arguments {-HF:\MyProject\app\src\main\cpp -BF:\MyProject\app\.externalNativeBuild\cmake\x86_64Debug\x86_64 -GAndroid Gradle - Ninja -DANDROID_ABI=x86_64 -DANDROID_NDK=C:\Users\User\AppData\Local\Android\Sdk\ndk-bundle -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=F:\MyProject\app\build\intermediates\cmake\x86_64\debug\obj\x86_64 -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MAKE_PROGRAM=C:\Users\User\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\ninja.exe -DCMAKE_TOOLCHAIN_FILE=C:\Users\User\AppData\Local\Android\Sdk\ndk-bundle\build\cmake\android.toolchain.cmake -DANDROID_NATIVE_API_LEVEL=21 -DANDROID_TOOLCHAIN=clang}
I don't know what's wrong here.

How to set up the SuperPowered SDK on Android

Reading through the README on the SuperPowered SDK GitHub page, I notice that for having it working on Android you need to:
Create the jni folder inside the project's folder: app/src/main/jni
Copy the contents of the following files from one of the example
projects: gradle/wrapper/gradle-wrapper.properties, local.properties,
build.gradle, app/build.gradle, app/src/main/jni/CMakeLists.txt Open
build.gradle (Module: app), and change the applicationId
I've done all of that, still when I'm trying to sync my project with gradle, I get the following error message:
Error:(34, 0) Could not find method arguments() for arguments [-DANDROID_PLATFORM=android-16, -DANDROID_TOOLCHAIN=clang, -DANDROID_ARM_NEON=TRUE, -DANDROID_STL=gnustl_static, -DPATH_TO_SUPERPOWERED:STRING=null] on object of type com.android.build.gradle.internal.dsl.CmakeOptions.
Open File
This is how my app/build.gradle looks like:
apply plugin: 'com.android.application'
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def superpowered_sdk_path = properties.getProperty('superpowered.dir')
android {
signingConfigs {
dancam_dev_key {
keyAlias ######
keyPassword ######
storeFile file('/Users/daniele/Desktop/Chords/#####')
storePassword ########
}
}
compileSdkVersion 26
buildToolsVersion "26.0.1"
defaultConfig {
applicationId #####
minSdkVersion 21
targetSdkVersion 26
versionCode 17
versionName "2.1"
signingConfig #######
multiDexEnabled true
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' // these platforms cover 99% percent of all Android devices
}
}
externalNativeBuild {
cmake {
arguments '-DANDROID_PLATFORM=android-16', '-DANDROID_TOOLCHAIN=clang', '-DANDROID_ARM_NEON=TRUE', '-DANDROID_STL=gnustl_static', "-DPATH_TO_SUPERPOWERED:STRING=${superpowered_sdk_path}"
cFlags '-O3', '-fsigned-char' // full optimization, char data type is signed
cppFlags '-fsigned-char', "-I${superpowered_sdk_path}"
}
}
buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
productFlavors {
}
dataBinding {
enabled = true
}
}
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jni']
}
}
externalNativeBuild {
cmake {
path 'src/main/jni/CMakeLists.txt'
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
....
}
EDIT:
Here is the cmake.txt file
cmake_minimum_required(VERSION 3.4.1)
set(
PATH_TO_SUPERPOWERED
CACHE STRING ""
)
message(${ANDROID_ABI})
file(GLOB CPP_FILES "*.cpp")
add_library(
SuperpoweredExample
SHARED
${CPP_FILES}
${PATH_TO_SUPERPOWERED}/AndroidIO/SuperpoweredAndroidAudioIO.cpp
)
include_directories(src/main/jni)
include_directories(${PATH_TO_SUPERPOWERED})
target_link_libraries(
SuperpoweredExample
log
android
OpenSLES
${PATH_TO_SUPERPOWERED}/libSuperpoweredAndroid${ANDROID_ABI}.a
)
I have a very similar config (as it inherits the default suggested config) but found some differences.
You provide the cmake config like this:
externalNativeBuild {
cmake {
path 'src/main/jni/CMakeLists.txt'
}
}
but as I understood you saved it as "cmake.txt" which is never linked or found.
Does renaming cmake.txt to CMakeLists.txt help?

How to add cpufeatures to android jni cmake gradle build?

If I have a build.gradle for an application:
android {
compileSdkVersion 24
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.ndkcmaketest.headwayent.ndkcmaketest"
minSdkVersion 19
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=gcc"//, "-DANDROID_ALLOW_UNDEFINED_SYMBOLS=TRUE"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
How do I add cpufeatures as ldlibs? Adding ldLibs.addAll(["cpufeatures"]) in externalNativeBuild does not work. And neither adding in an ndk block.
Do you have to add this to build.gradle specifically? If not, add the following to one of your CMakeLists.txt files:
include(AndroidNdkModules)
android_ndk_import_module_cpufeatures()
Then you can target_link_libraries(<your target>, cpufeatures).
That macro and a couple of others are defined in $ANDROID_SDK/cmake/<cmake-version>/share/cmake-<version>/Modules/AndroidNdkModules.cmake.

Categories

Resources