NDK 22.0.7026061 在为 armeabi-v7a 编译时未定义 __RENAME_IF_FILE_OFFSET64

NDK 22.0.7026061 has undefined __RENAME_IF_FILE_OFFSET64 when compiling for armeabi-v7a

此软件针对 x86_64 linux 和 windows 进行编译。它是用 C+ 编写的,在很大程度上依赖于 SDL 以及 curl、microhttp、libharu 等库。大约 2 年前,它还使用 Pelya 的 [commandergenious][1] 为 android x86 和 arm32 编译端口,但知识丢失了,开发仍在继续,我是新来者。我不是那么精通 Android 或他们对 makefile 的理解。

我设法在 commandergenious 中包含了一个库 (haru),但尝试包含其他库导致了多次失败,所以就此止步了。我在使用自述文件中建议的自定义 makefile 时也遇到了一些问题。

我已经修改了现有的常规 makefile,但它最终与现有的依赖项发生冲突,即 ndk 编译的 cyptopp.so 会在 clang 编译的应用程序上导致未定义的符号,即使签名是“相同的” “(std::__ndk1::basic_string 对比 std::__cxx11::basic_string)。

从那以后,我开始使用 clang 而不是 gcc 重新编译代码(由于 clang 更严格而修复了一些错误)并使用 Android.mk 而不是常规的 makefile,这样我就可以交叉-仅使用 NDK 编译所有组件。

我尝试尝试 Android 的 LOCAL_MODULE,但是相互依赖的 LOCAL_PATH 变得太乱了。我可能会改用 [prebuilts][2] 回到这条路线。它将有助于隔离出现的一些问题。

由于我的主机是 x86_68 Ubuntu Xenial 我采用了(可能不正确的)设置目录的路径,其中包含 armeabi-v7a arm64-v8a x86 x86_64 子目录和 ar xing .deb 文件(来自 Debian Buster,因为 Xenial 具有稀疏的 arm .debs)到所有库的文件中,包括我需要的文件。 (下面是 $(HOME)/dev/multiarch。)

此刻,这是我的 Application.mk

APP_OPTIM := debug
APP_DEBUG := true

APP_ABI := armeabi-v7a
APP_STL := c++_shared # default
APP_PLATFORM := android-16 # Jelly Bean, android v4.1 - 4.3.1, rel July 9 2012

APP_PROJECT_PATH := $(call my-dir)
NDK_PROJECT_PATH := $(APP_PROJECT_PATH)

APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/Android.mk

APP_CPPFLAGS := -frtti -fexceptions

这是我的 Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := mylocalmodule

# { target architecture, arch-specific include paths, arch-specific library paths
#

        MULTILIB_IDIR := -I$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/usr/include
    ifeq ($(TARGET_ARCH_ABI),x86)
        CLANG_TARGET  := -target i386-unknown-linux-android
        MULTILIB_IDIR += -I$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/usr/include/i386-linux-gnu
        MULTILIB_LDIR := -L$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/usr/lib/i386-linux-gnu
        MULTILIB_LDIR += -L$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/lib/i386-linux-gnu
    endif
    ifeq ($(TARGET_ARCH_ABI),x86_64)
        CLANG_TARGET  := -target x86_64-unknown-linux-android
        MULTILIB_IDIR += -I$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/usr/include/x86_64-linux-gnu
        MULTILIB_LDIR := -L$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/usr/lib/x86_64-linux-gnu
        MULTILIB_LDIR += -L$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/lib/x86_64-linux-gnu
    endif
    ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
        CLANG_TARGET  := -target armv7a-unknown-linux-android
        MULTILIB_IDIR += -I$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/usr/include/arm-linux-gnueabi
        MULTILIB_LDIR := -L$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/usr/lib/arm-linux-gnueabi
        MULTILIB_LDIR += -L$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/lib/arm-linux-gnueabi
    endif
    ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
        CLANG_TARGET  := -target arm64v8a-unknown-linux-android
        MULTILIB_IDIR += -I$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/usr/include/aarch64-linux-gnu
        MULTILIB_LDIR := -L$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/usr/lib/aarch64-linux-gnu
        MULTILIB_LDIR += -L$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/lib/aarch64-linux-gnu
    endif

