ndk交叉编译libnfs库

81 阅读3分钟

环境

  • Ubuntu 20.04.6 LTS 64位
  • android-ndk-r27c
  • libfuse
  • autoconf

年代久远,部分需要安装的基础库作者已忘记,编译时根据报错信息上网查找安装对应库即可。

版本

libnfs 6.0.2

编译脚本

  • build.sh
#!/bin/bash

export NDK=你的ndk路径
export API=24
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
export SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot

# 指定ABI
export TARGET=armv7a-linux-androideabi
# export TARGET=aarch64-linux-android
# export TARGET=i686-linux-android
# export TARGET=x86_64-linux-android

export AR=$TOOLCHAIN/bin/llvm-ar
export CC=$TOOLCHAIN/bin/${TARGET}${API}-clang
export CXX=$TOOLCHAIN/bin/${TARGET}${API}-clang++
export LD=$TOOLCHAIN/bin/ld.lld

export FUSE_DIR=${pwd}/fuse

CFLAGS="--target=${TARGET}${API} --sysroot=$SYSROOT -O3 -D_FILE_OFFSET_BITS=64 -I$FUSE_DIR/include -DFUSE_USE_VERSION=30"
LDFLAGS="--target=${TARGET}${API} -fuse-ld=lld -L$FUSE_DIR/lib -lfuse"

make distclean

autoreconf -ivf

./configure \
--host="$TARGET" \
CC="$CC" \
CXX="$CXX" \
AR="$AR" \
CFLAGS="$CFLAGS" \
LDFLAGS="$LDFLAGS" \
--enable-shared \
--disable-static \
--without-libkrb5 \
--with-gnu-ld=yes \
--disable-werror

rm -rf build

mkdir build

cd build

cmake -DCMAKE_BUILD_TYPE=Release ..

make

修改文件

  • configure.ac
diff --git a/configure.ac b/configure.ac
index e627961..e3642eb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -231,15 +231,29 @@ AC_CHECK_HEADERS([arpa/inet.h])
 dnl Check for sys/uio.h
 AC_CHECK_HEADERS([sys/uio.h])
 
+AC_CACHE_CHECK([for sa_len in struct sockaddr],
+    [ac_cv_member_struct_sockaddr_sa_len],
+    [
+        case $host in
+            *android*)
+                ac_cv_member_struct_sockaddr_sa_len=no
+                ;;
+            *)
+                AC_COMPILE_IFELSE([...])
+                ;;
+        esac
+    ]
+)
+
 # check for SA_LEN
 dnl Check if sockaddr data structure includes a "sa_len"
-AC_CHECK_MEMBER([struct sockaddr.sa_len],
-                [ AC_DEFINE(HAVE_SOCKADDR_LEN,1,[Whether sockaddr struct has sa_len]) ],
-                [],
-                [
+#AC_CHECK_MEMBER([struct sockaddr.sa_len],
+#                [ AC_DEFINE(HAVE_SOCKADDR_LEN,1,[Whether sockaddr struct has sa_len]) ],
+#                [],
+#                [
 #include <sys/types.h>
 #include <sys/socket.h>
-])
+#])
 
 # check for sockaddr_storage
 dnl Check if sockaddr structure includes a "ss_family"
@@ -266,35 +280,35 @@ else
 fi
 
 # check for tevent + talloc
