我正试图设置
HelloJNI tutorial
文件结构如下:
âââ app
â  âââ libs
â  â  âââ bthread
â  â  â  âââ CMakeLists.txt
â  â  â  âââ include
â  â  âââ cuse
â  â  â  âââ CMakeLists.txt
â  â  â  âââ include
â  â  âââ fuse
â  â  âââ CMakeLists.txt
â  â  âââ include
â  â  âââ modules
â  âââ src
â  âââ main
â  â  âââ cpp
â  â  â  âââ hello-jni.cpp
â  â  â  âââ daemon.cpp
这个
CMakeLists.txt
中库的文件
libs
cmake_minimum_required(VERSION 3.4.1)
# Create a library called "Hello" which includes the source file "hello.cxx".
# The extension is already found. Any number of sources could be listed here.
include_directories(
${CMAKE_SOURCE_DIR}/lib/fuse/include
${CMAKE_SOURCE_DIR}/lib/cuse/include)
add_library (cuse SHARED
cuse.c)
add_executable (cuse_client cuse_client.c)
# Make sure the compiler can find include files for our Hello library
# when other libraries or executables link to Hello
target_include_directories(cuse PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
set_target_properties(cuse PROPERTIES PUBLIC_HEADER "include/cuse.h")
target_link_libraries( # Specifies the target library.
cuse
fuse)
install(TARGETS cuse
EXPORT cuse-targets
PUBLIC_HEADER DESTINATION include
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
install(EXPORT cuse-targets
NAMESPACE cuse::
FILE cuse-config.cmake
DESTINATION lib/cmake/cuse)
对于每个库。
cuse
取决于
fuse
取决于
bthread
,并将每个库设置为“共享”
add_library()
这个
app/CMakeLists.txt
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
project(app)
include_directories(
${CMAKE_SOURCE_DIR}/libs/cuse/include
${CMAKE_SOURCE_DIR}/libs/fuse/include)
add_subdirectory(libs/bthread)
add_subdirectory(libs/fuse)
add_subdirectory(libs/cuse)
#find_library(LIB_CUSE NAMES cuse libcuse HINTS libs libs/cuse)
add_library(hello-jni SHARED src/main/cpp/hello-jni.cpp
src/main/cpp/daemon.cpp)
target_link_libraries( # Specifies the target library.
hello-jni
${LIB_CUSE})
cuse.c
. 例如:
src/main/cpp/daemon.cpp.o: In function `start_cuse_server()':
src/main/cpp/daemon.cpp:65: undefined reference to `cusexmp_process_arg(void*, char const*, int, fuse_args*)'
我改了
app/CMakeLists.txt' several times to try and link to the
头文件
cuse.h
:
#ifndef CUSE_H
#define CUSE_H
#include "cuse_lowlevel.h"
#include <fuse_opt.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "ioctl.h"
#define CUSEXMP_OPT(t, p) { t, offsetof(struct cusexmp_param, p), 1 }
void *cusexmp_buf;
size_t cusexmp_size;
int cusexmp_resize(size_t new_size);
void cusexmp_open(fuse_req_t req, struct fuse_file_info *fi);
void cusexmp_read(fuse_req_t req, size_t size, off_t off,
struct fuse_file_info *fi);
int cusexmp_expand(size_t new_size);
void cusexmp_write(fuse_req_t req, const char *buf, size_t size,
off_t off, struct fuse_file_info *fi);
void fioc_do_rw(fuse_req_t req, void *addr, const void *in_buf,
size_t in_bufsz, size_t out_bufsz, int is_read);
void cusexmp_ioctl(fuse_req_t req, int cmd, void *arg,
struct fuse_file_info *fi, unsigned flags,
const void *in_buf, size_t in_bufsz, size_t out_bufsz);
int cusexmp_process_arg(void *data, const char *arg, int key,
struct fuse_args *outargs);
struct cusexmp_param {
unsigned major;
unsigned minor;
char *dev_name;
int is_help;
};
const struct cuse_lowlevel_ops cusexmp_clop = {
.open = cusexmp_open,
.read = cusexmp_read,
.write = cusexmp_write,
.ioctl = cusexmp_ioctl,
};
const struct fuse_opt cusexmp_opts[] = {
CUSEXMP_OPT("--maj=%u", major),
CUSEXMP_OPT("-m %u", minor),
CUSEXMP_OPT("--min=%u", minor),
CUSEXMP_OPT("-n %s", dev_name),
CUSEXMP_OPT("--name=%s", dev_name),
FUSE_OPT_KEY("-h", 0),
FUSE_OPT_KEY("--help", 0),
FUSE_OPT_END
};
const char *usage =
"usage: cusexmp [options]\n"
"\n"
"options:\n"
" --help|-h print this help message\n"
" --maj=MAJ|-M MAJ device major number\n"
" --min=MIN|-m MIN device minor number\n"
" --name=NAME|-n NAME device name (mandatory)\n"
" -d -o debug enable debug output (implies -f)\n"
" -f foreground operation\n"
" -s disable multi-threaded operation\n"
"\n";
#endif
因为
图书馆编译得很好。Gradle的示例输出:
Build hello-jni arm64-v8a
[1/3] Building CXX object CMakeFiles/hello-jni.dir/src/main/cpp/hello-jni.cpp.o
[2/3] Building CXX object CMakeFiles/hello-jni.dir/src/main/cpp/daemon.cpp.o
/home/mike/Desktop/hellojni/app/src/main/cpp/daemon.cpp:76:20: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]
param.dev_name="/dev/chardev_test";
^
1 warning generated.
[3/3] Linking CXX shared library ../../../../build/intermediates/cmake/debug/obj/arm64-v8a/libhello-jni.so
FAILED: : && /data/android-ndk-r17b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=aarch64-none-linux-android --gcc-toolchain=/data/android-ndk-r17b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64 --sysroot=/data/android-ndk-r17b/sysroot -fPIC -isystem /data/android-ndk-r17b/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -nostdlib++ --sysroot /data/android-ndk-r17b/platforms/android-21/arch-arm64 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -L/data/android-ndk-r17b/sources/cxx-stl/llvm-libc++/libs/arm64-v8a -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libhello-jni.so -o ../../../../build/intermediates/cmake/debug/obj/arm64-v8a/libhello-jni.so CMakeFiles/hello-jni.dir/src/main/cpp/hello-jni.cpp.o CMakeFiles/hello-jni.dir/src/main/cpp/daemon.cpp.o -latomic -lm "/data/android-ndk-r17b/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_static.a" "/data/android-ndk-r17b/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++abi.a" && :
CMakeFiles/hello-jni.dir/src/main/cpp/daemon.cpp.o:(.bss+0x0): multiple definition of `cusexmp_buf'
CMakeFiles/hello-jni.dir/src/main/cpp/hello-jni.cpp.o:(.bss+0x0): first defined here
CMakeFiles/hello-jni.dir/src/main/cpp/daemon.cpp.o: In function `__daemon_init()':
/home/mike/Desktop/hellojni/app/src/main/cpp/daemon.cpp:65: multiple definition of `cusexmp_size'
CMakeFiles/hello-jni.dir/src/main/cpp/hello-jni.cpp.o:/data/android-ndk-r17b/sources/cxx-stl/llvm-libc++/include/string:1543: first defined here
CMakeFiles/hello-jni.dir/src/main/cpp/daemon.cpp.o: In function `__daemon_init()':
/home/mike/Desktop/hellojni/app/src/main/cpp/daemon.cpp:65: multiple definition of `usage'
CMakeFiles/hello-jni.dir/src/main/cpp
/hello-jni.cpp.o:/data/android-ndk-r17b/sources/cxx-stl/llvm-libc++/include/string:1543: first defined here
CMakeFiles/hello-jni.dir/src/main/cpp/daemon.cpp.o: In function `start_cuse_server()':
/home/mike/Desktop/hellojni/app/src/main/cpp/daemon.cpp:65: undefined reference to `cusexmp_process_arg(void*, char const*, int, fuse_args*)'
/home/mike/Desktop/hellojni/app/src/main/cpp/daemon.cpp:65: undefined reference to `cusexmp_process_arg(void*, char const*, int, fuse_args*)'
/home/mike/Desktop/hellojni/app/src/main/cpp/daemon.cpp:81: undefined reference to `fuse_opt_parse'
/home/mike/Desktop/hellojni/app/src/main/cpp/daemon.cpp:101: undefined reference to `cuse_lowlevel_main'
CMakeFiles/hello-jni.dir/src/main/cpp/daemon.cpp.o:(.data.rel.ro+0xd8): undefined reference to `cusexmp_open(fuse_req*, fuse_file_info*)'
CMakeFiles/hello-jni.dir/src/main/cpp/daemon.cpp.o:(.data.rel.ro+0xe0): undefined reference to `cusexmp_read(fuse_req*, unsigned long, long, fuse_file_info*)'
CMakeFiles/hello-jni.dir/src/main/cpp/daemon.cpp.o:(.data.rel.ro+0xe8): undefined reference to `cusexmp_write(fuse_req*, char const*, unsigned long, long, fuse_file_info*)'
CMakeFiles/hello-jni.dir/src/main/cpp/daemon.cpp.o:(.data.rel.ro+0x108): undefined reference to `cusexmp_ioctl(fuse_req*, int, void*, fuse_file_info*, unsigned int, void const*, unsigned long, unsigned long)'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
:app:externalNativeBuildDebug FAILED
这个
multiple definition
我的问题是
:How to next fix/Troubleshow this error:似乎CMake没有正确链接库,但我对CMake或链接器不够熟悉,不知道如何调试此问题。我尝试了很多不同的符号库的组合。
我怎么跑
cmake
在bash中,查看
cmake公司
ld
找到错误了吗?
更新
我不知道
find_library()
在里面
仍然被注释掉了。取消对该行的注释会产生以下错误:
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
LIB_CUSE
linked by target "hello-jni" in directory /home/mike/Desktop/hellojni/app