How I can add a cflag in cmake Android Studio? - android-ndk

How I can add -D_FILE_OFFSET_BITS=64 in Cmake config file. I'm trying to add as cflag in build.gradle but it not work.
externalNativeBuild {
cmake {
cppFlags ""
cFlags "-D_FILE_OFFSET_BITS=64"
arguments "-DANDROID_TOOLCHAIN=gcc"
}
}

In the CMakeLists.txt file, I do something like:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__ANDROID__ -DANDROID -DCUSTOM_FLAG")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGL_GLEXT_PROTOTYPES=1 -DIOAPI_NO_64 -DUSE_FILE32API ")
However, you can use gradle too, but externalNativeBuild needs to be under defaultConfig or release or debug (a build flavor) for cmake options to pass the flags.
For Example:
android {
compileSdkVersion 25
buildToolsVersion '25.0.3'
defaultConfig {
applicationId "..."
externalNativeBuild {
cmake {
// here, arguments, cppFlags, cFlags, .. all work
arguments '-DANDROID_PLATFORM=android-15',
'-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static',
'-DANDROID_CPP_FEATURES=rtti exceptions'
}
}
}
externalNativeBuild {
cmake {
// only 'path' variable is valid here
path '../../gameSource/CMakeLists.txt'
}
}
buildTypes {
release {
// .. release flavor
}
debug {
//... debug flavor
}
}
}

Related

Android Studio with Native Code: Debugger process finished with exit code -1073741515 (0xC0000135)

