koreader/koreader-base

Android aarch64 build.

pazos opened this issue · 33 comments

pazos commented

It has a few fancy things (NEON and VFPv4)

  • SDK API needs to be bumped from API14 to API21 (that's easy and doesn't affect other builds: we can have both armeabi-v7a and x86 with a min api of 14 and build aarch64 with a min api of 21). The build system just need to have the target api installed (which is 28 right now)

  • NDK API can stay in r15c, AFAICT. That's cool because I'm unable to build luajit with something newer.

Claaaaaang! \o/.

If Clang is required for aarch64 (?) then it'd still be a bit of effort to make that all work for Android. :-)

I dunno, but I'd highly recommend not bothering with this if it's to keep using GCC 4.9, because if there was AArch64 support in there, it's likely to be impressively crappy compared to current GCC/Clang ;).

I consider Clang a goal (even if only because it's forced by Google's GCC 4.9 behavior); better aarch64 would just be a side effect.

@pazos Btw, what do you mean unable to build LuaJIT with something newer? I know that Google customizes Clang, but the program has been tested for building with (regular) Clang since ~2014.

Okay, there's https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/AArch64-Options.html#AArch64-Options so, yeah, probably early days, but it's in there ;).

Which, duh, I shouldn't even had had to check, because of the very few OEM's actually building a Linux kernel with Clang, so I knew that worked -_-".

pazos commented

Btw, what do you mean unable to build LuaJIT with something newer?

I tried to bump the NDK to the latest one that supports ICS (r17b). I didn't change the toolchain, so I was trying to build with gcc, not clang. Lua throw an error, I didn't investigate the error.

I dunno, but I'd highly recommend not bothering with this if it's to keep using GCC 4.9, because if there was AArch64 support in there, it's likely to be impressively crappy compared to current GCC/Clang ;).

I consider Clang a goal (even if only because it's forced by Google's GCC 4.9 behavior); better aarch64 would just be a side effect.

The main benefit of aarch64, without changing the toolchain, is that neon is a must. But yeah 64 bits can wait and we can start playing with the new toolchain (I would go for r19 as things are way easier). In any case the old toolchain is still a must for legacy targets.

So, in the long run:

  • NDK r15c, SDK 14 -> "legacy" for armeabi-v7a
  • NDK r19?, SDK 17 -> "standard" for armeabi-v7a and x86 (with a modern TC)
  • NDK r19?, SDK 21 -> "new" for aarch64.

I tried to bump the NDK to the latest one that supports ICS (r17b). I didn't change the toolchain, so I was trying to build with gcc, not clang. Lua throw an error, I didn't investigate the error.

Probably due to #510 (comment)

Google is almost unbelievably terrible at maintaining any kind of backward compatibility. I strongly suspect they're breaking it on purpose. Also see #792 for the (luckily not overly complex) type of stuff required for compatibility with multiple versions at once if desired.

pazos commented

@Frenzie: your comment on #510 is out of date since https://github.com/koreader/koreader-base/pull/930/files

We still download the ndk because sdkmanager just has the latest ndk, which is incompatible with ICS.

Google is almost unbelievably terrible at maintaining any kind of backward compatibility. I strongly suspect they're breaking it on purpose.

Yup, Google is enforcing its "open" business. They can't kill lower apis (3-15), but they're forcing newer target apis to build (26-28), and these newer targets require tools that are, in fact, incompatible with lower apis.

The solution google provides includes the new ndk r20, which is clang only, and works in apis 16-29.
We actually build with support for apis 14-29.

pazos commented

@NiLuJe: LuaJIT works using https://github.com/koreader/android-luajit-launcher/pull/196/files#diff-5b290749f947ec669d6ffea0c0e9c3f9.

And the aarch64 toolchain seems to work with some changes in base:

diff --git a/Makefile.defs b/Makefile.defs
index 8508f36..3f386ec 100644
--- a/Makefile.defs
+++ b/Makefile.defs
@@ -17,7 +17,12 @@ POCKETBOOK_TOOLCHAIN?=$(TOOLCHAIN_DIR)/pocketbook-toolchain
 ANDROID_ARCH?=arm
 ANDROID_TOOLCHAIN=$(TOOLCHAIN_DIR)/android-toolchain-$(ANDROID_ARCH)
 NDK?=$(TOOLCHAIN_DIR)/android-ndk-r15c
