Tried to build Anki for Termux on android using recently added packages pyqt5 and pyqtwebwngine

I have tried to build anki in termux, the wheels successfully built but anki is not running giving following errors.

ImportError: dlopen failed: cannot locate symbol "__extenddftf2" referenced by "/data/data/com.termux/files/home/anki/out/rust/debug/librsbridge.so"...

0. Requirements for building

  • aarch64
  • 10 GB space on device
  • install x11-repo and tur-repo
    pkg install x11-repo
    pkg install tur-repo
    

1. Install required packages

  1. Install PyQt5 and PyQtWebEngine

    pkg install pyqt5 python-pyqtwebengine
    
  2. Install required packages

    pkg install wget grep findutils curl git rsync ninja binutils rust protobuf nodejs-lts python3.9
    
  3. Install pip-tools for pip-sync

    pip install pip-tools
    
  4. Build and install maturin and orjson, it will takes time to build

    export RUSTFLAGS+=" -C lto=no"
    CARGO_BUILD_TARGET=aarch64-linux-android pip install maturin==0.14.10
    CARGO_BUILD_TARGET=aarch64-linux-android pip install orjson==3.8.5
    

2. Build Anki

  1. Export variables for Python binary and path

    export PYTHON_BINARY=/data/data/com.termux/files/usr/bin/python
    export PYTHONPATH=/data/data/com.termux/files/usr/lib/python3.11/site-packages
    
  2. Clone anki source

    git clone --recurse-submodules https://github.com/ankitects/anki.git
    

    It may needs to checkout to this commit hash c8275257ce4f507cf3292d6d4d7185d05088e310 before applying patch.

    git checkout c8275257ce4f507cf3292d6d4d7185d05088e310 -b termux-android
    
  3. Download android.patch

    wget https://gist.githubusercontent.com/krmanik/1230b138ce4308e93c512265006b6a8a/raw/8a7027dace3b5e2f72da0bc60350f07728abbf26/android.patch
    
  4. Apply patch to anki for using android.patch.
    The patch changes PyQt5, PyQtWebEngine and orjson version and copy nodejs and protoc from /usr/bin/ dir to out/extracted/ dir.

    cd anki
    git apply ../android.patch
    ./run
    
  5. It needs to do change in anki/out/pyenv/pyvenv.cfg to use system-site-packages after creation of pyenv in anki/out/pyenv or when errors occur.

    include-system-site-packages = true
    

    Tried to add --system-site-package to anki/build/ninja_gen/src/python.rs but didn’t work.

  6. It needs to manually copy this file, the patch is not updating it.

    cd anki
    # remove
    rm out/extracted/protoc/bin/protoc
    rm out/extracted/node/bin/node
    # copy
    cp  /data/data/com.termux/files/usr/bin/protoc   out/extracted/protoc/bin/protoc
    cp  /data/data/com.termux/files/usr/bin/node     out/extracted/node/bin/node
    

3. Result

  1. Result for building wheels, ./tools/build
~/anki $ ./tools/build
    Finished dev [unoptimized + debuginfo] target(s) in 2.32s
[29/29; 1 active; 1087.665s] wheels:anki

Build succeeded.
wheels are in out/wheels
  1. Result for ./run
~/anki $ ./run
Finished dev [unoptimized + debuginfo] target(s) in 2.36s
[26/26; 1 active; 115.654s] qt/aqt:data/web/js
Build succeeded.
Traceback (most recent call last):
File "/data/data/com.termux/files/home/anki/tools/run.py", line 9, in <module>
import aqt
File "/data/data/com.termux/files/home/anki/qt/aqt/__init__.py", line 40, in <module>
import anki.lang
File "/data/data/com.termux/files/home/anki/pylib/anki/lang.py", line 12, in <module>
import anki._backend
File "/data/data/com.termux/files/home/anki/pylib/anki/_backend.py", line 14, in <module>
from anki import _rsbridge, backend_pb2, i18n_pb2
ImportError: dlopen failed: cannot locate symbol "__extenddftf2" referenced by "/data/data/com.termux/files/home/anki/out/rust/debug/librsbridge.so"...

Download built wheel and related packages

Maybe downgrading Rust to 1.64 will help. [Bug]: Rust compiling rusqlite fails in rust 1.66.1 · Issue #14576 · termux/termux-packages · GitHub

1 Like

I have tried rust 1.64.0 but getting segmentation fault. I will test 1.65.0 later.
used rust 1.64.0 to build · GitHub

Three changes needs to be done in anki source.

  1. Python pyenv creation with --system-site-packages. I have done using following.

    diff --git a/build/runner/src/pyenv.rs b/build/runner/src/pyenv.rs
    index 491f0b80d..0d536cadc 100644
    --- a/build/runner/src/pyenv.rs
    +++ b/build/runner/src/pyenv.rs
    @@ -32,6 +32,7 @@ pub fn setup_pyenv(args: PyenvArgs) {
                 Command::new(&args.python_bin)
                     .args(["-m", "venv"])
                     .args(args.venv_args)
    +                .arg("--system-site-packages")
                     .arg(pyenv_folder),
             );
     
    
  2. Protoc binary used from installed directory instead of downloaded version. I have completed it in this commit and will create PR for this.
    Comparing ankitects:main...krmanik:protoc-binary-path · ankitects/anki · GitHub

    which protoc
    export PROTOC_BINARY=/path/to/protoc
    export PROTOC=$PROTOC_BINARY
    
  3. Also node js binary and its folder from path, I have tried but need help here.
    Comparing ankitects:main...krmanik:node-binary-path · ankitects/anki · GitHub

I don’t mind accepting changes to the build scripts to optionally swap out dependencies with local binaries, but the current approach is a bit messy. Please see the commit I just pushed to the main branch, which should require fewer changes when switching out things.

1 Like