Android NDK - Android studio gradle undefined reference to __android_log_write - android-studio

I am trying to debug a JNI C function by inserting log messages, but I can't get it to work. To start with I am just trying to modify the hello-jni example that comes with Android Studio. This is the modified code:
#include <string.h>
#include <jni.h>
#include <android/log.h>
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#if defined(__ARM_PCS_VFP)
#define ABI "armeabi-v7a/NEON (hard-float)"
#else
#define ABI "armeabi-v7a/NEON"
#endif
#else
#if defined(__ARM_PCS_VFP)
#define ABI "armeabi-v7a (hard-float)"
#else
#define ABI "armeabi-v7a"
#endif
#endif
#else
#define ABI "armeabi"
#endif
#elif defined(__i386__)
#define ABI "x86"
#elif defined(__x86_64__)
#define ABI "x86_64"
#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */
#define ABI "mips64"
#elif defined(__mips__)
#define ABI "mips"
#elif defined(__aarch64__)
#define ABI "arm64-v8a"
#else
#define ABI "unknown"
#endif
__android_log_write(ANDROID_LOG_ERROR, "TEST_TAG", "Error here");
return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");
}
And this is my Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
LOCAL_LDFLAGS := -llog
include $(BUILD_SHARED_LIBRARY)
When I use the ndk-build script the libhello-jni.so files get built no problem. When I try to build the project in Android Studio I get the following gradle error message
Information:Gradle tasks [:app:assembleDebug]
:app:preBuild
:app:compileDebugNdk
C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\obj/local/arm64-v8a/objs/hello-jni/C_\Android\projects\hello-jni\app\src\main\jni\hello-jni.o: In function `Java_com_example_hellojni_HelloJni_stringFromJNI':
hello-jni.c:(.text.Java_com_example_hellojni_HelloJni_stringFromJNI+0x24): undefined reference to `__android_log_write'
Error:error: ld returned 1 exit status
make.exe: *** [C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\obj/local/arm64-v8a/libhello-jni.so] Error 1
Error:Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.internal.LoggedErrorException: Failed to run command:
C:\Android\android-ndk-r10c\ndk-build.cmd NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\Android.mk APP_PLATFORM=android-19 NDK_OUT=C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\obj NDK_LIBS_OUT=C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\lib APP_ABI=all
Error Code:
2
Output:
C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\obj/local/arm64-v8a/objs/hello-jni/C_\Android\projects\hello-jni\app\src\main\jni\hello-jni.o: In function `Java_com_example_hellojni_HelloJni_stringFromJNI':
hello-jni.c:(.text.Java_com_example_hellojni_HelloJni_stringFromJNI+0x24): undefined reference to `__android_log_write'
collect2.exe: error: ld returned 1 exit status
make.exe: *** [C:\Android\projects\hello-jni\app\build\intermediates\ndk\debug\obj/local/arm64-v8a/libhello-jni.so] Error 1
Information:BUILD FAILED
Information:Total time: 3.297 secs
Information:2 errors
Information:0 warnings
Information:See complete output in console
I've tried the suggestions given in this question, but I still get the same error: What is the Log API to call from an Android JNI program?
What am I doing wrong?
I'm using Android Studio 0.8.9 and NDK r10c.

I found an answer after a bit more searching.
If I build the .so files using the ndk-build script on the command line and add
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
into my build.gradle file so gradle doesn't try to build the .so files it all then works. Looks like a problem with Android Studio-Gradle-NDK integration?
I found the answer here https://stackoverflow.com/a/21111458/4182796

Ugly workaround is to remove function call and rebuild sources just add this after includes :
#if 1
#undef __android_log_print
#define __android_log_print(...) {}
#endif

Related

Getting error LNK2019: unresolved external symbol when compiling SDL2 code in Windows using MSVC