-NDKABI?=14
+
+ifeq ($(ANDROID_ARCH), arm64)
+	NDKABI=21
+else
+	NDKABI?=14
+endif
 
 # Some CMake flags
 CMAKE_BUILD_TYPE?=Release
@@ -125,6 +130,8 @@ else ifeq ($(TARGET), android)
 	export SYSROOT=$(NDK)/platforms/android-$(NDKABI)/arch-$(ANDROID_ARCH)
 	ifeq ($(ANDROID_ARCH), x86)
 		CHOST?=i686-linux-android
+	else ifeq ($(ANDROID_ARCH), arm64)
+		CHOST?=aarch64-linux-android
 	else
 		CHOST?=arm-linux-androideabi
 	endif
@@ -332,6 +339,8 @@ ifeq ($(ANDROID_ARCH), arm)
 	ANDROID_ARM_ARCH:=-march=armv7-a -mfpu=vfpv3-d16
 	ANDROID_ARM_ARCH+=-mthumb
 	ANDROID_ARM_ARCH+=-ffunction-sections -funwind-tables -fstack-protector -no-canonical-prefixes
+else ifeq($(ANDROID_ARCH), arm64)
+        ANDROID_ARM_ARCH+=-ffunction-sections -funwind-tables -fstack-protector -no-canonical-prefixes
 endif
 
 # Use target-specific CFLAGS
@@ -386,8 +395,11 @@ else ifeq ($(TARGET), android)
 	COMPAT_CXXFLAGS:=$(ANDROID_COMPAT_CXXFLAGS)
 	ifeq ($(ANDROID_ARCH), arm)
 		ARM_ARCH:=$(ANDROID_ARM_ARCH)
-		ARM_ARCH+=-mfloat-abi=softfp
+                ARM_ARCH+=-mfloat-abi=softfp
 		export ac_cv_type_in_port_t=yes
+        else ifeq($(ANDROID_ARCH), arm64)
+                ARM_ARCH:=$(ANDROID_ARM_ARCH)
+                export ac_cv_type_in_port_t=yes
 	endif
 else ifeq ($(TARGET), sony-prstux)
 	ARM_ARCH:=$(ARMV7_A8_ARCH)
@@ -457,9 +469,9 @@ endif
 
 # NOTE: Follow the NDK's lead
 ifeq ($(TARGET), android)
-	LDFLAGS+=-no-canonical-prefixes -Wl,--fix-cortex-a8
+	LDFLAGS+=-no-canonical-prefixes
 	ifeq ($(ANDROID_ARCH), arm)
-		LDFLAGS+=-march=armv7-a
+		LDFLAGS+=-Wl,--fix-cortex-a8 -march=armv7-a
 	endif
 endif
 
diff --git a/thirdparty/kpvcrlib/crengine b/thirdparty/kpvcrlib/crengine
index 647821c..71dd858 160000
--- a/thirdparty/kpvcrlib/crengine
+++ b/thirdparty/kpvcrlib/crengine
@@ -1 +1 @@
-Subproject commit 647821c033e2e99f36d64f88fc73a85387704060
+Subproject commit 71dd8583cf9b1bd09e6efd906834ebc2521b59f3
diff --git a/thirdparty/luajit/CMakeLists.txt b/thirdparty/luajit/CMakeLists.txt
index 99b5883..04d69dd 100644
--- a/thirdparty/luajit/CMakeLists.txt
+++ b/thirdparty/luajit/CMakeLists.txt
@@ -52,6 +52,8 @@ if(${XCOMPILE})
         # Add -m32 when cross compile on 64 bit host for 32bit target, Per:
         # http://luajit.org/install.html#cross
         set(HOST_CC "${CC} -m32")
+    elseif(HOST_CC_MACHINE MATCHES "^aarch64*")
+        set(HOST_CC "${CC} -m64")
     else()
         set(HOST_CC "${CC}")
     endif()

Some help with CMake, to build luajit with "-DLJ_ABI_SOFTFP=0 -DLJ_ARCH_HASFPU=1 -DLUAJIT_ENABLE_GC64=1", would be awesome. 🙆‍♂️

That should be automagically detected by the Makefile & lj_arch.h :?

Might need some default CFLAGS, though. IIRC, I pulled the arm ones from somewhere in the NDK, there might be a link in one of the comments?

Okay, indirectly in a comment ;p. #201 (comment)

My point being you shouldn't be enforcing those LJ_ defines yourself.

