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 $ python3.9 -m venv ~/pyenv
$ ~/pyenv/bin/pip install --upgrade pip $ ~/pyenv/bin/pip install --upgrade pip
$ ~/pyenv/bin/pip install aqt $ ~/pyenv/bin/pip install aqt[qt6]
``` ```
Then to run Anki: Then to run Anki:
@ -38,7 +38,7 @@ $ ~/pyenv/bin/anki
``` ```
c:\> python -m venv \pyenv c:\> python -m venv \pyenv
c:\> \pyenv\scripts\pip install --upgrade pip c:\> \pyenv\scripts\pip install --upgrade pip
c:\> \pyenv\scripts\pip install aqt c:\> \pyenv\scripts\pip install aqt[qt6]
``` ```
Then to run Anki: 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. 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 ## Running tests
You can run all tests at once. From the top level project folder: 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), 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). 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**: **Ensure some basic tools are installed**:
``` ```
@ -99,6 +101,29 @@ To run Anki in optimized mode, use:
./scripts/runopt ./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 ## More
For info on running tests, building wheels and so on, please see [Development](./development.md). 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_arm64": "@clang_format_macos_x86_64//:clang-format",
"@ankidesktop//platforms:macos_x86_64": "@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_x86_64": "@clang_format_linux_x86_64//:clang-format",
"@ankidesktop//platforms:linux_arm64": "@clang_format_local//:clang-format",
}), }),
visibility = ["//visibility:public"] 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): if not native.existing_rule(name):
_setup_clang_format( _setup_clang_format(
name = name, name = name,

View file

@ -74,7 +74,8 @@ py_wheel(
"//platforms:windows_x86_64": "win_amd64", "//platforms:windows_x86_64": "win_amd64",
"//platforms:macos_x86_64": "macosx_10_13_x86_64", "//platforms:macos_x86_64": "macosx_10_13_x86_64",
"//platforms:linux_x86_64": "manylinux_2_28_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", python_tag = "cp39",
requires = [ requires = [
@ -84,7 +85,7 @@ py_wheel(
"protobuf>=3.17", "protobuf>=3.17",
"markdown", "markdown",
"stringcase", "stringcase",
'orjson; platform_machine == "x86_64"', "orjson",
'psutil; sys_platform == "win32"', 'psutil; sys_platform == "win32"',
'distro; sys_platform != "darwin" and 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", 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", 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( "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", 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", sha256 = "80370f232fd63d5cb3ff9418121acb87276228b0dafbeee3c57af143aca11f89",
), ),
} }
def get_platform(rctx): def _unix_arch(rctx):
result = rctx.execute(["arch"])
if result.return_code:
fail("invoking arch failed", result.stderr)
return result.stdout.strip()
def _get_platform(rctx):
if rctx.os.name == "mac os x": if rctx.os.name == "mac os x":
result = rctx.execute(["arch"]) arch = _unix_arch(rctx)
if result.return_code:
fail("invoking arch failed", result.stderr)
arch = result.stdout.strip()
if arch == "i386": if arch == "i386":
return "macos_amd64" return "macos_amd64"
elif arch == "arm64": elif arch == "arm64":
return "macos_arm64" return "macos_arm64"
else: else:
fail("unexpected arch:", arch) fail("unexpected arch", arch)
elif rctx.os.name == "linux": elif rctx.os.name == "linux":
return "linux_amd64" 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"): elif rctx.os.name.startswith("windows"):
return "windows_amd64" return "windows_amd64"
else: else:
@ -43,7 +57,7 @@ def _impl(rctx):
path = rctx.os.environ.get("PYO3_PYTHON") path = rctx.os.environ.get("PYO3_PYTHON")
rctx.symlink(path, "python") rctx.symlink(path, "python")
else: else:
platform = get_platform(rctx) platform = _get_platform(rctx)
distro = _python_distros.get(platform) distro = _python_distros.get(platform)
rctx.download_and_extract( rctx.download_and_extract(
url = distro.url, url = distro.url,

View file

@ -2,7 +2,13 @@ import re
import sys import sys
import io import io
import os import os
from PyQt6.uic import compileUi 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 from dataclasses import dataclass
@ -45,8 +51,13 @@ def with_fixes_for_qt6(code: str) -> str:
def with_fixes_for_qt5(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("Qt6", "Qt5")
code = code.replace("QtGui.QAction", "QtWidgets.QAction") code = code.replace("QtGui.QAction", "QtWidgets.QAction")
code = code.replace("import icons_rc", "")
return code return code