The complete error output:
SDL2main.lib(SDL_windows_main.obj) : error LNK2019: unresolved external symbol __imp_CommandLineToArgvW referenced in function main_getcmdline
My compiler options:
cl -D WINDOWS -nologo -W4 -WX -wd4100 -Fe"output_file.exe" input_file.c SDL2.lib SDL2main.lib -I ./SDL2-2.0.12/include -link -LIBPATH:./SDL2-2.0.12/lib/x64 -SUBSYSTEM:CONSOLE
My input_file.c header and main function:
#ifdef LINUX
#include <SDL2/SDL.h> /* Comes with stdio.h and stdlib.h */
#elif WINDOWS
#include <stdio.h>
#include "SDL.h"
#endif
int main(int argc, char* argv[]) {
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_TIMER) != 0)
{
fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError());
return -1;
}
. . .
The SDL development folder used in the command line arguments is the development libraries zip file downloaded from libsdl.org
Why am I getting this error?
you also need to use the library called "shell32.lib"
cl -D WINDOWS -nologo -W4 -WX -wd4100 -Fe"output_file.exe" input_file.c shell32.lib SDL2.lib SDL2main.lib -I ./SDL2-2.0.12/include -link -LIBPATH:./SDL2-2.0.12/lib/x64 -SUBSYSTEM:CONSOLE

Building pjSip 2.5 - unable to undefined reference to 'pj_jni_jvm'

Trying to build pjSIP from sources for Android, using following guide - https://trac.pjsip.org/repos/wiki/Getting-Started/Android
Checkout sources of pjsip (2.5)
export ANDROID_NDK_ROOT=/home/dev/android/android-ndk-r9b
export TARGET_ABI=armeabi
export APP_PLATFORM=android-13
./configure-android --use-ndk-cflags --disable-video --disable-l16-codec --disable-gsm-codec --disable-g722-codec --disable-g7221-codec --disable-ssl --disable-ilbc-codec --disable-tls
configuration is completed successfully.
make dep && make clean && make
And I got following error - >
../src/pj/guid_android.c:43: error: undefined reference to 'pj_jni_jvm'
../src/pj/guid_android.c:117: error: undefined reference to 'pj_jni_jvm'
The command invoked by linked which leads to this error
/home/dev/android/android-ndk-r9b/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -o ../bin/pjlib-test-arm-unknown-linux-androideabi \
output/pjlib-test-arm-unknown-linux-androideabi/main.o output/pjlib-test-arm-unknown-linux-androideabi/activesock.o output/pjlib-test-arm-unknown-linux-androideabi/atomic.o output/pjlib-test-arm-unknown-linux-androideabi/echo_clt.o output/pjlib-test-arm-unknown-linux-androideabi/errno.o output/pjlib-test-arm-unknown-linux-androideabi/exception.o output/pjlib-test-arm-unknown-linux-androideabi/fifobuf.o output/pjlib-test-arm-unknown-linux-androideabi/file.o output/pjlib-test-arm-unknown-linux-androideabi/hash_test.o output/pjlib-test-arm-unknown-linux-androideabi/ioq_perf.o output/pjlib-test-arm-unknown-linux-androideabi/ioq_udp.o output/pjlib-test-arm-unknown-linux-androideabi/ioq_unreg.o output/pjlib-test-arm-unknown-linux-androideabi/ioq_tcp.o output/pjlib-test-arm-unknown-linux-androideabi/list.o output/pjlib-test-arm-unknown-linux-androideabi/mutex.o output/pjlib-test-arm-unknown-linux-androideabi/os.o output/pjlib-test-arm-unknown-linux-androideabi/pool.o output/pjlib-test-arm-unknown-linux-androideabi/pool_perf.o output/pjlib-test-arm-unknown-linux-androideabi/rand.o output/pjlib-test-arm-unknown-linux-androideabi/rbtree.o output/pjlib-test-arm-unknown-linux-androideabi/select.o output/pjlib-test-arm-unknown-linux-androideabi/sleep.o output/pjlib-test-arm-unknown-linux-androideabi/sock.o output/pjlib-test-arm-unknown-linux-androideabi/sock_perf.o output/pjlib-test-arm-unknown-linux-androideabi/ssl_sock.o output/pjlib-test-arm-unknown-linux-androideabi/string.o output/pjlib-test-arm-unknown-linux-androideabi/test.o output/pjlib-test-arm-unknown-linux-androideabi/thread.o output/pjlib-test-arm-unknown-linux-androideabi/timer.o output/pjlib-test-arm-unknown-linux-androideabi/timestamp.o output/pjlib-test-arm-unknown-linux-androideabi/udp_echo_srv_sync.o output/pjlib-test-arm-unknown-linux-androideabi/udp_echo_srv_ioqueue.o output/pjlib-test-arm-unknown-linux-androideabi/util.o -lpj-arm-unknown-linux-androideabi -nostdlib -L/home/dev/android/android-ndk-r9b/platforms/android-13/arch-arm/usr/lib -L/home/dev/android/android-ndk-r9b/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/ -lm /home/dev/android/android-ndk-r9b/platforms/android-13/arch-arm/usr/lib/crtbegin_so.o -lgnustl_static -lc -lgcc -ldl -lOpenSLES -llog -L/home/dev/android/pjproject-2.5/pjlib/lib -L/home/dev/android/pjproject-2.5/pjlib-util/lib -L/home/dev/android/pjproject-2.5/pjnath/lib -L/home/dev/android/pjproject-2.5/pjmedia/lib -L/home/dev/android/pjproject-2.5/pjsip/lib -L/home/dev/android/pjproject-2.5/third_party/lib -nostdlib -L/home/dev/android/android-ndk-r9b/platforms/android-13/arch-arm/usr/lib -L/home/dev/android/android-ndk-r9b/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/
Code of guid_androind.c
#include <pj/guid.h>
#include <pj/log.h>
#include <pj/string.h>
#include <jni.h>
extern JavaVM *pj_jni_jvm;
static pj_bool_t attach_jvm(JNIEnv **jni_env)
{
if ((*pj_jni_jvm)->GetEnv(pj_jni_jvm, (void **)jni_env,
JNI_VERSION_1_4) < 0)
{
if ((*pj_jni_jvm)->AttachCurrentThread(pj_jni_jvm, jni_env, NULL) < 0)
{
jni_env = NULL;
return PJ_FALSE;
}
return PJ_TRUE;
}
return PJ_FALSE;
}
#define detach_jvm(attached) \
if (attached) \
(*pj_jni_jvm)->DetachCurrentThread(pj_jni_jvm);
Struggling with this error for whole day, any clue is highly appreciated. Meanwhile I'm able to build version 2.3 without any errors, but not 2.5
I believe you missed a step.
https://trac.pjsip.org/repos/wiki/Getting-Started/Android#BuildPreparation
Set your config_site.h to the following:
/* Activate Android specific settings in the 'config_site_sample.h' */
#define PJ_CONFIG_ANDROID 1
#include <pj/config_site_sample.h>

