undefined reference to `__android_log_print'

AndroidJava Native-InterfaceLoggingAndroid Ndk

Android Problem Overview


What is wrong with my make file?

Android.mk

LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
LOCAL_MODULE    := foo
LOCAL_SRC_FILES := foo.c
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)

foo.c

#include <string.h>
#include <jni.h>
#include <android/log.h>

#define  LOG_TAG    "foo"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
 
void test() {
    LOGI("test");
}

ndk-build

foo.c:9: undefined reference to `__android_log_print'

Android Solutions


Solution 1 - Android

You need to add

LOCAL_LDLIBS := -llog

to Android.mk

Solution 2 - Android

Try the following in your Android.mk file:

LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog

Solution 3 - Android

If you use Android Studio and gradle, it ignores Android.mk. Add this to your build.gradle file:

android {
    defaultConfig {
        ndk {
            moduleName "your_module_name"
            ldLibs "log"
        }
    }
}

Solution 4 - Android

For Android Studio 2.2 and tools.build:gradle:2.2.0 using CMake add or edit row in CMakeLists.txt:

target_link_libraries(<your_library_name> 
                      android 
                      log)

Thats connecting log library to yours.

Solution 5 - Android

If you upgrade to Android Studio 2.1, above answers do not work, need use ldLibs.add() to load the lib as below:

android.ndk {
    moduleName = "[the_module_name]"
    ldLibs.addAll(['android', 'log'])
}

Solution 6 - Android

In case the project you are working on has the following characteristics that differ from other 'standard' answers:

  • Not using Android Studio
  • Not using gradle and the integrated CMake
  • No Android.mk or Application.mk used at all for build
  • Using CMake and the toolchain directly (maybe your project is Qt based and without using QtCreator neither)

The following target_link_libraries usage makes it:

    find_library(ANDROID_LOG_LIB log)
    target_link_libraries(${TARGET_NAME} ${ANDROID_LOG_LIB})

Being TARGET_NAMEthe name of the target to build (having set it up before with add_library or add_executable).

find_library is equally important as well as setting up the toolchain properly (use the toolchain provided by Android SDK at ANDROID_SDK_HOME/cmake/<version>/android.toolchain.cmake so it sets up CMAKE_SYSROOTwhich is used by find_ commands).

Solution 7 - Android

We can link a shared library in Android in 3 ways. In below 3 cases, the lines mentioned should be added in Android.mk

So here are the three ways.

1. LOCAL_LDLIBS way
LOCAL_LDLIBS := -llog

For some reason if 1 doesnt work(it did not work for me), You can try below 2 ways

2. LOCAL_LDFLAGS way
LOCAL_LDFLAGS := -llog

3. LOCAL_SHARED_LIBRARIES way
LOCAL_SHARED_LIBRARIES += liblog

Of course you also need to include #include <android/log.h> in your C/H file.

Solution 8 - Android

Yes, you do need to add: LOCAL_LDLIBS := -llog as the other answers/comments have specified, however the original question did not specify if he use the jni library as: LOCAL_JNI_SHARED_LIBRARIES or as LOCAL_REQUIRED_MODULES.

I can pretty much say for sure that he has it used it as: LOCAL_REQUIRED_MODULES because of the LOCAL_EXPORT_LDLIBS := -llog in the question... unless that was added after an edit.

If you use LOCAL_REQUIRED_MODULES the shared library is installed in /system/lib instead of into the apk, because it is a required module. Therefore you will need to add LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog instead of just LOCAL_LDLIBS := -llog so that when the build system is building & linking the jni shared library, it will have the -llog definitions in the correct place, available to be built under $OUT/root/system/lib. Otherwise you will continue to get the same answer, even if you only add LOCAL_LDLIBS := -llog.

So, those who commented that the -L is not needed, and the other answer was correct, they were actually incorrect in this situation.

Solution 9 - Android

In lieu with

> If using the new Gradle NDK integration in Android Studio 1.3, you need to add ldLibs = ["android", "log"] to your android.ndk options – Stephen Kaiser Sep 24 at 4:20

use ldLibs.addAll(["android", "log"]) for the experimental plugin

Solution 10 - Android

Add

LOCAL_SHARED_LIBRARIES:= \
        libbinder                       \
        liblog                          \

to Android.mk

Solution 11 - Android

-DCMAKE_CXX_FLAGS="-llog" helps me

Solution 12 - Android

This helped for me:

Android.mk

    LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE    := nativeDemo
LOCAL_SRC_FILES := main.cpp
LOCAL_LDLIBS += -llog

include $(BUILD_SHARED_LIBRARY)

Solution 13 - Android

In the android studio version 2.2 and higher, there is inbuilt support for CPP when you create a new project. Also, the liblog.so is included by default. Nothing to be done apart from including the header file (android/log.h).

Checkout app/CMakeLists.txt that is created by the studio when we create new android studio project. We can see that the find_library() block and target_link_libraries() block for loglib are already present.

Also, pay attention towards the function syntax. It should be:

> **__android_log_print (int priority, const char tag, const char fmt,...);

In my case, I had left out tag parameter and ended up spending good 3 days in figuring it out.

More about CMake: Add C and C++ Code to Your Project

Solution 14 - Android

add LOCAL_SHARED_LIBRARIES:= liblog to Android.mk can solve my isuue. This is because the __android_log_print is defined in libLog

Solution 15 - Android

TO build with Android.bp, follow the below solution:

In this -android_log_print is defined in NDK, so for this, there is already a library is available. Use "liblog" library using shared_libs tag, take reference of the below code:

target: {
        android: {
            cppflags: [
                "-g",
                "-DUSE_LIBLOG",
            ],
            shared_libs: ["liblog"], // can use other dependency if required.
        },
        darwin: {
            enabled: false,
        },
    },	

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionalex2k8View Question on Stackoverflow
Solution 1 - AndroidKyleView Answer on Stackoverflow
Solution 2 - AndroidRyan ReevesView Answer on Stackoverflow
Solution 3 - AndroidBoredTView Answer on Stackoverflow
Solution 4 - AndroidlewkkaView Answer on Stackoverflow
Solution 5 - AndroidDroidlikeCodeView Answer on Stackoverflow
Solution 6 - AndroidDNaxView Answer on Stackoverflow
Solution 7 - AndroidSandeepView Answer on Stackoverflow
Solution 8 - AndroidSudoSURootView Answer on Stackoverflow
Solution 9 - AndroidsethbabsView Answer on Stackoverflow
Solution 10 - Androiduser3535040View Answer on Stackoverflow
Solution 11 - AndroidJamesView Answer on Stackoverflow
Solution 12 - AndroidNickUnuchekView Answer on Stackoverflow
Solution 13 - AndroidPraveen Kumar KRView Answer on Stackoverflow
Solution 14 - Androidnld2019View Answer on Stackoverflow
Solution 15 - AndroidBudhdi SharmaView Answer on Stackoverflow