If they get misdetected, that's another kettle of fish (but they shouldn't, it's a simple cascade of preprocessor checks).

TL;DR: An aarch64-friendly Makefile.defs should be enough ;).

i.e., something like that should be enough, no need to tweak thirdparty/luajit/CMakeLists.txt either.

diff --git a/Makefile.defs b/Makefile.defs
index 8508f36..9fd0ee3 100644
--- a/Makefile.defs
+++ b/Makefile.defs
@@ -17,7 +17,12 @@ POCKETBOOK_TOOLCHAIN?=$(TOOLCHAIN_DIR)/pocketbook-toolchain
 ANDROID_ARCH?=arm
 ANDROID_TOOLCHAIN=$(TOOLCHAIN_DIR)/android-toolchain-$(ANDROID_ARCH)
 NDK?=$(TOOLCHAIN_DIR)/android-ndk-r15c
-NDKABI?=14
+
+ifeq ($(ANDROID_ARCH), arm64)
+       NDKABI=21
+else
+       NDKABI?=14
+endif
 
 # Some CMake flags
 CMAKE_BUILD_TYPE?=Release
@@ -125,6 +130,8 @@ else ifeq ($(TARGET), android)
        export SYSROOT=$(NDK)/platforms/android-$(NDKABI)/arch-$(ANDROID_ARCH)
        ifeq ($(ANDROID_ARCH), x86)
                CHOST?=i686-linux-android
+       else ifeq ($(ANDROID_ARCH), arm64)
+               CHOST?=aarch64-linux-android
        else
                CHOST?=arm-linux-androideabi
        endif
@@ -332,6 +339,14 @@ ifeq ($(ANDROID_ARCH), arm)
        ANDROID_ARM_ARCH:=-march=armv7-a -mfpu=vfpv3-d16
        ANDROID_ARM_ARCH+=-mthumb
        ANDROID_ARM_ARCH+=-ffunction-sections -funwind-tables -fstack-protector -no-canonical-prefixes
+else ifeq($(ANDROID_ARCH), arm64)
+       # NOTE: This should be the default on both Clang & GCC, but keep enforcing it for clarity's sake.
+       ANDROID_ARM_ARCH:=-march=armv8-a+fp+simd
+       # c.f., https://github.com/koreader/koreader-base/issues/993#issuecomment-543442597
+       ANDROID_ARM_ARCH+=-fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes
+       # c.f., https://android.googlesource.com/platform/ndk.git/+/refs/heads/master/build/tools/prebuilt-common.sh#1036
+       # TODO: Get rid of it when moving to Clang
+       ANDROID_ARM_ARCH+=-ffixed-x18
 endif
 
 # Use target-specific CFLAGS
@@ -388,6 +403,9 @@ else ifeq ($(TARGET), android)
                ARM_ARCH:=$(ANDROID_ARM_ARCH)
                ARM_ARCH+=-mfloat-abi=softfp
                export ac_cv_type_in_port_t=yes
+       else ifeq($(ANDROID_ARCH), arm64)
+               ARM_ARCH:=$(ANDROID_ARM_ARCH)
+               export ac_cv_type_in_port_t=yes
        endif
 else ifeq ($(TARGET), sony-prstux)
        ARM_ARCH:=$(ARMV7_A8_ARCH)
@@ -457,9 +475,11 @@ endif
 
 # NOTE: Follow the NDK's lead
 ifeq ($(TARGET), android)
-       LDFLAGS+=-no-canonical-prefixes -Wl,--fix-cortex-a8
+       LDFLAGS+=-no-canonical-prefixes
        ifeq ($(ANDROID_ARCH), arm)
-               LDFLAGS+=-march=armv7-a
+               LDFLAGS+=-march=armv7-a -Wl,--fix-cortex-a8
+       else ifeq($(ANDROID_ARCH), arm64)
+               LDFLAGS+=-Wl,--gc-sections
        endif
 endif

And in jni/luajit/mk-luajit.sh, set NDKARCH to what we set ANDROID_ARM_ARCH here, like is done on other arches.

pazos commented

Thanks a lot @NiLuJe for your guidance.

I get this error while building luajit (with some context)

