Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
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
6 changes: 5 additions & 1 deletion docs/recipe-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ The following values are accepted:

Name | Meaning
--------|-------------------------------------------------------------------------
`rmall` | Packages which work on all reMarkable devices without modification.
`rmall` | Packages which work on all reMarkable devices without modification. These packages must be cpu architecture independent, which generally means that they do not contain binaries, only scripts and configuration files.
`rm1` | Packages requiring reMarkable 1-specific resources or compilation flags.
`rm2` | Packages requiring reMarkable 2-specific resources or compilation flags.
`rmpp` | Packages requiring reMarkable Paper Pro-specific resources or compilation flags.
`rmppm` | Packages requiring reMarkable Paper Pro Move-specific resources or compilation flags.

For example, use `archs=(rm1)` for a package that only works on reMarkable 1, or `archs=(rm1 rm2)` for a package that works both on reMarkable 1 and reMarkable 2 but needs different dependencies or compilation flags for each of those.

Expand Down Expand Up @@ -230,6 +232,8 @@ Should match the upstream name as closely as possible.
The `build()` function runs in the context of a Docker container with the chosen `image`.
This function has access to all the metadata variables declared above, plus the `$arch` variable which contains the name of the architecture the recipe is currently being built for.
The working directory is `$srcdir`, which is populated with all the sources declared in `sources`.
If you are going to build aarch64 binaries, you must switch to suitable environment variables by sourcing `/opt/x-tools/switch-aarch64.sh`.
If you need to go back to ARMv7, you can source `/opt/x-tools/switch-arm.sh`.

### Package Section

Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
[project]
name = "toltecmk"
version = "0.3.7"
version = "0.4.0"
authors = [
{ name="Mattéo Delabre", email="[email protected]" },
{ name="Eeems", email="[email protected]" },
{ name="Noa Himesaka", email="[email protected]" },
]
description = "Build system used for the Toltec community repository"
requires-python = ">=3.11"
Expand Down
3 changes: 2 additions & 1 deletion tests/fixtures/hello/package
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ license=MIT
pkgver=0.0.1-1
section="utils"
flags=()
archs=(rm1 rmpp)

image=base:v2.1
image=base:v4.0
source=(hello.c)
sha256sums=(SKIP)

