fixes and documentation for Linux ARM64

+ add qt6 dep to wheel install docs
+ remove x86_64 constraint on orjson
This commit is contained in:
Damien Elmes 2021-10-23 14:57:48 +10:00
parent 02409d083b
commit ee644e08a3
6 changed files with 74 additions and 13 deletions

View file

@ -24,7 +24,7 @@ been fully updated yet. You can install Python from python.org or from your dist
```
$ python3.9 -m venv ~/pyenv
$ ~/pyenv/bin/pip install --upgrade pip
$ ~/pyenv/bin/pip install aqt
$ ~/pyenv/bin/pip install aqt[qt6]
```
Then to run Anki:
@ -38,7 +38,7 @@ $ ~/pyenv/bin/anki
```
c:\> python -m venv \pyenv
c:\> \pyenv\scripts\pip install --upgrade pip
c:\> \pyenv\scripts\pip install aqt
c:\> \pyenv\scripts\pip install aqt[qt6]
```
Then to run Anki:
@ -89,6 +89,8 @@ pip install --upgrade bazel-dist/*.whl
On Windows you'll need to list out the filenames manually.
If building on ARM Linux, please see the notes at the bottom of [Linux](./linux.md).
## Running tests
You can run all tests at once. From the top level project folder:

View file

@ -10,6 +10,8 @@ Glibc is required - if you are on a distro like Alpine that uses musl, you'll ne
to contribute fixes to the upstream [Rust rules](https://github.com/bazelbuild/rules_rust/issues/390),
then follow the steps in [Other Platforms](./new-platform.md).
Users on ARM64, see the notes at the bottom of this file before proceeding.
**Ensure some basic tools are installed**:
```
@ -99,6 +101,29 @@ To run Anki in optimized mode, use:
./scripts/runopt
```
## ARM64 support
Other platforms download PyQt binary wheels from PyPI. There are no PyQt wheels available
for ARM Linux, so you will need to rely on your system-provided libraries instead. As Anki
requires Python 3.9, this means you will need a fairly up-to-date distro such as Debian 11.
After installing the system libraries (eg 'sudo apt install python3-pyqt5.qtwebengine'),
find the place they are installed (eg '/usr/lib/python3/dist-packages'). Then before
running any commands like './run', tell Anki where they can be found:
```
export PYTHON_SITE_PACKAGES=/usr/lib/python3/dist-packages/
```
Note: the trailing slash at the end is required.
There are a few things to be aware of when doing this:
- You should use ./run and not scripts/run-qt5\*, even if your system libraries are Qt5.
- If your system libraries are Qt5, when creating an aqt wheel, the wheel will not work
on Qt6 environments.
- Some of the tests only work with PyQt6, and will show failures when run under PyQt5.
## More
For info on running tests, building wheels and so on, please see [Development](./development.md).

View file

@ -18,6 +18,7 @@ alias(
"@ankidesktop//platforms:macos_arm64": "@clang_format_macos_x86_64//:clang-format",
"@ankidesktop//platforms:macos_x86_64": "@clang_format_macos_x86_64//:clang-format",
"@ankidesktop//platforms:linux_x86_64": "@clang_format_linux_x86_64//:clang-format",
"@ankidesktop//platforms:linux_arm64": "@clang_format_local//:clang-format",
}),
visibility = ["//visibility:public"]
)
@ -60,6 +61,13 @@ def setup_clang_format(name):
],
)
if not native.existing_rule("clang_format_local"):
native.new_local_repository(
name = "clang_format_local",
path = "/usr/bin",
build_file_content = "exports_files(['clang-format'])",
)
if not native.existing_rule(name):
_setup_clang_format(
name = name,

View file

@ -74,7 +74,8 @@ py_wheel(
"//platforms:windows_x86_64": "win_amd64",
"//platforms:macos_x86_64": "macosx_10_13_x86_64",
"//platforms:linux_x86_64": "manylinux_2_28_x86_64",
"//platforms:linux_arm64": "manylinux_2_28_aarch64",
# Built on a Debian 11 image that has Qt 5.15
"//platforms:linux_arm64": "manylinux_2_31_aarch64",
}),
python_tag = "cp39",
requires = [
@ -84,7 +85,7 @@ py_wheel(
"protobuf>=3.17",
"markdown",
"stringcase",
'orjson; platform_machine == "x86_64"',
"orjson",
'psutil; sys_platform == "win32"',
'distro; sys_platform != "darwin" and sys_platform != "win32"',
],

View file

@ -12,26 +12,40 @@ _python_distros = {
url = "https://github.com/ankitects/python-build-standalone/releases/download/anki-2021-10-15/cpython-3.9.7-x86_64-unknown-linux-gnu-install_only-20211013T1538.tar.gz",
sha256 = "6a42fe15950f4e42000f5c68ebefacf8fce024f4d80a446789c18b174efdec1b",
),
"linux_arm64": struct(
# pending https://github.com/indygreg/python-build-standalone/issues/95
url = "https://github.com/ankitects/python-build-standalone/releases/download/anki-2021-10-15/cpython-3.9.7-aarch64-unknown-linux-gnu-install_only-20211013T1538.tar.gz",
sha256 = "2c5812d2e29b83b428a3da1f6c1a99b0581382e65290a767f8de25cbd1269d2a",
),
"windows_amd64": struct(
url = "https://github.com/indygreg/python-build-standalone/releases/download/20211012/cpython-3.9.7-x86_64-pc-windows-msvc-shared-install_only-20211011T1926.tar.gz",
sha256 = "80370f232fd63d5cb3ff9418121acb87276228b0dafbeee3c57af143aca11f89",
),
}
def get_platform(rctx):
if rctx.os.name == "mac os x":
def _unix_arch(rctx):
result = rctx.execute(["arch"])
if result.return_code:
fail("invoking arch failed", result.stderr)
arch = result.stdout.strip()
return result.stdout.strip()
def _get_platform(rctx):
if rctx.os.name == "mac os x":
arch = _unix_arch(rctx)
if arch == "i386":
return "macos_amd64"
elif arch == "arm64":
return "macos_arm64"
else:
fail("unexpected arch:", arch)
fail("unexpected arch", arch)
elif rctx.os.name == "linux":
arch = _unix_arch(rctx)
if arch == "x86_64":
return "linux_amd64"
elif arch == "aarch64":
return "linux_arm64"
else:
fail("unexpected arch", arch)
elif rctx.os.name.startswith("windows"):
return "windows_amd64"
else:
@ -43,7 +57,7 @@ def _impl(rctx):
path = rctx.os.environ.get("PYO3_PYTHON")
rctx.symlink(path, "python")
else:
platform = get_platform(rctx)
platform = _get_platform(rctx)
distro = _python_distros.get(platform)
rctx.download_and_extract(
url = distro.url,

View file

@ -2,7 +2,13 @@ import re
import sys
import io
import os
try:
from PyQt6.uic import compileUi
except ImportError:
# ARM64 Linux builds may not have access to PyQt6, and may have aliased
# it to PyQt5. We allow fallback, but the _qt6.py files will not be valid.
from PyQt5.uic import compileUi
from dataclasses import dataclass
@ -45,8 +51,13 @@ def with_fixes_for_qt6(code: str) -> str:
def with_fixes_for_qt5(code: str) -> str:
code = code.replace(
"from PyQt5 import QtCore, QtGui, QtWidgets",
"from PyQt5 import QtCore, QtGui, QtWidgets\nfrom aqt.utils import tr\n",
)
code = code.replace("Qt6", "Qt5")
code = code.replace("QtGui.QAction", "QtWidgets.QAction")
code = code.replace("import icons_rc", "")
return code