Android ndk 构建无法构建 32 位可执行文件
Android ndk build can't build 32bit executable file
根据我的第一个 , I tried to include the fanotify.h
header in my application. The application is based on fsmon(一个使用 fanotify 系统调用的小应用程序),我更改了一些代码行并创建了一个 Android.mk 生成文件:
APP_PLATFORM := android-23
TARGET_PLATFORM := android-23
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Enable PIE manually. Will get reset on $(CLEAR_VARS). This
# is what enabling PIE translates to behind the scenes.
LOCAL_CFLAGS += -fPIE -DHAVE_FANOTIFY=1 -DHAVE_SYS_FANOTIFY=0
LOCAL_LDFLAGS += -fPIE -pie
# give module name
LOCAL_MODULE := fsmon
# include fanotify by api 23:
LOCAL_C_INCLUDES := /home/fabian/Android/Sdk/ndk-bundle/platforms/android-23/arch-arm/usr/include
# include fanotify by sysroot ->
# LOCAL_C_INCLUDES := /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/
# list your C files to compile
LOCAL_SRC_FILES := inotify.c fanotify.c util.c main.c
# this option will build executables instead of building library for android application.
include $(BUILD_EXECUTABLE)
我需要包括 linux/inotify.h
和 linux/fanotify.h
headers。
在执行 ndk-build
时,只有 arm64-v8a
、mips64
和 x86_64
可执行文件(在 libs/xxx 中)被创建,导致以下错误消息:
fabian@fabian-ubuntu:~/kernel_android_goldfish/fsmon/fsmon/jni$ ndk-build
[arm64-v8a] Compile : fsmon <= inotify.c
[arm64-v8a] Compile : fsmon <= fanotify.c
[arm64-v8a] Compile : fsmon <= util.c
[arm64-v8a] Compile : fsmon <= main.c
[arm64-v8a] Executable : fsmon
[arm64-v8a] Install : fsmon => libs/arm64-v8a/fsmon
[x86_64] Compile : fsmon <= inotify.c
[x86_64] Compile : fsmon <= fanotify.c
[x86_64] Compile : fsmon <= util.c
[x86_64] Compile : fsmon <= main.c
[x86_64] Executable : fsmon
[x86_64] Install : fsmon => libs/x86_64/fsmon
[mips64] Compile : fsmon <= inotify.c
[mips64] Compile : fsmon <= fanotify.c
[mips64] Compile : fsmon <= util.c
[mips64] Compile : fsmon <= main.c
[mips64] Executable : fsmon
[mips64] Install : fsmon => libs/mips64/fsmon
[armeabi-v7a] Compile thumb : fsmon <= inotify.c
In file included from /home/fabian/kernel_android_goldfish/fsmon/fsmon/jni/inotify.c:9:
In file included from /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/signal.h:49:
In file included from /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/linux/signal.h:21:
In file included from /home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:82:
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:92:21: error: use of undeclared identifier
'__BITS_PER_LONG'
unsigned long sig[_NSIG_WORDS];
^
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:25:38: note: expanded from macro '_NSIG_WORDS'
#define _NSIG_WORDS (_KERNEL__NSIG / _NSIG_BPW)
^
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:24:19: note: expanded from macro '_NSIG_BPW'
#define _NSIG_BPW __BITS_PER_LONG
^
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:94:3: error: typedef redefinition with different
types ('struct (anonymous struct at /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:91:9)' vs
'unsigned long')
} sigset_t;
^
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:20:23: note: previous definition is here
typedef unsigned long sigset_t;
^
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:84:8: error: redefinition of 'sigaction'
struct sigaction {
^
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:101:8: note: previous definition is here
struct sigaction {
^
In file included from /home/fabian/kernel_android_goldfish/fsmon/fsmon/jni/inotify.c:9:
In file included from /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/signal.h:49:
In file included from /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/linux/signal.h:21:
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:97:16: error: redefinition of
'sigaltstack'
typedef struct sigaltstack {
^
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:111:16: note: previous definition is here
typedef struct sigaltstack {
^
In file included from /home/fabian/kernel_android_goldfish/fsmon/fsmon/jni/inotify.c:9:
In file included from /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/signal.h:49:
In file included from /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/linux/signal.h:21:
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:101:3: error: typedef redefinition with
different types ('struct (anonymous struct at
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:97:16)' vs 'struct sigaltstack')
} stack_t;
^
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:116:3: note: previous definition is here
} stack_t;
^
In file included from /home/fabian/kernel_android_goldfish/fsmon/fsmon/jni/inotify.c:9:
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/signal.h:71:9: warning: 'NSIG' macro redefined [-Wmacro-redefined]
#define NSIG _NSIG
^
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:19:9: note: previous definition is here
#define NSIG 32
^
In file included from /home/fabian/kernel_android_goldfish/fsmon/fsmon/jni/inotify.c:9:
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/signal.h:79:9: warning: 'SIGRTMIN' macro redefined [-Wmacro-redefined]
#define SIGRTMIN (__libc_current_sigrtmin())
^
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:58:9: note: previous definition is here
#define SIGRTMIN 32
^
In file included from /home/fabian/kernel_android_goldfish/fsmon/fsmon/jni/inotify.c:9:
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/signal.h:80:9: warning: 'SIGRTMAX' macro redefined [-Wmacro-redefined]
#define SIGRTMAX (__libc_current_sigrtmax())
^
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:59:9: note: previous definition is here
#define SIGRTMAX _NSIG
^
5 errors generated.
make: *** [/home/fabian/kernel_android_goldfish/fsmon/fsmon/obj/local/armeabi-v7a/objs/fsmon/inotify.o] Error 1
inotify.c
的原因包括 signal.h
header 其中 re-includes linux/signal.h
而这又是 platforms/android-9/arch-arm/usr/include/asm/signal.h
,其中错误出现。 (突然从android-9)。
我不知道问题出在哪里。我试图从 sysroot 中包含 include 文件夹 - 但出现了类似的错误。
源文件:
inotify.c
fanotify.c
您不应在 LOCAL_C_INCLUDES
中手动指向 NDK headers。这应该自动添加,指向正确的版本。但是,这里实际上没有使用变量 APP_PLATFORM
或 TARGET_PLATFORM
。
相反,在文件 jni/Application.mk
中添加 APP_PLATFORM := android-23
。这应该使它使用正确的平台构建 headers,适用于所有架构。
除了@mstorsjo 的回答之外,您还可以在 NDK r14 和更新版本中使用 Unified Headers。这些是 headers 的新形式,它将始终保持最新状态,而不是为每个 API 级别设置不同的 headers 集。
与增加 APP_PLATFORM
相比,这样做的好处是您的 APP_PLAFORM
不能高于 minSdkVersion
(请参阅我们的 common problems doc)。由于 fanotify 是在相当旧的内核版本中引入的(2.6.36 for fanotify_init
),你应该仍然可以使用 syscall(__NR_fanotify_init)
调用它,即使该函数在 libc 中不存在旧版。不过,ENOSYS
总是有可能的。
默认情况下,在 r14 中您仍然会得到 headers 的旧形式。新的 "unified headers" 有您正在寻找的 headers。如果你想尝试统一 headers,请在你的 Application.mk 中设置 APP_UNIFIED_HEADERS := true
(其他构建系统的设置可以在上面的 link 中找到)。
在 r15 中(第一个测试版即将推出),默认设置已更改为新的 headers,并且禁用它们的选项也已更改(请参阅 same doc in r15)。
根据我的第一个 fanotify.h
header in my application. The application is based on fsmon(一个使用 fanotify 系统调用的小应用程序),我更改了一些代码行并创建了一个 Android.mk 生成文件:
APP_PLATFORM := android-23
TARGET_PLATFORM := android-23
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Enable PIE manually. Will get reset on $(CLEAR_VARS). This
# is what enabling PIE translates to behind the scenes.
LOCAL_CFLAGS += -fPIE -DHAVE_FANOTIFY=1 -DHAVE_SYS_FANOTIFY=0
LOCAL_LDFLAGS += -fPIE -pie
# give module name
LOCAL_MODULE := fsmon
# include fanotify by api 23:
LOCAL_C_INCLUDES := /home/fabian/Android/Sdk/ndk-bundle/platforms/android-23/arch-arm/usr/include
# include fanotify by sysroot ->
# LOCAL_C_INCLUDES := /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/
# list your C files to compile
LOCAL_SRC_FILES := inotify.c fanotify.c util.c main.c
# this option will build executables instead of building library for android application.
include $(BUILD_EXECUTABLE)
我需要包括 linux/inotify.h
和 linux/fanotify.h
headers。
在执行 ndk-build
时,只有 arm64-v8a
、mips64
和 x86_64
可执行文件(在 libs/xxx 中)被创建,导致以下错误消息:
fabian@fabian-ubuntu:~/kernel_android_goldfish/fsmon/fsmon/jni$ ndk-build
[arm64-v8a] Compile : fsmon <= inotify.c
[arm64-v8a] Compile : fsmon <= fanotify.c
[arm64-v8a] Compile : fsmon <= util.c
[arm64-v8a] Compile : fsmon <= main.c
[arm64-v8a] Executable : fsmon
[arm64-v8a] Install : fsmon => libs/arm64-v8a/fsmon
[x86_64] Compile : fsmon <= inotify.c
[x86_64] Compile : fsmon <= fanotify.c
[x86_64] Compile : fsmon <= util.c
[x86_64] Compile : fsmon <= main.c
[x86_64] Executable : fsmon
[x86_64] Install : fsmon => libs/x86_64/fsmon
[mips64] Compile : fsmon <= inotify.c
[mips64] Compile : fsmon <= fanotify.c
[mips64] Compile : fsmon <= util.c
[mips64] Compile : fsmon <= main.c
[mips64] Executable : fsmon
[mips64] Install : fsmon => libs/mips64/fsmon
[armeabi-v7a] Compile thumb : fsmon <= inotify.c
In file included from /home/fabian/kernel_android_goldfish/fsmon/fsmon/jni/inotify.c:9:
In file included from /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/signal.h:49:
In file included from /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/linux/signal.h:21:
In file included from /home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:82:
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:92:21: error: use of undeclared identifier
'__BITS_PER_LONG'
unsigned long sig[_NSIG_WORDS];
^
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:25:38: note: expanded from macro '_NSIG_WORDS'
#define _NSIG_WORDS (_KERNEL__NSIG / _NSIG_BPW)
^
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:24:19: note: expanded from macro '_NSIG_BPW'
#define _NSIG_BPW __BITS_PER_LONG
^
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:94:3: error: typedef redefinition with different
types ('struct (anonymous struct at /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:91:9)' vs
'unsigned long')
} sigset_t;
^
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:20:23: note: previous definition is here
typedef unsigned long sigset_t;
^
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:84:8: error: redefinition of 'sigaction'
struct sigaction {
^
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:101:8: note: previous definition is here
struct sigaction {
^
In file included from /home/fabian/kernel_android_goldfish/fsmon/fsmon/jni/inotify.c:9:
In file included from /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/signal.h:49:
In file included from /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/linux/signal.h:21:
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:97:16: error: redefinition of
'sigaltstack'
typedef struct sigaltstack {
^
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:111:16: note: previous definition is here
typedef struct sigaltstack {
^
In file included from /home/fabian/kernel_android_goldfish/fsmon/fsmon/jni/inotify.c:9:
In file included from /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/signal.h:49:
In file included from /home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/linux/signal.h:21:
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:101:3: error: typedef redefinition with
different types ('struct (anonymous struct at
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:97:16)' vs 'struct sigaltstack')
} stack_t;
^
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/asm-generic/signal.h:116:3: note: previous definition is here
} stack_t;
^
In file included from /home/fabian/kernel_android_goldfish/fsmon/fsmon/jni/inotify.c:9:
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/signal.h:71:9: warning: 'NSIG' macro redefined [-Wmacro-redefined]
#define NSIG _NSIG
^
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:19:9: note: previous definition is here
#define NSIG 32
^
In file included from /home/fabian/kernel_android_goldfish/fsmon/fsmon/jni/inotify.c:9:
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/signal.h:79:9: warning: 'SIGRTMIN' macro redefined [-Wmacro-redefined]
#define SIGRTMIN (__libc_current_sigrtmin())
^
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:58:9: note: previous definition is here
#define SIGRTMIN 32
^
In file included from /home/fabian/kernel_android_goldfish/fsmon/fsmon/jni/inotify.c:9:
/home/fabian/Android/Sdk/ndk-bundle/sysroot/usr/include/signal.h:80:9: warning: 'SIGRTMAX' macro redefined [-Wmacro-redefined]
#define SIGRTMAX (__libc_current_sigrtmax())
^
/home/fabian/Android/Sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include/asm/signal.h:59:9: note: previous definition is here
#define SIGRTMAX _NSIG
^
5 errors generated.
make: *** [/home/fabian/kernel_android_goldfish/fsmon/fsmon/obj/local/armeabi-v7a/objs/fsmon/inotify.o] Error 1
inotify.c
的原因包括 signal.h
header 其中 re-includes linux/signal.h
而这又是 platforms/android-9/arch-arm/usr/include/asm/signal.h
,其中错误出现。 (突然从android-9)。
我不知道问题出在哪里。我试图从 sysroot 中包含 include 文件夹 - 但出现了类似的错误。
源文件: inotify.c fanotify.c
您不应在 LOCAL_C_INCLUDES
中手动指向 NDK headers。这应该自动添加,指向正确的版本。但是,这里实际上没有使用变量 APP_PLATFORM
或 TARGET_PLATFORM
。
相反,在文件 jni/Application.mk
中添加 APP_PLATFORM := android-23
。这应该使它使用正确的平台构建 headers,适用于所有架构。
除了@mstorsjo 的回答之外,您还可以在 NDK r14 和更新版本中使用 Unified Headers。这些是 headers 的新形式,它将始终保持最新状态,而不是为每个 API 级别设置不同的 headers 集。
与增加 APP_PLATFORM
相比,这样做的好处是您的 APP_PLAFORM
不能高于 minSdkVersion
(请参阅我们的 common problems doc)。由于 fanotify 是在相当旧的内核版本中引入的(2.6.36 for fanotify_init
),你应该仍然可以使用 syscall(__NR_fanotify_init)
调用它,即使该函数在 libc 中不存在旧版。不过,ENOSYS
总是有可能的。
默认情况下,在 r14 中您仍然会得到 headers 的旧形式。新的 "unified headers" 有您正在寻找的 headers。如果你想尝试统一 headers,请在你的 Application.mk 中设置 APP_UNIFIED_HEADERS := true
(其他构建系统的设置可以在上面的 link 中找到)。
在 r15 中(第一个测试版即将推出),默认设置已更改为新的 headers,并且禁用它们的选项也已更改(请参阅 same doc in r15)。