Expand Down
48 changes: 47 additions & 1 deletion tests/recipe_parsers/test_installdepends.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def test_installdepends(self) -> None:
with open(path.join(rec_path, "package"), "w") as rec_def_file:
rec_def_file.write(
"""
archs=(rmall rmallos2 rmallos3 rm1 rm1os2 rm1os3 rm2 rm2os2 rm2os3)
archs=(rmall rmallos2 rmallos3 rm1 rm1os2 rm1os3 rm2 rm2os2 rm2os3 rmpp rmppos3 rmppm rmppmos3)
pkgnames=(toltec-base)
pkgdesc="Metapackage defining the base set of packages in a Toltec install"
url=https://toltec-dev.org/
Expand All @@ -49,6 +49,10 @@ def test_installdepends(self) -> None:
installdepends_rm1os3=(open-remarkable-shutdown)
installdepends_rm2os2=(rm2-suspend-fix)
installdepends_rm2os3=(rm2-suspend-fix)
installdepends_rmpp=(rmpp-make-root-rw)
installdepends_rmppos3=(rmpp-make-root-rw)
installdepends_rmppm=(rmpp-make-root-rw)
installdepends_rmppmos3=(rmpp-make-root-rw)

image=base:v2.1
source=("https://example.org/toltec/${pkgnames[0]}/release-${pkgver%-*}.zip")
Expand Down Expand Up @@ -80,6 +84,8 @@ def test_installdepends(self) -> None:
Dependency(DependencyKind.HOST, "open-remarkable-shutdown")
]
rm2_depends = [Dependency(DependencyKind.HOST, "rm2-suspend-fix")]
rmpp_depends = [Dependency(DependencyKind.HOST, "rmpp-make-root-rw")]
rmppm_depends = [Dependency(DependencyKind.HOST, "rmpp-make-root-rw")]

recipes = parse_recipe(rec_path)

Expand All @@ -95,6 +101,10 @@ def test_installdepends(self) -> None:
"rm2",
"rm2os2",
"rm2os3",
"rmpp",
"rmppos3",
"rmppm",
"rmppmos3",
],
)
recipe = recipes["rmall"]
Expand Down Expand Up @@ -177,3 +187,39 @@ def test_installdepends(self) -> None:
package.installdepends,
set(basic_depends + rm2_depends),
)

recipe = recipes["rmpp"]
self.assertIs(type(recipe), Recipe)
package = recipe.packages["toltec-base"]
self.assertEqual(list(recipe.packages.keys()), ["toltec-base"])
self.assertEqual(
package.installdepends,
set(basic_depends + rmpp_depends),
)

recipe = recipes["rmppos3"]
self.assertIs(type(recipe), Recipe)
package = recipe.packages["toltec-base"]
self.assertEqual(list(recipe.packages.keys()), ["toltec-base"])
self.assertEqual(
package.installdepends,
set(basic_depends + rmpp_depends),
)

recipe = recipes["rmppm"]
self.assertIs(type(recipe), Recipe)
package = recipe.packages["toltec-base"]
self.assertEqual(list(recipe.packages.keys()), ["toltec-base"])
self.assertEqual(
package.installdepends,
set(basic_depends + rmppm_depends),
)

recipe = recipes["rmppmos3"]
self.assertIs(type(recipe), Recipe)
package = recipe.packages["toltec-base"]
self.assertEqual(list(recipe.packages.keys()), ["toltec-base"])
self.assertEqual(
package.installdepends,
set(basic_depends + rmppm_depends),
)
49 changes: 49 additions & 0 deletions tests/test_arch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright (c) 2023 The Toltec Contributors
# SPDX-License-Identifier: MIT

import unittest
import subprocess

from os import path
from tempfile import TemporaryDirectory
from elftools.elf.elffile import ELFFile


class TestBuild(unittest.TestCase):
def setUp(self) -> None:
self.dir = path.dirname(path.realpath(__file__))
self.fixtures_dir = path.join(self.dir, "fixtures")

def test_arch(self) -> None:
with TemporaryDirectory() as tmp_dir:
rec_dir = path.join(self.fixtures_dir, "hello")
work_dir = path.join(tmp_dir, "build")
dist_dir = path.join(tmp_dir, "dist")

result = subprocess.run(
[
"python3",
"-m",
"toltec",
"--work-dir",
work_dir,
"--dist-dir",
dist_dir,
"--",
rec_dir,
],
capture_output=True,
check=False,
)
self.assertEqual(
result.returncode, 0, result.stderr.decode("utf-8")
)
self.assertEqual(result.stdout.decode("utf-8"), "")
with open(
path.join(tmp_dir, "build", "rm1", "src", "hello"), "rb"
) as f:
self.assertEqual(ELFFile(f).get_machine_arch(), "ARM")
with open(
path.join(tmp_dir, "build", "rmpp", "src", "hello"), "rb"
) as f:
self.assertEqual(ELFFile(f).get_machine_arch(), "AArch64")
32 changes: 27 additions & 5 deletions toltec/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ def _prepare(recipe: Recipe, src_dir: str) -> None:
)
bash.pipe_logs(logger, logs, "prepare()")

# pylint: disable=too-many-locals
def _build(self, recipe: Recipe, src_dir: str) -> None:
"""Build artifacts for a recipe."""
if not recipe.build:
Expand Down Expand Up @@ -316,13 +317,31 @@ def _build(self, recipe: Recipe, src_dir: str) -> None:
)

if host_deps:
opkg_conf_path = "$SYSROOT/etc/opkg/opkg.conf"
opkg_conf_path = (
"$SYSROOT_AARCH64/etc/opkg/opkg.conf"
if recipe.arch.startswith("rmpp")
else "$SYSROOT/etc/opkg/opkg.conf"
)
opkg_exec = (
"opkg-aarch64" if recipe.arch.startswith("rmpp") else "opkg"
)
opkg_arch = (
"aarch64-3.10"
if recipe.arch.startswith("rmpp")
else "armv7-3.2"
)
opkg_src = (
"aarch64-k3.10"
if recipe.arch.startswith("rmpp")
else "armv7sf-k3.2"
)

pre_script.extend(
(
'echo -n "dest root /',
"arch all 100",
"arch armv7-3.2 160",
"src/gz entware https://bin.entware.net/armv7sf-k3.2",
f"arch {opkg_arch} 160",
f"src/gz entware https://bin.entware.net/{opkg_src}",
"arch rmall 200",
"src/gz toltec-rmall file:///repo/rmall",
f'" > "{opkg_conf_path}"',
Expand All @@ -340,12 +359,15 @@ def _build(self, recipe: Recipe, src_dir: str) -> None:

pre_script.extend(
(
"opkg update --verbosity=0",
"opkg install --verbosity=0 --no-install-recommends"
f"{opkg_exec} update --verbosity=0",
f"{opkg_exec} install --verbosity=0 --no-install-recommends"
" -- " + " ".join(host_deps),
)
)

if recipe.arch.startswith("rmpp"):
pre_script.append(("source /opt/x-tools/switch-aarch64.sh"))

logs = bash.run_script_in_container(
self.docker,
image=self.IMAGE_PREFIX + recipe.image,
Expand Down
27 changes: 25 additions & 2 deletions toltec/hooks/strip.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
logger = logging.getLogger(__name__)

MOUNT_SRC = "/src"
TOOLCHAIN = "toolchain:v3.1"
TOOLCHAIN = "toolchain:v4.0"


def walk_elfs(src_dir: str, for_each: Callable) -> None:
Expand Down Expand Up @@ -73,6 +73,7 @@ def post_build( # pylint: disable=too-many-locals,too-many-branches

# Search for binary objects that can be stripped
strip_arm: List[str] = []
strip_aarch64: List[str] = []
strip_x86: List[str] = []

def filter_elfs(info: ELFFile, file_path: str) -> None:
Expand All @@ -81,12 +82,14 @@ def filter_elfs(info: ELFFile, file_path: str) -> None:
return
if info.get_machine_arch() == "ARM":
strip_arm.append(file_path)
elif info.get_machine_arch() == "AArch64":
strip_aarch64.append(file_path)
elif info.get_machine_arch() in ("x86", "x64"):
strip_x86.append(file_path)

walk_elfs(src_dir, filter_elfs)

if not strip_arm and not strip_x86:
if not strip_arm and not strip_aarch64 and not strip_x86:
logger.debug("Skipping, no binaries found")
return

Expand Down Expand Up @@ -139,6 +142,26 @@ def docker_file_path(file_path: str) -> str:
os.path.relpath(file_path, src_dir),
)

if strip_aarch64:
script.extend(
(
"source /opt/x-tools/switch-aarch64.sh",
'"${CROSS_COMPILE}strip" --strip-all -- '
+ " ".join(
docker_file_path(file_path)
for file_path in strip_aarch64
),
)
)

logger.debug("AArch64 binaries to be stripped:")

for file_path in strip_aarch64:
logger.debug(
" - %s",
os.path.relpath(file_path, src_dir),
)

run_in_container(builder, src_dir, logger, script)

# Restore original mtimes
Expand Down