Kernel module with multiple files - unknown symbol

Hello stackoverflowers :)
For the last several hours I've been trying to compile+load a multiple file module. The compilation emits a strange warning and the module fails to load. Here are the module, Makefile, compilation output and dmesg.
header:
// header.h
#ifndef _HEADER_H
#define _HEADER_H
void do_module_func(void);
void do_other_func(void);
#endif
'main' module file:
//mymodule.c
#include <linux/module.h>
#include <linux/kernel.h>
#include "header.h"
void do_module_func(void)
{
printk(KERN_INFO "module_func\n");
}
static int mymodule_init(void)
{
printk(KERN_INFO "Hello world\n");
do_other_func();
return 0;
}
module_init(mymodule_init);
static void mymodule_exit(void)
{
printk(KERN_INFO "Goodbye, cruel world\n");
}
module_exit(mymodule_exit);
MODULE_LICENSE("GPL")
other c file, which calls do_module_func() that sits in the 'main' module
//other_file.c
#include "header.h"
#include <linux/kernel.h>
void do_other_func(void)
{
printk(KERN_INFO "other_func\n");
do_module_func();
}
Makefile
//Makefile
obj-m := mymodule.o
mymodule-objs := other_file.o
CROSS:=arm-unknown-linux-gnueabi-
KERNEL:= ~/work/linux-davinci-2.6.38/
ARCH:=arm
PWD:=$(shell pwd)
all:
$(MAKE) CROSS_COMPILE=$(CROSS) ARCH=$(ARCH) -C $(KERNEL) M=$(PWD) modules
clean:
$(MAKE) CROSS_COMPILE=$(CROSS) ARCH=$(ARCH) -C $(KERNEL) M=$(PWD) clean
I'm cross compiling but I believe this shouldn't be a problem.
make output:
make CROSS_COMPILE....
make[1]: Entering directory .../linux-davinci-2.6.38
CC [M] .../other_file.o
LD [M] .../mymodule.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "do_module_func" [.../mymodule.o] undefined! <--- warning here
CC .../mymodule.mod.o
LD [M] .../mymodule.ko
make[1]: Leaving directory .../linux-davinci-2.6.38
insmod output:
can't insert 'mymodule.ko': unknown symbol in module, or unknown parameter
dmesg:
mymodule: Unknown symbol do_mdule_func (err 0)
Thus the module compiles with a (linkage?) warning and the module doesn't load.
Now, I see that in the make output there appears to be a linkage attempt after compiling other_file.c, but shouldn't there be a compilation of also mymodule.c before the linkage?
Thanks! :)
Turns out the problem was in the Makefile. The 'trick' is that you define in obj-m the module that will be compiled (into a .ko) and in the -objs you write all the source files.
Thus the definitions in this Makefile turn to:
obj-m := moduleko.o
moduleko-objs := other_file.o mymodule.o
and this is compiled into moduleko.ko.
This is because file_2 required file_1 symbol reference for building file_2 as LKM.
To overcome this, build file_1(LKM) and place the Module.symvers of file_1 in file_2 location. And build the file_2 again.
all:
$(MAKE) CROSS_COMPILE=$(CROSS) ARCH=$(ARCH) -C $(KERNEL) M=$(PWD) modules
instead try like this
$(MAKE) -C $(KERNEL) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS) M=$(PWD) /
this will run each file and links with object.hope this would solve your problem

