android build

Discussion of anything and everything relating to chess playing software and machines.

Moderators: hgm, Rebel, chrisw

User avatar
flok
Posts: 481
Joined: Tue Jul 03, 2018 10:19 am
Full name: Folkert van Heusden

android build

Post by flok »

Hi,

Trying to build Embla for android.
The problem is, it keeps becoming a dynamic binary, even with the static build-flag:

Code: Select all

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := Embla
LOCAL_SRC_FILES := ../IO_perft.cpp ../Rng.cpp ../IO_EPD.cpp ../Board.cpp ../ChessPiece.cpp ../Exception.cpp ../IO.cpp ../IO_stderr.cpp ../IO_Console.cpp ../Scene.cpp ../Brain.cpp ../Debug.cpp ../Move.cpp ../Tpt.cpp ../IO_AutoPlay.cpp ../IO_UCI.cpp ../MoveSort.cpp ../Semaphore.cpp ../config.cpp ../ALG_position.cpp ../MoveList.cpp ../error.cpp ../db.cpp ../Utils.cpp ../Book.cpp ../DBBook.cpp ../DBBookWDL.cpp ../DBBookEval.cpp ../History.cpp ../PV.cpp ../BookPolyglot.cpp ../DetectBookFile.cpp ../DBBookEvalSqlite3.cpp ../DBBookLearn.cpp ../Tune.cpp ../IO_Xboard.cpp ../Ptt.cpp ../Main.cpp

LOCAL_CPPFLAGS := -std=gnu++14 -Wall -fPIE -DVERSION=\"2.0.7\" -DNAME_EXTRA=\"\" -fexceptions
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -fPIE -pie -static

LOCAL_LDFLAGS := -static

include $(BUILD_EXECUTABLE)

Results in:

Code: Select all

folkert@belle:~/Projects … .9.1_2205/branches/Android/jni Android(1) 6s ‡ file ../libs/armeabi/Embla
../libs/armeabi/Embla: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /usr/lib/libc.so.1, BuildID[sha1]=1292a6bce7808ecddf110f5aa7a43d154248f472, stripped
Any ideas?
User avatar
flok
Posts: 481
Joined: Tue Jul 03, 2018 10:19 am
Full name: Folkert van Heusden

Re: android build

Post by flok »

flok wrote: Fri May 31, 2019 10:01 am Any ideas?
Yes: remove the position-independent-code-flag.
Then the resulting binary is static and can be used in Aart's chess board program!
https://vanheusden.com/Embla/files/android-2.0.7.zip
Ras
Posts: 2487
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: android build

Post by Ras »

flok wrote: Fri May 31, 2019 10:01 amThe problem is, it keeps becoming a dynamic binary, even with the static build-flag:
That's a good thing because executables with position independent code are technically libraries that happen to have a main(). Here's what my Engine looks like:

Code: Select all

$ file CT800_V1.34_64
CT800_V1.34_64: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, stripped

$ file CT800_V1.34_32
CT800_V1.34_32: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, stripped
You shouldn't link statically for 3 reasons:

1) It increases up the file size both for storage and runtime.
2) Bugfixes for the standard library will not reach static binaries.
3) You cannot have position independent code in a static binary.

Position independent code is required under Android 5.0 (from 2014) or later. Unless you are using Android older than 5.0, the static executable should not run. However, the oldest Android that supports PIE is 4.1 (from 2012), so Android 4.0 or older cannot run position independent code.
Rasmus Althoff
https://www.ct800.net
User avatar
flok
Posts: 481
Joined: Tue Jul 03, 2018 10:19 am
Full name: Folkert van Heusden

Re: android build

Post by flok »

Ras wrote: Fri May 31, 2019 10:41 amPosition independent code is required under Android 5.0 (from 2014) or later. Unless you are using Android older than 5.0, the static executable should not run.
Hmmm, it runs fine on my samsung galaxy s9 with android 9.
Ras
Posts: 2487
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: android build

Post by Ras »

flok wrote: Fri May 31, 2019 10:49 amHmmm, it runs fine on my samsung galaxy s9 with android 9.
Actually, also my Nokia 6 with Android 9 runs the static engines which look like this (PIE removed in build script, static added):

Code: Select all

$ file CT800_V1.34_S64
CT800_V1.34_S64: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, stripped

$ file CT800_V1.34_S32
CT800_V1.34_S32: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, stripped
That's strange because some years ago, Android wouldn't run them.
Rasmus Althoff
https://www.ct800.net
User avatar
pedrox
Posts: 1056
Joined: Fri Mar 10, 2006 6:07 am
Location: Basque Country (Spain)

Re: android build

Post by pedrox »