-AC_CACHE_CHECK([for talloc and tevent support],libnfs_cv_HAVE_TALLOC_TEVENT,[
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#AC_CACHE_CHECK([for talloc and tevent support],libnfs_cv_HAVE_TALLOC_TEVENT,[
+#AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
 #include <talloc.h>
 #include <tevent.h>]], [[struct tevent_context *ctx = tevent_context_init(NULL);
- int major = talloc_version_major();]])],[libnfs_cv_HAVE_TALLOC_TEVENT=yes],[libnfs_cv_HAVE_TALLOC_TEVENT=no])])
-if test x"$libnfs_cv_HAVE_TALLOC_TEVENT" = x"yes"; then
-    AC_DEFINE(HAVE_TALLOC_TEVENT,1,[Whether we have talloc nad tevent support])
-fi
-AM_CONDITIONAL([HAVE_TALLOC_TEVENT], [test $libnfs_cv_HAVE_TALLOC_TEVENT = yes])
+# int major = talloc_version_major();]])],[libnfs_cv_HAVE_TALLOC_TEVENT=yes],[libnfs_cv_HAVE_TALLOC_TEVENT=no])])
+#if test x"$libnfs_cv_HAVE_TALLOC_TEVENT" = x"yes"; then
+#    AC_DEFINE(HAVE_TALLOC_TEVENT,1,[Whether we have talloc nad tevent support])
+#fi
+#AM_CONDITIONAL([HAVE_TALLOC_TEVENT], [test $libnfs_cv_HAVE_TALLOC_TEVENT = yes])
 
 # check for linux tls
-AC_CACHE_CHECK([for linux tls support],libnfs_cv_HAVE_TLS,[
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#AC_CACHE_CHECK([for linux tls support],libnfs_cv_HAVE_TLS,[
+#AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
 #include <gnutls/gnutls.h>
 #include <linux/tls.h>]],
-[[const char *v = GNUTLS_VERSION;]])],[libnfs_cv_HAVE_TLS=yes],[libnfs_cv_HAVE_TLS=no])])
-if test x"$libnfs_cv_HAVE_TLS" = x"yes"; then
-    AC_DEFINE(HAVE_TLS,1,[Whether we have linux tls support])
-fi
-AM_CONDITIONAL([HAVE_TLS], [test $libnfs_cv_HAVE_TLS = yes])
+#[[const char *v = GNUTLS_VERSION;]])],[libnfs_cv_HAVE_TLS=yes],[libnfs_cv_HAVE_TLS=no])])
+#if test x"$libnfs_cv_HAVE_TLS" = x"yes"; then
+#    AC_DEFINE(HAVE_TLS,1,[Whether we have linux tls support])
+#fi
+#AM_CONDITIONAL([HAVE_TLS], [test $libnfs_cv_HAVE_TLS = yes])
 
 AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec])
 
-AC_CHECK_HEADERS(dispatch/dispatch.h)
+#AC_CHECK_HEADERS(dispatch/dispatch.h)
 
-AC_CHECK_FUNCS(pthread_threadid_np)
+#AC_CHECK_FUNCS(pthread_threadid_np)
 
 # check where makedev is defined
