Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • postmarketOS/pmbootstrap
  • fossdd/pmbootstrap
  • Adrian/pmbootstrap
  • JustSoup321/pmbootstrap
  • longnoserob/pmbootstrap
  • sixthkrum/pmbootstrap
  • ollieparanoid/pmbootstrap
  • magdesign/pmbootstrap
  • anjandev/pmbootstrap
  • HenriDellal/pmbootstrap
  • Minecrell/pmbootstrap
  • chipiguay/pmbootstrap
  • ijiki16/pmbootstrap
  • whynothugo/pmbootstrap
  • amessier/pmbootstrap
  • Eisenbahnfan/pmbootstrap
  • user0-07161/pmbootstrap
  • SzczurekYT/pmbootstrap
  • neuschaefer/pmbootstrap
  • knuxify/pmbootstrap
  • Frieder.Hannenheim/pmbootstrap
  • tgirl/pmbootstrap
22 results
Show changes
Commits on Source (18)
......@@ -10,7 +10,8 @@ if [ "$(id -u)" = 0 ]; then
apk -q add \
py3-myst-parser \
py3-sphinx_rtd_theme \
py3-sphinxcontrib-autoprogram
py3-sphinxcontrib-autoprogram \
py3-sphinxcontrib-jquery
exec su "${TESTUSER:-build}" -c "sh -e $0"
fi
......
......@@ -39,6 +39,7 @@ extensions = [
"sphinx.ext.autosummary",
"sphinx.ext.doctest",
"sphinxcontrib.autoprogram",
"sphinxcontrib.jquery",
]
templates_path = ["_templates"]
......
......@@ -16,7 +16,7 @@ def generate(pkgname: str) -> None:
context = get_context()
# Parse version from APKINDEX
package_data = pmb.parse.apkindex.package("busybox")
package_data = pmb.parse.apkindex.package("busybox", arch=arch)
if package_data is None:
raise RuntimeError("Couldn't find APKINDEX for busybox!")
......
......@@ -208,7 +208,7 @@ def get_upstream_aport(pkgname: str, arch: Arch | None = None, retain_branch: bo
repo = split[-2]
pkgname = split[-1]
index_path = pmb.helpers.repo.alpine_apkindex_path(repo, arch)
package = pmb.parse.apkindex.package(pkgname, indexes=[index_path])
package = pmb.parse.apkindex.package(pkgname, indexes=[index_path], arch=arch)
if package is None:
raise RuntimeError(f"Couldn't find {pkgname} in APKINDEX!")
......
......@@ -15,7 +15,7 @@ def generate(pkgname: str) -> None:
arch = Arch.x86
if pkgname != "grub-efi-x86":
raise RuntimeError("only grub-efi-x86 is available")
package_data = pmb.parse.apkindex.package("grub")
package_data = pmb.parse.apkindex.package("grub", arch=arch)
if package_data is None:
raise RuntimeError("Couldn't find package grub!")
version = package_data.version
......
......@@ -15,7 +15,7 @@ def generate(pkgname: str) -> None:
arch = Arch.from_str(pkgname.split("-")[1])
# Parse musl version from APKINDEX
package_data = pmb.parse.apkindex.package("musl")
package_data = pmb.parse.apkindex.package("musl", arch=arch)
if package_data is None:
raise RuntimeError("Couldn't find package musl!")
version = package_data.version
......
......@@ -132,7 +132,7 @@ def run_abuild(
"""
chroot = Chroot.native()
build_path = Path("/home/pmos/build")
kbuild_out_source = "/mnt/linux/.output"
kbuild_out_source = f"/mnt/linux/{kbuild_out}"
# If the kernel was cross-compiled on the host rather than with the envkernel
# helper, we can still use the envkernel logic to package the artifacts for
......@@ -180,13 +180,7 @@ def run_abuild(
)
# Create symlink from abuild working directory to envkernel build directory
if kbuild_out != "":
if os.path.islink(chroot / "mnt/linux" / kbuild_out) and os.path.lexists(
chroot / "mnt/linux" / kbuild_out
):
pmb.chroot.root(["rm", Path("/mnt/linux", kbuild_out)])
pmb.chroot.root(["ln", "-s", "/mnt/linux", build_path / "src"])
pmb.chroot.root(["ln", "-s", kbuild_out_source, build_path / "src" / kbuild_out])
pmb.chroot.root(["ln", "-sf", "/mnt/linux", build_path / "src"])
cmd: list[PathString] = ["cp", apkbuild_path, chroot / build_path / "APKBUILD"]
pmb.helpers.run.root(cmd)
......
......@@ -15,6 +15,7 @@ from pmb.core import Chroot
def newapkbuild(folder, args_passed, force=False):
# Initialize build environment and build folder
pmb.build.init()
pmb.chroot.init(Chroot.native())
build = Path("/home/pmos/build")
build_outside = Chroot.native() / build
if build_outside.exists():
......
......@@ -31,6 +31,7 @@ apk_keys_path: Path = pmb_src / "pmb/data/keys"
# exploit the system!)
apk_tools_min_version = {
"edge": "2.14.4-r4",
"v3.21": "2.14.4-r4",
"v3.20": "2.14.4-r1",
"v3.19": "2.14.4-r0",
"v3.18": "2.14.4-r0",
......
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
import enum
from pathlib import Path, PosixPath, PurePosixPath
import platform
# Initialised at the bottom
_cached_native_arch: "Arch"
_cached_native_arch: Arch
class Arch(enum.Enum):
......@@ -38,30 +40,34 @@ class Arch(enum.Enum):
return self.value
@staticmethod
def from_str(arch: str) -> "Arch":
def from_str(arch: str) -> Arch:
try:
return Arch(arch)
except ValueError:
raise ValueError(
f"Invalid architecture: '{arch}',"
" expected something like:"
f" {', '.join([str(a) for a in Arch.supported()])}"
f" {', '.join(sorted(str(a) for a in Arch.supported()))}"
)
@staticmethod
def from_machine_type(machine_type: str) -> "Arch":
mapping = {
"i686": Arch.x86,
"x86_64": Arch.x86_64,
"aarch64": Arch.aarch64,
"armv6l": Arch.armhf,
"armv7l": Arch.armv7,
"armv8l": Arch.armv7,
}
return mapping[machine_type]
def from_machine_type(machine_type: str) -> Arch:
match machine_type:
case "i686":
return Arch.x86
case "x86_64":
return Arch.x86_64
case "aarch64":
return Arch.aarch64
case "armv6l":
return Arch.armhf
case "armv7l" | "armv8l":
return Arch.armv7
case _:
raise ValueError(f"Unsupported machine type '{machine_type}'")
@staticmethod
def native() -> "Arch":
def native() -> Arch:
global _cached_native_arch
return _cached_native_arch
......@@ -69,7 +75,7 @@ class Arch(enum.Enum):
return self == Arch.native()
@staticmethod
def supported() -> set["Arch"]:
def supported() -> set[Arch]:
"""Officially supported host/target architectures for postmarketOS. Only
specify architectures supported by Alpine here. For cross-compiling,
we need to generate the "musl-$ARCH" and "gcc-$ARCH" packages (use
......@@ -83,61 +89,86 @@ class Arch(enum.Enum):
Arch.x86_64,
Arch.x86,
Arch.riscv64,
Arch.ppc64le,
Arch.native(),
]
)
def kernel(self) -> str:
mapping = {
Arch.x86: "x86",
Arch.x86_64: "x86_64",
Arch.armhf: "arm",
Arch.armv7: "arm",
Arch.aarch64: "arm64",
Arch.riscv64: "riscv",
Arch.ppc64le: "powerpc",
Arch.ppc64: "powerpc",
Arch.ppc: "powerpc",
Arch.s390x: "s390",
}
return mapping.get(self, self.value)
match self:
case Arch.x86:
return "x86"
case Arch.x86_64:
return "x86_64"
case Arch.armhf | Arch.armv7:
return "arm"
case Arch.aarch64:
return "arm64"
case Arch.riscv64:
return "riscv"
case Arch.ppc64le | Arch.ppc64 | Arch.ppc:
return "powerpc"
case Arch.s390x:
return "s390"
case _:
return self.value
def qemu(self) -> str:
mapping = {
Arch.x86: "i386",
Arch.armhf: "arm",
Arch.armv7: "arm",
}
return mapping.get(self, self.value)
match self:
case Arch.x86:
return "i386"
case Arch.armhf | Arch.armv7:
return "arm"
case Arch.ppc64le:
return "ppc64"
case _:
return self.value
def alpine_triple(self) -> str:
"""Get the cross compiler triple for this architecture on Alpine."""
mapping = {
Arch.aarch64: "aarch64-alpine-linux-musl",
Arch.armel: "armv5-alpine-linux-musleabi",
Arch.armhf: "armv6-alpine-linux-musleabihf",
Arch.armv7: "armv7-alpine-linux-musleabihf",
Arch.loongarch32: "loongarch32-alpine-linux-musl",
Arch.loongarchx32: "loongarchx32-alpine-linux-musl",
Arch.loongarch64: "loongarch64-alpine-linux-musl",
Arch.mips: "mips-alpine-linux-musl",
Arch.mips64: "mips64-alpine-linux-musl",
Arch.mipsel: "mipsel-alpine-linux-musl",
Arch.mips64el: "mips64el-alpine-linux-musl",
Arch.ppc: "powerpc-alpine-linux-musl",
Arch.ppc64: "powerpc64-alpine-linux-musl",
Arch.ppc64le: "powerpc64le-alpine-linux-musl",
Arch.riscv32: "riscv32-alpine-linux-musl",
Arch.riscv64: "riscv64-alpine-linux-musl",
Arch.s390x: "s390x-alpine-linux-musl",
Arch.x86: "i586-alpine-linux-musl",
Arch.x86_64: "x86_64-alpine-linux-musl",
}
if self in mapping:
return mapping[self]
raise ValueError(f"Can not map Alpine architecture '{self}'" " to the right hostspec value")
match self:
case Arch.aarch64:
return "aarch64-alpine-linux-musl"
case Arch.armel:
return "armv5-alpine-linux-musleabi"
case Arch.armhf:
return "armv6-alpine-linux-musleabihf"
case Arch.armv7:
return "armv7-alpine-linux-musleabihf"
case Arch.loongarch32:
return "loongarch32-alpine-linux-musl"
case Arch.loongarchx32:
return "loongarchx32-alpine-linux-musl"
case Arch.loongarch64:
return "loongarch64-alpine-linux-musl"
case Arch.mips:
return "mips-alpine-linux-musl"
case Arch.mips64:
return "mips64-alpine-linux-musl"
case Arch.mipsel:
return "mipsel-alpine-linux-musl"
case Arch.mips64el:
return "mips64el-alpine-linux-musl"
case Arch.ppc:
return "powerpc-alpine-linux-musl"
case Arch.ppc64:
return "powerpc64-alpine-linux-musl"
case Arch.ppc64le:
return "powerpc64le-alpine-linux-musl"
case Arch.riscv32:
return "riscv32-alpine-linux-musl"
case Arch.riscv64:
return "riscv64-alpine-linux-musl"
case Arch.s390x:
return "s390x-alpine-linux-musl"
case Arch.x86:
return "i586-alpine-linux-musl"
case Arch.x86_64:
return "x86_64-alpine-linux-musl"
case _:
raise ValueError(
f"Can not map Alpine architecture '{self}' to the right hostspec value"
)
def cpu_emulation_required(self) -> bool:
# Obvious case: host arch is target arch
......
......@@ -41,21 +41,12 @@ class Chroot:
"""
Ensures that this suffix follows the correct format.
"""
valid_arches = [
"x86",
"x86_64",
"aarch64",
"armhf", # XXX: remove this?
"armv7",
"riscv64",
]
if self.__type not in ChrootType._member_map_.values():
raise ValueError(f"Invalid chroot type: '{self.__type}'")
# A buildroot suffix must have a name matching one of alpines
# architectures.
if self.__type == ChrootType.BUILDROOT and self.__name not in valid_arches:
if self.__type == ChrootType.BUILDROOT and self.arch not in Arch.supported():
raise ValueError(f"Invalid buildroot suffix: '{self.__name}'")
# A rootfs or installer suffix must have a name matching a device.
......
......@@ -27,6 +27,8 @@ def test_valid_arches():
assert Arch.aarch64 in Arch.supported()
assert Arch.armhf in Arch.supported()
assert Arch.armv7 in Arch.supported()
assert Arch.riscv64 in Arch.supported()
assert Arch.ppc64le in Arch.supported()
# kernel arch
assert Arch.x86.kernel() == "x86"
......@@ -42,7 +44,7 @@ def test_valid_arches():
assert Arch.armhf.qemu() == "arm"
assert Arch.armv7.qemu() == "arm"
assert Arch.ppc64.qemu() == "ppc64"
assert Arch.ppc64le.qemu() == "ppc64le"
assert Arch.ppc64le.qemu() == "ppc64"
# Check that Arch.cpu_emulation_required() works
assert Arch.native() == Arch.x86_64 or Arch.x86_64.cpu_emulation_required()
......@@ -75,3 +77,7 @@ def test_invalid_arches():
with pytest.raises(TypeError) as excinfo:
"bap" / Arch.aarch64
assert "unsupported operand type(s) for /: 'str' and 'Arch'" in str(excinfo.value)
with pytest.raises(ValueError) as excinfo:
Arch.from_machine_type("invalid")
assert "Unsupported machine type 'invalid'" in str(excinfo.value)
......@@ -42,7 +42,10 @@ def test_invalid_chroots(pmb_args):
with pytest.raises(ValueError) as excinfo:
Chroot(ChrootType.BUILDROOT, "BAD_ARCH")
assert str(excinfo.value) == "Invalid buildroot suffix: 'BAD_ARCH'"
assert (
str(excinfo.value)
== "Invalid architecture: 'BAD_ARCH', expected something like: aarch64, armhf, armv7, ppc64le, riscv64, x86, x86_64"
)
with pytest.raises(ValueError) as excinfo:
Chroot(ChrootType.NATIVE, "aarch64")
......
......@@ -116,7 +116,7 @@ def get_upstream_remote(aports: Path) -> str:
urls = pmb.config.git_repos[name_repo]
lines = list_remotes(aports)
for line in lines:
if any(u in line for u in urls):
if any(u.lower() in line.lower() for u in urls):
return line.split("\t", 1)[0]
# Fallback to old URLs, in case the migration was not done yet
......
......@@ -68,6 +68,35 @@ def guess_main_dev(subpkgname: str) -> Path | None:
return None
def guess_main_cross(subpkgname: str) -> Path | None:
"""Check if a subpackage that is part of the cross toolchain is in pmaports or not, and log the appropriate message.
Don't call this function directly, use guess_main() instead.
:param subpkgname: subpackage name
:returns: full path to the pmaport or None
"""
# If it contains -dev-, assume the parent package is the same, without the infix
if "-dev-" in subpkgname:
pkgname = subpkgname.replace("-dev-", "-")
else:
pkgname = subpkgname.replace("g++", "gcc")
path = _find_apkbuilds().get(pkgname)
if path:
logging.verbose(subpkgname + ": guessed to be a subpackage of " + pkgname)
return path.parent
logging.verbose(
subpkgname
+ ": guessed to be a subpackage of "
+ pkgname
+ ", which we can't find in pmaports, so it's probably in"
" Alpine"
)
return None
def guess_main(subpkgname: str) -> Path | None:
"""Find the main package by assuming it is a prefix of the subpkgname.
......@@ -90,6 +119,12 @@ def guess_main(subpkgname: str) -> Path | None:
if subpkgname.endswith("-dev"):
return guess_main_dev(subpkgname)
# cross/* packages have a bunch of subpackages that do not have the main
# package name as a prefix (i.e. g++-*). Further, the -dev check fails here
# since the name ends with the name of the architecture.
if any(subpkgname.endswith("-" + str(arch)) for arch in Arch.supported()):
return guess_main_cross(subpkgname)
# Iterate until the cut up subpkgname is gone
words = subpkgname.split("-")
while len(words) > 1:
......@@ -187,20 +222,21 @@ def find(package, must_exist=True, subpackages=True, with_extra_repos="default")
# Parse the APKBUILD and verify if the guess was right
if _find_package_in_apkbuild(package, guess / "APKBUILD"):
ret = guess
else:
# Otherwise parse all APKBUILDs (takes time!), is the
# package we are looking for a subpackage of any of those?
for path_current in _find_apkbuilds().values():
if _find_package_in_apkbuild(package, path_current):
ret = path_current.parent
break
# If we still didn't find anything, as last resort: assume our
# initial guess was right and the APKBUILD parser just didn't
# find the subpackage in there because it is behind shell logic
# that we don't parse.
if not ret:
ret = guess
if not guess or (guess and not ret):
# Otherwise parse all APKBUILDs (takes time!), is the
# package we are looking for a subpackage of any of those?
for path_current in _find_apkbuilds().values():
if _find_package_in_apkbuild(package, path_current):
ret = path_current.parent
break
# If we still didn't find anything, as last resort: assume our
# initial guess was right and the APKBUILD parser just didn't
# find the subpackage in there because it is behind shell logic
# that we don't parse.
if not ret:
ret = guess
# Crash when necessary
if ret is None and must_exist:
......
......@@ -205,7 +205,7 @@ def command_qemu(
]
)
]
command += [chroot_native / "usr/bin" / f"qemu-system-{arch}"]
command += [chroot_native / "usr/bin" / f"qemu-system-{arch.qemu()}"]
command += ["-L", chroot_native / "usr/share/qemu/"]
command += ["-nodefaults"]
......@@ -249,6 +249,9 @@ def command_qemu(
elif arch == Arch.riscv64:
command += ["-M", "virt"]
command += ["-device", "virtio-gpu-pci"]
elif arch == Arch.ppc64le:
command += ["-M", "pseries"]
command += ["-device", "virtio-gpu-pci"]
else:
raise RuntimeError(f"Architecture {arch} not supported by this command" " yet.")
......