I am trying to debug an android app in android studio with native code c++. Where, a message is showing saying
Debugger process finished with exit code -1073741515 (0xC0000135). A
library required by the native debugger might be missing on your
system.
Kindly look over the following:
this is my CMAKEList.txt file content
cmake_minimum_required(VERSION 3.18.1)
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
set(CMAKE_BUILD_TYPE Debug)
include_directories(${CMAKE_SOURCE_DIR}/jniIncludes/)
project("nativecpp")
add_library(
nativecpp
SHARED
native-lib.cpp)
find_library(
log-lib
log)
target_link_libraries(
nativecpp
${log-lib})
this is my build.gradle file content
plugins {
id 'com.android.application'
}
android {
compileSdk 32
defaultConfig {
applicationId "com.testing.nativecpp"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
// cppFlags ""
arguments "-DCMAKE_BUILD_TYPE=DEBUG"
cppFlags "-std=c++14 -fexceptions -frtti"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
version '3.18.1'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation project(path: ':OpenCV460')
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
my MainActivity.java and native-lib.cpp files contain the default generated code by Android Studio for Native Code template to run stringFromJNI function that shows text message of "Hello from C++"
also, this post does not provide a solution, please advise.

Android Studio 2.3.3 using gradle component model was creating .aar automagically; Android Studio 3.4.1 now using CMake or NDK-Build does not

My wavvoxlibrary/build.gradle is not only serving the main program (app/build.gradle) but also creating the shared library .aar.
And that is working nicely with Android Studio 2.3.3 and -- for the library -- gradle-experimental 0.9.3. The gradle component model, however, does not support abifilters, say, to build the JNI / c/c++ programs in 64-bit.
So I upgraded to Android Studio 3.4.1, and my wavvoxlibrary/build.gradle moved away form said component model and got the appropriate CMakeList.txt file to list the c/c++ programs and any compiler options that used to be part of the older build.gradle. And I also added the NDK-Build option with the Application.mk and Android.mk make files.
So far so good. My app is built and running correctly -- including the shared libraries for both, armabi-v7a (32-bit) and arm64-v8a (64-bit).
What's missing: to create the .aar file, I have to explicitly call the gradle task wavvoxlibrary .. assemble.
Is there some way to generate the .aar that during build of my, say, signed apk?
I have removed the gradle component model to move from gradle:2.3.3 and gradle-experimental:0.9.3 with "apply plugin: 'com.android.model.library' "
to gradle:3.4.1 with "apply plugin: 'com.android.library' " and also called the cmake (or, optionally ndkBuild instead) to list the c/c++ files and compiler options there.
See my blog with the details: http://jurgenmenge.com/blog/computer/migrate-a-library-in-android-studio/
import java.text.SimpleDateFormat
// migrate from Android Studio with gradle:2.3.3 + gradle-experimental:0.9.3
// to Android Studio with gradle:3.4.1 + Cmake + ndkBuild
// jm*20190614
apply plugin: 'com.android.library'
//apply plugin: 'com.android.model.library'
/**
* Each subversion code should be exactly 2 numeric digits or we will get wrong versions published
* in the Google Play Store; buildType to switch between "cmake" and "ndkBuild"
*/
ext.majorVersion = "03"
ext.minorVersion = "08"
ext.patchVersion = "03"
static String buildKind() { // neat trick I created :-) // jm*20190614
//return "gradle" // model - experimental
//return "cmake"
return "ndkBuild"
}
/**
* The name of the app version, using the Semantic Versioning format (major.minor.patch)
* #return
*/
String appVersionName() {
String appVersion = removeLeadingZeros(ext.majorVersion) + "." \
+ removeLeadingZeros(ext.minorVersion) + "." \
+ ext.patchVersion
System.out.println(" ************************************************")
System.out.println(" *** WavvoxLibrary version: " + appVersion + " ")
System.out.println(" *** buildKind " + buildKind() )
System.out.println(" ************************************************")
return appVersion
}
//model {
android {
compileSdkVersion 28
buildToolsVersion "28.0.3" // "25.0.3"
defaultConfig {
minSdkVersion 16 /*** was: 8 ***/
targetSdkVersion 28
//
versionName appVersionName() + "_" + buildKind()
setProperty("archivesBaseName", "wavvoxlibrary-$versionName")
buildConfigField "String", "VERSION_NAME_WAVVOX_FORMAT", versionNameWavvoxFormat()
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
//} // defaultConfig
ndk {
moduleName "wavvox-decoder"
ldLibs "log", "android"
// these platforms cover 99% percent of all Android devices
abiFilters "arm64-v8a", "armeabi-v7a"
//, "x86", "x86_64"
} // ndk
externalNativeBuild {
switch (buildKind()) {
case "ndkBuild":
ndkBuild {
cFlags "-std=c99", "-O3", "-Ofast", "-mfpu=neon" // jm*20190616
// "-Wno-error=format-security", "-mfloat-abi=softfp:, "-g"
abiFilters "armeabi-v7a", "arm64-v8a"
}
break
case "cmake":
cmake {
cFlags "-std=c99", "-O3", "-Ofast", "-mfpu=neon" // jm*20190616
// "-Wno-error=format-security", "-mfloat-abi=softfp:, "-g"
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
break
default:
println "**** unknown buildType value: " + buildType() + " ****"
}
} // externalNativeBuild
} // defaultConfig
buildTypes {
release {
minifyEnabled true
proguardFiles "proguard-rules.pro"
}
} // buildTypes
// } // android // jm*20190405
// android.ndk { // jm*20190405
// C source files to include in the build script
// android.sources.main.jni { // jm*20190405
/* if (buildKind() == "gradle") // using "model" in gradle_experimental
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jni'] // for pre-built .so files
jni {
//source {
include "wavvoxNativeApp.c"
// ... and all the other c/c++ programs
srcDir "jni"
//}
} // jni
} // main
} // source
*/
externalNativeBuild {
switch (buildKind()) {
case "ndkBuild":
ndkBuild {
path 'src/main/jni/Android.mk'
}
break
case "cmake":
cmake {
version '3.10.2'
path 'src/main/jni/CMakeLists.txt'
}
break
default:
println "**** unknown buildType value: " + buildType() + " ****"
}
} // externalNativeBuild
} // android // jm*20190405
//} // model
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:support-annotations:28.0.0'
testImplementation 'junit:junit:4.12'
testImplementation 'org.hamcrest:hamcrest-junit:2.0.0.0'
}
/**
* Workaround for using ProGuard with the experimental Gradle plugin.
*
* Trouble seems to be that unless process(Debug|Release)Resources task is needed, it is not created
* and VariantOutputScope.setProcessResourcesTask in TaskManager.createProcessResTask() is not
* called so when TaskManager.applyProguardConfig() calls
* BaseVariantOutputData.processResouresTask.getProguardOutputFile() it does so on a null object.
* So, by making transformClassesAndResourcesWithProguardFor(Debug|Release) depend on
* process(Debug|Release)Resources I force the task to be created
*
* More discussions here: https://issuetracker.google.com/issues/37079003
*/
tasks.all { task ->
def match = task.name =~ /^transformClassesAndResourcesWithProguardFor(.*)$/
if (match) {
task.dependsOn "process${match.group(1)}Resources"
return
}
}
// ToDo: get automatic build of .aar libraries working;
// currently, double-click on Gradle "wavvoxlibrary / Tasks / build / assemble"
}
I wanted to get the .aar file created automagically while building the signed app (.apk) without the extra step running gradle task wavvoxlibrary assemble.
What do I miss?
Thanks, jm.
I think you might have tried this, but still adding this as answer, if it does not help, will delete this answer.
Add your library module to your settings.gradle file.
include ':app', ':my-library-module'
https://developer.android.com/studio/projects/android-library#AddDependency

Loading shared libraries with Gradle 2.2.1

I'm trying to use a shared library, libavcodec-56.so, in my Android app and I can't find the way. I'm using Gradle 2.2.1 and Android Studio 1.0. What I have done so far is the following:
-I built libavcodec-56.so from source code using a NDK toolchain.
-I copied libavcodec-56.so into src/main/jniLibs/armeabi
-I'm able to create a .c file in the project and communicate with the java files using private native void nameOfTheNativeMethod()
-I can load some external libraries like ldLibs "m"
However, if I try to use #include <libavcodec/avcodec.h> I get the error
No such file or directory
#include <libavcodec/avcodec.h>
My gradle file looks like:
apply plugin: 'com.android.library'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
ndk {
moduleName "ffmpeg"
cFlags "-std=c99"
ldLibs "log", "m"
}
}
sourceSets.main {
jni.srcDirs = ["src/main/jni"];
//jniLibs.srcDirs = ['src/main/jniLibs'];
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
Any ideas?
Thanks in advance
the current NDK support with the gradle android plugin is incomplete and now deprecated. You can't have native dependencies between native local libraries.
The only solution with gradle right now is to directly use ndk-build with your own Makefiles to generate all your libs, with such build.gradle file:
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.library'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
sourceSets.main {
jni.srcDirs = [] //disable automatic ndk-build call
jniLibs.srcDir 'src/main/libs' //integrate your libs from libs instead of jniLibs
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
// call regular ndk-build(.cmd) script from app directory
task ndkBuild(type: Exec) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePath
} else {
commandLine 'ndk-build', '-C', file('src/main').absolutePath
}
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}

