Android NDK JNI 构建错误 : undefined reference to 'function_name'

标签 android c cmake android-ndk java-native-interface

我有一个带有 JNI 的简单 Android NDK 代码。不幸的是,由于错误,它没有构建:

error: undefined reference to 'get_hello()' 

我检查了其他 Stackoverflow 问题,也有同样的错误。但它们都与我的文件结构相似。

文件结构

├── app
│   └── src
│       ├── main
│       │   ├── AndroidManifest.xml
│       │   ├── cpp
│       │   │   ├── CMakeLists.txt
│       │   │   ├── native-lib.cpp
│       │   │   ├── my_hello
│       │   │   │   ├── hello.c
│       │   │   │   └── hello.h
│       │   │   └── your_hello
│       │   │       ├── hihi.c
│       │   │       └── hihi.h
│       │   ├── java
│       │   │   └── com
│       │   │       └── example
│       │   │           └── myapplication
│       │   │               └── MainActivity.java

CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

add_library( native-lib
             SHARED
             native-lib.cpp )

add_library( hello-lib
             STATIC
             my_hello/hello.c )

add_library( hihi-lib
             STATIC
             your_hello/hihi.c )

include_directories( my_hello/ )
include_directories( your_hello/ )

find_library( log-lib
              log )

target_link_libraries( hihi-lib
                       hello-lib
                       native-lib

                       ${log-lib} )

native-lib.cpp

#include <jni.h>

#include "my_hello/hello.h"

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {

    return env->NewStringUTF(get_hello());
}

my_hello/hello.h

#ifndef MY_APPLICATION_HELLO_H
#define MY_APPLICATION_HELLO_H

const char *get_hello();

#endif //MY_APPLICATION_HELLO_H

my_hello/hello.c

#include "hello.h"
#include "../your_hello/hihi.h"

const char *get_hello() {
    return get_your_hello();
}

your_hello/hihi.h

#ifndef MY_APPLICATION_HIHI_H
#define MY_APPLICATION_HIHI_H

const char* get_your_hello();

#endif //MY_APPLICATION_HIHI_H

your_hello/hihi.c

#include "hihi.h"

const char* get_your_hello() {
    return "your hello";
}

Cmake 错误

> Task :app:externalNativeBuildDebug FAILED
Build native-lib_armeabi-v7a
ninja: Entering directory `/home/myname/AndroidStudioProjects/MyApplication/app/.cxx/cmake/debug/armeabi-v7a'
[1/1] Linking CXX shared library /home/myname/AndroidStudioProjects/MyApplication/app/build/intermediates/cmake/debug/obj/armeabi-v7a/libnative-lib.so
FAILED: /home/myname/AndroidStudioProjects/MyApplication/app/build/intermediates/cmake/debug/obj/armeabi-v7a/libnative-lib.so 
: && /home/myname/Android/Sdk/ndk/21.3.6528147/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=armv7-none-linux-androideabi23 --gcc-toolchain=/home/myname/Android/Sdk/ndk/21.3.6528147/toolchains/llvm/prebuilt/linux-x86_64 --sysroot=/home/myname/Android/Sdk/ndk/21.3.6528147/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security   -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id -Wl,--fatal-warnings -Wl,--exclude-libs,libunwind.a -Wl,--no-undefined -Qunused-arguments -shared -Wl,-soname,libnative-lib.so -o /home/myname/AndroidStudioProjects/MyApplication/app/build/intermediates/cmake/debug/obj/armeabi-v7a/libnative-lib.so CMakeFiles/native-lib.dir/native-lib.cpp.o  -latomic -lm && :
/home/myname/AndroidStudioProjects/MyApplication/app/src/main/cpp/native-lib.cpp:10: error: undefined reference to 'get_hello()'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

最佳答案

您的 native-lib 库在链接期间失败,因为您没有告诉它在哪里可以找到 get_hello() 的定义。您需要将包含 get_hello() 定义的库链接native-lib 库。

您的代码有这一行:

target_link_libraries( hihi-lib
                       hello-lib
                       native-lib
                       ${log-lib} )

它将所有其他库链接到 hihi-lib 库。这可能不是您想要做的。

查看您的代码,native-lib 依赖于 hello-lib,而 hello-lib 依赖于 hihi-lib 。因此,您需要使用 target_link_libraries() 命令指定这些依赖项:

# Link hihi-lib to hello-lib.
target_link_libraries( hello-lib PUBLIC hihi-lib )

# Link hello-lib (and others) to native-lib, hihi-lib will be propagated via hello-lib.
target_link_libraries( native-lib PRIVATE hello-lib ${log-lib} )

请注意,您应该始终使用作用域运算符(例如PUBLICPRIVATE等)来指定如何 CMake 在使用 target_link_libraries 时应该链接库.

关于Android NDK JNI 构建错误 : undefined reference to 'function_name' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62964094/

相关文章:

c - 初级 C 数组和递增

c - 以编程方式创建 VS 解决方案/项目文件

qt - 使用 CMake 检测 Qt5

python - 如何设置python的默认库路径

android - 反转drawable的颜色

java - W/System.err : org. json.JSONException : Value <br of type java. lang.String 无法转换为 JSONObject

android - 720x1280 设备的布局文件夹名称,如三星 Galaxy S3

android - 如何将多部分表单数据和图像上传到android中的服务器?

c - C 中的 BinarySearchTree - deleteWord - 保留对从树中删除的元素的引用

c++ - 如何使用 MinGW 生成器从 powershell 调用 cmake