Android ndk build can't build 32bit executable file

大兔子大兔子 提交于 2019-12-12 04:12:27

问题


Depending on my first question, I tried to include the fanotify.h header in my application. The application is based on fsmon (a small application to use the fanotify syscall), I changed some code lines for my purpose and created an Android.mk makefile:

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)

I need to include the linux/inotify.h and the linux/fanotify.h headers.

On executing ndk-build, only the arm64-v8a, mips64 and x86_64 executable files (in libs/xxx) get created cause of following error messages:

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

Cause of inotify.c including the signal.h header which re-includes the linux/signal.h and this in turn the platforms/android-9/arch-arm/usr/include/asm/signal.h , where the error appears. (suddenly from android-9).

I can't figure out where the problem is.. I tried to include the include folder from sysroot - but similar errors appear.

Source file: inotify.c fanotify.c


回答1:


You shouldn't manually point to the NDK headers in LOCAL_C_INCLUDES. This should be added automatically, pointing to the right version. However, nothing actually uses the variables APP_PLATFORM or TARGET_PLATFORM here.

Instead, add APP_PLATFORM := android-23 in the file jni/Application.mk. That should make it build using the right platform headers, for all architectures.




回答2:


In addition to @mstorsjo's answer, you can use Unified Headers in NDK r14 and newer. These are a new form of the headers that will always be up to date rather than having a different set of headers for each API level.

The advantage of this over increasing your APP_PLATFORM is that your APP_PLAFORM cannot be higher than your minSdkVersion (see our common problems doc). Since fanotify was introduced in a fairly old version of the kernel (2.6.36 for fanotify_init), you should still be able to call it with syscall(__NR_fanotify_init) even though the function doesn't exist in libc in the old version. Still, ENOSYS is always a possibility.

By default in r14 you still get the old form of the headers. The new "unified headers" have the headers you're looking for. If you want to try unified headers, set APP_UNIFIED_HEADERS := true in your Application.mk (settings for other build systems can be found in the link above).

In r15 (first beta due out soon), the default has changed to the new headers, and the option for disabling them has changed (see the same doc in r15).



来源:https://stackoverflow.com/questions/43140359/android-ndk-build-cant-build-32bit-executable-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!