Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android build with Cross Compilation for BLAS and OpenCL back-ends #848

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c954e33
Android build
lealgo May 10, 2019
6afb880
Move lzma link argument after opencl detection
lealgo May 13, 2019
c9039f3
Initial support for cross-compilation
lealgo May 19, 2019
75eb1ba
Remove unneeded -ldl from Android cross-files, remove /usr/include/ f…
lealgo May 20, 2019
f0b1c16
Add cross-file for Cortex-A57
lealgo May 25, 2019
1430507
Target lower Android API levels for wider device support
lealgo May 29, 2019
4173b92
Merge branch 'master' into android-build, getting the new eigen support
lealgo May 30, 2019
c933b1a
Add alternate paths for the tuning file on Android
lealgo Jun 4, 2019
68281b4
Build armv7a with NDK r14b
lealgo Jun 6, 2019
3d55004
Revert "Add alternate paths for the tuning file on Android"
lealgo Jun 10, 2019
241ed4a
Revert to master's tuning file location
lealgo Jun 10, 2019
090e68c
add link to zlib issue with older NDK's
lealgo Jun 16, 2019
5535d75
v0.23.0-dev -> v0.23.0-rc1
mooskagh Nov 21, 2019
12bc3f0
Merge remote-tracking branch 'origin/master' into release/0.23
mooskagh Nov 27, 2019
65e13d8
v0.23.0-rc2
mooskagh Nov 27, 2019
e4d50c4
Merge remote-tracking branch 'upstream/release/0.23' into android-build
lealgo Nov 28, 2019
b966995
Fix meson opencl vars messed up after merge
lealgo Nov 28, 2019
89a9ec3
make eigen the last blas option (#1025)
borg323 Nov 28, 2019
02fc8e0
v0.23.0-rc2 -> v0.23.0
mooskagh Dec 1, 2019
2498564
Merge remote-tracking branch 'upstream/release/0.23' into android-build
lealgo Dec 2, 2019
120566e
Add PIE switches to armv7 cross-file
lealgo Dec 2, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions android_build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@

# Building lc0 on Android, with Termux

This is a quick way of compiling lc0 on Android by using Termux, it might not be the best way to do it but it works now. First, install Termux from Google Play:

[https://play.google.com/store/apps/details?id=com.termux](https://play.google.com/store/apps/details?id=com.termux)

After the install you should be ready to start adding packages.

## Add repos and required packages

You will need to add a custom repo that has clang, openblas and other goodies. Don't worry, the repo is listed on the Termux wiki [https://wiki.termux.com/wiki/Package_Management](https://wiki.termux.com/wiki/Package_Management).

```
pkg install coreutils curl git
curl -L https://its-pointless.github.io/setup-pointless-repo.sh | sh
```

After the repo is added you should add the required packages:

```
pkg install clang ninja openblas python
pip3 install meson
```

## Get the project from git

Get lc0 from git, you might use depth 1 for a smaller download:

```
git clone --depth 1 https://github.com/LeelaChessZero/lc0.git
cd lc0
git submodule update --init --recursive
```

## Tweak some parameters and build

Now you can start the build process, it will take a long time depending on your phone.

```
CC=clang CXX=clang++ ./build.sh -Ddefault_library=static -Dandroid=true
```

Hopefully no error will appear and you will have a successful build.

## Test the binary

You can test the binary right away from Termux. It just needs a weights file, let's say you copied it to the root of your phone:

```
lc0/build/release/lc0 benchmark -w /sdcard/11258-48x5-se.pb.gz
```

## Building the OpenCL back-end

This step is optional and requires a little more knowledge of your Android system, also a phone that supports OpenCL. First get these three things:

* Locate the library libOpenCL.so and remember its path, usually it's on `/system/vendor/lib64`
* Locate the library liblzma.so and remember its path, usually `/system/lib64/`
* Get the OpenCL headers from here [https://github.com/KhronosGroup/OpenCL-Headers](https://github.com/KhronosGroup/OpenCL-Headers) expand & copy them let's say on the parent folder of your lc0 source. Remember its relative path, for example `../include/`

Now edit the `meson.build` file and find the following line:

```
add_project_link_arguments('/system/lib64/liblzma.so', language:'cpp')
```

you should replace the path with the exact one you've got for the `libzma` library. Now there is a longer command for performing the build:

```
CC=clang CXX=clang++ ./build.sh -Ddefault_library=static -Dandroid=true -Dopencl_include=../include/ -Dopencl_libdirs=/system/vendor/lib64
```

replacing the two paths for the include and lib dirs with your own. That's it, if you got all the paths right there's a good chance the build will succeed and you'll have a working OpenCL back-end.

## Issues

The generated binary is dynamically linked. Most chess GUIs will fail when loading it because they'll be missing the libraries it has in the Termux environment. Even when you copy the libraries along with the binary, the GUIs won't search the libraries on the current path. In my phone the dependencies are the following:

```
ldd lc0/build/release/lc0
libc.so
libopenblas.so
libOpenCL.so
liblog.so
libc++_shared.so
libm.so
libdl.so
```

The solution is to make a static-linked binary. I tried passing -static on LDFLAGS but then more errors appeared.

## Future work

The ideal outcome of this is to generate an installable package that's compatible with Android chess GUIs, for example by implementing the Open Exchange Protocol for engines [https://github.com/garawaa/chessenginesupport-androidlib/](https://github.com/garawaa/chessenginesupport-androidlib/)

It's really a very straightforward implementation. Libraries and dependent files remain something to be tested.

10 changes: 9 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if cc.get_id() == 'clang' or cc.get_id() == 'gcc'
add_project_arguments('-Wextra', language : 'cpp')
add_project_arguments('-pedantic', language : 'cpp')

if get_option('buildtype') == 'release'
if get_option('buildtype') == 'release' and cc.has_argument('-march=native')
add_project_arguments('-march=native', language : 'cpp')
endif
endif
Expand All @@ -41,6 +41,14 @@ has_backends = false
# Third party files.
includes += include_directories('third_party', is_system: true)

# Android support
if get_option('android')
add_global_link_arguments('-llog', language:'cpp')
if get_option('opencl')
borg323 marked this conversation as resolved.
Show resolved Hide resolved
add_project_link_arguments('/system/lib64/liblzma.so', language:'cpp')
endif
endif

# Both protobuf and protoc must be the same version, so couple them together.
protobuf_lib = cc.find_library('libprotobuf', dirs : get_option('protobuf_libdir'), required : false)
if not protobuf_lib.found()
Expand Down
5 changes: 5 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ option('pext',
value: false,
description: 'Use the pext instruction')

option('android',
type: 'boolean',
value: false,
description: 'Enable Android support')

option('gtest',
type: 'boolean',
value: true,
Expand Down