การอ้างอิงที่ไม่ได้กำหนดถึง `__android_log_print '


100

ไฟล์ make ของฉันมีอะไรผิดปกติ

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'

คำตอบ:


89

ลองทำสิ่งต่อไปนี้ในAndroid.mkไฟล์ของคุณ:

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

1
อะไรคือสิ่งที่จำเป็นในการเพิ่มสิ่งนี้? คุณช่วยอธิบายรายละเอียดได้ไหม
Dhasneem

มันเพิ่มไลบรารี android ลงในไฟล์ make - และมันก็ใช้ได้สำหรับฉันด้วย
gheese

9
-L ไม่จำเป็น โปรดยอมรับคำตอบอื่นแทน
Jeff Allen

5
หากใช้การรวม Gradle NDK ใหม่ใน Android Studio 1.3 คุณต้องเพิ่มldLibs = ["android", "log"]ตัวเลือก android.ndk ของคุณ
Stephen Kaiser

1
จะเกิดอะไรขึ้นถ้าเราไม่ได้ใช้ Android.mk
cagdas

99

คุณต้องเพิ่ม

LOCAL_LDLIBS := -llog

เป็น Android.mk


1
แก้ไข. หากมีหลายไลบรารีต้องเพิ่มคำสั่งนี้สำหรับแต่ละไลบรารี (หลัง CLEAR VARS)
user13107

86

หากคุณใช้ Android Studio และ gradle จะไม่สนใจ Android.mk เพิ่มสิ่งนี้ในไฟล์ build.gradle ของคุณ:

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

7
ฉันสงสัยว่าเอกสารนี้อยู่ที่ไหน ฉันกำลังมองหาสิ่งนี้เช่นกัน
Randy Sugianto 'Yuku'

1
ผมได้รับ "การอ้างอิงที่ไม่ได้กำหนดที่จะ '__android_log_print" ldLibsก่อนที่ผมจะได้เพิ่ม ขอบคุณ.
Denis Kniazhev

2
การเพิ่มสิ่งนี้แก้ไขให้ฉัน ตรวจสอบให้แน่ใจว่าได้เพิ่มndkส่วนใน build.gradle ภายในappโฟลเดอร์แทนที่จะเป็นส่วนในโฟลเดอร์โครงการ (ชื่อโมดูล)
mathiass

ในขณะที่ Gradle 2.5 ใช้ 'ldLibs + = "log"' การเปลี่ยนแปลงไวยากรณ์เล็กน้อย
Lorne K

15
สิ่งนี้ไม่ได้ผลสำหรับฉัน นี่คือสิ่งที่ฉันต้องทำ:ldLibs.addAll(["android", "log"])
ᴛʜᴇᴘᴀᴛᴇʟ

29

สำหรับ Android Studio 2.2 และ tools.build:gradle:2.2.0 โดยใช้ CMake เพิ่มหรือแก้ไขแถวใน CMakeLists.txt:

target_link_libraries(<your_library_name> 
                      android 
                      log)

นั่นคือการเชื่อมต่อห้องสมุดบันทึกกับของคุณ


16

หากคุณอัปเกรดเป็น Android Studio 2.1 คำตอบข้างต้นใช้ไม่ได้ต้องใช้ ldLibs.add () เพื่อโหลด lib ดังต่อไปนี้:

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

คำตอบที่ทันสมัยที่สุด (ปลายปี 2017)
Edgar Aroutiounian

7

เราสามารถเชื่อมโยงไลบรารีที่ใช้ร่วมกันใน Android ได้ 3 วิธี ใน 3 กรณีด้านล่างนี้ควรเพิ่มบรรทัดที่กล่าวถึงAndroid.mk

นี่คือสามวิธี

1. LOCAL_LDLIBS way
LOCAL_LDLIBS := -llog

ด้วยเหตุผลบางประการหาก 1 ใช้งานไม่ได้ (ไม่ได้ผลสำหรับฉัน) คุณสามารถลอง 2 วิธีด้านล่างนี้

2. LOCAL_LDFLAGS way
LOCAL_LDFLAGS := -llog

3. LOCAL_SHARED_LIBRARIES way
LOCAL_SHARED_LIBRARIES += liblog

แน่นอนคุณต้องรวม#include <android/log.h> ไว้ในไฟล์ C / H ของคุณด้วย


6

ในกรณีที่โครงการที่คุณกำลังดำเนินการมีลักษณะดังต่อไปนี้ที่แตกต่างจากคำตอบ 'มาตรฐาน' อื่น ๆ :

  • ไม่ได้ใช้ Android Studio
  • ไม่ใช้ gradle และ CMake ในตัว
  • ไม่มีการใช้ Android.mk หรือ Application.mk เลยในการสร้าง
  • การใช้ CMake และ toolchain โดยตรง (บางทีโครงการของคุณอาจใช้ Qt และไม่ใช้ QtCreator ก็ได้)

การใช้งานtarget_link_librariesต่อไปนี้ทำให้:

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

เป็นTARGET_NAMEชื่อของเป้าหมายที่จะสร้าง (มีชุดมันขึ้นมาก่อนด้วยadd_libraryหรือadd_executable)

find_libraryมีความสำคัญเท่าเทียมกันกับการตั้งค่า toolchain อย่างถูกต้อง (ใช้ toolchain ที่จัดเตรียมโดย Android SDK ANDROID_SDK_HOME/cmake/<version>/android.toolchain.cmakeเพื่อตั้งค่าCMAKE_SYSROOTที่ใช้โดยfind_คำสั่ง)


ทางออกเดียวที่ช่วยฉันได้! ขอบคุณมากฉันจะขยายมันโดยการทดสอบว่าพบไลบรารีสำหรับข้อเสนอแนะที่ดีกว่าสำหรับนักพัฒนาหรือไม่ที่นี่stackoverflow.com/a/37868829/10030695
ManuelTS

4

ใช่คุณไม่จำเป็นต้องเพิ่ม: LOCAL_LDLIBS := -llogเป็นคำตอบอื่น ๆ / ความคิดเห็นได้ระบุ แต่คำถามเดิมไม่ได้ระบุว่าเขาใช้ห้องสมุด JNI เป็น: หรือเป็นLOCAL_JNI_SHARED_LIBRARIESLOCAL_REQUIRED_MODULES

ฉันสามารถพูดได้อย่างแน่นอนว่าเขาใช้มันเป็น: LOCAL_REQUIRED_MODULESเพราะLOCAL_EXPORT_LDLIBS := -llogในคำถาม ... เว้นแต่จะมีการเพิ่มหลังจากแก้ไข

หากคุณใช้LOCAL_REQUIRED_MODULESไลบรารีที่ใช้ร่วมกันจะถูกติดตั้งใน / system / lib แทนที่จะเป็นใน apk เนื่องจากเป็นโมดูลที่จำเป็น ดังนั้นคุณจะต้องเพิ่มLOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llogแทนเพียงLOCAL_LDLIBS := -llogเพื่อที่ว่าเมื่อสร้างระบบคือการสร้างและเชื่อมโยงห้องสมุดที่ใช้ร่วมกัน JNI ก็จะมีคำจำกัดความในสถานที่ที่ถูกต้องพร้อมที่จะสร้างขึ้นภายใต้-llog มิฉะนั้นคุณจะยังคงได้คำตอบเดียวกันแม้ว่าคุณจะเพิ่ม$OUT/root/system/libLOCAL_LDLIBS := -llog

ดังนั้นผู้ที่แสดงความคิดเห็นว่า-Lไม่จำเป็นและคำตอบอื่นถูกต้องจริงๆแล้วพวกเขาไม่ถูกต้องในสถานการณ์นี้


ขอบคุณที่อธิบายว่าเกิดอะไรขึ้น!
Richard

4

แทนด้วย

หากใช้การผสานรวม Gradle NDK ใหม่ใน Android Studio 1.3 คุณต้องเพิ่ม ldLibs = ["android", "log"] ในตัวเลือก android.ndk - Stephen Kaiser 24 ก.ย. เวลา 4:20 น.

ใช้ldLibs.addAll(["android", "log"])สำหรับปลั๊กอินทดลอง



1

สิ่งนี้ช่วยฉันได้:

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)

0

ใน android studio เวอร์ชัน 2.2 ขึ้นไปมีการรองรับ CPP ในตัวเมื่อคุณสร้างโปรเจ็กต์ใหม่ นอกจากนี้ liblog.so ยังรวมอยู่โดยค่าเริ่มต้น ไม่มีอะไรต้องทำนอกเหนือจากการรวมไฟล์ส่วนหัว (android / log.h)

แอป Checkout / CMakeLists.txt ที่สตูดิโอสร้างขึ้นเมื่อเราสร้างโครงการสตูดิโอ Android ใหม่ เราจะเห็นว่าบล็อก find_library () และ target_link_libraries () สำหรับ loglib มีอยู่แล้ว

นอกจากนี้ควรให้ความสนใจกับไวยากรณ์ของฟังก์ชันด้วย มันควรจะเป็น:

__android_log_print (ลำดับความสำคัญ int, แท็ก const char *, const char * fmt, ... );

ในกรณีของฉันฉันไม่ได้ใช้พารามิเตอร์แท็กและลงเอยด้วยการใช้เวลา 3 วันในการหาค่า

เพิ่มเติมเกี่ยวกับ CMake: เพิ่มรหัส C และ C ++ ในโครงการของคุณ



0

เพิ่มลง LOCAL_SHARED_LIBRARIES:= liblog ใน Android.mk สามารถแก้ปัญหา isuue ของฉันได้ เนื่องจาก__android_log_printถูกกำหนดไว้ใน libLog


0

ในการสร้างด้วย Android.bp ให้ทำตามวิธีแก้ปัญหาด้านล่าง:

ในสิ่งนี้ - android_log_printถูกกำหนดไว้ใน NDK ดังนั้นจึงมีไลบรารีอยู่แล้ว ใช้ไลบรารี " liblog " โดยใช้แท็กshared_libsอ้างอิงโค้ดด้านล่าง:

target: {
        android: {
            cppflags: [
                "-g",
                "-DUSE_LIBLOG",
            ],
            shared_libs: ["liblog"], // can use other dependency if required.
        },
        darwin: {
            enabled: false,
        },
    },  
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.