I've recently moved from sourcery codebench to NDK. The main problem I had with codebench sourcery is that it is no longer free and I do not know if it is being continued. On the other hand, the executable I did does not work on android 8 on a tablet huwai mediapad t5. With codebench sourcery I always created statical binaries, they worked on android version 4 but I also tried it in version 5 and 7.

To compile with make I created a bat file:

Code: Select all

@echo off

rem currently, Android NDK r19c has been used with the standalone toolchain generated with:
rem make_standalone_toolchain.py --arch arm64 --api 21 --install-dir d:\android-standalone-64
rem the script make_standalone_toolchain.py is in the NDK under: build\tools

set "make_path_64=D:\android-standalone-64\bin"
set "make_64=%make_path_64%\make"
set "OLD_PATH=%PATH%"
set "PATH=%make_path_64%;%OLD_PATH%"

echo Generating DanaSah 64 bit for ARM-Android.

cmd /c "%make_64%"

pause
My Makefile file:

Code: Select all

CC = clang
CFLAGS = -m64 -march=armv8-a -DUNDER_ARM -DUNDER_64BIT -fPIE -Wall -Wextra -Werror -O2 -std=c99 -fno-strict-aliasing -fno-strict-overflow -ffunction-sections -fdata-sections
LIBS = -static -ldl -lm -s ./gtb/ARM/64/libgtb.a

.SUFFIXES: .c .o
 
OBJS = aleatorio.o atacado.o busqueda.o configura.o consola.o danasah.o \
     egbb.o egtb.o entradas.o evalua.o fen.o hash.o libro.o movimientos.o \
	 multipv.o salidas.o see.o test.o uci.o variables.o xboard.o
	 
all: danasah

.c.o: 
	$(CC) $(CFLAGS) -c $< -o $@

danasah: $(OBJS) 
	$(CC) -o danasah $(OBJS) $(CFLAGS) $(LIBS)

clean:
	del *.o
	del danasah
I have continued creating a static binary, the executable created I tested it works well on android 7 and android 8.
Ras
Posts: 2487
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: android build

Post by Ras »

pedrox wrote: Fri May 31, 2019 3:16 pmTo compile with make I created a bat file:
That looks quite familiar to me. :wink: However, with NDK r19, building the standalone chains via the Python script is not necessary anymore. For now, this still works, but that will be removed in r20, see the changelog https://github.com/android-ndk/ndk/wiki/Changelog-r19 .

The guide has been updated, see here: https://developer.android.com/ndk/guide ... ld_systems . Basically, you just call Clang directly as delivered in the NDK download and hand over the -target flag, I have tried that, and it works.

Here's my batch file modified for NDK r19 or later, stripped down to ARM-Android 64 bit as target. Note that I have been using the 32 bit Windows download of the NDK - the path is a little different for the 64 bit download, see below.

Code: Select all

@echo off

rem currently, Android NDK r19c (32 bit Windows version) has been used.
rem replace the "windows" with whatever host system you are using:
rem Windows 32 bit: windows
rem Windows 64 bit: windows-x86_64
rem Linux 64 bit:   linux-x86_64
rem macOS 64 bit:   darwin-x86_64
set "compiler_path=C:\android-ndk-r19c\toolchains\llvm\prebuilt\windows\bin"

set "fw_ver=V1.34"
set "compiler=%compiler_path%\clang"

rem target options
set "arm64opt=-target aarch64-linux-android21"

rem get the current directory
set "starting_dir=%CD%"

rem changes the current directory to the directory where this batch file is.
rem not necessary when starting via the Windows explorer, but from IDEs or so.
cd "%~dp0"

rem it is not necessary to add the compiler paths to PATH, but it looks more
rem future proof to have that.
set "OLD_PATH=%PATH%"
set "PATH=%compiler_path%;%OLD_PATH%"

rem *** the source files are fetched relative to the path of this batch file

echo Generating CT800 64 bit for ARM-Android.
set "compiler_options=-DTARGET_BUILD=64 -m64 -march=armv8-a -pie -fPIE -Wl,-pie -Wall -Wextra -Wstrict-prototypes -Werror -O2 -std=c99 -fno-strict-aliasing -fno-strict-overflow -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,-s"
cmd /c "%compiler%" %arm64opt% %compiler_options% -o output\CT800_%fw_ver%_andarm64 play.c kpk.c eval.c move_gen.c hashtables.c search.c util.c book.c

set "PATH=%OLD_PATH%"

rem go back to the starting directory
cd "%starting_dir%"

pause
The resulting engine info, same as from NDK r18:

Code: Select all

$ file CT800_V1.34_64
CT800_V1.34_64: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, stripped
Rasmus Althoff
https://www.ct800.net