pazos@bowie:~/Escritorio/koreader$ ANDROID_ARCH=arm64 ./kodev release --ignore-translation android
v2019.09.3-84-gb24de3a4
Using NDK: /home/pazos/Escritorio/koreader/base/toolchain/android-ndk-r15c...
************ CMAKE_MAKE_PROGRAM: "make" **********
/bin/bash: aarch64-linux-android-gcc: orden no encontrada
/bin/bash: aarch64-linux-android-gcc: orden no encontrada
/bin/bash: aarch64-linux-android-gcc: orden no encontrada
make -C base
************ CMAKE_MAKE_PROGRAM: "make" **********
************ Building for MACHINE: "aarch64-linux-android" **********
************ PATH: "/home/pazos/Escritorio/koreader/base/toolchain/android-toolchain-arm64/bin:/home/pazos/Escritorio/koreader/base/toolchain/android-toolchain-arm64/bin:/home/pazos/Escritorio/koreader/base/toolchain/android-toolchain-arm64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/arm-cervantes-linux-gnueabi/bin" **********
************ CHOST: "aarch64-linux-android" **********
make[1]: Entering directory `/home/pazos/Escritorio/koreader/base'
install -d build/aarch64-linux-android/libs
install -d thirdparty/luajit/build/aarch64-linux-android
cd thirdparty/luajit/build/aarch64-linux-android && \
		cmake  -DCMAKE_TOOLCHAIN_FILE=/home/pazos/Escritorio/koreader/base/thirdparty/cmake_modules/CMakeCross.cmake  -DCC="gcc" \
		-DXCOMPILE:BOOL=on \
		-DBASE_CFLAGS="-O2 -ffast-math -pipe -fomit-frame-pointer" -DHOST_CFLAGS="-march=native -O2 -ffast-math -pipe -fomit-frame-pointer " \
		-DLDFLAGS="-Wl,-O1 -Wl,--as-needed -static-libstdc++ -no-canonical-prefixes -Wl,--gc-sections -static-libstdc++" \
		 \
		-DTARGET_SYS=Linux \
		-DTARGET_SONAME=libluajit.so \
		-DTARGET_CFLAGS="-O2 -ffast-math -pipe -fomit-frame-pointer  -std=gnu11  --sysroot /home/pazos/Escritorio/koreader/base/toolchain/android-ndk-r15c/platforms/android-21/arch-arm64 -static-libstdc++ -fPIC" \
		-DCROSS="aarch64-linux-android-" \
		/home/pazos/Escritorio/koreader/base/thirdparty/luajit && \
		make 
-- The C compiler identification is GNU 4.9.0
-- The CXX compiler identification is GNU 4.9.0
-- Check for working C compiler: /home/pazos/Escritorio/koreader/base/toolchain/android-toolchain-arm64/bin/aarch64-linux-android-gcc
-- Check for working C compiler: /home/pazos/Escritorio/koreader/base/toolchain/android-toolchain-arm64/bin/aarch64-linux-android-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /home/pazos/Escritorio/koreader/base/toolchain/android-toolchain-arm64/bin/aarch64-linux-android-g++
-- Check for working CXX compiler: /home/pazos/Escritorio/koreader/base/toolchain/android-toolchain-arm64/bin/aarch64-linux-android-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Git: /usr/bin/git (found version "2.17.1") 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android
make[2]: Entering directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android'
make[3]: Entering directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android'
make[4]: Entering directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android'
Scanning dependencies of target luajit
make[4]: Leaving directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android'
make[4]: Entering directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android'
[ 12%] Creating directories for 'luajit'
[ 25%] Performing download step for 'luajit'
[ 37%] Performing patch step for 'luajit'
patching file src/Makefile
[ 50%] No update step for 'luajit'
[ 62%] No configure step for 'luajit'
[ 75%] Performing build step for 'luajit'
make[5]: Entering directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android/luajit-prefix/src/luajit'
Building LuaJIT 2.1.0-beta3
make[6]: Entering directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android/luajit-prefix/src/luajit/src'
+--------------------------------------------------------------------------+
| WARNING: Compiling the amalgamation needs a lot of virtual memory        |
| (around 300 MB with GCC 4.x)! If you don't have enough physical memory   |
| your machine will start swapping to disk and the compile will not finish |
| within a reasonable amount of time.                                      |
| So either compile on a bigger machine or use the non-amalgamated build.  |
+--------------------------------------------------------------------------+
make[7]: Entering directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android/luajit-prefix/src/luajit/src'
HOSTCC    host/minilua.o
HOSTCC    host/buildvm_asm.o
HOSTCC    host/buildvm_peobj.o
HOSTCC    host/buildvm_lib.o
HOSTCC    host/buildvm_fold.o
In file included from host/buildvm.h:15:0,
                 from host/buildvm_lib.c:6:
./lj_def.h:355:47: error: size of array ‘STATIC_ASSERTION_FAILED’ is negative
   extern void LJ_ASSERT_NAME(__COUNTER__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
                                               ^
./lj_obj.h:699:1: note: in expansion of macro ‘LJ_STATIC_ASSERT’
 LJ_STATIC_ASSERT(offsetof(GChead, metatable) == offsetof(GCudata, metatable));
 ^~~~~~~~~~~~~~~~
In file included from host/buildvm_lib.c:7:0:
./lj_obj.h: In function ‘setlightudV’:
./lj_obj.h:830:12: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
   o->u64 = (uint64_t)p | (((uint64_t)LJ_TLIGHTUD) << 47);
            ^
./lj_obj.h: In function ‘setgcVraw’:
./lj_obj.h:70:17: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
   (r).gcptr64 = (uint64_t)&(gc)->gch | (((uint64_t)(it)) << 47)
                 ^
./lj_obj.h:865:3: note: in expansion of macro ‘setgcreft’
   setgcreft(o->gcr, v, itype);
   ^~~~~~~~~
CC        luajit.o
make[7]: *** [host/buildvm_lib.o] Error 1
make[7]: *** Waiting for unfinished jobs....
In file included from host/buildvm.h:15:0,
                 from host/buildvm_fold.c:6:
./lj_def.h:355:47: error: size of array ‘STATIC_ASSERTION_FAILED’ is negative
   extern void LJ_ASSERT_NAME(__COUNTER__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
                                               ^
./lj_obj.h:699:1: note: in expansion of macro ‘LJ_STATIC_ASSERT’
 LJ_STATIC_ASSERT(offsetof(GChead, metatable) == offsetof(GCudata, metatable));
 ^~~~~~~~~~~~~~~~
In file included from host/buildvm_fold.c:7:0:
./lj_obj.h: In function ‘setlightudV’:
./lj_obj.h:830:12: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
   o->u64 = (uint64_t)p | (((uint64_t)LJ_TLIGHTUD) << 47);
            ^
./lj_obj.h: In function ‘setgcVraw’:
./lj_obj.h:70:17: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
   (r).gcptr64 = (uint64_t)&(gc)->gch | (((uint64_t)(it)) << 47)
                 ^
./lj_obj.h:865:3: note: in expansion of macro ‘setgcreft’
   setgcreft(o->gcr, v, itype);
   ^~~~~~~~~
make[7]: *** [host/buildvm_fold.o] Error 1
make[7]: Leaving directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android/luajit-prefix/src/luajit/src'
make[6]: *** [amalg] Error 2
make[6]: Leaving directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android/luajit-prefix/src/luajit/src'
make[5]: *** [amalg] Error 2
make[5]: Leaving directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android/luajit-prefix/src/luajit'
make[4]: *** [luajit-prefix/src/luajit-stamp/luajit-build] Error 2
make[4]: Leaving directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android'
make[3]: *** [CMakeFiles/luajit.dir/all] Error 2
make[3]: Leaving directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android'
make[2]: *** [all] Error 2
make[2]: Leaving directory `/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android'
make[1]: *** [build/aarch64-linux-android/libs/libluajit.so] Error 2
make[1]: Leaving directory `/home/pazos/Escritorio/koreader/base'
Makefile:69: recipe for target 'all' failed
make: *** [all] Error 2

FWIW, I can build standalone luajit with mk-luajit, following your suggestion: remove LJ build flags and using NDKARCH="-march=armv8-a+fp+simd"

Can you try that again with a verbose build?

IIRC, something like

export VERBOSE=1
export V=1

Should do it?

(And, to be extra clear: that's only the CMake-wrapped build that's eating dirt? The mk-luajit Android thingy one goes through fine?)

Also, as that's the early HOSTCC bit that's face-planting, what is your host CC, exactly?

And, just in case, do you have CC/CFLAGS & co exported in your env?

pazos commented

@NiLuJe issue triaged:

if(HOST_CC_MACHINE MATCHES "^x86_64*")
# Add -m32 when cross compile on 64 bit host for 32bit target, Per:
# http://luajit.org/install.html#cross
set(HOST_CC "${CC} -m32")
else()

As you see luajit is forced to be 32 bits while building for arm, this clashes with aarch64 support. I'm building the rest of the software without issues after removing those lines.

Gah. Of course. It needs another depth of testing for a 32b target :/.

Hopefully, something resembling that?

diff --git a/thirdparty/luajit/CMakeLists.txt b/thirdparty/luajit/CMakeLists.txt
index 99b5883..b56cd98 100644
--- a/thirdparty/luajit/CMakeLists.txt
+++ b/thirdparty/luajit/CMakeLists.txt
@@ -48,7 +48,7 @@ if(${XCOMPILE})
         COMMAND "${CC}" -dumpmachine
         OUTPUT_VARIABLE HOST_CC_MACHINE
     )
-    if(HOST_CC_MACHINE MATCHES "^x86_64*")
+    if((HOST_CC_MACHINE MATCHES ".*64$") AND (NOT CMAKE_SYSTEM_PROCESSOR MATCHES ".*64$"))
         # Add -m32 when cross compile on 64 bit host for 32bit target, Per:
         # http://luajit.org/install.html#cross
         set(HOST_CC "${CC} -m32")

EDIT: Broken, see below. -dumpmachine reports the triple, not the arch (I was designing the regex with uname -m in mind).

Okay, that one at least isn't plain wrong anymore ;p.

Quick testing seems to hint at it holding up, but I haven't done an actual build.

diff --git a/thirdparty/luajit/CMakeLists.txt b/thirdparty/luajit/CMakeLists.txt
index 99b5883..6efe3b0 100644
--- a/thirdparty/luajit/CMakeLists.txt
+++ b/thirdparty/luajit/CMakeLists.txt
@@ -48,7 +48,7 @@ if(${XCOMPILE})
         COMMAND "${CC}" -dumpmachine
         OUTPUT_VARIABLE HOST_CC_MACHINE
     )
-    if(HOST_CC_MACHINE MATCHES "^x86_64*")
+    if((HOST_CC_MACHINE MATCHES "^.+64-.+$") AND (NOT CMAKE_SYSTEM_PROCESSOR MATCHES ".+64$"))
         # Add -m32 when cross compile on 64 bit host for 32bit target, Per:
         # http://luajit.org/install.html#cross
         set(HOST_CC "${CC} -m32")

It should also handle the unlikely event of anyone ever cross-compiling from a different 64bit arch than x86_64 ;).

This assumes CMAKE_SYSTEM_PROCESSOR is sane, which should always be the case with our ToolChain file:

# AArch64
if($ENV{CROSS_TC} MATCHES "^aarch64-.*")
set(CMAKE_SYSTEM_PROCESSOR aarch64)
endif()

pazos commented

Quick testing seems to hint at it holding up, but I haven't done an actual build.

Yeah, I talked too soon. I'm stuck with lpeg build, that fails with:

aarch64-linux-android-gcc -static-libstdc++ -O2 -ffast-math -pipe -fomit-frame-pointer  -std=gnu11  --sysroot /home/pazos/Escritorio/koreader/base/toolchain/android-ndk-r15c/platforms/android-21/arch-arm64 -static-libstdc++ -fPIC -I/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android/luajit-prefix/src/luajit/src -I/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android/luajit-prefix/src/luajit/src -c lpvm.c -o lpvm.o
In file included from lpcap.h:9:0,
                 from lpvm.c:13:
lptypes.h:38:0: warning: "luaL_newlib" redefined
 #define luaL_newlib(L,f) luaL_register(L,"lpeg",f)
 ^
In file included from lpvm.c:11:0:
/home/pazos/Escritorio/koreader/base/thirdparty/luajit/build/aarch64-linux-android/luajit-prefix/src/luajit/src/lauxlib.h:125:0: note: this is the location of the previous definition
 #define luaL_newlib(L, l) (luaL_newlibtable(L, l), luaL_setfuncs(L, l, 0))

Logic dictates #ifndef luaL_newlib… but that doesn't answer the question of why this would randomly come up.

That's just a warning though, not a build failure?

(Adn, FWIW, I think we get that warning everywhere, it sounds really familiar).

You're right, this looks like a warning on all platforms, presumably caused by the fact that LuaJIT now implements some select Lua 5.2 stuff.

pazos commented

Many moons passed since I played with it, but now it should be easier given that we have support for other aarch64 devices.

Still stuck with lpeg. I'm attaching a verbose log (lets clean everything and start from scratch :))

verbose.log

That's a missing link to the Lua dynamic library. I'm not quite sure why this wouldn't already affect our current build, but it wouldn't be the first time a rockspec was broken on Android ;).

pazos commented

That's a missing link to the Lua dynamic library. I'm not quite sure why this wouldn't already affect our current build, but it wouldn't be the first time a rockspec was broken on Android ;).

@NiLuJe: good to know, thanks. I'm very unproductive with build systems, so if you or @Frenzie want to try here's the diff I'm using to build for arm64-v8a:

diff --git a/Makefile.defs b/Makefile.defs
index 378e4e40..65a09e6c 100644
--- a/Makefile.defs
+++ b/Makefile.defs
@@ -16,6 +16,9 @@ TOOLCHAIN_DIR=$(MAKEFILE_DIR)toolchain
 ANDROID_ARCH?=arm
 ANDROID_TOOLCHAIN=$(TOOLCHAIN_DIR)/android-toolchain-$(ANDROID_ARCH)
 NDK?=$(TOOLCHAIN_DIR)/android-ndk-r15c
+ifeq ($(ANDROID_ARCH), arm64)
+	NDKABI=21
+endif
 NDKABI?=14
 
 # Detect LuaRocks 3
@@ -136,6 +139,8 @@ else ifeq ($(TARGET), android)
 	export SYSROOT=$(NDK)/platforms/android-$(NDKABI)/arch-$(ANDROID_ARCH)
 	ifeq ($(ANDROID_ARCH), x86)
 		CHOST?=i686-linux-android
+	else ifeq ($(ANDROID_ARCH), arm64)
+		CHOST?=aarch64-linux-android
 	else
 		CHOST?=arm-linux-androideabi
 	endif
@@ -359,6 +364,8 @@ ifeq ($(ANDROID_ARCH), arm)
 	ANDROID_ARM_ARCH:=-march=armv7-a -mfpu=vfpv3-d16
 	ANDROID_ARM_ARCH+=-mthumb
 	ANDROID_ARM_ARCH+=-ffunction-sections -funwind-tables -fstack-protector -no-canonical-prefixes
+else ifeq ($(ANDROID_ARCH), arm64)
+	ANDROID_ARM_ARCH+=-ffunction-sections -funwind-tables -fstack-protector -no-canonical-prefixes
 endif
 
 # Use target-specific CFLAGS
@@ -423,6 +430,9 @@ else ifeq ($(TARGET), android)
 		ARM_ARCH:=$(ANDROID_ARM_ARCH)
 		ARM_ARCH+=-mfloat-abi=softfp
 		export ac_cv_type_in_port_t=yes
+	else ifeq ($(ANDROID_ARCH), arm64)
+		ARM_ARCH:=$(ANDROID_ARM_ARCH)
+		export ac_cv_type_in_port_t=yes
 	endif
 else ifeq ($(TARGET), remarkable)
 	ARM_ARCH:=$(ARMV7_A9_ARCH)
@@ -509,9 +519,9 @@ endif
 
 # NOTE: Follow the NDK's lead
 ifeq ($(TARGET), android)
-	LDFLAGS+=-no-canonical-prefixes -Wl,--fix-cortex-a8
+	LDFLAGS+=-no-canonical-prefixes
 	ifeq ($(ANDROID_ARCH), arm)
-		LDFLAGS+=-march=armv7-a
+		LDFLAGS+=-Wl,--fix-cortex-a8 -march=armv7-a
 	endif
 endif
 
diff --git a/thirdparty/openssl/CMakeLists.txt b/thirdparty/openssl/CMakeLists.txt
index facadc5f..28ee4d34 100644
--- a/thirdparty/openssl/CMakeLists.txt
+++ b/thirdparty/openssl/CMakeLists.txt
@@ -41,6 +41,8 @@ if($ENV{ANDROID})
     # If we're on ARM, make it so
     if (${CHOST} MATCHES "^arm-.*")
         set(CFG_OPTS "android-arm ${CFG_OPTS}")
+    elseif (${CHOST} MATCHES "^aarch64-.*")
+        set(CFG_OPTS "android-arm64 ${CFG_OPTS}")
     else()
         set(CFG_OPTS "android-x86 ${CFG_OPTS}")
     endif()

Not for breakfast, mayyyyyyybe tonight.