How does APP_OPTIM manifest in code?

In Application.mk you can set:
APP_OPTIM := release
APP_OPTIM := debug
How can I test for release/debug build in C++?
I'm assuming there are defines so I've tried this, but only "NOT" messages are logged:
#ifdef RELEASE
LOGV("RELEASE");
#else
LOGV("NOT RELEASE");
#endif
#ifdef DEBUG
LOGV("DEBUG");
#else
LOGV("NOT DEBUG");
#endif
In android-ndk-r8b/build/core/add-application.mk we read:
ifeq ($(APP_OPTIM),debug)
APP_CFLAGS := -O0 -g $(APP_CFLAGS)
else
APP_CFLAGS := -O2 -DNDEBUG -g $(APP_CFLAGS)
endif
So, to answer your question: in NDK r8b (the latest for today) you can check
#ifdef NDEBUG
// this is "release"
#else
// this is "debug"
#endif
But you can add any other compilation flags through your Android.mk or Application.mk depending on $(APP_OPTIM), if you want.

Visual C++ MySQL Connector/C errors?

My source code results in this:
// MySQL.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <winsock.h>
#include <string>
#include <sstream>
#include <stdio.h>
#include <mysql.h>
#define TABLE_OF_INTEREST "some_table"
#define SERVER_NAME "mysql_server"
#define DB_USER "user"
#define DB_USERPASS "pa55w0rd"
#define DB_NAME "db_name"
#define NEWLINE "\n"
using namespace std;
int main()
{
MYSQL *hnd = NULL; // mysql connection handle
const char *sinf = NULL; // mysql server information
if(!mysql_real_connect(hnd, SERVER_NAME, DB_USER, DB_USERPASS, DB_NAME, 0, NULL, 0)
cout << "Something happened.";
return 0;
}
error:
1>------ Build started: Project: MySQL, Configuration: Release Win32 ------
1> MySQL.cpp
1>MySQL.obj : error LNK2001: unresolved external symbol _mysql_real_connect#32
1>c:\users\josiah\documents\visual studio 2010\Projects\MySQL\Release\MySQL.exe : fatal error LNK1120: 1 unresolved external
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I don't think there issues with the source, I just need help on how to figure out where the problem is.
You're missing a reference to a lib. The C connector should have come with a .lib, add it to the additional input for the linker

Resources