-AC_HEADER_MAJOR
+#AC_HEADER_MAJOR
 
 #output
 AC_CONFIG_FILES([Makefile]
  • CMakeLists.txt
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4b9f40c..3db562a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -61,38 +61,38 @@ if(WIN32 AND BUILD_SHARED_LIBS)
   add_definitions(-Dlibnfs_EXPORTS)
 endif()
 
-if(CMAKE_SYSTEM_NAME STREQUAL Linux)
-  add_definitions("-D_U_=__attribute__((unused))")
-  #
-  # Currently RPC-with-TLS support is only available on Linux since it depends on kTLS support
-  # on Linux.
-  #
-  # TODO: BSD also has kTLS support, but that will need separate validation.
-  #
-  find_package(GnuTLS "3.4.6")
-  if(GNUTLS_FOUND)
-    #
-    # Make sure the two most important header files are present before we enable TLS support,
-    # to avoid running into issues later during build. GnuTLS package found but gnutls/gnutls.h
-    # not found is a serious issue while if linux/tls.h is not found it would likely mean that
-    # user is using a kernel not supporting kTLS so we simply don't turn on TLS support.
-    #
-    check_include_file("gnutls/gnutls.h" HAVE_GNUTLS_H)
-    if(NOT HAVE_GNUTLS_H EQUAL "1")
-      message(FATAL_ERROR "GnuTLS found but gnutls/gnutls.h not found, GNUTLS_INCLUDE_DIR is ${GNUTLS_INCLUDE_DIR}")
-    endif()
-
-    check_include_file("linux/tls.h" HAVE_LINUX_TLS_H)
-    if(NOT HAVE_LINUX_TLS_H EQUAL "1")
-      message(STATUS "GnuTLS found but linux/tls.h not found, likely a kernel w/o kTLS support, can't enable TLS support")
-    else()
-      message(STATUS "Using ${GNUTLS_LIBRARIES}")
-      add_definitions(-DHAVE_TLS)
-      list(APPEND SYSTEM_LIBRARIES ${GNUTLS_LIBRARIES})
-      add_subdirectory(tls)
-    endif()
-  endif()
-elseif(CMAKE_SYSTEM_NAME STREQUAL Windows OR CMAKE_SYSTEM_NAME STREQUAL WindowsStore)
+#if(CMAKE_SYSTEM_NAME STREQUAL Linux)
+#  add_definitions("-D_U_=__attribute__((unused))")
+#  #
+#  # Currently RPC-with-TLS support is only available on Linux since it depends on kTLS support
+#  # on Linux.
+#  #
+#  # TODO: BSD also has kTLS support, but that will need separate validation.
+#  #
+#  find_package(GnuTLS "3.4.6")
+#  if(GNUTLS_FOUND)
+#    #
+#    # Make sure the two most important header files are present before we enable TLS support,
+#    # to avoid running into issues later during build. GnuTLS package found but gnutls/gnutls.h
+#    # not found is a serious issue while if linux/tls.h is not found it would likely mean that
+#    # user is using a kernel not supporting kTLS so we simply don't turn on TLS support.
+#    #
+#    check_include_file("gnutls/gnutls.h" HAVE_GNUTLS_H)
+#    if(NOT HAVE_GNUTLS_H EQUAL "1")
+#      message(FATAL_ERROR "GnuTLS found but gnutls/gnutls.h not found, GNUTLS_INCLUDE_DIR is ${GNUTLS_INCLUDE_DIR}")
+#    endif()
+
+#    check_include_file("linux/tls.h" HAVE_LINUX_TLS_H)
+#    if(NOT HAVE_LINUX_TLS_H EQUAL "1")
+#      message(STATUS "GnuTLS found but linux/tls.h not found, likely a kernel w/o kTLS support, can't enable TLS support")
+#    else()
+#      message(STATUS "Using ${GNUTLS_LIBRARIES}")
+#      add_definitions(-DHAVE_TLS)
+#      list(APPEND SYSTEM_LIBRARIES ${GNUTLS_LIBRARIES})
+#      add_subdirectory(tls)
+#    endif()
+#  endif()
+if(CMAKE_SYSTEM_NAME STREQUAL Windows OR CMAKE_SYSTEM_NAME STREQUAL WindowsStore)
   add_definitions("-D_U_=" -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
   list(APPEND SYSTEM_LIBRARIES ws2_32)
   add_subdirectory(win32)
@@ -118,18 +118,18 @@ add_subdirectory(portmap)
 add_subdirectory(rquota)
 add_subdirectory(lib)   # this has to be last (it links all static libs mentioned in CORE_LIBRARIES)
 
-if(ENABLE_DOCUMENTATION)
-  add_subdirectory(doc)
-endif()
+#if(ENABLE_DOCUMENTATION)
+#  add_subdirectory(doc)
+#endif()
 
-if(ENABLE_EXAMPLES)
-  add_subdirectory(examples)
-endif()
+#if(ENABLE_EXAMPLES)
+#  add_subdirectory(examples)
+#endif()
 
-if(ENABLE_TESTS)
-  enable_testing()
-  add_subdirectory(tests)
-endif()
+#if(ENABLE_TESTS)
+#  enable_testing()
+#  add_subdirectory(tests)
+#endif()
 
 if(ENABLE_UTILS)
   add_subdirectory(utils)

如何编译

  1. 通过git克隆或下载zip包将源码下载到本地。
  2. 在源码根目录创建build.sh,修改对应文件。
  3. 在源码根目录创建fuse文件夹,将编译好的libfuse库的so和头文件拷贝进fuse目录。
  4. 根据需要可切换编出的so所对应的abi,修改build.sh脚本中的TARGET。
  5. 根据需要可修改Android版本,修改build.sh脚本中的API。
  6. 执行build.sh脚本,编译出的so在build/lib目录下。