#
# } target architecture, arch-specific include paths, arch-specific library paths

# { source files
#

    PROJECT_FILES += $(wildcard $(LOCAL_PATH)/*.c)
    PROJECT_FILES += $(wildcard $(LOCAL_PATH)/*.cpp)
    PROJECT_FILES := $(PROJECT_FILES:$(LOCAL_PATH)/%=%)
    PROJECT_FILES := $(filter-out file01.cpp file02.cpp subdir/file03.cpp,$(PROJECT_FILES)) # windows only
    LOCAL_SRC_FILES := $(PROJECT_FILES)

#
# } source files

# { compiler flags
#

    INCLUDES  := -I. -I.. -I../libjson/ -I$(HOME)/dev/commandergenius/project/jni/xml2/include -I$(HOME)/dev/libharu/libharu-2.0.8/include
   #INCLUDES  += -I$(ANDROID_NDK_ROOT)/sources/android/cpufeatures # crypto++
    INCLUDES  += -I$(ANDROID_NDK_ROOT)/sources/cxx-stl/llvm-libc++/include # STL
    INCLUDES  += $(MULTILIB_IDIR)
    DEFINES   := -D_LINUX_ -D__LINUX__ -DMYSQLDB -DANDROID -D_ANDROID -D_ANDROID_ -D__ANDROID__ -D__DEBUG__ -DDEBUG_SAFE #-DHAVE_CONFIG_H # libQRcode
    ALL_FLAGS := $(CLANG_TARGET) $(ALL_FLAGS) -v -w -Wno-gnu-array-member-paren-init -fpermissive -g -Wall $(DEFINES)

    # C/C++:
    LOCAL_CFLAGS += $(INCLUDES) -Wno-return-type $(ALL_FLAGS) -nostdinc++

    # C only:
    LOCAL_CONLYFLAGS += -std=c99 -Wabi-tag -D_GLIBCXX_USE_CXX11_ABI=0
    
    # C++ only:
    LOCAL_CPPFLAGS   += -std=c++11 -Wno-return-type #-stdlib=libc++

#
# } compiler flags

# { linker flags
#

    LOCAL_LDFLAGS += -Wl,--verbose -Wl,--exclude-libs,ALL -Wl,--as-needed
    LOCAL_LDFLAGS += -L/home/myuser/dev/myapp/libjson/bin/debug -L/home/myuser/dev/myapp/anothercomponent/bin/debug
    LOCAL_LDFLAGS += -L$(HOME)/dev/commandergenius/project/jni/xml2/libs/$(TARGET_ARCH_ABI)
    LOCAL_LDFLAGS += -L$(HOME)/dev/libharu/libharu-2.0.8/libs/$(TARGET_ARCH_ABI)
    LOCAL_LDFLAGS += -L$(HOME)/dev/libqrencode-android/library/libs/$(TARGET_ARCH_ABI)

    LOCAL_LDFLAGS += -L$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/lib

    LOCAL_LDFLAGS += -lmysqlclient -lpthread -lz -lm -lrt -lssl -lcrypto -ldl -lcurl -lSDL_image -lSDL_gfx -lSDL_ttf -lSDL
    LOCAL_LDFLAGS += -lmicrohttpd -lzip -lxml2 -lvncserver -lhpdf -lanothercomponent -ljson -lqrencode -lpng

#
# } linker flags

include $(BUILD_EXECUTABLE)

使用 ndk-build NDK_PROJECT_PATH="$PWD" NDK_APPLICATION_MK="$PWD/Application.mk" V=1 编译时出现此错误:

<ANDROID_NDK_ROOT>/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/android/asset_manager.h:140:5: error: expected function body after function declarator
    __RENAME_IF_FILE_OFFSET64(AAsset_seek64);
    ^

因为__RENAME_IF_FILE_OFFSET64没有定义。我认为也不应该,因为我目前只针对 32 位的 armeabi-v7a。其他文件正确编译为 ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV).

我认为主要问题是我对使用哪些 C 库以及“常规”PC 库如何与 android 交互感到困惑。

为了完整性,这里是完整的编译行(第一个错误是因为我添加了一个 #ifndef):

a b Compile++ thumb: myapp <= myfile.cpp
rm -f /home/myuser/dev/myproject/nyapp/obj/local/armeabi-v7a/objs-debug/myapp/myfile.o
/home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ -MMD -MP -MF /home/myuser/dev/myproject/nyapp/obj/local/armeabi-v7a/objs-debug/myapp/myfile.o.d -target armv7-no
Android (6875598, based on r399163b) clang version 11.0.5 (https://android.googlesource.com/toolchain/llvm-project 87f1315dfbea7c137aa2e6d362dbb457e388158d)
Target: armv7a-unknown-linux-android
Thread model: posix
InstalledDir: /home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin
Found candidate GCC installation: /home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x
Selected GCC installation: /home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x
Candidate multilib: thumb;@mthumb
Candidate multilib: armv7-a;@march=armv7-a
Candidate multilib: armv7-a/thumb;@march=armv7-a@mthumb
Candidate multilib: .;
Selected multilib: armv7-a/thumb;@march=armv7-a@mthumb
 (in-process)
 "/home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++" -cc1 -triple thumbv7-unknown-linux-android -emit-obj -mrelax-all -mnoexecstack -disable-free -disable-llvm-ve
clang -cc1 version 11.0.5 based upon LLVM 11.0.5git default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/sysroot/include"
ignoring duplicate directory "/home/myuser/dev/myproject/nyapp"
ignoring duplicate directory "/home/myuser/Android/Sdk/ndk/22.0.7026061/sources/cxx-stl/llvm-libc++/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/myuser/Android/Sdk/ndk/22.0.7026061/sources/cxx-stl/llvm-libc++/include
 /home/myuser/Android/Sdk/ndk/22.0.7026061/sources/cxx-stl/llvm-libc++/../llvm-libc++abi/include
 /home/myuser/dev/myproject/nyapp
 ..
 ../libjson
 /home/myuser/dev/commandergenius/project/jni/xml2/include
 /home/myuser/dev/libharu/libharu-2.0.8/include
 /home/myuser/dev/multiarch/armeabi-v7a/usr/include
 /home/myuser/dev/multiarch/armeabi-v7a/usr/include/arm-linux-gnueabi
 /home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/local/include
 /home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/11.0.5/include
 /home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/arm-linux-androideabi
 /home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include
End of search list.
In file included from /home/myuser/dev/myproject/nyapp/myfile.cpp:17:
In file included from /home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/android/native_activity.h:34:
/home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/android/asset_manager.h:141:2: error: __RENAME_IF_FILE_OFFSET64 is not defined
#error __RENAME_IF_FILE_OFFSET64 is not defined
 ^
/home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/android/asset_manager.h:143:5: error: expected function body after function declarator
    __RENAME_IF_FILE_OFFSET64(AAsset_seek64);
    ^
/home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/android/asset_manager.h:172:5: error: expected function body after function declarator
    __RENAME_IF_FILE_OFFSET64(AAsset_getLength64);
    ^
/home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/android/asset_manager.h:184:5: error: expected function body after function declarator
    __RENAME_IF_FILE_OFFSET64(AAsset_getRemainingLength64);
    ^
/home/myuser/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/android/asset_manager.h:202:5: error: expected function body after function declarator
    __RENAME_IF_FILE_OFFSET64(AAsset_openFileDescriptor64);
    ^
5 errors generated.
make: *** [/home/myuser/Android/Sdk/ndk/22.0.7026061/build/core/build-binary.mk:478: /home/myuser/dev/myproject/nyapp/obj/local/armeabi-v7a/objs-debug/myapp/myfile.o] Error 1

如有指点,将不胜感激。

        MULTILIB_IDIR += -I$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/usr/include/arm-linux-gnueabi
        MULTILIB_LDIR := -L$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/usr/lib/arm-linux-gnueabi
        MULTILIB_LDIR += -L$(HOME)/dev/multiarch/$(TARGET_ARCH_ABI)/lib/arm-linux-gnueabi

你不能这样做。 Android 不是 GNU 系统。您的所有依赖项都必须为 Android 构建,而不是为您的 GNU 系统构建。

https://developer.android.com/ndk/guides/other_build_systems 是您要查找的文档。