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'
alex2k8
  • 42,496
  • 57
  • 170
  • 221

16 Answers16

103

You need to add

LOCAL_LDLIBS := -llog

to Android.mk

Kyle
  • 1,039
  • 1
  • 6
  • 2
  • 1
    correct. if there are multiple libraries, need to add this statement for each one of them (after CLEAR VARS) – user13107 Jan 19 '16 at 04:17
94

Try the following in your Android.mk file:

LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
Ryan Reeves
  • 10,209
  • 3
  • 42
  • 26
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"
        }
    }
}
BoredT
  • 1,590
  • 15
  • 19
35

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.

lewkka
  • 1,019
  • 15
  • 25
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'])
}
DroidlikeCode
  • 292
  • 3
  • 6
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).

DNax
  • 1,413
  • 1
  • 19
  • 29
  • 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://stackoverflow.com/a/37868829/10030695 – ManuelTS Jan 06 '19 at 15:02
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.

Sandeep
  • 18,356
  • 16
  • 68
  • 108
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.

SudoSURoot
  • 443
  • 3
  • 8
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

sethbabs
  • 41
  • 1
3

Add

LOCAL_SHARED_LIBRARIES:= \
        libbinder                       \
        liblog                          \

to Android.mk

2

-DCMAKE_CXX_FLAGS="-llog" helps me

James
  • 111
  • 9
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)
NickUnuchek
  • 11,794
  • 12
  • 98
  • 138
1

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,
        },
    },  
1

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

VinceStyling
  • 3,707
  • 3
  • 29
  • 44
  • 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! – ONE Feb 12 '23 at 19:14
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

0

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

jizhihaoSAMA
  • 12,336
  • 9
  • 27
  • 49
nld2019
  • 21
  • 2