undefined reference to `__android_log_print'
Asked Answered
M

16

106

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'
Missioner answered 15/12, 2010 at 23:15 Comment(1)
Modify line LOCAL_EXPORT_LDLIBS := -llog to LOCAL_LDLIBS := -llogSpree
P
94

Try the following in your Android.mk file:

LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
Parentage answered 15/12, 2010 at 23:29 Comment(10)
What is the necessary to add this? Would you Please explain in detail?Montgomery
its adding an android library to the make file - and it worked for me tooRijeka
the -L is unnecessary. Please accept the other answer instead.Coating
Why is the -L unnecessary?Dragonhead
The -L is useful when you have subdirectories that build libraries. Otherwise, just having -llog works fine.Entoblast
The -L flag specifies an additional path that the linker should use to search for libraries. If liblog doesn't reside under $(SYSROOT)/usr/lib then it is unnecessary.Trapshooting
If using the new Gradle NDK integration in Android Studio 1.3, you need to add ldLibs = ["android", "log"] to your android.ndk optionsDian
@StephenKaiser unbelievable, I don't know how I noticed your comment, but you're THE SAVIORYoungran
What if we are not using Android.mk's ?Gapes
@Gapes for AS 2.2, stable plugin and CMake look at my answerLeslielesly
O
103

You need to add

LOCAL_LDLIBS := -llog

to Android.mk

Odessaodetta answered 31/1, 2011 at 5:46 Comment(1)
correct. if there are multiple libraries, need to add this statement for each one of them (after CLEAR VARS)Tayib
P
94

Try the following in your Android.mk file:

LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
Parentage answered 15/12, 2010 at 23:29 Comment(10)
What is the necessary to add this? Would you Please explain in detail?Montgomery
its adding an android library to the make file - and it worked for me tooRijeka
the -L is unnecessary. Please accept the other answer instead.Coating
Why is the -L unnecessary?Dragonhead
The -L is useful when you have subdirectories that build libraries. Otherwise, just having -llog works fine.Entoblast
The -L flag specifies an additional path that the linker should use to search for libraries. If liblog doesn't reside under $(SYSROOT)/usr/lib then it is unnecessary.Trapshooting
If using the new Gradle NDK integration in Android Studio 1.3, you need to add ldLibs = ["android", "log"] to your android.ndk optionsDian
@StephenKaiser unbelievable, I don't know how I noticed your comment, but you're THE SAVIORYoungran
What if we are not using Android.mk's ?Gapes
@Gapes for AS 2.2, stable plugin and CMake look at my answerLeslielesly
S
86

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"
        }
    }
}
Scum answered 4/12, 2014 at 14:58 Comment(6)
I wonder where this is documented. I was looking for this as well.Plunder
I was getting "undefined reference to '__android_log_print'" before I have added ldLibs. Thanks.Winifredwinikka
Adding this fixed it for me. Just make sure to add the ndk part in the build.gradle inside the app folder instead of the one in the project folder (module name).Flitting
As of Gradle 2.5 use 'ldLibs += "log"' slight syntax changeWhole
this did NOT work for me. this is what I had to do: ldLibs.addAll(["android", "log"])Depraved
Using the latest versions of everything as of 21-Jun-2016, the ldLibs "log" line fails for me with Cause: org.gradle.api.internal.ExtensibleDynamicObject. The ldLibs.addAll statement in the above comment works. I also tried +=, but that failed in a different way.Wilbert
L
36

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.

Leslielesly answered 9/11, 2016 at 17:22 Comment(0)
H
16

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'])
}
Handyman answered 5/5, 2016 at 16:49 Comment(1)
best modern (late 2017) answerMagee
O
12

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).

Oskar answered 14/12, 2017 at 0:5 Comment(1)
Only solution that helped me! Thanks a ton, I would extend it by a test if the library was found for better feedback to the developer as here https://mcmap.net/q/205399/-how-to-test-if-cmake-found-a-library-with-find_libraryBarbershop
W
7

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.

Wizardry answered 9/10, 2014 at 6:16 Comment(0)
Z
4

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.

Zarger answered 5/9, 2014 at 21:17 Comment(0)
P
4

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

Pad answered 27/11, 2015 at 1:40 Comment(0)
F
4

for the case who use CMakeLists.txt to make

    externalNativeBuild {
        cmake {
            path 'src/main/cpp/CMakeLists.txt'
        }
    }

just add -llog into target_link_libraries:

target_link_libraries(<your_library_name> -llog)

the env I used are :

gradle-6.5-all.zip

classpath 'com.android.tools.build:gradle:4.1.1'

Android Studio Arctic Fox | 2020.3.1 Patch 1 Build #AI-203.7717.56.2031.7621141, built on August 8, 2021

Fi answered 26/10, 2022 at 3:55 Comment(1)
After scouring for hours, found the ONLY solution (your post) to make it work for CMakeLists.txt (all existing sources are for Android.mk). Added "target_link_libraries(native-lib -llog)" to CMakeLists.txt and PRESTO! I'm crying. Thank you!Derouen
B
3

Add

LOCAL_SHARED_LIBRARIES:= \
        libbinder                       \
        liblog                          \

to Android.mk

Brose answered 15/4, 2014 at 8:24 Comment(1)
Why? Please explain why this answer should work for the asker.Lysippus
S
2

-DCMAKE_CXX_FLAGS="-llog" helps me

Sharpeared answered 17/3, 2020 at 9:47 Comment(0)
H
2

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,
        },
    },  
Hairstreak answered 31/7, 2020 at 12:56 Comment(0)
G
1

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)
Gironde answered 7/8, 2015 at 12:12 Comment(0)
A
0

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

Ault answered 27/9, 2017 at 16:23 Comment(0)
P
0

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

Parr answered 3/7, 2020 at 6:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.