'sizeof(off_t) != 8' 为 android 编译 libfuse 时

'sizeof(off_t) != 8' when compiling libfuse for android

我正在尝试使用 NDK 编译 libfuse,我的环境:

Win10(64位) + NDK(r14b,64位) + libfuse(3.1.0)

fuse_common.h 中发生错误,它检查 off_t 的大小:

$ ndk-build
[armeabi-v7a] Compile thumb  : fuse <= buffer.c
In file included from jni/../../libfuse/lib/buffer.c:15:
In file included from jni/../../libfuse/lib/fuse_i.h:9:
In file included from jni/../../libfuse/include\fuse.h:19:
jni/../../libfuse/include/fuse_common.h:745:13: error: bit-field
      '_fuse_off_t_must_be_64bit' has negative width (-1)
        { unsigned _fuse_off_t_must_be_64bit:((sizeof(off_t) == 8) ? 1 : -1); };
                   ^
1 error generated.
make: *** [obj/local/armeabi-v7a/objs/fuse/__/__/libfuse/lib/buffer.o] Error 1

这是fuse_common.h中的支票:

struct _fuse_off_t_must_be_64bit_dummy_struct \
    { unsigned _fuse_off_t_must_be_64bit:((sizeof(off_t) == 8) ? 1 : -1); };

我在 google 上搜索,有 _FILE_OFFSET_BITS=64 定义,可以用来改变 off_t 的大小,我有这个定义我的 'Android.mk' 文件:

LOCAL_CFLAGS := \
    ....
    -D_FILE_OFFSET_BITS=64 \
    ....

甚至在 fuse_common.h

的开头加上这一行
#define _FILE_OFFSET_BITS 64

仍然无法正常工作,如何解决?

注意 提供的解决方案很像变通方法,请参阅@Dan 的回答以获取可靠且官方的 64 位 off_t

On Android off_t 始终为 32 位长度,并且没有控制其大小的预处理器宏。 (虽然这仅适用于 NDK 开发,因为现代仿生允许在编译时配置 off_t 大小)。因此你不能直接编译你的库。

但我想有一些方法可以解决这个问题。 Android NDK 提供 non-POSIX 扩展类型 - off64_t,并且它还提供了一组补充库函数来接受它而不是 off_t。它们以64后缀区分,即lseek64()mmap64()。因此,为了使事情正常进行,您可以尝试将全局配置 header 添加到您的项目中:

/* let off_t to be a 64-bit length */
typedef off64_t off_t;

/* use appropriate versions of system functions */
/* list here only functions that have off_t parameters and are used by your library */
#define mmap mmap64
#define lseek lseek64

当然请记住,编译后的代码现在链接到 *64() 函数而不是常规函数,任何 public 接口都期望 off64_t 而不是 off_t

更新到 NDK r15c。 _FILE_OFFSET_BITS=64 从那时起开始工作。

请注意,大多数 off64_t 系统调用在 android-21 之前不可用。如果您的 minSdkVersion 设置低于该值并且您使用 _FILE_OFFSET_BITS=64,许多功能将不可用。