This software compiles for x86_64 linux and windows. It's written in C+ and relies heavily on the SDL as well as depending on libraries such as curl, microhttp, libharu, etc. Some 2 years ago it also compiled for android x86 and arm32 using Pelya's [commandergenious][1] port but that knowledge was lost, development continued and i'm the newcomer. I'm not that versed on Android or their take on makefiles.
I managed to include one library (haru) in commandergenious but trying to include other libraries resulted in multiple failures, so kinda stopped at that. I also had some issues using custom makefiles as suggested in the readme.
I've adapted an existing regular makefile but it ends up conflicting with existing dependencies, i.e., ndk-compiled cyptopp.so would cause undefined symbols on clang-compiled app, even though the signatures are "the same" (std::__ndk1::basic_string
vs std::__cxx11::basic_string
).
I've since taken to recompiling the code with clang instead of gcc (fixing a few bugs on the way due to clang being more strict) and using Android.mk
instead of regular makefiles so i could cross-compile all components using just the NDK.
I tried giving a go at Android's LOCAL_MODULE
s but the interdependent LOCAL_PATH
s became too messy. I may get back to this route using [prebuilts][2] instead. It'll help segregate some issues should they arise.
Since my host is x86_68 Ubuntu Xenial i took the (maybe incorrect) path of setting up a directory with armeabi-v7a arm64-v8a x86 x86_64 subdirectories and ar x
ing .deb files (from Debian Buster as Xenial has sparse arm .debs) into those for all the libraries and includes i need. (It's $(HOME)/dev/multiarch
bellow.)
At the moment, this is my 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
And this is my 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)
When compiling with ndk-build NDK_PROJECT_PATH="$PWD" NDK_APPLICATION_MK="$PWD/Application.mk" V=1
i get this error:
<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);
^
because __RENAME_IF_FILE_OFFSET64
is not defined. Nor, i think, it should be, as i'm currently only targetting armeabi-v7a which is 32bit. Other files are correctly compiled as ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV)
.
I assume the main issue is my confusion with which C libraries to use and how the "regular" PC libs interact with android's.
For completeness, here's the full compile line (the first error is because i added an #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
Any pointers would greatly appreciated.