Android NDK JNI build error: undefined reference to 'function_name'
Android NDK JNI build error: undefined reference to 'function_name'
我有一个简单的 Android NDK 代码和 JNI。不幸的是,由于错误,它没有构建:
error: undefined reference to 'get_hello()'
我已经检查了其他 Whosebug 问题,同样的错误。但其中 none 个与我的文件结构相似。
文件结构
├── 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} )
原生-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
库在 linking 期间失败,因为您没有告诉它在哪里可以找到 get_hello()
的定义。您需要 link 包含 get_hello()
定义的库到 native-lib
库。
您的代码有这一行:
target_link_libraries( hihi-lib
hello-lib
native-lib
${log-lib} )
其中 link 将所有其他库添加到 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} )
请注意,您应该始终使用范围运算符(例如PUBLIC
、PRIVATE
等)来指定如何 CMake 在使用 target_link_libraries
.
时应该 link 库
我有一个简单的 Android NDK 代码和 JNI。不幸的是,由于错误,它没有构建:
error: undefined reference to 'get_hello()'
我已经检查了其他 Whosebug 问题,同样的错误。但其中 none 个与我的文件结构相似。
文件结构
├── 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} )
原生-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
库在 linking 期间失败,因为您没有告诉它在哪里可以找到 get_hello()
的定义。您需要 link 包含 get_hello()
定义的库到 native-lib
库。
您的代码有这一行:
target_link_libraries( hihi-lib
hello-lib
native-lib
${log-lib} )
其中 link 将所有其他库添加到 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} )
请注意,您应该始终使用范围运算符(例如PUBLIC
、PRIVATE
等)来指定如何 CMake 在使用 target_link_libraries
.