Using clang from NDK gradle build system

Using the old Makefile-based Android build system it is possible to using clang to compile sources by adding
NDK_TOOLCHAIN_VERSION=clang
Is there some way to achieve the same thing using the new gradle build system?
It's not directly possible for now, but you can still use the regular Makefiles from gradle:
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'android'
android {
...
sourceSets.main {
jniLibs.srcDir 'src/main/libs' //set jniLibs directory to ./libs
jni.srcDirs = [] //disable automatic ndk-build call
}
// call regular ndk-build(.cmd) script from main src directory
task ndkBuild(type: Exec) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePath
} else {
commandLine 'ndk-build', '-C', file('src/main').absolutePath
}
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
}
Newer NDK revisions default to Clang. However, you can explicitly request a toolchain using the -DANDROID_TOOLCHAIN switch.
As of the Android Gradle Plugin 2.2.0 things have become much better. You can also adopt cmake. You should look over the new documentation.
android {
...
defaultConfig {
...
// This block is different from the one you use to link Gradle
// to your CMake or ndk-build script.
externalNativeBuild {
// For ndk-build, instead use ndkBuild {}
cmake {
// Passes optional arguments to CMake.
arguments "-DANDROID_TOOLCHAIN=clang"
// Sets optional flags for the C compiler.
cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2"
// Sets a flag to enable format macro constants for the C++ compiler.
cppFlags "-D__STDC_FORMAT_MACROS"
}
}
}
buildTypes {...}
productFlavors {
...
demo {
...
externalNativeBuild {
cmake {
...
// Specifies which native libraries to build and package for this
// product flavor. If you don't configure this property, Gradle
// builds and packages all shared object libraries that you define
// in your CMake or ndk-build project.
targets "native-lib-demo"
}
}
}
paid {
...
externalNativeBuild {
cmake {
...
targets "native-lib-paid"
}
}
}
}
// Use this block to link Gradle to your CMake or ndk-build script.
externalNativeBuild {
cmake {...}
// or ndkBuild {...}
}
}

How to set standard c99 for compile android NDK project

I want to build small library which was written in C99 for Android, but compiler gave log as
note: use option -std=c99 or -std=gnu99 to compile your code
Where can I set it?
In your Android.mk add
LOCAL_CFLAGS += -std=c99
For example:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS += -std=c99
LOCAL_SRC_FILES := com_example_ndktest_TestLib.c
LOCAL_MODULE := com_example_ndktest_TestLib
include $(BUILD_SHARED_LIBRARY)
Make sure you add 'LOCAL_CFLAGS' after adding 'include $(CLEAR_VARS)'
An addendum to auselen's answer:
According to the NDK docs (kandroid.org mirror), LOCAL_CFLAGS will only apply to each module - if you want this behavior across an entire project, set APP_CFLAGS in Application.mk. Also, CFLAGS will cover C and C++ sources, CPPFLAGS covers C++ only.
As people may be arriving here looking to "set standard c99 for compile android NDK project", I think this needs an update.
For Android Studio 1.4 with Gradle 2.5, the c99 can be set in build.gradle
NOTE THAT THE CASE SENSITIVE SYNTAX WITHIN BUILD.GRADLE HAS CHANGED FROM cFlags TO CFlags (many examples online use the old syntax).
here is a build.gradle modified from the sample hello-jni project with C99 support added.
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.0"
defaultConfig.with {
applicationId = "com.example.hellojni"
minSdkVersion.apiLevel = 4
targetSdkVersion.apiLevel = 23
}
}
compileOptions.with {
sourceCompatibility=JavaVersion.VERSION_1_7
targetCompatibility=JavaVersion.VERSION_1_7
}
/*
* native build settings
*/
android.ndk {
moduleName = "hello-jni"
CFlags += "-std=c99"
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles += file('proguard-rules.txt')
}
}
android.productFlavors {
// for detailed abiFilter descriptions, refer to "Supported ABIs" #
// https://developer.android.com/ndk/guides/abis.html#sa
create("arm") {
ndk.abiFilters += "armeabi"
}
create("arm7") {
ndk.abiFilters += "armeabi-v7a"
}
create("arm8") {
ndk.abiFilters += "arm64-v8a"
}
create("x86") {
ndk.abiFilters += "x86"
}
create("x86-64") {
ndk.abiFilters += "x86_64"
}
create("mips") {
ndk.abiFilters += "mips"
}
create("mips-64") {
ndk.abiFilters += "mips64"
}
// To include all cpu architectures, leaves abiFilters empty
create("all")
}
}

Resources