test: drop all tests (MR 2252)

(Commit message written by Oliver)

The tests relied on a lot of specifics of the old codebase. We decided
that it makes more sense to just remove all tests for now to get this
large patchset of refactorings and improvements done, and then gradually
add new tests / possibly adjust some of the old ones and bring them back
in future patches.

Future tests will not be in the "test" directory, Caleb's reasoning:
> Easier to find relevant tests for a module, and avoid the big flat
> list of test files like we had before. Honestly was just a vibes
> thing after reading the docs.

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
Tweaked-By: Oliver Smith <ollieparanoid@postmarketos.org>
This commit is contained in:
Caleb Connolly 2024-06-05 02:31:49 +02:00 committed by Oliver Smith
parent 48cd886401
commit 1f7e352278
No known key found for this signature in database
GPG key ID: 5AE7F5513E0885CB
104 changed files with 0 additions and 8791 deletions

View file

@ -1,8 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import os
import sys
# Add topdir to import path
topdir = os.path.realpath(os.path.join(os.path.dirname(__file__) + "/../.."))
sys.path.insert(0, topdir)

View file

@ -1,6 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import pmb.config
testdata = pmb.config.pmb_src / "test/testdata"

View file

@ -1,67 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
""" Common code for git tests """
import os
from pmb.types import PmbArgs
import pmb.helpers.git
import pmb.helpers.run
import shutil
from pmb.types import PmbArgs
def prepare_tmpdir(args: PmbArgs, monkeypatch, tmpdir):
""" Prepare git repositories in tmpdir, and override related functions.
Git repositories:
* local: like local clone of pmaports.git
* remote: emulate a remote repository that we can add to "local", so
we can pass the tracking-remote tests in pmb.helpers.git.pull
* remote2: unexpected remote that pmbootstrap can complain about
Function overrides:
* pmb.helpers.git.get_path: always return path to "local" repo
* pmb.helpers.git.get_upstream_remote: always return "origin"
:returns: path_local, run_git
* path_local: path to "local" repo
* run_git(git_args, repo="local"): convenience function """
# Directory structure
tmpdir = str(tmpdir)
path_local = tmpdir + "/local"
path_remote = tmpdir + "/remote"
path_remote2 = tmpdir + "/remote2"
os.makedirs(path_local)
os.makedirs(path_remote)
os.makedirs(path_remote2)
def run_git(git_args, repo="local"):
path = tmpdir + "/" + repo
pmb.helpers.run.user(["git"] + git_args, path, "stdout", output_return=True)
# Remote repos
run_git(["init", "-b", "master", "."], "remote")
run_git(["commit", "--allow-empty", "-m", "commit: remote"], "remote")
run_git(["init", "-b", "master", "."], "remote2")
run_git(["commit", "--allow-empty", "-m", "commit: remote2"], "remote2")
# Local repo (with master -> origin2/master)
run_git(["init", "-b", "master", "."])
run_git(["remote", "add", "-f", "origin", path_remote])
run_git(["remote", "add", "-f", "origin2", path_remote2])
run_git(["checkout", "-b", "master", "--track", "origin2/master"])
# Override get_path()
def get_path(args: PmbArgs, name_repo):
return path_local
monkeypatch.setattr(pmb.helpers.git, "get_path", get_path)
# Override get_upstream_remote()
def get_u_r(args: PmbArgs, name_repo):
return "origin"
monkeypatch.setattr(pmb.helpers.git, "get_upstream_remote", get_u_r)
return path_local, run_git
def copy_dotgit(args: PmbArgs, tmpdir):
shutil.copytree(args.aports / ".git", tmpdir + "/.git", ignore_dangling_symlinks=True)

View file

@ -1,165 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import fnmatch
from typing import List
import pytest
import sys
from pmb.types import PathString
import pmb_test # noqa
import pmb.build
import pmb.chroot.apk
from pmb.core import Chroot
cmds_progress: List[PathString] = []
cmds: List[PathString] = []
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_install_build(monkeypatch, args):
func = pmb.chroot.apk.install_build
ret_apkindex_package = None
def fake_build_package(args: PmbArgs, package, arch):
return "build-pkg"
monkeypatch.setattr(pmb.build, "package", fake_build_package)
def fake_apkindex_package(args: PmbArgs, package, arch, must_exist):
return ret_apkindex_package
monkeypatch.setattr(pmb.parse.apkindex, "package", fake_apkindex_package)
package = "hello-world"
arch = "x86_64"
# invoked as pmb install, build_pkgs_on_install disabled
args.action = "install"
args.build_pkgs_on_install = False
with pytest.raises(RuntimeError) as e:
func(args, package, arch)
assert "no binary package found" in str(e.value)
# invoked as pmb install, build_pkgs_on_install disabled, binary exists
args.action = "install"
args.build_pkgs_on_install = False
ret_apkindex_package = {"pkgname": "hello-world"}
assert func(args, package, arch) is None
# invoked as pmb install, build_pkgs_on_install enabled
args.action = "install"
args.build_pkgs_on_install = True
assert func(args, package, arch) == "build-pkg"
# invoked as not pmb install
args.action = "chroot"
args.build_pkgs_on_install = False
assert func(args, package, arch) == "build-pkg"
def test_packages_split_to_add_del():
packages = ["hello", "!test", "hello2", "test2", "!test3"]
to_add, to_del = pmb.chroot.apk.packages_split_to_add_del(packages)
assert to_add == ["hello", "hello2", "test2"]
assert to_del == ["test", "test3"]
def test_packages_get_locally_built_apks(monkeypatch, args):
args.assume_yes = True
arch = pmb.config.arch_native
packages = ["hello-world", # will exist in repo and locally
"postmarketos-base", # will exist in repo only
"package-that-does-not-exist"] # will not exist at all
pmb.chroot.zap(args, pkgs_local=True)
pmb.build.package(args, "hello-world", force=True)
ret = pmb.chroot.apk.packages_get_locally_built_apks(args, packages, arch)
assert len(ret) == 1
assert fnmatch.fnmatch(ret[0], "*/hello-world-*.apk")
def test_install_run_apk(monkeypatch, args):
global cmds_progress
global cmds
func = pmb.chroot.apk.install_run_apk
suffix = Chroot.native()
def fake_chroot_root(args: PmbArgs, command, suffix):
global cmds
cmds += [command]
monkeypatch.setattr(pmb.chroot, "root", fake_chroot_root)
def fake_apk_progress(args: PmbArgs, command, chroot, suffix):
global cmds_progress
cmds_progress += [command]
monkeypatch.setattr(pmb.helpers.apk, "apk_with_progress", fake_apk_progress)
def reset_cmds():
global cmds_progress, cmds
cmds = []
cmds_progress = []
# Simple add
reset_cmds()
to_add = ["postmarketos-base", "device-ppp"]
to_add_local = []
to_del = []
func(args, to_add, to_add_local, to_del, suffix)
assert cmds_progress == [["apk", "add", "postmarketos-base", "device-ppp",
"--no-interactive"]]
assert cmds == []
# Add and delete
reset_cmds()
to_add = ["postmarketos-base", "device-ppp"]
to_add_local = []
to_del = ["unl0kr"]
func(args, to_add, to_add_local, to_del, suffix)
assert cmds_progress == [["apk", "add", "postmarketos-base", "device-ppp",
"--no-interactive"]]
assert cmds == [["apk", "--no-progress", "del", "unl0kr",
"--no-interactive"]]
# Add with local package
reset_cmds()
to_add = ["postmarketos-base", "device-ppp"]
to_add_local = ["/tmp/device-ppp.apk"]
to_del = []
func(args, to_add, to_add_local, to_del, suffix)
assert cmds_progress == [["apk", "add", "postmarketos-base", "device-ppp",
"--no-interactive"]]
assert cmds == [["apk", "--no-progress", "add", "-u", "--virtual",
".pmbootstrap", "/tmp/device-ppp.apk", "--no-interactive"],
["apk", "--no-progress", "del", ".pmbootstrap",
"--no-interactive"]]
# Add with --no-network
reset_cmds()
args.offline = True
to_add = ["hello-world"]
to_add_local = []
to_del = []
func(args, to_add, to_add_local, to_del, suffix)
assert cmds_progress == [["apk", "--no-network", "add", "hello-world",
"--no-interactive"]]
assert cmds == []
# Package name starting with '-'
reset_cmds()
to_add = ["hello-world", "--allow-untrusted"]
to_add_local = []
to_del = []
with pytest.raises(ValueError) as e:
func(args, to_add, to_add_local, to_del, suffix)
assert "Invalid package name" in str(e.value)

View file

@ -1,133 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import os
import copy
from pathlib import Path
import sys
import tarfile
import glob
import pytest
import pmb_test # noqa
import pmb.chroot.apk_static
import pmb.config
import pmb.parse.apkindex
import pmb.helpers.logging
from pmb.types import PmbArgs
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_read_signature_info(args: PmbArgs):
# Tempfolder inside chroot for fake apk files
tmp_path = Path("/tmp/test_read_signature_info")
tmp_path_outside = get_context().config.work / "chroot_native" / tmp_path
if os.path.exists(tmp_path_outside):
pmb.chroot.root(["rm", "-r", tmp_path])
pmb.chroot.user(["mkdir", "-p", tmp_path])
# No signature found
pmb.chroot.user(["tar", "-czf", tmp_path / "no_sig.apk",
"/etc/issue"])
with tarfile.open(tmp_path_outside / "no_sig.apk", "r:gz") as tar:
with pytest.raises(RuntimeError) as e:
pmb.chroot.apk_static.read_signature_info(tar)
assert "Could not find signature" in str(e.value)
# Signature file with invalid name
pmb.chroot.user(["mkdir", "-p", tmp_path / "sbin"])
pmb.chroot.user(["cp", "/etc/issue", tmp_path /
"sbin/apk.static.SIGN.RSA.invalid.pub"])
pmb.chroot.user(["tar", "-czf", tmp_path / "invalid_sig.apk",
"sbin/apk.static.SIGN.RSA.invalid.pub"],
working_dir=tmp_path)
with tarfile.open(tmp_path_outside / "invalid_sig.apk", "r:gz") as tar:
with pytest.raises(RuntimeError) as e:
pmb.chroot.apk_static.read_signature_info(tar)
assert "Invalid signature key" in str(e.value)
# Signature file with realistic name
path = list(pmb.config.apk_keys_path.glob("/*.pub"))[0]
name = os.path.basename(path)
path_archive = "sbin/apk.static.SIGN.RSA." + name
pmb.chroot.user(["mv",
tmp_path / "sbin/apk.static.SIGN.RSA.invalid.pub",
tmp_path / path_archive])
pmb.chroot.user(["tar", "-czf", tmp_path / "realistic_name_sig.apk",
path_archive], working_dir=tmp_path)
with tarfile.open(tmp_path_outside / "realistic_name_sig.apk", "r:gz")\
as tar:
sigfilename, sigkey_path = pmb.chroot.apk_static.read_signature_info(
tar)
assert sigfilename == path_archive
assert sigkey_path == path
# Clean up
pmb.chroot.user(["rm", "-r", tmp_path])
def test_successful_extraction(args: PmbArgs, tmpdir):
if os.path.exists(get_context().config.work / "apk.static"):
os.remove(get_context().config.work / "apk.static")
pmb.chroot.apk_static.init(args)
assert os.path.exists(get_context().config.work / "apk.static")
os.remove(get_context().config.work / "apk.static")
def test_signature_verification(args: PmbArgs, tmpdir):
if os.path.exists(get_context().config.work / "apk.static"):
os.remove(get_context().config.work / "apk.static")
version = pmb.parse.apkindex.package("apk-tools-static")["version"]
apk_path = pmb.chroot.apk_static.download(
args, f"apk-tools-static-{version}.apk")
# Extract to temporary folder
with tarfile.open(apk_path, "r:gz") as tar:
sigfilename, sigkey_path = pmb.chroot.apk_static.read_signature_info(
tar)
files = pmb.chroot.apk_static.extract_temp(tar, sigfilename)
# Verify signature (successful)
pmb.chroot.apk_static.verify_signature(args, files, sigkey_path)
# Append data to extracted apk.static
with open(files["apk"]["temp_path"], "ab") as handle:
handle.write("appended something".encode())
# Verify signature again (fail) (this deletes the tempfiles)
with pytest.raises(RuntimeError) as e:
pmb.chroot.apk_static.verify_signature(args, files, sigkey_path)
assert "Failed to validate signature" in str(e.value)
#
# Test "apk.static --version" check
#
with pytest.raises(RuntimeError) as e:
pmb.chroot.apk_static.extract(args, "99.1.2-r1", apk_path)
assert "downgrade attack" in str(e.value)
def test_outdated_version(args: PmbArgs, monkeypatch):
if os.path.exists(get_context().config.work / "apk.static"):
os.remove(get_context().config.work / "apk.static")
# Change min version for all branches
min_copy = copy.copy(pmb.config.apk_tools_min_version)
for key, old_ver in min_copy.items():
min_copy[key] = "99.1.2-r1"
monkeypatch.setattr(pmb.config, "apk_tools_min_version", min_copy)
with pytest.raises(RuntimeError) as e:
pmb.chroot.apk_static.init(args)
assert "outdated version" in str(e.value)

View file

@ -1,132 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import os
import sys
from pmb.types import PmbArgs
import pytest
import shutil
import filecmp
import pmb_test
import pmb_test.git
import pmb_test.const
import pmb.aportgen
import pmb.aportgen.core
import pmb.config
import pmb.helpers.logging
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
cfg = f"{pmb_test.const.testdata}/channels.cfg"
sys.argv = ["pmbootstrap.py", "--config-channels", cfg, "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
args.fork_alpine = False
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_aportgen_compare_output(args: PmbArgs, tmpdir, monkeypatch):
# Fake aports folder in tmpdir
tmpdir = str(tmpdir)
pmb_test.git.copy_dotgit(args, tmpdir)
args.aports = tmpdir
os.mkdir(tmpdir + "/cross")
testdata = pmb_test.const.testdata + "/aportgen"
# Override get_upstream_aport() to point to testdata
def func(args: PmbArgs, upstream_path, arch=None):
return testdata + "/aports/main/" + upstream_path
monkeypatch.setattr(pmb.aportgen.core, "get_upstream_aport", func)
# Run aportgen and compare output
pkgnames = ["gcc-armhf"]
for pkgname in pkgnames:
pmb.aportgen.generate(args, pkgname)
path_new = args.aports + "/cross/" + pkgname + "/APKBUILD"
path_old = testdata + "/pmaports/cross/" + pkgname + "/APKBUILD"
assert os.path.exists(path_new)
assert filecmp.cmp(path_new, path_old, False)
def test_aportgen_fork_alpine_compare_output(args: PmbArgs, tmpdir, monkeypatch):
# Fake aports folder in tmpdir
tmpdir = str(tmpdir)
pmb_test.git.copy_dotgit(args, tmpdir)
args.aports = tmpdir
os.mkdir(tmpdir + "/temp")
testdata = pmb_test.const.testdata + "/aportgen"
args.fork_alpine = True
# Override get_upstream_aport() to point to testdata
def func(args: PmbArgs, upstream_path, arch=None):
return testdata + "/aports/main/" + upstream_path
monkeypatch.setattr(pmb.aportgen.core, "get_upstream_aport", func)
# Run aportgen and compare output
pkgname = "binutils"
pmb.aportgen.generate(args, pkgname)
path_new = args.aports + "/temp/" + pkgname + "/APKBUILD"
path_old = testdata + "/pmaports/temp/" + pkgname + "/APKBUILD"
assert os.path.exists(path_new)
assert filecmp.cmp(path_new, path_old, False)
def test_aportgen(args: PmbArgs, tmpdir):
# Fake aports folder in tmpdir
testdata = pmb_test.const.testdata
tmpdir = str(tmpdir)
pmb_test.git.copy_dotgit(args, tmpdir)
args.aports = tmpdir
shutil.copy(f"{testdata}/pmaports.cfg", args.aports)
os.mkdir(tmpdir + "/cross")
# Create aportgen folder -> code path where it still exists
pmb.helpers.run.user(["mkdir", "-p", get_context().config.work / "aportgen"])
# Generate all valid packages (gcc twice -> different code path)
pkgnames = ["musl-armv7",
"busybox-static-armv7",
"gcc-armv7",
"gcc-armv7"]
for pkgname in pkgnames:
pmb.aportgen.generate(args, pkgname)
def test_aportgen_invalid_generator(args: PmbArgs):
with pytest.raises(ValueError) as e:
pmb.aportgen.generate(args, "pkgname-with-no-generator")
assert "No generator available" in str(e.value)
def test_aportgen_get_upstream_aport(args: PmbArgs, monkeypatch):
# Fake pmb.parse.apkbuild()
def fake_apkbuild(*args, **kwargs):
return apkbuild
monkeypatch.setattr(pmb.parse, "apkbuild", fake_apkbuild)
# Fake pmb.parse.apkindex.package()
def fake_package(*args, **kwargs):
return package
monkeypatch.setattr(pmb.parse.apkindex, "package", fake_package)
# Equal version
func = pmb.aportgen.core.get_upstream_aport
upstream = "gcc"
upstream_full = get_context().config.work / "cache_git/aports_upstream/main/" + upstream
apkbuild = {"pkgver": "2.0", "pkgrel": "0"}
package = {"version": "2.0-r0"}
assert func(args, upstream) == upstream_full
# APKBUILD < binary
apkbuild = {"pkgver": "1.0", "pkgrel": "0"}
package = {"version": "2.0-r0"}
assert func(args, upstream) == upstream_full
# APKBUILD > binary
apkbuild = {"pkgver": "3.0", "pkgrel": "0"}
package = {"version": "2.0-r0"}
assert func(args, upstream) == upstream_full

View file

@ -1,185 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
from pmb.core import get_context
from pmb.helpers import logging
from pmb.types import PmbArgs
import pytest
import sys
import shutil
import pmb_test # noqa
import pmb_test.git
import pmb_test.const
import pmb.aportgen
import pmb.config
import pmb.helpers.logging
import pmb.parse
@pytest.fixture
def args(tmpdir, request):
cfg = f"{pmb_test.const.testdata}/channels.cfg"
sys.argv = ["pmbootstrap.py", "--config-channels", cfg, "build", "-i",
"device-testsuite-testdevice"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
# Fake aports folder:
tmpdir = str(tmpdir)
pmb_test.git.copy_dotgit(args, tmpdir)
setattr(args, "_aports_real", args.aports)
args.aports = tmpdir
# Copy the devicepkg-dev package (shared device-* APKBUILD code)
pmb.helpers.run.user(["mkdir", "-p", tmpdir + "/main"])
path_dev = args._aports_real + "/main/devicepkg-dev"
pmb.helpers.run.user(["cp", "-r", path_dev, tmpdir + "/main"])
# Copy the linux-lg-mako aport (we currently copy patches from there)
pmb.helpers.run.user(["mkdir", "-p", tmpdir + "/device/testing"])
path_mako = args._aports_real + "/device/testing/linux-lg-mako"
pmb.helpers.run.user(["cp", "-r", path_mako,
f"{tmpdir}/device/testing"])
# Copy pmaports.cfg
shutil.copy(f"{pmb_test.const.testdata}/pmaports.cfg", args.aports)
return args
def generate(args: PmbArgs, monkeypatch, answers):
"""
Generate the device-new-device and linux-new-device aports (with a patched
pmb.helpers.cli()).
:returns: (deviceinfo, apkbuild, apkbuild_linux) - the parsed dictionaries
of the created files, as returned by pmb.parse.apkbuild() and
pmb.parse.deviceinfo().
"""
# Patched function
def fake_ask(question="Continue?", choices=["y", "n"], default="n",
lowercase_answer=True, validation_regex=None, complete=None):
for substr, answer in answers.items():
if substr in question:
logging.info(question + ": " + answer)
# raise RuntimeError("test>" + answer)
return answer
raise RuntimeError("This testcase didn't expect the question '" +
question + "', please add it to the mapping.")
# Generate the aports
monkeypatch.setattr(pmb.helpers.cli, "ask", fake_ask)
pmb.aportgen.generate(args, "device-testsuite-testdevice")
pmb.aportgen.generate(args, "linux-testsuite-testdevice")
monkeypatch.undo()
aports = get_context().config.aports
apkbuild_path = (aports / "device/testing/"
"device-testsuite-testdevice/APKBUILD")
apkbuild_path_linux = (aports / "device/testing/"
"linux-testsuite-testdevice/APKBUILD")
# The build fails if the email is not a valid email, so remove them just
# for tests
remove_contributor_maintainer_lines(args, apkbuild_path)
remove_contributor_maintainer_lines(args, apkbuild_path_linux)
# Parse the deviceinfo and apkbuilds
pmb.helpers.other.cache["apkbuild"] = {}
apkbuild = pmb.parse.apkbuild(apkbuild_path)
apkbuild_linux = pmb.parse.apkbuild(apkbuild_path_linux,
check_pkgver=False)
deviceinfo = pmb.parse.deviceinfo("testsuite-testdevice")
return (deviceinfo, apkbuild, apkbuild_linux)
def remove_contributor_maintainer_lines(path):
with open(path, "r+", encoding="utf-8") as handle:
lines_new = []
for line in handle.readlines():
# Skip maintainer/contributor
if line.startswith("# Maintainer") or line.startswith(
"# Contributor"):
continue
lines_new.append(line)
# Write back
handle.seek(0)
handle.write("".join(lines_new))
handle.truncate()
def test_aportgen_device_wizard(args: PmbArgs, monkeypatch):
"""
Generate a device-testsuite-testdevice and linux-testsuite-testdevice
package multiple times and check if the output is correct. Also build the
device package once.
"""
# Answers to interactive questions
answers = {
"Device architecture": "armv7",
"external storage": "y",
"hardware keyboard": "n",
"Flash method": "heimdall",
"Manufacturer": "Testsuite",
"Name": "Testsuite Testdevice",
"Year": "1337",
"Chassis": "handset",
"Type": "isorec",
}
# First run
deviceinfo, apkbuild, apkbuild_linux = generate(args, monkeypatch, answers)
assert apkbuild["pkgname"] == "device-testsuite-testdevice"
assert apkbuild["pkgdesc"] == "Testsuite Testdevice"
assert apkbuild["depends"] == ["linux-testsuite-testdevice",
"postmarketos-base"]
assert apkbuild_linux["pkgname"] == "linux-testsuite-testdevice"
assert apkbuild_linux["pkgdesc"] == "Testsuite Testdevice kernel fork"
assert apkbuild_linux["arch"] == ["armv7"]
assert apkbuild_linux["_flavor"] == "testsuite-testdevice"
assert deviceinfo["name"] == "Testsuite Testdevice"
assert deviceinfo["manufacturer"] == answers["Manufacturer"]
assert deviceinfo["arch"] == "armv7"
assert deviceinfo["year"] == "1337"
assert deviceinfo["chassis"] == "handset"
assert deviceinfo["keyboard"] == "false"
assert deviceinfo["external_storage"] == "true"
assert deviceinfo["flash_method"] == "heimdall-isorec"
assert deviceinfo["generate_bootimg"] == ""
assert deviceinfo["generate_legacy_uboot_initfs"] == ""
# Build the device package
pkgname = "device-testsuite-testdevice"
pmb.build.checksum.update(args, pkgname)
pmb.build.package(args, pkgname, "armv7", force=True)
# Abort on overwrite confirmation
answers["overwrite"] = "n"
with pytest.raises(RuntimeError) as e:
deviceinfo, apkbuild, apkbuild_linux = generate(args, monkeypatch,
answers)
assert "Aborted." in str(e.value)
# fastboot (mkbootimg)
answers["overwrite"] = "y"
answers["Flash method"] = "fastboot"
answers["Path"] = ""
deviceinfo, apkbuild, apkbuild_linux = generate(args, monkeypatch, answers)
assert apkbuild["depends"] == ["linux-testsuite-testdevice",
"mkbootimg",
"postmarketos-base"]
assert deviceinfo["flash_method"] == answers["Flash method"]
assert deviceinfo["generate_bootimg"] == "true"
# 0xffff (legacy uboot initfs)
answers["Flash method"] = "0xffff"
deviceinfo, apkbuild, apkbuild_linux = generate(args, monkeypatch, answers)
assert apkbuild["depends"] == ["linux-testsuite-testdevice",
"postmarketos-base",
"uboot-tools"]
assert deviceinfo["generate_legacy_uboot_initfs"] == "true"

View file

@ -1,27 +0,0 @@
# SPDX-License-Identifier: GPL-3.0-or-later
import argparse
import pytest
from pmb.parse.arguments import toggle_other_boolean_flags
@pytest.fixture
def example_cli_with_flags():
parser = argparse.ArgumentParser(prog="sample cli")
parser.add_argument("-f1", "--flag1", action="store_true")
parser.add_argument("-f2", "--flag2", action="store_true")
return parser
def test_toggle_other_boolean_flags(example_cli_with_flags):
other_flags = ["flag1", "flag2"]
example_cli_with_flags.add_argument(
"-f12", "--flag12",
action=toggle_other_boolean_flags(*other_flags))
args = example_cli_with_flags.parse_args(['-f12'])
expected_flags_true = other_flags + ["flag12"]
for flag in expected_flags_true:
assert getattr(args, flag)

View file

@ -1,162 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import sys
import pytest
import pmb_test
import pmb_test.const
import pmb.chroot.apk_static
import pmb.parse.apkindex
import pmb.helpers.logging
import pmb.parse.bootimg
from pmb.core import get_context
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_bootimg_invalid_path(args: PmbArgs):
with pytest.raises(RuntimeError) as e:
pmb.parse.bootimg(args, "/invalid-path")
assert "Could not find file" in str(e.value)
def test_bootimg_kernel(args: PmbArgs):
path = pmb_test.const.testdata + "/bootimg/kernel-boot.img"
with pytest.raises(RuntimeError) as e:
pmb.parse.bootimg(args, path)
assert "heimdall-isorec" in str(e.value)
def test_bootimg_invalid_file(args: PmbArgs):
with pytest.raises(RuntimeError) as e:
pmb.parse.bootimg(args, __file__)
assert "File is not an Android boot.img" in str(e.value)
def test_bootimg_normal(args: PmbArgs):
path = pmb_test.const.testdata + "/bootimg/normal-boot.img"
output = {"header_version": "0",
"base": "0x80000000",
"kernel_offset": "0x00008000",
"ramdisk_offset": "0x04000000",
"second_offset": "0x00f00000",
"tags_offset": "0x0e000000",
"pagesize": "2048",
"cmdline": "bootopt=64S3,32S1,32S1",
"qcdt": "false",
"dtb_second": "false"}
assert pmb.parse.bootimg(args, path) == output
def test_bootimg_qcdt(args: PmbArgs):
path = pmb_test.const.testdata + "/bootimg/qcdt-boot.img"
output = {"base": "0x80000000",
"kernel_offset": "0x00008000",
"ramdisk_offset": "0x04000000",
"second_offset": "0x00f00000",
"tags_offset": "0x0e000000",
"pagesize": "2048",
"cmdline": "bootopt=64S3,32S1,32S1",
"qcdt": "true",
"dtb_second": "false"}
assert pmb.parse.bootimg(args, path) == output
def test_bootimg_mtk(args: PmbArgs):
path = pmb_test.const.testdata + "/bootimg/mtk-boot.img"
output = {"header_version": "0",
"base": "0x10000000",
"kernel_offset": "0x00008000",
"ramdisk_offset": "0x01000000",
"second_offset": "0x00f00000",
"tags_offset": "0x00000100",
"pagesize": "2048",
"mtk_label_kernel": "KERNEL",
"mtk_label_ramdisk": "ROOTFS",
"cmdline": "",
"qcdt": "false",
"dtb_second": "false"}
assert pmb.parse.bootimg(args, path) == output
def test_bootimg_mtk_recovery(args: PmbArgs):
path = pmb_test.const.testdata + "/bootimg/mtk-boot-recovery.img"
output = {"header_version": "0",
"base": "0x80000000",
"kernel_offset": "0x00008000",
"ramdisk_offset": "0x04000000",
"second_offset": "0x00f00000",
"tags_offset": "0x00000100",
"pagesize": "2048",
"mtk_label_kernel": "KERNEL",
"mtk_label_ramdisk": "ROOTFS",
"cmdline": "",
"qcdt": "false",
"dtb_second": "false"}
assert pmb.parse.bootimg(args, path) == output
def test_bootimg_mtk_kernelonly(args: PmbArgs):
path = pmb_test.const.testdata + "/bootimg/mtk-boot-kernel-only.img"
output = {"header_version": "0",
"base": "0x10000000",
"kernel_offset": "0x00008000",
"ramdisk_offset": "0x01000000",
"second_offset": "0xf0000000",
"tags_offset": "0x00000100",
"pagesize": "2048",
"mtk_label_kernel": "KERNEL",
"cmdline": "",
"qcdt": "false",
"dtb_second": "false"}
assert pmb.parse.bootimg(args, path) == output
def test_bootimg_dtb_second(args: PmbArgs):
path = pmb_test.const.testdata + "/bootimg/dtb-second-boot.img"
output = {"header_version": "0",
"base": "0x00000000",
"kernel_offset": "0x00008000",
"ramdisk_offset": "0x02000000",
"second_offset": "0x00f00000",
"tags_offset": "0x00000100",
"pagesize": "2048",
"cmdline": "bootopt=64S3,32S1,32S1",
"qcdt": "false",
"dtb_second": "true"}
assert pmb.parse.bootimg(args, path) == output
def test_bootimg_v2(args: PmbArgs):
path = pmb_test.const.testdata + "/bootimg/boot-header-v2.img"
output = {"header_version": "2",
"base": "0x40078000",
"kernel_offset": "0x00008000",
"ramdisk_offset": "0x07c08000",
"second_offset": "0x00e10000",
"tags_offset": "0x0bc08000",
"pagesize": "2048",
"dtb_offset": "0x0bc08000",
"cmdline": "bootopt=64S3,32N2,64N2 systempart=/dev/mapper/system",
"qcdt": "false",
"dtb_second": "false"}
assert pmb.parse.bootimg(args, path) == output
def test_bootimg_v3(args: PmbArgs):
path = pmb_test.const.testdata + "/bootimg/boot-header-v3.img"
output = {"header_version": "3",
"pagesize": "4096",
"cmdline": "twrpfastboot=1",
"qcdt": "false",
"dtb_second": "false"}
assert pmb.parse.bootimg(args, path) == output

View file

@ -1,90 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import os
import sys
from pmb.types import PmbArgs
import pytest
import pmb_test # noqa
import pmb.helpers.logging
import pmb.helpers.pmaports
@pytest.fixture
def args(request, tmpdir):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
# Create an empty APKINDEX.tar.gz file, so we can use its path and
# timestamp to put test information in the cache.
apkindex_path = str(tmpdir) + "/APKINDEX.tar.gz"
open(apkindex_path, "a").close()
lastmod = os.path.getmtime(apkindex_path)
pmb.helpers.other.cache["apkindex"][apkindex_path] = {"lastmod": lastmod,
"multiple": {}}
return args
def cache_apkindex(version):
"""
Modify the cache of the parsed binary package repository's APKINDEX
for the "hello-world" package.
:param version: full version string, includes pkgver and pkgrl (e.g. 1-r2)
"""
apkindex_path = list(pmb.helpers.other.cache["apkindex"].keys())[0]
providers = pmb.helpers.other.cache[
"apkindex"][apkindex_path]["multiple"]["hello-world"]
providers["hello-world"]["version"] = version
def test_build_is_necessary(args: PmbArgs):
# Prepare APKBUILD and APKINDEX data
aport = pmb.helpers.pmaports.find("hello-world")
apkbuild = pmb.parse.apkbuild(f"{aport}/APKBUILD")
apkbuild["pkgver"] = "1"
apkbuild["pkgrel"] = "2"
indexes = list(pmb.helpers.other.cache["apkindex"].keys())
apkindex_path = indexes[0]
cache = {"hello-world": {"hello-world": {"pkgname": "hello-world",
"version": "1-r2"}}}
pmb.helpers.other.cache["apkindex"][apkindex_path]["multiple"] = cache
# Binary repo has a newer version
cache_apkindex("999-r1")
assert pmb.build.is_necessary(args, None, apkbuild, indexes) is False
# Aports folder has a newer version
cache_apkindex("0-r0")
assert pmb.build.is_necessary(args, None, apkbuild, indexes) is True
# Same version
cache_apkindex("1-r2")
assert pmb.build.is_necessary(args, None, apkbuild, indexes) is False
def test_build_is_necessary_no_binary_available(args: PmbArgs):
"""
APKINDEX cache is set up to fake an empty APKINDEX, which means that the
hello-world package has not been built yet.
"""
indexes = list(pmb.helpers.other.cache["apkindex"].keys())
aport = pmb.helpers.pmaports.find("hello-world")
apkbuild = pmb.parse.apkbuild(f"{aport}/APKBUILD")
assert pmb.build.is_necessary(args, None, apkbuild, indexes) is True
def test_build_is_necessary_cant_build_pmaport_for_arch(args: PmbArgs):
""" pmaport version is higher than Alpine's binary package, but pmaport
can't be built for given arch. (#1897) """
apkbuild = {"pkgname": "alpine-base",
"arch": "armhf", # can't build for x86_64!
"pkgver": "9999",
"pkgrel": "0"}
assert pmb.build.is_necessary(args, "x86_64", apkbuild) is False
assert pmb.build.is_necessary(args, "armhf", apkbuild) is True

View file

@ -1,489 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
""" Tests all functions from pmb.build._package """
import datetime
import glob
import os
from pmb.types import PmbArgs
import pytest
import shutil
import sys
import pmb_test # noqa
import pmb_test.git
import pmb.build
import pmb.build._package
import pmb.config
import pmb.config.init
import pmb.helpers.logging
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap", "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def return_none(*args, **kwargs):
return None
def return_string(*args, **kwargs):
return "some/random/path.apk"
def return_true(*args, **kwargs):
return True
def return_false(*args, **kwargs):
return False
def return_fake_build_depends(*args, **kwargs):
"""
Fake return value for pmb.build._package.build_depends:
depends: ["alpine-base"], depends_built: []
"""
return (["alpine-base"], [])
def args_patched(monkeypatch, argv):
monkeypatch.setattr(sys, "argv", argv)
return pmb.parse.arguments()
def test_skip_already_built(args: PmbArgs):
func = pmb.build._package.skip_already_built
assert pmb.helpers.other.cache["built"] == {}
assert func("test-package", "armhf") is False
assert pmb.helpers.other.cache["built"] == {"armhf": ["test-package"]}
assert func("test-package", "armhf") is True
def test_get_apkbuild(args: PmbArgs):
func = pmb.build._package.get_apkbuild
# Valid aport
pkgname = "postmarketos-base"
assert func(args, pkgname, "x86_64")["pkgname"] == pkgname
# Valid binary package
assert func(args, "alpine-base", "x86_64") is None
# Invalid package
with pytest.raises(RuntimeError) as e:
func(args, "invalid-package-name", "x86_64")
assert "Could not find" in str(e.value)
def test_check_build_for_arch(monkeypatch, args):
# Fake APKBUILD data
apkbuild = {"pkgname": "testpkgname"}
def fake_helpers_pmaports_get(args: PmbArgs, pkgname):
return apkbuild
monkeypatch.setattr(pmb.helpers.pmaports, "get", fake_helpers_pmaports_get)
# pmaport with arch exists
func = pmb.build._package.check_build_for_arch
apkbuild["arch"] = ["armhf"]
assert func(args, "testpkgname", "armhf") is True
apkbuild["arch"] = ["noarch"]
assert func(args, "testpkgname", "armhf") is True
apkbuild["arch"] = ["all"]
assert func(args, "testpkgname", "armhf") is True
# No binary package exists and can't build it
apkbuild["arch"] = ["x86_64"]
with pytest.raises(RuntimeError) as e:
func(args, "testpkgname", "armhf")
assert "Can't build" in str(e.value)
# pmaport can't be built for x86_64, but binary package exists in Alpine
apkbuild = {"pkgname": "mesa",
"arch": "armhf",
"pkgver": "9999",
"pkgrel": "0"}
assert func(args, "mesa", "x86_64") is False
def test_get_depends(monkeypatch):
func = pmb.build._package.get_depends
apkbuild = {"pkgname": "test", "depends": ["a"], "makedepends": ["c", "b"],
"checkdepends": "e", "subpackages": {"d": None}, "options": []}
# Depends + makedepends
args = args_patched(monkeypatch, ["pmbootstrap", "build", "test"])
assert func(args, apkbuild) == ["a", "b", "c", "e"]
args = args_patched(monkeypatch, ["pmbootstrap", "install"])
assert func(args, apkbuild) == ["a", "b", "c", "e"]
# Ignore depends (-i)
args = args_patched(monkeypatch, ["pmbootstrap", "build", "-i", "test"])
assert func(args, apkbuild) == ["b", "c", "e"]
# Package depends on its own subpackage
apkbuild["makedepends"] = ["d"]
args = args_patched(monkeypatch, ["pmbootstrap", "build", "test"])
assert func(args, apkbuild) == ["a", "e"]
# Package depends on itself
apkbuild["makedepends"] = ["c", "b", "test"]
args = args_patched(monkeypatch, ["pmbootstrap", "build", "test"])
assert func(args, apkbuild) == ["a", "b", "c", "e"]
def test_build_depends(args: PmbArgs, monkeypatch):
# Shortcut and fake apkbuild
func = pmb.build._package.build_depends
apkbuild = {"pkgname": "test", "depends": ["a", "!c"],
"makedepends": ["b"], "checkdepends": [],
"subpackages": {"d": None}, "options": []}
# No depends built (first makedepends + depends, then only makedepends)
monkeypatch.setattr(pmb.build._package, "package", return_none)
assert func(args, apkbuild, "armhf", True) == (["!c", "a", "b"], [])
# All depends built (makedepends only)
monkeypatch.setattr(pmb.build._package, "package", return_string)
assert func(args, apkbuild, "armhf", False) == (["!c", "a", "b"],
["a", "b"])
def test_build_depends_no_binary_error(args: PmbArgs, monkeypatch):
# Shortcut and fake apkbuild
func = pmb.build._package.build_depends
apkbuild = {"pkgname": "test", "depends": ["some-invalid-package-here"],
"makedepends": [], "checkdepends": [], "subpackages": {},
"options": []}
# pmbootstrap build --no-depends
args.no_depends = True
# Missing binary package error
with pytest.raises(RuntimeError) as e:
func(args, apkbuild, "armhf", True)
assert str(e.value).startswith("Missing binary package for dependency")
# All depends exist
apkbuild["depends"] = ["alpine-base"]
assert func(args, apkbuild, "armhf", True) == (["alpine-base"], [])
def test_build_depends_binary_outdated(args: PmbArgs, monkeypatch):
""" pmbootstrap runs with --no-depends and dependency binary package is
outdated (#1895) """
# Override pmb.parse.apkindex.package(): pretend hello-world-wrapper is
# missing and hello-world is outdated
func_orig = pmb.parse.apkindex.package
def func_patch(args: PmbArgs, package, *args2, **kwargs):
print(f"func_patch: called for package: {package}")
if package == "hello-world-wrapper":
print("pretending that it does not exist")
return None
if package == "hello-world":
print("pretending that it is outdated")
ret = func_orig(args, package, *args2, **kwargs)
ret["version"] = "0-r0"
return ret
return func_orig(args, package, *args2, **kwargs)
monkeypatch.setattr(pmb.parse.apkindex, "package", func_patch)
# Build hello-world-wrapper with --no-depends and expect failure
args.no_depends = True
pkgname = "hello-world-wrapper"
arch = "x86_64"
force = False
strict = True
with pytest.raises(RuntimeError) as e:
pmb.build.package(args, pkgname, arch, force, strict)
assert "'hello-world' of 'hello-world-wrapper' is outdated" in str(e.value)
def test_is_necessary_warn_depends(args: PmbArgs, monkeypatch):
# Shortcut and fake apkbuild
func = pmb.build._package.is_necessary_warn_depends
apkbuild = {"pkgname": "test"}
# Necessary
monkeypatch.setattr(pmb.build, "is_necessary", return_true)
assert func(args, apkbuild, "armhf", False, []) is True
# Necessary (strict=True overrides is_necessary())
monkeypatch.setattr(pmb.build, "is_necessary", return_false)
assert func(args, apkbuild, "armhf", True, []) is True
# Not necessary (with depends: different code path that prints a warning)
assert func(args, apkbuild, "armhf", False, []) is False
assert func(args, apkbuild, "armhf", False, ["first", "second"]) is False
def test_init_buildenv(args: PmbArgs, monkeypatch):
# First init native chroot buildenv properly without patched functions
pmb.build.init(args)
# Disable effects of functions we don't want to test here
monkeypatch.setattr(pmb.build._package, "build_depends",
return_fake_build_depends)
monkeypatch.setattr(pmb.build._package, "is_necessary_warn_depends",
return_true)
monkeypatch.setattr(pmb.chroot.apk, "install", return_none)
# Shortcut and fake apkbuild
func = pmb.build._package.init_buildenv
apkbuild = {"pkgname": "test", "depends": ["a"], "makedepends": ["b"],
"options": []}
# Build is necessary (various code paths)
assert func(args, apkbuild, "armhf", strict=True) is True
assert func(args, apkbuild, "armhf", cross="native") is True
# Build is not necessary (only builds dependencies)
monkeypatch.setattr(pmb.build._package, "is_necessary_warn_depends",
return_false)
assert func(args, apkbuild, "armhf") is False
def test_get_pkgver(monkeypatch):
# With original source
func = pmb.build._package.get_pkgver
assert func("1.0", True) == "1.0"
# Without original source
now = datetime.date(2018, 1, 1)
assert func("1.0", False, now) == "1.0_p20180101000000"
assert func("1.0_git20170101", False, now) == "1.0_p20180101000000"
def test_run_abuild(args: PmbArgs, monkeypatch):
# Disable effects of functions we don't want to test here
monkeypatch.setattr(pmb.build, "copy_to_buildpath", return_none)
monkeypatch.setattr(pmb.chroot, "user", return_none)
# Shortcut and fake apkbuild
func = pmb.build._package.run_abuild
apkbuild = {"pkgname": "test", "pkgver": "1", "pkgrel": "2", "options": []}
# Normal run
output = "armhf/test-1-r2.apk"
env = {"CARCH": "armhf",
"GOCACHE": "/home/pmos/.cache/go-build",
"RUSTC_WRAPPER": "/usr/bin/sccache",
"SUDO_APK": "abuild-apk --no-progress"}
cmd = ["abuild", "-D", "postmarketOS", "-d"]
assert func(args, apkbuild, "armhf") == (output, cmd, env)
# Force and strict
cmd = ["abuild", "-D", "postmarketOS", "-r", "-f"]
assert func(args, apkbuild, "armhf", True, True) == (output, cmd, env)
# cross=native
env = {"CARCH": "armhf",
"GOCACHE": "/home/pmos/.cache/go-build",
"RUSTC_WRAPPER": "/usr/bin/sccache",
"SUDO_APK": "abuild-apk --no-progress",
"CROSS_COMPILE": "armv6-alpine-linux-musleabihf-",
"CC": "armv6-alpine-linux-musleabihf-gcc"}
cmd = ["abuild", "-D", "postmarketOS", "-d"]
assert func(args, apkbuild, "armhf", cross="native") == (output, cmd, env)
def test_finish(args: PmbArgs, monkeypatch):
# Real output path
output = pmb.build.package(args, "hello-world", force=True)
# Disable effects of functions we don't want to test below
monkeypatch.setattr(pmb.chroot, "user", return_none)
# Shortcut and fake apkbuild
func = pmb.build._package.finish
apkbuild = {"options": []}
# Non-existing output path
with pytest.raises(RuntimeError) as e:
func(args, apkbuild, "armhf", "/invalid/path")
assert "Package not found" in str(e.value)
# Existing output path
func(args, apkbuild, pmb.config.arch_native, output)
def test_package(args: PmbArgs):
# First build
assert pmb.build.package(args, "hello-world", force=True)
# Package exists
pmb.helpers.other.cache["built"] = {}
assert pmb.build.package(args, "hello-world") is None
# Force building again
pmb.helpers.other.cache["built"] = {}
assert pmb.build.package(args, "hello-world", force=True)
# Build for another architecture
# TODO: test disabled, seems to *only* fail on gitlab runners and nowhere else.
# See: https://gitlab.com/postmarketOS/pmbootstrap/-/issues/2346
# assert pmb.build.package(args, "hello-world", "armhf", force=True)
# Upstream package, for which we don't have an aport
assert pmb.build.package(args, "alpine-base") is None
def test_build_depends_high_level(args: PmbArgs, monkeypatch):
"""
"hello-world-wrapper" depends on "hello-world". We build both, then delete
"hello-world" and check that it gets rebuilt correctly again.
"""
# Patch pmb.build.is_necessary() to always build the hello-world package
def fake_build_is_necessary(args: PmbArgs, arch, apkbuild, apkindex_path=None):
if apkbuild["pkgname"] == "hello-world":
return True
return pmb.build.other.is_necessary(args, arch, apkbuild,
apkindex_path)
monkeypatch.setattr(pmb.build, "is_necessary",
fake_build_is_necessary)
# Build hello-world to get its full output path
channel = pmb.config.pmaports.read_config()["channel"]
output_hello = pmb.build.package(args, "hello-world")
output_hello_outside = get_context().config.work / "packages" / channel / output_hello
assert output_hello_outside.exists()
# Make sure the wrapper exists
pmb.build.package(args, "hello-world-wrapper")
# Remove hello-world
pmb.helpers.run.root(["rm", output_hello_outside])
pmb.build.index_repo(args, pmb.config.arch_native)
pmb.helpers.other.cache["built"] = {}
# Ask to build the wrapper. It should not build the wrapper (it exists, not
# using force), but build/update its missing dependency "hello-world"
# instead.
assert pmb.build.package(args, "hello-world-wrapper") is None
assert os.path.exists(output_hello_outside)
def test_build_local_source_high_level(args: PmbArgs, tmpdir):
"""
Test building a package with overriding the source code:
pmbootstrap build --src=/some/path hello-world
We use a copy of the hello-world APKBUILD here that doesn't have the
source files it needs to build included. And we use the original aport
folder as local source folder, so pmbootstrap should take the source files
from there and the build should succeed.
"""
# aports: Add deviceinfo (required by pmbootstrap to start)
tmpdir = str(tmpdir)
aports = tmpdir + "/aports"
aport = aports + "/device/testing/device-" + args.devicesdhbfvhubsud
os.makedirs(aport)
path_original = pmb.helpers.pmaports.find(f"device-{args.devicesdhbfvhubsud}")
shutil.copy(f"{path_original}/deviceinfo", aport)
# aports: Add modified hello-world aport (source="", uses $builddir)
aport = aports + "/main/hello-world"
os.makedirs(aport)
shutil.copy(pmb.config.pmb_src + "/test/testdata/build_local_src/APKBUILD",
aport)
# aports: Add pmaports.cfg, .git
shutil.copy(args.aports + "/pmaports.cfg", aports)
pmb_test.git.copy_dotgit(args, tmpdir)
# src: Copy hello-world source files
src = tmpdir + "/src"
os.makedirs(src)
shutil.copy(args.aports + "/main/hello-world/Makefile", src)
shutil.copy(args.aports + "/main/hello-world/main.c", src)
# src: Create unreadable file (rsync should skip it)
unreadable = src + "/_unreadable_file"
shutil.copy(args.aports + "/main/hello-world/main.c", unreadable)
pmb.helpers.run.root(["chown", "root:root", unreadable])
pmb.helpers.run.root(["chmod", "500", unreadable])
# Test native arch and foreign arch chroot
channel = pmb.config.pmaports.read_config()["channel"]
# TODO: test disabled, seems to *only* fail on gitlab runners and nowhere else.
# See: https://gitlab.com/postmarketOS/pmbootstrap/-/issues/2346
# for arch in [pmb.config.arch_native, "armhf"]:
for arch in [pmb.config.arch_native]:
# Delete all hello-world --src packages
pattern = f"{args.work}/packages/{channel}/{arch}/hello-world-*_p*.apk"
for path in glob.glob(pattern):
pmb.helpers.run.root(["rm", path])
assert len(glob.glob(pattern)) == 0
# Build hello-world --src package
pmb.helpers.run.user([pmb.config.pmb_src + "/pmbootstrap.py",
"--aports", aports, "build", "--src", src,
"hello-world", "--arch", arch])
# Verify that the package has been built and delete it
paths = glob.glob(pattern)
assert len(paths) == 1
pmb.helpers.run.root(["rm", paths[0]])
# Clean up: update index, delete temp folder
pmb.build.index_repo(args, pmb.config.arch_native)
pmb.helpers.run.root(["rm", "-r", tmpdir])
def test_build_abuild_leftovers(args: PmbArgs, tmpdir):
"""
Test building a package with having abuild leftovers, that will error if
copied:
pmbootstrap build hello-world
"""
# aports: Add deviceinfo (required by pmbootstrap to start)
tmpdir = str(tmpdir)
aports = f"{tmpdir}/aports"
aport = f"{aports}/device/testing/device-{args.devicesdhbfvhubsud}"
os.makedirs(aport)
path_original = pmb.helpers.pmaports.find(f"device-{args.devicesdhbfvhubsud}")
shutil.copy(f"{path_original}/deviceinfo", aport)
# aports: Add modified hello-world aport (source="", uses $builddir)
test_aport = "main/hello-world"
aport = f"{aports}/{test_aport}"
shutil.copytree(f"{args.aports}/{test_aport}", aport)
# aports: Add pmaports.cfg, .git
shutil.copy(f"{args.aports}/pmaports.cfg", aports)
pmb_test.git.copy_dotgit(args, aports)
# aport: create abuild dir with broken symlink
src = f"{aport}/src"
os.makedirs(src)
os.symlink("/var/cache/distfiles/non-existent.tar.gz",
f"{src}/broken-tarball-symlink.tar.gz")
# Delete all hello-world packages
channel = pmb.config.pmaports.read_config()["channel"]
pattern = f"{args.work}/packages/{channel}/*/hello-world-*_p*.apk"
for path in glob.glob(pattern):
pmb.helpers.run.root(["rm", path])
assert len(glob.glob(pattern)) == 0
# Build hello-world package
pmb.helpers.run.user([f"{pmb.config.pmb_src}/pmbootstrap.py",
"--aports", aports, "build", "--src", src,
"hello-world", "--arch", pmb.config.arch_native])
# Verify that the package has been built and delete it
paths = glob.glob(pattern)
assert len(paths) == 1
pmb.helpers.run.root(["rm", paths[0]])
# Clean up: update index, delete temp folder
pmb.build.index_repo(args, pmb.config.arch_native)
pmb.helpers.run.root(["rm", "-r", tmpdir])

View file

@ -1,52 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import subprocess
import os
import pmb_test # noqa
import pmb.config
def test_chroot_interactive_shell():
"""
Open a shell with 'pmbootstrap chroot' and pass 'echo hello_world\n' as
stdin.
"""
os.chdir(pmb.config.pmb_src)
ret = subprocess.check_output(["./pmbootstrap.py", "-q", "chroot", "sh"],
timeout=300, input="echo hello_world\n",
universal_newlines=True,
stderr=subprocess.STDOUT)
assert ret == "hello_world\n"
def test_chroot_interactive_shell_user():
"""
Open a shell with 'pmbootstrap chroot' as user, and test the resulting ID.
"""
os.chdir(pmb.config.pmb_src)
ret = subprocess.check_output(["./pmbootstrap.py", "-q", "chroot",
"--user", "sh"], timeout=300,
input="id -un",
universal_newlines=True,
stderr=subprocess.STDOUT)
assert ret == "pmos\n"
def test_chroot_arguments():
"""
Open a shell with 'pmbootstrap chroot' for every architecture, pass
'uname -m\n' as stdin and check the output
"""
os.chdir(pmb.config.pmb_src)
for arch in ["armhf", "aarch64", "x86_64"]:
ret = subprocess.check_output(["./pmbootstrap.py", "-q", "chroot",
"-b", arch, "sh"],
timeout=300,
input="uname -m\n",
universal_newlines=True,
stderr=subprocess.STDOUT)
if arch == "armhf":
assert ret == "armv7l\n"
else:
assert ret == arch + "\n"

View file

@ -1,41 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
""" Test pmb/chroot/mount.py """
import os
from pmb.types import PmbArgs
import pytest
import sys
import pmb_test # noqa
import pmb.chroot
from pmb.core import Chroot
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap", "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_chroot_mount(args: PmbArgs):
chroot = Chroot.native()
mnt_dir = chroot / "mnt/pmbootstrap"
# Run something in the chroot to have the dirs created
pmb.chroot.root(["true"])
assert mnt_dir.exists()
assert (mnt_dir / "packages").exists()
# Umount everything, like in pmb.install.install_system_image
pmb.helpers.mount.umount_all(chroot.path)
# Remove all /mnt/pmbootstrap dirs
pmb.chroot.remove_mnt_pmbootstrap(args, chroot)
assert not mnt_dir.exists()
# Run again: it should not crash
pmb.chroot.remove_mnt_pmbootstrap(args, chroot)

View file

@ -1,20 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import pytest
import pmb_test # noqa
import pmb.config.init
def test_require_programs(monkeypatch):
func = pmb.config.init.require_programs
# Nothing missing
func()
# Missing program
invalid = "invalid-program-name-here-asdf"
monkeypatch.setattr(pmb.config, "required_programs", [invalid])
with pytest.raises(RuntimeError) as e:
func()
assert str(e.value).startswith("Can't find all programs")

View file

@ -1,74 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
""" Test pmb/config/pmaports.py """
from pmb.types import PmbArgs
import pytest
import sys
import pmb_test
import pmb_test.const
import pmb_test.git
import pmb.config
import pmb.config.workdir
import pmb.config.pmaports
@pytest.fixture
def args(request):
import pmb.parse
cfg = f"{pmb_test.const.testdata}/channels.cfg"
sys.argv = ["pmbootstrap.py", "--config-channels", cfg, "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_switch_to_channel_branch(args: PmbArgs, monkeypatch, tmpdir):
path, run_git = pmb_test.git.prepare_tmpdir(args, monkeypatch, tmpdir)
args.aports = path
# Pretend to have channel=edge in pmaports.cfg
def read_config(args):
return {"channel": "edge"}
monkeypatch.setattr(pmb.config.pmaports, "read_config", read_config)
# Success: Channel does not change
func = pmb.config.pmaports.switch_to_channel_branch
assert func(args, "edge") is False
# Fail: git error (could be any error, but here: branch does not exist)
with pytest.raises(RuntimeError) as e:
func(args, "v20.05")
assert str(e.value).startswith("Failed to switch branch")
# Success: switch channel and change branch
run_git(["checkout", "-b", "v20.05"])
run_git(["checkout", "master"])
assert func(args, "v20.05") is True
branch = pmb.helpers.git.rev_parse(path, extra_args=["--abbrev-ref"])
assert branch == "v20.05"
def test_read_config_channel(args: PmbArgs, monkeypatch):
channel = "edge"
# Pretend to have a certain channel in pmaports.cfg
def read_config(args):
return {"channel": channel}
monkeypatch.setattr(pmb.config.pmaports, "read_config", read_config)
# Channel found
func = pmb.config.pmaports.read_config_channel
exp = {"description": "Rolling release channel",
"branch_pmaports": "master",
"branch_aports": "master",
"mirrordir_alpine": "edge"}
assert func(args) == exp
# Channel not found
channel = "non-existing"
with pytest.raises(RuntimeError) as e:
func(args)
assert "channel was not found in channels.cfg" in str(e.value)

View file

@ -1,69 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import sys
from pmb.types import PmbArgs
import pytest
import pmb_test # noqa
import pmb.aportgen
import pmb.config
import pmb.helpers.frontend
import pmb.helpers.logging
import pmb.helpers.run
import pmb.helpers.run_core
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def change_config(monkeypatch, path_config, key, value):
args = args_patched(monkeypatch, ["pmbootstrap.py", "-c", path_config,
"config", key, value])
pmb.helpers.frontend.config(args)
def args_patched(monkeypatch, argv):
monkeypatch.setattr(sys, "argv", argv)
return pmb.parse.arguments()
def test_config_user(args: PmbArgs, tmpdir, monkeypatch):
# Temporary paths
tmpdir = str(tmpdir)
path_work = tmpdir + "/work"
path_config = tmpdir + "/pmbootstrap.cfg"
# Generate default config (only uses tmpdir)
cmd = pmb.helpers.run_core.flat_cmd(["./pmbootstrap.py",
"-c", path_config,
"-w", path_work,
"--aports", args.aports,
"init"])
pmb.helpers.run.user(["sh", "-c", "yes '' | " + cmd],
pmb.config.pmb_src)
# Load and verify default config
argv = ["pmbootstrap.py", "-c", path_config, "config"]
args_default = args_patched(monkeypatch, argv)
assert args_default.work == path_work
# Modify jobs count
change_config(monkeypatch, path_config, "jobs", "9000")
assert args_patched(monkeypatch, argv).jobs == "9000"
# Override jobs count via commandline (-j)
argv_jobs = ["pmbootstrap.py", "-c", path_config, "-j", "1000", "config"]
assert args_patched(monkeypatch, argv_jobs).jobs == "1000"
# Override a config option with something that evaluates to false
argv_empty = ["pmbootstrap.py", "-c", path_config, "-w", "",
"--details-to-stdout", "config"]
assert args_patched(monkeypatch, argv_empty).work == ""

View file

@ -1,152 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
""" Test pmb/config/workdir.py """
import os
from pmb.types import PmbArgs
import pytest
import sys
import time
import pmb_test # noqa
import pmb.config
import pmb.config.pmaports
import pmb.config.workdir
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap", "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_chroot_save_init(args: PmbArgs, tmpdir, monkeypatch):
# Override time.time()
def fake_time():
return 1234567890.1234
monkeypatch.setattr(time, "time", fake_time)
# Pretend channel=v20.05 in pmaports.cfg
def read_config(args):
return {"channel": "v20.05"}
monkeypatch.setattr(pmb.config.pmaports, "read_config", read_config)
args.work = str(tmpdir)
func = pmb.config.workdir.chroot_save_init
func(args, "native")
expected = ("[chroot-init-dates]\n"
"native = 1234567890\n\n"
"[chroot-channels]\n"
"native = v20.05\n\n")
with open(get_context().config.work / "workdir.cfg", "r") as handle:
assert handle.read() == expected
# Write again (different code path)
func(args, "buildroot_armhf")
expected = ("[chroot-init-dates]\n"
"native = 1234567890\n"
"buildroot_armhf = 1234567890\n\n"
"[chroot-channels]\n"
"native = v20.05\n"
"buildroot_armhf = v20.05\n\n")
with open(get_context().config.work / "workdir.cfg", "r") as handle:
assert handle.read() == expected
def test_chroots_outdated(args: PmbArgs, tmpdir, monkeypatch):
args.work = str(tmpdir)
# Override time.time(): now is "100"
def fake_time():
return 100.0
monkeypatch.setattr(time, "time", fake_time)
# workdir.cfg does not exist
func = pmb.config.workdir.chroots_outdated
assert func(args) is False
# workdir.cfg is empty file
with open(get_context().config.work / "workdir.cfg", "w") as handle:
handle.write("")
assert func(args) is False
# Write fake workdir.cfg: native was created at "90"
with open(get_context().config.work / "workdir.cfg", "w") as handle:
handle.write("[chroot-init-dates]\nnative = 90\n\n")
# Outdated (date_outdated: 90)
monkeypatch.setattr(pmb.config, "chroot_outdated", 10)
assert func(args) is True
# Not outdated (date_outdated: 89)
monkeypatch.setattr(pmb.config, "chroot_outdated", 11)
assert func(args) is False
def test_chroot_check_channel(args: PmbArgs, tmpdir, monkeypatch):
func = pmb.config.workdir.chroot_check_channel
args.work = str(tmpdir)
channel = "edge"
# Pretend to have a certain channel in pmaports.cfg
def read_config(args):
return {"channel": channel}
monkeypatch.setattr(pmb.config.pmaports, "read_config", read_config)
# workdir.cfg does not exist
with pytest.raises(RuntimeError) as e:
func(args, "native")
assert "Could not figure out on which release channel" in str(e.value)
# Write workdir.cfg
with open(f"{args.work}/workdir.cfg", "w") as handle:
handle.write("[chroot-channels]\nnative = v20.05\n\n")
# workdir.cfg: no entry for buildroot_armhf chroot
with pytest.raises(RuntimeError) as e:
func(args, "buildroot_armhf")
assert "Could not figure out on which release channel" in str(e.value)
# Chroot was created for wrong channel
with pytest.raises(RuntimeError) as e:
func(args, "native")
exp = "created for the 'v20.05' channel, but you are on the 'edge'"
assert exp in str(e.value)
# Check runs through without raising an exception
channel = "v20.05"
func(args, "native")
def test_clean(args: PmbArgs, tmpdir):
args.work = str(tmpdir)
# 0. workdir.cfg does not exist
func = pmb.config.workdir.clean
assert func(args) is None
# Write fake workdir.cfg
cfg_fake = "[chroot-init-dates]\nnative = 1337\n\n"
with open(get_context().config.work / "workdir.cfg", "w") as handle:
handle.write(cfg_fake)
# 1. chroot_native dir exists
os.makedirs(get_context().config.work / "chroot_native")
assert func(args) is False
# workdir.cfg: unchanged
with open(get_context().config.work / "workdir.cfg", "r") as handle:
assert handle.read() == cfg_fake
# 2. chroot_native dir does not exist
os.rmdir(get_context().config.work / "chroot_native")
assert func(args) is True
# workdir.cfg: "native" entry removed
with open(get_context().config.work / "workdir.cfg", "r") as handle:
assert handle.read() == "[chroot-init-dates]\n\n"

View file

@ -1,120 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import sys
from pmb.types import PmbArgs
import pytest
import pmb_test
import pmb_test.const
import pmb.aportgen
import pmb.aportgen.core
import pmb.build
import pmb.build.envkernel
import pmb.config
import pmb.helpers.logging
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_package_kernel_args(args: PmbArgs):
args.packages = ["package-one", "package-two"]
with pytest.raises(RuntimeError) as e:
pmb.build.envkernel.package_kernel(args)
assert "--envkernel needs exactly one linux-* package as argument." in \
str(e.value)
def test_find_kbuild_output_dir():
# Test parsing an APKBUILD
pkgname = "linux-envkernel-test"
path = pmb_test.const.testdata + "/apkbuild/APKBUILD." + pkgname
function_body = pmb.parse.function_body(path, "package")
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
assert kbuild_out == "build"
# Test full function body
function_body = [
" install -Dm644 \"$srcdir\"/build/arch/arm/boot/dt.img ",
" \"$pkgdir\"/boot/dt.img",
"",
" install -Dm644 \"$srcdir\"/build/arch/arm/boot/zImage-dtb ",
" \"$pkgdir\"/boot/vmlinuz-$_flavor",
"",
" install -D \"$srcdir\"/build/include/config/kernel.release ",
" \"$pkgdir\"/usr/share/kernel/$_flavor/kernel.release",
"",
" cd \"$srcdir\"/build",
" unset LDFLAGS",
"",
" make ARCH=\"$_carch\" CC=\"${CC:-gcc}\" ",
" KBUILD_BUILD_VERSION=\"$((pkgrel + 1))-Alpine\" ",
" INSTALL_MOD_PATH=\"$pkgdir\" modules_install",
]
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
assert kbuild_out == "build"
# Test no kbuild out dir
function_body = [
" install -Dm644 \"$srcdir\"/arch/arm/boot/zImage ",
" \"$pkgdir\"/boot/vmlinuz-$_flavor",
" install -D \"$srcdir\"/include/config/kernel.release ",
" \"$pkgdir\"/usr/share/kernel/$_flavor/kernel.release",
]
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
assert kbuild_out == ""
# Test curly brackets around srcdir
function_body = [
" install -Dm644 \"${srcdir}\"/build/arch/arm/boot/zImage ",
" \"$pkgdir\"/boot/vmlinuz-$_flavor",
" install -D \"${srcdir}\"/build/include/config/kernel.release ",
" \"$pkgdir\"/usr/share/kernel/$_flavor/kernel.release",
]
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
assert kbuild_out == "build"
# Test multiple sub directories
function_body = [
" install -Dm644 \"${srcdir}\"/sub/dir/arch/arm/boot/zImage-dtb ",
" \"$pkgdir\"/boot/vmlinuz-$_flavor",
" install -D \"${srcdir}\"/sub/dir/include/config/kernel.release ",
" \"$pkgdir\"/usr/share/kernel/$_flavor/kernel.release",
]
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
assert kbuild_out == "sub/dir"
# Test no kbuild out dir found
function_body = [
" install -Dm644 \"$srcdir\"/build/not/found/zImage-dtb ",
" \"$pkgdir\"/boot/vmlinuz-$_flavor",
" install -D \"$srcdir\"/not/found/kernel.release ",
" \"$pkgdir\"/usr/share/kernel/$_flavor/kernel.release",
]
with pytest.raises(RuntimeError) as e:
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
assert ("Couldn't find a kbuild out directory. Is your APKBUILD messed up?"
" If not, then consider adjusting the patterns in "
"pmb/build/envkernel.py to work with your APKBUILD, or submit an "
"issue.") in str(e.value)
# Test multiple different kbuild out dirs
function_body = [
" install -Dm644 \"$srcdir\"/build/arch/arm/boot/zImage-dtb ",
" \"$pkgdir\"/boot/vmlinuz-$_flavor",
" install -D \"$srcdir\"/include/config/kernel.release ",
" \"$pkgdir\"/usr/share/kernel/$_flavor/kernel.release",
]
with pytest.raises(RuntimeError) as e:
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
assert ("Multiple kbuild out directories found. Can you modify your "
"APKBUILD so it only has one output path? If you can't resolve it,"
" please open an issue.") in str(e.value)

View file

@ -1,37 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import os
import sys
import time
from pmb.types import PmbArgs
import pytest
import pmb_test # noqa
import pmb.helpers.git
import pmb.helpers.logging
import pmb.parse.version
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_file_is_older_than(args: PmbArgs, tmpdir):
# Create a file last modified 10s ago
tempfile = str(tmpdir) + "/test"
pmb.helpers.run.user(["touch", tempfile])
past = time.time() - 10
os.utime(tempfile, (-1, past))
# Check the bounds
func = pmb.helpers.file.is_older_than
assert func(tempfile, 9) is True
assert func(tempfile, 10) is True
assert func(tempfile, 11) is False

View file

@ -1,38 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import sys
from pmb.types import PmbArgs
import pytest
import pmb_test # noqa
import pmb.helpers.logging
import pmb.helpers.other
import pmb.helpers.run
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.details_to_stdout = True
pmb.helpers.logging.init(args)
return args
def test_get_folder_size(args: PmbArgs, tmpdir):
# Write five 200 KB files to tmpdir
tmpdir = str(tmpdir)
files = 5
for i in range(files):
pmb.helpers.run.user(["dd", "if=/dev/zero", "of=" +
tmpdir + "/" + str(i), "bs=1K",
"count=200", "conv=notrunc"])
# Check if the size is correct. Unfortunately, the `du` call
# in pmb.helpers.other.folder_size is not very accurate, so we
# allow 30kb of tolerance (good enough for our use case): #760 #1717
tolerance = 30
size = 200 * files
result = pmb.helpers.other.folder_size(args, tmpdir)
assert (result < size + tolerance and result > size - tolerance)

View file

@ -1,19 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import sys
import pytest
import pmb_test # noqa
import pmb.config
import pmb.parse
import pmb.helpers.frontend
import pmb.helpers.logging
def test_build_src_invalid_path():
sys.argv = ["pmbootstrap.py", "build", "--src=/invalidpath", "hello-world"]
args = pmb.parse.arguments()
with pytest.raises(RuntimeError) as e:
pmb.helpers.frontend.build(args)
assert str(e.value).startswith("Invalid path specified for --src:")

View file

@ -1,168 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import os
import sys
from pmb.types import PmbArgs
import pytest
import shutil
import pmb_test # noqa
import pmb_test.const
import pmb_test.git
import pmb.helpers.git
import pmb.helpers.logging
import pmb.helpers.run
@pytest.fixture
def args(request):
import pmb.parse
cfg = f"{pmb_test.const.testdata}/channels.cfg"
sys.argv = ["pmbootstrap.py", "--config-channels", cfg, "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_get_path(args: PmbArgs):
func = pmb.helpers.git.get_path
args.work = "/wrk"
args.aports = "/tmp/pmaports"
assert func(args, "aports_upstream") == "/wrk/cache_git/aports_upstream"
assert func(args, "pmaports") == "/tmp/pmaports"
def test_can_fast_forward(args: PmbArgs, tmpdir):
tmpdir = str(tmpdir)
func = pmb.helpers.git.can_fast_forward
branch_origin = "fake-branch-origin"
def run_git(git_args):
pmb.helpers.run.user(["git"] + git_args, tmpdir, "stdout")
# Create test git repo
run_git(["init", "-b", "master", "."])
run_git(["commit", "--allow-empty", "-m", "commit on master"])
run_git(["checkout", "-b", branch_origin])
run_git(["commit", "--allow-empty", "-m", "commit on branch_origin"])
run_git(["checkout", "master"])
# Can fast-forward
assert func(args, tmpdir, branch_origin) is True
# Can't fast-forward
run_git(["commit", "--allow-empty", "-m", "commit on master #2"])
assert func(args, tmpdir, branch_origin) is False
# Git command fails
with pytest.raises(RuntimeError) as e:
func(args, tmpdir, "invalid-branch")
assert str(e.value).startswith("Unexpected exit code")
def test_clean_worktree(args: PmbArgs, tmpdir):
tmpdir = str(tmpdir)
func = pmb.helpers.git.clean_worktree
def run_git(git_args):
pmb.helpers.run.user(["git"] + git_args, tmpdir, "stdout")
# Create test git repo
run_git(["init", "-b", "master", "."])
run_git(["commit", "--allow-empty", "-m", "commit on master"])
assert func(args, tmpdir) is True
pmb.helpers.run.user(["touch", "test"], tmpdir)
assert func(args, tmpdir) is False
def test_get_upstream_remote(args: PmbArgs, monkeypatch, tmpdir):
tmpdir = str(tmpdir)
func = pmb.helpers.git.get_upstream_remote
name_repo = "test"
# Override get_path()
def get_path(args: PmbArgs, name_repo):
return tmpdir
monkeypatch.setattr(pmb.helpers.git, "get_path", get_path)
# Override pmb.config.git_repos
url = "https://postmarketos.org/get-upstream-remote-test.git"
git_repos = {"test": url}
monkeypatch.setattr(pmb.config, "git_repos", git_repos)
def run_git(git_args):
pmb.helpers.run.user(["git"] + git_args, tmpdir, "stdout")
# Create git repo
run_git(["init", "-b", "master", "."])
run_git(["commit", "--allow-empty", "-m", "commit on master"])
# No upstream remote
with pytest.raises(RuntimeError) as e:
func(args, name_repo)
assert "could not find remote name for URL" in str(e.value)
run_git(["remote", "add", "hello", url])
assert func(args, name_repo) == "hello"
def test_parse_channels_cfg(args: PmbArgs):
exp = {"meta": {"recommended": "edge"},
"channels": {"edge": {"description": "Rolling release channel",
"branch_pmaports": "master",
"branch_aports": "master",
"mirrordir_alpine": "edge"},
"v20.05": {"description": "For workgroups",
"branch_pmaports": "v20.05",
"branch_aports": "3.11-stable",
"mirrordir_alpine": "v3.11"},
"v21.03": {"description": "Second beta release",
"branch_pmaports": "v21.03",
"branch_aports": "3.13-stable",
"mirrordir_alpine": "v3.13"}}}
assert pmb.helpers.git.parse_channels_cfg(args) == exp
def test_pull_non_existing(args: PmbArgs):
assert pmb.helpers.git.pull("non-existing-repo-name") == 1
def test_pull(args: PmbArgs, monkeypatch, tmpdir):
""" Test pmb.helpers.git.pull """
path, run_git = pmb_test.git.prepare_tmpdir(args, monkeypatch, tmpdir)
# Not on official branch
func = pmb.helpers.git.pull
name_repo = "test"
run_git(["checkout", "-b", "inofficial-branch"])
assert func(args, name_repo) == -1
# Workdir is not clean
run_git(["checkout", "master"])
shutil.copy(__file__, path + "/test.py")
assert func(args, name_repo) == -2
os.unlink(path + "/test.py")
# Tracking different remote
assert func(args, name_repo) == -3
# Let master track origin/master
run_git(["checkout", "-b", "temp"])
run_git(["branch", "-D", "master"])
run_git(["checkout", "-b", "master", "--track", "origin/master"])
# Already up to date
assert func(args, name_repo) == 2
# Can't fast-forward
run_git(["commit", "--allow-empty", "-m", "test"])
assert func(args, name_repo) == -4
# Fast-forward successfully
run_git(["reset", "--hard", "origin/master"])
run_git(["commit", "--allow-empty", "-m", "new"], "remote")
assert func(args, name_repo) == 0

View file

@ -1,44 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import os
from pmb.types import PmbArgs
import pytest
import shutil
import sys
import pmb_test
import pmb_test.const
import pmb.helpers.lint
import pmb.helpers.run
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap", "lint"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_pmbootstrap_lint(args: PmbArgs, tmpdir):
args.aports = tmpdir = str(tmpdir)
# Create hello-world pmaport in tmpdir
apkbuild_orig = f"{pmb_test.const.testdata}/apkbuild/APKBUILD.lint"
apkbuild_tmp = f"{tmpdir}/hello-world/APKBUILD"
os.makedirs(f"{tmpdir}/hello-world")
shutil.copyfile(apkbuild_orig, apkbuild_tmp)
# Lint passes
assert pmb.helpers.lint.check(args, ["hello-world"]) == ""
# Change "pmb:cross-native" to non-existing "pmb:invalid-opt"
pmb.helpers.run.user(["sed", "s/pmb:cross-native/pmb:invalid-opt/g",
"-i", apkbuild_tmp])
# Lint error
err_str = "invalid option 'pmb:invalid-opt'"
assert err_str in pmb.helpers.lint.check(args, ["hello-world"])

View file

@ -1,138 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import sys
from pmb.types import PmbArgs
import pytest
import pmb_test # noqa
import pmb.helpers.logging
import pmb.helpers.package
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap", "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_helpers_package_get_pmaports_and_cache(args: PmbArgs, monkeypatch):
""" Test pmb.helpers.package.get(): find in pmaports, use cached result """
# Fake APKBUILD data
def stub(args: PmbArgs, pkgname, must_exist):
return {"arch": ["armv7"],
"depends": ["testdepend"],
"pkgname": "testpkgname",
"provides": ["testprovide"],
"options": [],
"checkdepends": [],
"subpackages": {},
"makedepends": [],
"pkgver": "1.0",
"pkgrel": "1"}
monkeypatch.setattr(pmb.helpers.pmaports, "get", stub)
package = {"arch": ["armv7"],
"depends": ["testdepend"],
"pkgname": "testpkgname",
"provides": ["testprovide"],
"version": "1.0-r1"}
func = pmb.helpers.package.get
assert func(args, "testpkgname", "armv7") == package
# Cached result
monkeypatch.delattr(pmb.helpers.pmaports, "get")
assert func(args, "testpkgname", "armv7") == package
def test_helpers_package_get_apkindex(args: PmbArgs, monkeypatch):
""" Test pmb.helpers.package.get(): find in apkindex """
# Fake APKINDEX data
fake_apkindex_data = {"arch": "armv7",
"depends": ["testdepend"],
"pkgname": "testpkgname",
"provides": ["testprovide"],
"version": "1.0-r1"}
def stub(args: PmbArgs, pkgname, arch, must_exist):
if arch != fake_apkindex_data["arch"]:
return None
return fake_apkindex_data
monkeypatch.setattr(pmb.parse.apkindex, "package", stub)
# Given arch
package = {"arch": ["armv7"],
"depends": ["testdepend"],
"pkgname": "testpkgname",
"provides": ["testprovide"],
"version": "1.0-r1"}
func = pmb.helpers.package.get
assert func(args, "testpkgname", "armv7") == package
# Other arch
assert func(args, "testpkgname", "x86_64") == package
def test_helpers_package_depends_recurse(args: PmbArgs):
""" Test pmb.helpers.package.depends_recurse() """
# Put fake data into the pmb.helpers.package.get() cache
cache = {"a": {False: {"pkgname": "a", "depends": ["b", "c"]}},
"b": {False: {"pkgname": "b", "depends": []}},
"c": {False: {"pkgname": "c", "depends": ["d"]}},
"d": {False: {"pkgname": "d", "depends": ["b"]}}}
pmb.helpers.other.cache["pmb.helpers.package.get"]["armhf"] = cache
# Normal runs
func = pmb.helpers.package.depends_recurse
assert func(args, "a", "armhf") == ["a", "b", "c", "d"]
assert func(args, "d", "armhf") == ["b", "d"]
# Cached result
pmb.helpers.other.cache["pmb.helpers.package.get"]["armhf"] = {}
assert func(args, "d", "armhf") == ["b", "d"]
def test_helpers_package_check_arch_package(args: PmbArgs):
""" Test pmb.helpers.package.check_arch(): binary = True """
# Put fake data into the pmb.helpers.package.get() cache
func = pmb.helpers.package.check_arch
cache = {"a": {False: {"arch": []}}}
pmb.helpers.other.cache["pmb.helpers.package.get"]["armhf"] = cache
cache["a"][False]["arch"] = ["all !armhf"]
assert func(args, "a", "armhf") is False
cache["a"][False]["arch"] = ["all"]
assert func(args, "a", "armhf") is True
cache["a"][False]["arch"] = ["noarch"]
assert func(args, "a", "armhf") is True
cache["a"][False]["arch"] = ["armhf"]
assert func(args, "a", "armhf") is True
cache["a"][False]["arch"] = ["aarch64"]
assert func(args, "a", "armhf") is False
def test_helpers_package_check_arch_pmaports(args: PmbArgs, monkeypatch):
""" Test pmb.helpers.package.check_arch(): binary = False """
func = pmb.helpers.package.check_arch
fake_pmaport = {"arch": []}
def fake_pmaports_get(args: PmbArgs, pkgname, must_exist=False):
return fake_pmaport
monkeypatch.setattr(pmb.helpers.pmaports, "get", fake_pmaports_get)
fake_pmaport["arch"] = ["armhf"]
assert func(args, "a", "armhf", False) is True
fake_pmaport["arch"] = ["all", "!armhf"]
assert func(args, "a", "armhf", False) is False

View file

@ -1,53 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import os
from pmb.types import PmbArgs
import pytest
import sys
import pmb_test # noqa
import pmb.build.other
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap", "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_guess_main(args: PmbArgs, tmpdir):
# Fake pmaports folder
tmpdir = str(tmpdir)
args.aports = tmpdir
for aport in ["temp/qemu", "main/some-pkg"]:
os.makedirs(tmpdir + "/" + aport)
with open(tmpdir + "/" + aport + "/APKBUILD", 'w'):
pass
func = pmb.helpers.pmaports.guess_main
assert func(args, "qemu-x86_64") == tmpdir + "/temp/qemu"
assert func(args, "qemu-system-x86_64") == tmpdir + "/temp/qemu"
assert func(args, "some-pkg-sub-pkg") == tmpdir + "/main/some-pkg"
assert func(args, "qemuPackageWithoutDashes") is None
def test_guess_main_dev(args: PmbArgs, tmpdir):
# Fake pmaports folder
tmpdir = str(tmpdir)
args.aports = tmpdir
os.makedirs(tmpdir + "/temp/plasma")
with open(tmpdir + "/temp/plasma/APKBUILD", 'w'):
pass
func = pmb.helpers.pmaports.guess_main_dev
assert func(args, "plasma-framework-dev") is None
assert func(args, "plasma-dev") == tmpdir + "/temp/plasma"
func = pmb.helpers.pmaports.guess_main
assert func(args, "plasma-framework-dev") is None
assert func(args, "plasma-randomsubpkg") == tmpdir + "/temp/plasma"

View file

@ -1,74 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
""" Test pmb.helpers.repo """
from pmb.types import PmbArgs
import pytest
import sys
import pmb_test # noqa
import pmb_test.const
import pmb.helpers.repo
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
cfg = f"{pmb_test.const.testdata}/channels.cfg"
sys.argv = ["pmbootstrap.py", "--config-channels", cfg, "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_hash():
url = "https://nl.alpinelinux.org/alpine/edge/testing"
hash = "865a153c"
assert pmb.helpers.repo.apkindex_hash(url, 8) == hash
def test_alpine_apkindex_path(args: PmbArgs):
func = pmb.helpers.repo.alpine_apkindex_path
args.mirror_alpine = "http://dl-cdn.alpinelinux.org/alpine/"
ret = get_context().config.work / "cache_apk_armhf/APKINDEX.30e6f5af.tar.gz"
assert func(args, "testing", "armhf") == ret
def test_urls(args: PmbArgs, monkeypatch):
func = pmb.helpers.repo.urls
channel = "v20.05"
args.mirror_alpine = "http://localhost/alpine/"
# Second mirror with /master at the end is legacy, gets fixed by func.
# Note that bpo uses multiple postmarketOS mirrors at the same time, so it
# can use its WIP repository together with the final repository.
args.mirrors_postmarketos = ["http://localhost/pmos1/",
"http://localhost/pmos2/master"]
# Pretend to have a certain channel in pmaports.cfg
def read_config(args):
return {"channel": channel}
monkeypatch.setattr(pmb.config.pmaports, "read_config", read_config)
# Channel: v20.05
assert func(args) == ["/mnt/pmbootstrap/packages",
"http://localhost/pmos1/v20.05",
"http://localhost/pmos2/v20.05",
"http://localhost/alpine/v3.11/main",
"http://localhost/alpine/v3.11/community"]
# Channel: edge (has Alpine's testing)
channel = "edge"
assert func(args) == ["/mnt/pmbootstrap/packages",
"http://localhost/pmos1/master",
"http://localhost/pmos2/master",
"http://localhost/alpine/edge/main",
"http://localhost/alpine/edge/community",
"http://localhost/alpine/edge/testing"]
# Only Alpine's URLs
exp = ["http://localhost/alpine/edge/main",
"http://localhost/alpine/edge/community",
"http://localhost/alpine/edge/testing"]
assert func(args, False, False) == exp

View file

@ -1,139 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
from pmb.types import PmbArgs
import pytest
import sys
import pmb_test # noqa
import pmb.build.other
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap", "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_filter_missing_packages_invalid(args: PmbArgs):
""" Test ...repo_missing.filter_missing_packages(): invalid package """
func = pmb.helpers.repo_missing.filter_missing_packages
with pytest.raises(RuntimeError) as e:
func(args, "armhf", ["invalid-package-name"])
assert str(e.value).startswith("Could not find aport")
def test_filter_missing_packages_binary_exists(args: PmbArgs):
""" Test ...repo_missing.filter_missing_packages(): binary exists """
func = pmb.helpers.repo_missing.filter_missing_packages
assert func(args, "armhf", ["busybox"]) == []
def test_filter_missing_packages_pmaports(args: PmbArgs, monkeypatch):
""" Test ...repo_missing.filter_missing_packages(): pmaports """
build_is_necessary = None
func = pmb.helpers.repo_missing.filter_missing_packages
def stub(args: PmbArgs, arch, pmaport):
return build_is_necessary
monkeypatch.setattr(pmb.build, "is_necessary", stub)
build_is_necessary = True
assert func(args, "x86_64", ["busybox", "hello-world"]) == ["hello-world"]
build_is_necessary = False
assert func(args, "x86_64", ["busybox", "hello-world"]) == []
def test_filter_aport_packages(args: PmbArgs):
""" Test ...repo_missing.filter_aport_packages() """
func = pmb.helpers.repo_missing.filter_aport_packages
assert func(args, "armhf", ["busybox", "hello-world"]) == ["hello-world"]
def test_filter_arch_packages(args: PmbArgs, monkeypatch):
""" Test ...repo_missing.filter_arch_packages() """
func = pmb.helpers.repo_missing.filter_arch_packages
check_arch = None
def stub(args: PmbArgs, arch, pmaport, binary=True):
return check_arch
monkeypatch.setattr(pmb.helpers.package, "check_arch", stub)
check_arch = False
assert func(args, "armhf", ["hello-world"]) == []
check_arch = True
assert func(args, "armhf", []) == []
def test_get_relevant_packages(args: PmbArgs, monkeypatch):
""" Test ...repo_missing.get_relevant_packages() """
# Set up fake return values
stub_data = {"check_arch": False,
"depends_recurse": ["a", "b", "c", "d"],
"filter_arch_packages": ["a", "b", "c"],
"filter_aport_packages": ["b", "a"],
"filter_missing_packages": ["a"]}
def stub(args: PmbArgs, arch, pmaport, binary=True):
return stub_data["check_arch"]
monkeypatch.setattr(pmb.helpers.package, "check_arch", stub)
def stub(args: PmbArgs, arch, pmaport):
return stub_data["depends_recurse"]
monkeypatch.setattr(pmb.helpers.package, "depends_recurse", stub)
def stub(args: PmbArgs, arch, pmaport):
return stub_data["filter_arch_packages"]
monkeypatch.setattr(pmb.helpers.repo_missing, "filter_arch_packages", stub)
def stub(args: PmbArgs, arch, pmaport):
return stub_data["filter_aport_packages"]
monkeypatch.setattr(pmb.helpers.repo_missing, "filter_aport_packages",
stub)
def stub(args: PmbArgs, arch, pmaport):
return stub_data["filter_missing_packages"]
monkeypatch.setattr(pmb.helpers.repo_missing, "filter_missing_packages",
stub)
# No given package
func = pmb.helpers.repo_missing.get_relevant_packages
assert func(args, "armhf") == ["a"]
assert func(args, "armhf", built=True) == ["a", "b"]
# Package can't be built for given arch
with pytest.raises(RuntimeError) as e:
func(args, "armhf", "a")
assert "can't be built" in str(e.value)
# Package can be built for given arch
stub_data["check_arch"] = True
assert func(args, "armhf", "a") == ["a"]
assert func(args, "armhf", "a", True) == ["a", "b"]
def test_generate_output_format(args: PmbArgs, monkeypatch):
""" Test ...repo_missing.generate_output_format() """
def stub(args: PmbArgs, pkgname, arch, replace_subpkgnames=False):
return {"pkgname": "hello-world", "version": "1.0-r0",
"depends": ["depend1", "depend2"]}
monkeypatch.setattr(pmb.helpers.package, "get", stub)
def stub(args: PmbArgs, pkgname):
return "main"
monkeypatch.setattr(pmb.helpers.pmaports, "get_repo", stub)
func = pmb.helpers.repo_missing.generate_output_format
ret = [{"pkgname": "hello-world",
"repo": "main",
"version": "1.0-r0",
"depends": ["depend1", "depend2"]}]
assert func(args, "armhf", ["hello-world"]) == ret

View file

@ -1,36 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
from pmb.types import PmbArgs
import pytest
import sys
import pmb_test
import pmb_test.const
import pmb.helpers.logging
import pmb.helpers.ui
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
cfg = f"{pmb_test.const.testdata}/channels.cfg"
sys.argv = ["pmbootstrap.py", "--config-channels", cfg, "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_helpers_ui(args: PmbArgs):
""" Test the UIs returned by pmb.helpers.ui.list() with a testdata pmaports
dir. That test dir has a plasma-mobile UI, which is disabled for armhf,
so it must not be returned when querying the UI list for armhf. """
args.aports = f"{pmb_test.const.testdata}/helpers_ui/pmaports"
func = pmb.helpers.ui.list_ui
none_desc = "Bare minimum OS image for testing and manual" \
" customization. The \"console\" UI should be selected if" \
" a graphical UI is not desired."
assert func(args, "armhf") == [("none", none_desc)]
assert func(args, "x86_64") == [("none", none_desc),
("plasma-mobile", "cool pkgdesc")]

View file

@ -1,174 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
from pmb.types import PmbArgs
import pytest
import sys
import os
import shutil
import pmb_test
import pmb_test.const
import pmb.aportgen.device
import pmb.config
import pmb.config.init
import pmb.helpers.logging
import pmb.install._install
from pmb.core import Chroot, ChrootType
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_get_nonfree_packages(args: PmbArgs):
args.aports = pmb_test.const.testdata + "/init_questions_device/aports"
func = pmb.install._install.get_nonfree_packages
# Device without any non-free subpackages
assert func(args, "lg-mako") == []
# Device with non-free firmware and userland
device = "nonfree-firmware-and-userland"
assert func(args, device) == ["device-" + device + "-nonfree-firmware",
"device-" + device + "-nonfree-userland"]
# Device with non-free userland
device = "nonfree-userland"
assert func(args, device) == ["device-" + device + "-nonfree-userland"]
def test_get_recommends(args: PmbArgs):
args.aports = pmb_test.const.testdata + "/pmb_recommends"
func = pmb.install._install.get_recommends
# UI: none
args.install_recommends = True
assert func(args, ["postmarketos-ui-none"]) == []
# UI: test, --no-recommends
args.install_recommends = False
assert func(args, ["postmarketos-ui-test"]) == []
# UI: test
args.install_recommends = True
assert func(args, ["postmarketos-ui-test"]) == ["plasma-camera",
"plasma-angelfish"]
# UI: test + test-extras
args.install_recommends = True
assert func(args, ["postmarketos-ui-test",
"postmarketos-ui-test-extras"]) == ["plasma-camera",
"plasma-angelfish",
"buho", "kaidan",
"test-app", "foot",
"htop"]
# Non-UI package
args.install_recommends = True
args.ui_extras = False
assert func(args, ["test-app"]) == ["foot", "htop"]
def test_get_groups(args: PmbArgs):
args.aports = f"{pmb_test.const.testdata}/pmb_groups"
func = pmb.install.ui.get_groups
# UI: none:
args.ui = "none"
assert func(args) == []
# UI: test, without -extras
args.ui = "test"
args.ui_extras = False
assert func(args) == ["feedbackd"]
# UI: test, with -extras
args.ui = "test"
args.ui_extras = True
assert func(args) == ["feedbackd", "extra"]
# UI: invalid
args.ui = "invalid"
with pytest.raises(RuntimeError) as e:
func(args)
assert str(e.value).startswith("Could not find aport for package")
def test_generate_binary_list(args: PmbArgs):
suffix = Chroot(ChrootType.ROOTFS, "mysuffix")
args.work = "/tmp"
func = pmb.install._install.generate_binary_list
binary_dir = suffix / "usr/share"
os.makedirs(binary_dir, exist_ok=True)
step = 1024
binaries = [f"{pmb_test.const.testdata}/pmb_install/small.bin",
f"{pmb_test.const.testdata}/pmb_install/full.bin",
f"{pmb_test.const.testdata}/pmb_install/big.bin",
f"{pmb_test.const.testdata}/pmb_install/overrun.bin",
f"{pmb_test.const.testdata}/pmb_install/binary2.bin"]
for b in binaries:
shutil.copy(b, binary_dir)
# Binary that is small enough to fit the partition of 10 blocks
# of 512 bytes each
binaries = "small.bin:1,binary2.bin:11"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "128"}
assert func(args, suffix, step) == [('small.bin', 1), ('binary2.bin', 11)]
# Binary that is fully filling the partition of 10 blocks of 512 bytes each
binaries = "full.bin:1,binary2.bin:11"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "128"}
assert func(args, suffix, step) == [('full.bin', 1), ('binary2.bin', 11)]
# Binary that is too big to fit the partition of 10 blocks
# of 512 bytes each
binaries = "big.bin:1,binary2.bin:2"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "128"}
with pytest.raises(RuntimeError) as e:
func(args, suffix, step)
assert str(e.value).startswith("The firmware overlaps with at least one")
# Binary that overruns the first partition
binaries = "overrun.bin:1"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "1"}
with pytest.raises(RuntimeError) as e:
func(args, suffix, step)
assert str(e.value).startswith("The firmware is too big to embed in")
# Binary does not exist
binaries = "does-not-exist.bin:1,binary2.bin:11"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "128"}
with pytest.raises(RuntimeError) as e:
func(args, suffix, step)
assert str(e.value).startswith("The following firmware binary does not")
# Binaries are touching but not overlapping
# boot_part_start is at 2 sectors (1024 b)
# |-----|---------------------|-------------------|-------------------
# | … | binary2.bin (100 b) | small.bin (600 b) | /boot part start …
# |-----|---------------------|-------------------|-------------------
# 0 324 424 1024
step = 1
binaries = "binary2.bin:324,small.bin:424"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "2"}
assert func(args, suffix, step) == [('binary2.bin', 324),
('small.bin', 424)]
# Same layout written with different order in sd_embed_firmware
binaries = "small.bin:424,binary2.bin:324"
args.deviceinfo = {"sd_embed_firmware": binaries,
"boot_part_start": "2"}
assert func(args, suffix, step) == [('small.bin', 424),
('binary2.bin', 324)]

View file

@ -1,26 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
from pathlib import Path
import pmb_test # noqa
import pmb.helpers.mount
def test_umount_all_list(tmpdir):
# Write fake mounts file
fake_mounts = str(tmpdir + "/mounts")
with open(fake_mounts, "w") as handle:
handle.write("source /test/var/cache\n")
handle.write("source /test/home/pmos/packages\n")
handle.write("source /test\n")
handle.write("source /test/proc\n")
handle.write("source /test/dev/loop0p2\\040(deleted)\n")
ret = pmb.helpers.mount.umount_all_list(Path("/no/match"), fake_mounts)
assert ret == []
ret = pmb.helpers.mount.umount_all_list(Path("/test/var/cache"), fake_mounts)
assert ret == ["/test/var/cache"]
ret = pmb.helpers.mount.umount_all_list(Path("/test"), fake_mounts)
assert ret == ["/test/var/cache", "/test/proc", "/test/home/pmos/packages",
"/test/dev/loop0p2", "/test"]

View file

@ -1,74 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import glob
import os
from pmb.types import PmbArgs
import pytest
import shutil
import sys
import pmb_test # noqa
import pmb_test.const
import pmb.build.newapkbuild
import pmb.config
import pmb.config.init
import pmb.helpers.logging
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
cfg = f"{pmb_test.const.testdata}/channels.cfg"
sys.argv = ["pmbootstrap.py", "--config-channels", cfg, "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_newapkbuild(args: PmbArgs, monkeypatch, tmpdir):
testdata = pmb_test.const.testdata
# Fake functions
def confirm_true(*nargs):
return True
def confirm_false(*nargs):
return False
# Preparation
monkeypatch.setattr(pmb.helpers.cli, "confirm", confirm_false)
pmb.build.init(args)
args.aports = tmpdir = str(tmpdir)
shutil.copy(f"{testdata}/pmaports.cfg", args.aports)
func = pmb.build.newapkbuild
# Show the help
func(args, "main", ["-h"])
assert glob.glob(f"{tmpdir}/*") == [f"{tmpdir}/pmaports.cfg"]
# Test package
pkgname = "testpackage"
func(args, "main", [pkgname])
apkbuild_path = tmpdir + "/main/" + pkgname + "/APKBUILD"
apkbuild = pmb.parse.apkbuild(apkbuild_path)
assert apkbuild["pkgname"] == pkgname
assert apkbuild["pkgdesc"] == ""
# Don't overwrite
with pytest.raises(RuntimeError) as e:
func(args, "main", [pkgname])
assert "Aborted" in str(e.value)
# Overwrite
monkeypatch.setattr(pmb.helpers.cli, "confirm", confirm_true)
pkgdesc = "testdescription"
func(args, "main", ["-d", pkgdesc, pkgname])
pmb.helpers.other.cache["apkbuild"] = {}
apkbuild = pmb.parse.apkbuild(apkbuild_path)
assert apkbuild["pkgname"] == pkgname
assert apkbuild["pkgdesc"] == pkgdesc
# There should be no src folder
assert not os.path.exists(tmpdir + "/main/" + pkgname + "/src")

View file

@ -1,169 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
from pmb.types import PmbArgs
import pytest
import sys
import pmb_test
import pmb_test.const
import pmb.parse._apkbuild
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_subpackages(args):
testdata = pmb_test.const.testdata
path = testdata + "/apkbuild/APKBUILD.subpackages"
apkbuild = pmb.parse.apkbuild(path, check_pkgname=False)
subpkg = apkbuild["subpackages"]["simple"]
assert subpkg["pkgdesc"] == ""
# Inherited from parent package
assert subpkg["depends"] == ["postmarketos-base"]
subpkg = apkbuild["subpackages"]["custom"]
assert subpkg["pkgdesc"] == "This is one of the custom subpackages"
assert subpkg["depends"] == ["postmarketos-base", "glibc"]
subpkg = apkbuild["subpackages"]["different_arch"]
assert subpkg["pkgdesc"] == "This has a different architecture than the other subpackages"
# Successful extraction
path = (testdata + "/init_questions_device/aports/device/testing/"
"device-nonfree-firmware/APKBUILD")
apkbuild = pmb.parse.apkbuild(path)
subpkg = (apkbuild["subpackages"]
["device-nonfree-firmware-nonfree-firmware"])
assert subpkg["pkgdesc"] == "firmware description"
# Can't find the pkgdesc in the function
path = testdata + "/apkbuild/APKBUILD.missing-pkgdesc-in-subpackage"
apkbuild = pmb.parse.apkbuild(path, check_pkgname=False)
subpkg = (apkbuild["subpackages"]
["missing-pkgdesc-in-subpackage-subpackage"])
assert subpkg["pkgdesc"] == ""
# Can't find the function
assert apkbuild["subpackages"]["invalid-function"] is None
def test_kernels(args: PmbArgs):
# Kernel hardcoded in depends
args.aports = pmb_test.const.testdata + "/init_questions_device/aports"
func = pmb.parse._apkbuild.kernels
device = "lg-mako"
assert func(args, device) is None
# Upstream and downstream kernel
device = "sony-amami"
ret = {"downstream": "Downstream description",
"mainline": "Mainline description"}
assert func(args, device) == ret
# Long kernel name (e.g. two different mainline kernels)
device = "wileyfox-crackling"
ret = {"mainline": "Mainline kernel (no modem)",
"mainline-modem": "Mainline kernel (with modem)",
"downstream": "Downstream kernel"}
assert func(args, device) == ret
def test_depends_in_depends(args):
path = pmb_test.const.testdata + "/apkbuild/APKBUILD.depends-in-depends"
apkbuild = pmb.parse.apkbuild(path, check_pkgname=False)
assert apkbuild["depends"] == ["first", "second", "third"]
def test_parse_next_attribute(args):
# Convenience function for calling the function with a block of text
def func(block):
lines = block.split("\n")
for i in range(0, len(lines)):
lines[i] += "\n"
i = 0
path = "(testcase in " + __file__ + ")"
print("=== parsing next attribute in test block:")
print(block)
print("===")
return pmb.parse._apkbuild.parse_next_attribute(lines, i, path)
assert func("no variable here") == (None, None, 0)
assert func("\tno_top_level_var=1") == (None, None, 0)
assert func('pkgname="test"') == ("pkgname", "test", 0)
assert func("pkgname='test'") == ("pkgname", "test", 0)
assert func("pkgname=test") == ("pkgname", "test", 0)
assert func('pkgname="test\n"') == ("pkgname", "test", 1)
assert func('pkgname="\ntest\n"') == ("pkgname", "test", 2)
assert func('pkgname="test" # random comment\npkgrel=3') == \
("pkgname", "test", 0)
assert func('pkgver=2.37 # random comment\npkgrel=3') == \
("pkgver", "2.37", 0)
assert func("depends='\nfirst\nsecond\nthird\n'#") == \
("depends", "first second third", 4)
assert func('depends="\nfirst\n\tsecond third"') == \
("depends", "first second third", 2)
assert func('depends=') == ("depends", "", 0)
with pytest.raises(RuntimeError) as e:
func('depends="\nmissing\nend\nquote\nsign')
assert str(e.value).startswith("Can't find closing")
with pytest.raises(RuntimeError) as e:
func('depends="')
assert str(e.value).startswith("Can't find closing")
def test_variable_replacements():
path = pmb_test.const.testdata + "/apkbuild/APKBUILD.variable-replacements"
apkbuild = pmb.parse.apkbuild(path, check_pkgname=False)
assert apkbuild["pkgdesc"] == "this should not affect variable replacement"
assert apkbuild["url"] == "replacements variable string-replacements 1234"
assert list(apkbuild["subpackages"].keys()) == ["replacements", "test"]
assert apkbuild["subpackages"]["replacements"] is None
test_subpkg = apkbuild["subpackages"]["test"]
assert test_subpkg["pkgdesc"] == ("this should not affect variable "
"replacement")
def test_parse_maintainers(args):
path = pmb_test.const.testdata + "/apkbuild/APKBUILD.lint"
maintainers = [
"Oliver Smith <ollieparanoid@postmarketos.org>",
"Hello World <hello@world>"
]
assert pmb.parse._apkbuild.maintainers(path) == maintainers
def test_parse_archived(args):
path = (f"{pmb_test.const.testdata}/apkbuild"
"/APKBUILD.missing-pkgdesc-in-subpackage")
assert pmb.parse._apkbuild.archived(path) == "This is broken!"
def test_weird_pkgver(args):
path = (f"{pmb_test.const.testdata}/apkbuild"
"/APKBUILD.weird-pkgver")
apkbuild = pmb.parse.apkbuild(path, check_pkgname=False, check_pkgver=True)
assert apkbuild["pkgver"] == "3.0.0_alpha369-r0"

View file

@ -1,396 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
""" Test pmb.parse.apkindex """
import collections
import os
from pmb.types import PmbArgs
import pytest
import sys
import pmb_test # noqa
import pmb.parse.apkindex
import pmb.helpers.logging
import pmb.helpers.repo
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap", "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_parse_next_block_exceptions():
# Mapping of input files (inside the /test/testdata/apkindex) to
# error message substrings
mapping = {"key_twice": "specified twice",
"key_missing": "Missing required key",
"new_line_missing": "does not end with a new line!"}
# Parse the files
for file, error_substr in mapping.items():
path = pmb.config.pmb_src + "/test/testdata/apkindex/" + file
with open(path, "r", encoding="utf-8") as handle:
lines = handle.readlines()
with pytest.raises(RuntimeError) as e:
pmb.parse.apkindex.parse_next_block(path, lines, [0])
assert error_substr in str(e.value)
def test_parse_next_block_no_error():
# Read the file
func = pmb.parse.apkindex.parse_next_block
path = pmb.config.pmb_src + "/test/testdata/apkindex/no_error"
with open(path, "r", encoding="utf-8") as handle:
lines = handle.readlines()
# First block
start = [0]
block = {'arch': 'x86_64',
'depends': [],
'origin': 'musl',
'pkgname': 'musl',
'provides': ['so:libc.musl-x86_64.so.1'],
'timestamp': '1515217616',
'version': '1.1.18-r5'}
assert func(path, lines, start) == block
assert start == [24]
# Second block
block = {'arch': 'x86_64',
'depends': ['ca-certificates',
'so:libc.musl-x86_64.so.1',
'so:libcurl.so.4',
'so:libz.so.1'],
'origin': 'curl',
'pkgname': 'curl',
'provides': ['cmd:curl'],
'timestamp': '1512030418',
'version': '7.57.0-r0'}
assert func(path, lines, start) == block
assert start == [45]
# No more blocks
assert func(path, lines, start) is None
assert start == [45]
def test_parse_next_block_virtual():
"""
Test parsing a virtual package from an APKINDEX.
"""
# Read the file
func = pmb.parse.apkindex.parse_next_block
path = pmb.config.pmb_src + "/test/testdata/apkindex/virtual_package"
with open(path, "r", encoding="utf-8") as handle:
lines = handle.readlines()
# First block
start = [0]
block = {'arch': 'x86_64',
'depends': ['so:libc.musl-x86_64.so.1'],
'origin': 'hello-world',
'pkgname': 'hello-world',
'provides': ['cmd:hello-world'],
'timestamp': '1500000000',
'version': '2-r0'}
assert func(path, lines, start) == block
assert start == [20]
# Second block: virtual package
block = {'arch': 'noarch',
'depends': ['hello-world'],
'pkgname': '.pmbootstrap',
'provides': [],
'version': '0'}
assert func(path, lines, start) == block
assert start == [31]
# No more blocks
assert func(path, lines, start) is None
assert start == [31]
def test_parse_next_block_conflict():
"""
Test parsing a package that specifies a conflicting dependency from an
APKINDEX.
"""
# Read the file
func = pmb.parse.apkindex.parse_next_block
path = pmb.config.pmb_src + "/test/testdata/apkindex/conflict"
with open(path, "r", encoding="utf-8") as handle:
lines = handle.readlines()
# First block
start = [0]
block = {'arch': 'x86_64',
'depends': ['!conflict', 'so:libc.musl-x86_64.so.1'],
'origin': 'hello-world',
'pkgname': 'hello-world',
'provides': ['cmd:hello-world'],
'timestamp': '1500000000',
'version': '2-r0'}
assert func(path, lines, start) == block
assert start == [20]
# No more blocks
assert func(path, lines, start) is None
assert start == [20]
def test_parse_add_block(args: PmbArgs):
func = pmb.parse.apkindex.parse_add_block
multiple_providers = False
# One package without alias
ret = {}
block = {"pkgname": "test", "version": "2"}
alias = None
func(ret, block, alias, multiple_providers)
assert ret == {"test": block}
# Older packages must not overwrite newer ones
block_old = {"pkgname": "test", "version": "1"}
func(ret, block_old, alias, multiple_providers)
assert ret == {"test": block}
# Newer packages must overwrite older ones
block_new = {"pkgname": "test", "version": "3"}
func(ret, block_new, alias, multiple_providers)
assert ret == {"test": block_new}
# Add package with alias
alias = "test_alias"
func(ret, block_new, alias, multiple_providers)
assert ret == {"test": block_new, "test_alias": block_new}
def test_parse_add_block_multiple_providers(args: PmbArgs):
func = pmb.parse.apkindex.parse_add_block
# One package without alias
ret = {}
block = {"pkgname": "test", "version": "2"}
alias = None
func(ret, block, alias)
assert ret == {"test": {"test": block}}
# Older packages must not overwrite newer ones
block_old = {"pkgname": "test", "version": "1"}
func(ret, block_old, alias)
assert ret == {"test": {"test": block}}
# Newer packages must overwrite older ones
block_new = {"pkgname": "test", "version": "3"}
func(ret, block_new, alias)
assert ret == {"test": {"test": block_new}}
# Add package with alias
alias = "test_alias"
func(ret, block_new, alias)
assert ret == {"test": {"test": block_new},
"test_alias": {"test": block_new}}
# Add another package with the same alias
alias = "test_alias"
block_test2 = {"pkgname": "test2", "version": "1"}
func(ret, block_test2, alias)
assert ret == {"test": {"test": block_new},
"test_alias": {"test": block_new, "test2": block_test2}}
def test_parse_invalid_path():
assert pmb.parse.apkindex.parse("/invalid/path/APKINDEX") == {}
def test_parse_cached(args: PmbArgs, tmpdir):
# Create a real file (cache looks at the last modified date)
path = str(tmpdir) + "/APKINDEX"
pmb.helpers.run.user(["touch", path])
lastmod = os.path.getmtime(path)
# Fill the cache
pmb.helpers.other.cache["apkindex"][path] = {
"lastmod": lastmod,
"multiple": "cached_result_multiple",
"single": "cached_result_single",
}
# Verify cache usage
func = pmb.parse.apkindex.parse
assert func(path, True) == "cached_result_multiple"
assert func(path, False) == "cached_result_single"
# Make cache invalid
pmb.helpers.other.cache["apkindex"][path]["lastmod"] -= 10
assert func(path, True) == {}
# Delete the cache (run twice for both code paths)
assert pmb.parse.apkindex.clear_cache(path) is True
assert pmb.helpers.other.cache["apkindex"] == {}
assert pmb.parse.apkindex.clear_cache(path) is False
def test_parse():
path = pmb.config.pmb_src + "/test/testdata/apkindex/no_error"
block_musl = {'arch': 'x86_64',
'depends': [],
'origin': 'musl',
'pkgname': 'musl',
'provides': ['so:libc.musl-x86_64.so.1'],
'timestamp': '1515217616',
'version': '1.1.18-r5'}
block_curl = {'arch': 'x86_64',
'depends': ['ca-certificates',
'so:libc.musl-x86_64.so.1',
'so:libcurl.so.4',
'so:libz.so.1'],
'origin': 'curl',
'pkgname': 'curl',
'provides': ['cmd:curl'],
'timestamp': '1512030418',
'version': '7.57.0-r0'}
# Test without multiple_providers
ret_single = {'cmd:curl': block_curl,
'curl': block_curl,
'musl': block_musl,
'so:libc.musl-x86_64.so.1': block_musl}
assert pmb.parse.apkindex.parse(path, False) == ret_single
assert pmb.helpers.other.cache["apkindex"][path]["single"] == ret_single
# Test with multiple_providers
ret_multiple = {'cmd:curl': {"curl": block_curl},
'curl': {"curl": block_curl},
'musl': {"musl": block_musl},
'so:libc.musl-x86_64.so.1': {"musl": block_musl}}
assert pmb.parse.apkindex.parse(path, True) == ret_multiple
assert (
pmb.helpers.other.cache["apkindex"][path]["multiple"] == ret_multiple
)
def test_parse_virtual():
"""
This APKINDEX contains a virtual package .pbmootstrap. It must not be part
of the output.
"""
path = pmb.config.pmb_src + "/test/testdata/apkindex/virtual_package"
block = {'arch': 'x86_64',
'depends': ['so:libc.musl-x86_64.so.1'],
'origin': 'hello-world',
'pkgname': 'hello-world',
'provides': ['cmd:hello-world'],
'timestamp': '1500000000',
'version': '2-r0'}
ret = {"hello-world": block, "cmd:hello-world": block}
assert pmb.parse.apkindex.parse(path, False) == ret
assert pmb.helpers.other.cache["apkindex"][path]["single"] == ret
def test_providers_invalid_package(args: PmbArgs, tmpdir):
# Create empty APKINDEX
path = str(tmpdir) + "/APKINDEX"
pmb.helpers.run.user(["touch", path])
# Test with must_exist=False
func = pmb.parse.apkindex.providers
package = "test"
indexes = [path]
assert func(args, package, None, False, indexes) == {}
# Test with must_exist=True
with pytest.raises(RuntimeError) as e:
func(args, package, None, True, indexes)
assert str(e.value).startswith("Could not find package")
def test_providers_highest_version(args: PmbArgs, monkeypatch):
"""
In this test, we simulate 3 APKINDEX files ("i0", "i1", "i2" instead of
full paths to real APKINDEX.tar.gz files), and each of them has a different
version of the same package. The highest version must win, no matter in
which order the APKINDEX files are processed.
"""
# Fake parse function
def return_fake_parse(path):
version_mapping = {"i0": "2", "i1": "3", "i2": "1"}
package_block = {"pkgname": "test", "version": version_mapping[path]}
return {"test": {"test": package_block}}
monkeypatch.setattr(pmb.parse.apkindex, "parse", return_fake_parse)
# Verify that it picks the highest version
func = pmb.parse.apkindex.providers
providers = func(args, "test", indexes=["i0", "i1", "i2"])
assert providers["test"]["version"] == "3"
def test_provider_highest_priority(args: PmbArgs, monkeypatch):
# Verify that it picks the provider with highest priority
func = pmb.parse.apkindex.provider_highest_priority
provider_none_a = {"pkgname": "a", "provides": ["test"]}
provider_none_b = {"pkgname": "b", "provides": ["test"]}
provider_low_c = {"pkgname": "c", "provides": ["test"],
"provider_priority": 42}
provider_low_d = {"pkgname": "d", "provides": ["test"],
"provider_priority": 42}
provider_high = {"pkgname": "e", "provides": ["test"],
"provider_priority": 1337}
# No provider has a priority
providers = {"a": provider_none_a}
assert func(providers, "test") == providers
providers = {"a": provider_none_a, "b": provider_none_b}
assert func(providers, "test") == providers
# One provider has a priority, another one does not
providers = {"a": provider_none_a, "e": provider_high}
assert func(providers, "test") == {"e": provider_high}
# One provider has a priority, another one has a higher priority
providers = {"c": provider_low_c, "e": provider_high}
assert func(providers, "test") == {"e": provider_high}
# One provider has a priority, another one has the same priority
providers = {"c": provider_low_c, "d": provider_low_d}
assert func(providers, "test") == providers
# + some package without priority at all should be filtered out
providers2 = providers.copy()
providers2["a"] = provider_none_a
assert func(providers2, "test") == providers
def test_package(args: PmbArgs, monkeypatch):
# Override pmb.parse.apkindex.providers()
providers = collections.OrderedDict()
def return_providers(*args, **kwargs):
return providers
monkeypatch.setattr(pmb.parse.apkindex, "providers", return_providers)
# Provider with the same pkgname
func = pmb.parse.apkindex.package
pkgname = "test"
providers = {"test2": {"pkgname": "test2"}, "test": {"pkgname": "test"}}
assert func(args, pkgname) == {"pkgname": "test"}
# First provider
providers = {"test2": {"pkgname": "test2"}, "test3": {"pkgname": "test3"}}
assert func(args, pkgname) == {"pkgname": "test2"}
# No provider (with must_exist)
providers = {}
with pytest.raises(RuntimeError) as e:
func(args, pkgname)
assert "not found in any APKINDEX" in str(e.value)
# No provider (without must_exist)
assert func(args, pkgname, must_exist=False) is None

View file

@ -1,15 +0,0 @@
# Copyright 2024 Stefan "Newbyte" Hansson
# SPDX-License-Identifier: GPL-3.0-or-later
import pytest
import pmb.parse.arch
def test_machine_type_to_alpine() -> None:
fake_machine_type = "not-a-machine-type"
with pytest.raises(ValueError) as e:
pmb.parse.arch.machine_type_to_alpine(fake_machine_type)
assert e == f"Can not map machine type {fake_machine_type} to the right Alpine Linux architecture"
assert pmb.parse.arch.machine_type_to_alpine("armv7l") == "armv7"

View file

@ -1,168 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
""" Test pmb.parse.depends """
import collections
from pmb.types import PmbArgs
import pytest
import sys
import pmb_test # noqa
import pmb.config
import pmb.config.init
import pmb.helpers.logging
import pmb.parse.depends
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap", "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_package_from_aports(args: PmbArgs):
func = pmb.parse.depends.package_from_aports
assert func(args, "invalid-package") is None
assert func(args, "hello-world") == {"pkgname": "hello-world",
"depends": [],
"version": "1-r6"}
def test_package_provider(args: PmbArgs, monkeypatch):
# Override pmb.parse.apkindex.providers()
providers = collections.OrderedDict()
def return_providers(*args, **kwargs):
return providers
monkeypatch.setattr(pmb.parse.apkindex, "providers", return_providers)
# Override pmb.chroot.apk.installed()
installed = {}
def return_installed(*args, **kwards):
return installed
monkeypatch.setattr(pmb.chroot.apk, "installed", return_installed)
# 0. No provider
pkgname = "test"
pkgnames_install = []
func = pmb.parse.depends.package_provider
assert func(args, pkgname, pkgnames_install) is None
# 1. Only one provider
package = {"pkgname": "test", "version": "1234"}
providers = {"test": package}
assert func(args, pkgname, pkgnames_install) == package
# 2. Provider with the same package name
package_two = {"pkgname": "test-two", "provides": ["test"]}
providers = {"test-two": package_two, "test": package}
assert func(args, pkgname, pkgnames_install) == package
# 3. Pick a package that will be installed anyway
providers = {"test_": package, "test-two": package_two}
installed = {"test_": package}
pkgnames_install = ["test-two"]
assert func(args, pkgname, pkgnames_install) == package_two
# 4. Pick a package that is already installed
pkgnames_install = []
assert func(args, pkgname, pkgnames_install) == package
# 5. Pick package with highest priority
package_with_priority = {"pkgname": "test-priority", "provides": ["test"],
"provider_priority": 100}
providers = {"test-two": package_two,
"test-priority": package_with_priority}
assert func(args, pkgname, pkgnames_install) == package_with_priority
# 6. Pick the first one
providers = {"test_": package, "test-two": package_two}
installed = {}
assert func(args, pkgname, pkgnames_install) == package
def test_package_from_index(args: PmbArgs, monkeypatch):
# Override pmb.parse.depends.package_provider()
provider = None
def return_provider(*args, **kwargs):
return provider
monkeypatch.setattr(pmb.parse.depends, "package_provider",
return_provider)
func = pmb.parse.depends.package_from_index
aport = {"pkgname": "test", "version": "2"}
pkgname = "test"
pkgnames_install = []
# No binary package providers
assert func(args, pkgname, pkgnames_install, aport) is aport
# Binary package outdated
provider = {"pkgname": "test", "version": "1"}
assert func(args, pkgname, pkgnames_install, aport) is aport
# Binary package up-to-date
for version in ["2", "3"]:
provider = {"pkgname": "test", "version": version}
assert func(args, pkgname, pkgnames_install, aport) is provider
def test_recurse_invalid(args: PmbArgs, monkeypatch):
func = pmb.parse.depends.recurse
# Invalid package
with pytest.raises(RuntimeError) as e:
func(args, ["invalid-pkgname"])
assert str(e.value).startswith("Could not find dependency")
def return_none(*args, **kwargs):
return None
def test_recurse(args: PmbArgs, monkeypatch):
"""
Test recursing through the following dependencies:
test:
libtest
so:libtest.so.1
libtest:
libtest_depend
libtest_depend:
so:libtest.so.1:
libtest_depend
"""
# Override finding the package in aports: always no result
monkeypatch.setattr(pmb.parse.depends, "package_from_aports",
return_none)
# Override depends returned from APKINDEX
depends = {
"test": ["libtest", "so:libtest.so.1"],
"libtest": ["libtest_depend"],
"libtest_depend": ["!libtest_conflict", "!libtest_conflict_missing"],
"libtest_conflict": [],
"so:libtest.so.1": ["libtest_depend"],
}
def package_from_index(args: PmbArgs, pkgname, install, aport, suffix):
if pkgname in depends:
return {"pkgname": pkgname, "depends": depends[pkgname]}
else:
return None
monkeypatch.setattr(pmb.parse.depends, "package_from_index",
package_from_index)
# Run
func = pmb.parse.depends.recurse
pkgnames = ["test", "so:libtest.so.1"]
result = ["test", "so:libtest.so.1", "libtest", "libtest_depend",
"!libtest_conflict"]
assert func(args, pkgnames) == result

View file

@ -1,39 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
from pmb.types import PmbArgs
import pytest
import sys
import pmb_test.const
import pmb.parse
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_kernel_suffix(args: PmbArgs):
args.aports = pmb_test.const.testdata + "/deviceinfo/aports"
device = "multiple-kernels"
kernel = "mainline"
deviceinfo = pmb.parse.deviceinfo(device, kernel)
assert deviceinfo["append_dtb"] == "yes"
assert deviceinfo["dtb"] == "mainline-dtb"
kernel = "mainline-modem"
deviceinfo = pmb.parse.deviceinfo(device, kernel)
assert deviceinfo["append_dtb"] == "yes"
assert deviceinfo["dtb"] == "mainline-modem-dtb"
kernel = "downstream"
deviceinfo = pmb.parse.deviceinfo(device, kernel)
assert deviceinfo["append_dtb"] == "yes"
assert deviceinfo["dtb"] == "downstream-dtb"

View file

@ -1,467 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
""" Test pmb/parse/kconfig.py """
from pmb.types import PmbArgs
import pytest
import sys
import os
import pmb_test # noqa
import pmb.parse.kconfig
from pmb.helpers.exceptions import NonBugError
test_options_checked_count = None
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "kconfig", "check"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def patch_config(monkeypatch):
"""
Delete the real kconfig_options_* variables in pmb/config/__init__.py and
replace them with a very basic config for the tests. The idea is that it
should use all features of the kconfig check code, so we can test all the
code paths.
"""
for key in list(pmb.config.__dict__.keys()):
if key.startswith("kconfig_options"):
monkeypatch.delattr(pmb.config, key)
monkeypatch.setattr(pmb.config, "kconfig_options", {
">=0.0.0": { # all versions
"all": { # all arches
"ANDROID_PARANOID_NETWORK": False,
"BLK_DEV_INITRD": True,
"DEFAULT_HOSTNAME": "(none)",
},
},
">=2.6.0": {
"all": {
"BINFMT_ELF": True,
},
},
"<4.7.0": {
"all": {
"DEVPTS_MULTIPLE_INSTANCES": True,
},
},
"<5.2.0": {
"armhf armv7 x86": {
"LBDAF": True
},
},
}, False)
monkeypatch.setattr(pmb.config, "kconfig_options_waydroid", {
">=0.0.0": {
"all": {
"SQUASHFS": True,
"ANDROID_BINDERFS": False,
"ANDROID_BINDER_DEVICES": ["binder", "hwbinder", "vndbinder"],
}
},
}, False)
monkeypatch.setattr(pmb.config, "kconfig_options_nftables", {
">=3.13.0 <5.17": {
"all": {
"NFT_COUNTER": True,
},
},
}, False)
def test_get_all_component_names(monkeypatch):
patch_config(monkeypatch)
func = pmb.parse.kconfig.get_all_component_names
assert func() == ["waydroid", "nftables"]
def test_is_set():
config = ("CONFIG_WIREGUARD=m\n"
"# CONFIG_EXT2_FS is not set\n"
"CONFIG_EXT4_FS=y\n")
func = pmb.parse.kconfig.is_set
assert func(config, "WIREGUARD") is True
assert func(config, "EXT4_FS") is True
assert func(config, "NON_EXISTING") is False
def test_is_set_str():
config = 'CONFIG_DEFAULT_HOSTNAME="(none)"\n'
func = pmb.parse.kconfig.is_set_str
option = "DEFAULT_HOSTNAME"
assert func(config, option, "(none)") is True
assert func(config, option, "hello") is False
assert func(config, f"{option}_2", "(none)") is False
def test_is_in_array():
config = 'CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder"\n'
func = pmb.parse.kconfig.is_in_array
option = "ANDROID_BINDER_DEVICES"
assert func(config, option, "binder") is True
assert func(config, option, "hwbinder") is True
assert func(config, option, "vndbinder") is True
assert func(config, option, "invalidbinder") is False
assert func(config, f"{option}_2", "binder") is False
def test_check_option():
func = pmb.parse.kconfig.check_option
config = ('CONFIG_BOOL=m\n'
'CONFIG_LIST="a,b,c"\n'
'CONFIG_STR="test"\n')
path = "/home/user/myconfig.aarch64"
assert func("test", False, config, path, "BOOL", True) is True
assert func("test", True, config, path, "BOOL", True) is True
assert func("test", True, config, path, "NON_EXISTING", True) is False
assert func("test", True, config, path, "STR", "test") is True
assert func("test", True, config, path, "STR", "test2") is False
assert func("test", True, config, path, "LIST", ["a"]) is True
assert func("test", True, config, path, "LIST", ["d"]) is False
with pytest.raises(RuntimeError) as e:
func("test", True, config, path, "TEST", {"dict": "notsupported"})
assert "is not supported" in str(e.value)
with pytest.raises(RuntimeError) as e:
func("test", True, config, path, "TEST", None)
assert "is not supported" in str(e.value)
def test_check_config_options_set():
func = pmb.parse.kconfig.check_config_options_set
config = ('CONFIG_BOOL=m\n'
'CONFIG_LIST="a,b,c"\n'
'CONFIG_STR="test"\n')
path = "/home/user/myconfig.aarch64"
arch = "aarch64"
pkgver = "6.0"
component = "testcomponent"
# Skip check because version is too low
options = {
">=6.0.1": {
"all": {
"BOOL": False
}
}
}
assert func(config, path, arch, options, component, pkgver) is True
# Skip check because version is too high
options = {
"<6.0": {
"all": {
"BOOL": False
}
}
}
assert func(config, path, arch, options, component, pkgver) is True
# Skip with two version that don't match
options = {
"<6.2 >=6.0.1": {
"all": {
"BOOL": False
}
}
}
assert func(config, path, arch, options, component, pkgver) is True
# Version matches, arch does not match
options = {
">=6.0": {
"armhf": {
"BOOL": False
}
}
}
assert func(config, path, arch, options, component, pkgver) is True
# Version matches, arch matches (aarch64)
options = {
">=6.0": {
"aarch64": {
"BOOL": False
}
}
}
assert func(config, path, arch, options, component, pkgver) is False
# Version matches, arch matches (all)
options = {
">=6.0": {
"all": {
"BOOL": False
}
}
}
assert func(config, path, arch, options, component, pkgver) is False
# Version matches, arch matches (all), rule passes
options = {
">=6.0": {
"all": {
"BOOL": True
}
}
}
assert func(config, path, arch, options, component, pkgver) is True
def test_check_config_options_set_details(monkeypatch):
global test_options_checked_count
func = pmb.parse.kconfig.check_config_options_set
config = ('CONFIG_BOOL=m\n'
'CONFIG_LIST="a,b,c"\n'
'CONFIG_STR="test"\n')
path = "/home/user/myconfig.aarch64"
arch = "aarch64"
pkgver = "6.0"
component = "testcomponent"
def check_option_fake(*args, **kwargs):
global test_options_checked_count
test_options_checked_count += 1
return False
monkeypatch.setattr(pmb.parse.kconfig, "check_option", check_option_fake)
options = {
">=0.0.0": {
"all": {
"BOOL": False,
"STR": False,
}
}
}
# No details: stop after first error
details = False
test_options_checked_count = 0
assert func(config, path, arch, options, component, pkgver, details) is False
assert test_options_checked_count == 1
# Details: don't stop, do both checks
details = True
test_options_checked_count = 0
assert func(config, path, arch, options, component, pkgver, details) is False
assert test_options_checked_count == 2
def test_check_config(monkeypatch, tmpdir):
# Write test kernel config
tmpdir = str(tmpdir)
path = f"{tmpdir}/myconfig.aarch64"
with open(path, "w") as handle:
handle.write('CONFIG_BOOL=m\n'
'CONFIG_LIST="a,b,c"\n'
'CONFIG_STR="test"\n')
patch_config(monkeypatch)
func = pmb.parse.kconfig.check_config
arch = "aarch64"
pkgver = "6.0"
# Invalid component
components_list = ["invalid-component-name"]
with pytest.raises(AssertionError) as e:
func(path, arch, pkgver, components_list)
assert "invalid kconfig component name" in str(e.value)
# Fail base check
components_list = []
assert func(path, arch, pkgver, components_list) is False
# Fails base check, even with enforce=False
details = False
enforce = False
assert func(path, arch, pkgver, components_list, details, enforce) is False
# Pass base check
with open(path, "w") as handle:
handle.write('CONFIG_BLK_DEV_INITRD=y\n'
'CONFIG_DEFAULT_HOSTNAME="(none)"\n'
'CONFIG_BINFMT_ELF=y\n')
components_list = []
assert func(path, arch, pkgver, components_list) is True
# Fail additional check
components_list = ["waydroid"]
assert func(path, arch, pkgver, components_list) is False
# Fail additional check, but result is still True with enforce=False
components_list = ["waydroid"]
details = True
enforce = False
assert func(path, arch, pkgver, components_list, details, enforce) is True
def test_check(args: PmbArgs, monkeypatch, tmpdir):
func = pmb.parse.kconfig.check
details = True
components_list = []
patch_config(monkeypatch)
# Create fake pmaports kernel structure
tmpdir = str(tmpdir)
monkeypatch.setattr(args, "aports", tmpdir)
path_aport = f"{tmpdir}/device/community/linux-nokia-n900"
path_apkbuild = f"{path_aport}/APKBUILD"
os.makedirs(path_aport)
# APKBUILD
with open(path_apkbuild, "w") as handle:
handle.write('pkgname=linux-nokia-n900\n'
'pkgver=5.15\n'
'options="pmb:kconfigcheck-nftables"\n')
# Non-existing #1
must_exist = True
pkgname = "linux-does-not-exist"
with pytest.raises(RuntimeError) as e:
func(args, pkgname, components_list, details, must_exist)
assert "Could not find aport" in str(e.value)
# Non-existing #2
must_exist = False
pkgname = "linux-does-not-exist"
assert func(args, pkgname, components_list, details, must_exist) is None
# Invalid kernel config name
path_kconfig = f"{path_aport}/config-nokia-n900_armv7"
with open(path_kconfig, "w") as handle:
handle.write('CONFIG_BOOL=m\n')
must_exist = True
pkgname = "linux-nokia-n900"
with pytest.raises(NonBugError) as e:
func(args, pkgname, components_list, details, must_exist)
assert "is not a valid kernel config" in str(e.value)
os.unlink(path_kconfig)
# Pass checks of base and nftables
path_kconfig = f"{path_aport}/config-nokia-n900.armv7"
with open(path_kconfig, "w") as handle:
handle.write('CONFIG_BLK_DEV_INITRD=y\n'
'CONFIG_DEFAULT_HOSTNAME="(none)"\n'
'CONFIG_BINFMT_ELF=y\n'
'CONFIG_NFT_COUNTER=y\n')
must_exist = True
pkgname = "nokia-n900"
assert func(args, pkgname, components_list, details, must_exist) is True
# Don't pass nftables check
with open(path_kconfig, "w") as handle:
handle.write('CONFIG_BLK_DEV_INITRD=y\n'
'CONFIG_DEFAULT_HOSTNAME="(none)"\n'
'CONFIG_BINFMT_ELF=y\n')
assert func(args, pkgname, components_list, details, must_exist) is False
# Don't pass waydroid check (extra component check passed via cmdline)
with open(path_kconfig, "w") as handle:
handle.write('CONFIG_BLK_DEV_INITRD=y\n'
'CONFIG_DEFAULT_HOSTNAME="(none)"\n'
'CONFIG_BINFMT_ELF=y\n'
'CONFIG_NFT_COUNTER=y\n')
components_list = ["waydroid"]
assert func(args, pkgname, components_list, details, must_exist) is False
def test_extract_arch(tmpdir):
func = pmb.parse.kconfig.extract_arch
path = f"{tmpdir}/config"
with open(path, "w") as handle:
handle.write('CONFIG_ARM=y\n')
assert func(path) == "armv7"
with open(path, "w") as handle:
handle.write('CONFIG_ARM64=y\n')
assert func(path) == "aarch64"
with open(path, "w") as handle:
handle.write('CONFIG_RISCV=y\n')
assert func(path) == "riscv64"
with open(path, "w") as handle:
handle.write('CONFIG_X86_32=y\n')
assert func(path) == "x86"
with open(path, "w") as handle:
handle.write('CONFIG_X86_64=y\n')
assert func(path) == "x86_64"
with open(path, "w") as handle:
handle.write('hello')
assert func(path) == "unknown"
def test_extract_version(tmpdir):
func = pmb.parse.kconfig.extract_version
path = f"{tmpdir}/config"
with open(path, "w") as handle:
handle.write("#\n"
"# Automatically generated file; DO NOT EDIT.\n"
"# Linux/arm64 3.10.93 Kernel Configuration\n")
assert func(path) == "3.10.93"
with open(path, "w") as handle:
handle.write("#\n"
"# Automatically generated file; DO NOT EDIT.\n"
"# Linux/arm64 6.2.0 Kernel Configuration\n")
assert func(path) == "6.2.0"
with open(path, "w") as handle:
handle.write("#\n"
"# Automatically generated file; DO NOT EDIT.\n"
"# Linux/riscv 6.1.0-rc3 Kernel Configuration\n")
assert func(path) == "6.1.0_rc3"
with open(path, "w") as handle:
handle.write("#\n"
"# Automatically generated file; DO NOT EDIT.\n"
"# no version here\n")
assert func(path) == "unknown"
def test_check_file(tmpdir, monkeypatch):
patch_config(monkeypatch)
func = pmb.parse.kconfig.check_file
path = f"{tmpdir}/config"
# Fail the basic check
with open(path, "w") as handle:
handle.write("#\n"
"# Automatically generated file; DO NOT EDIT.\n"
"# Linux/arm64 3.10.93 Kernel Configuration\n"
"CONFIG_ARM64=y\n")
func(path) is False
# Pass the basic check
with open(path, "w") as handle:
handle.write("#\n"
"# Automatically generated file; DO NOT EDIT.\n"
"# Linux/arm64 3.10.93 Kernel Configuration\n"
"CONFIG_ARM64=y\n"
"BLK_DEV_INITRD=y\n"
"DEFAULT_HOSTNAME=\"(none)\"\n"
"BINFMT_ELF=y\n"
"DEVPTS_MULTIPLE_INSTANCES=y\n"
"LBDAF=y\n")
func(path) is True

View file

@ -1,172 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
""" Test pmb.helper.pkgrel_bump """
import glob
import os
from pmb.types import PmbArgs
import pytest
import sys
import pmb_test # noqa
import pmb_test.git
import pmb.helpers.pkgrel_bump
import pmb.helpers.logging
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def pmbootstrap(args: PmbArgs, tmpdir, parameters, zero_exit=True):
"""
Helper function for running pmbootstrap inside the fake work folder
(created by setup() below) with the binary repo disabled and with the
testdata configured as aports.
:param parameters: what to pass to pmbootstrap, e.g. ["build", "testlib"]
:param zero_exit: expect pmbootstrap to exit with 0 (no error)
"""
# Run pmbootstrap
aports = tmpdir + "/_aports"
config = tmpdir + "/_pmbootstrap.cfg"
# Copy .git dir to fake pmaports
dot_git = tmpdir + "/_aports/.git"
if not os.path.exists(dot_git):
pmb_test.git.copy_dotgit(args, aports)
try:
pmb.helpers.run.user(["./pmbootstrap.py", "--work=" + tmpdir,
"--mirror-pmOS=", "--aports=" + aports,
"--config=" + config] + parameters,
working_dir=pmb.config.pmb_src)
# Verify that it exits as desired
except Exception as exc:
if zero_exit:
raise RuntimeError("pmbootstrap failed") from exc
else:
return
if not zero_exit:
raise RuntimeError("Expected pmbootstrap to fail, but it did not!")
def setup_work(args: PmbArgs, tmpdir):
"""
Create fake work folder in tmpdir with everything symlinked except for the
built packages. The aports testdata gets copied to the tempfolder as
well, so it can be modified during testing.
"""
# Clean the chroots, and initialize the build chroot in the native chroot.
# We do this before creating the fake work folder, because then all
# packages are still present.
os.chdir(pmb.config.pmb_src)
pmb.helpers.run.user(["./pmbootstrap.py", "-y", "zap"])
pmb.helpers.run.user(["./pmbootstrap.py", "build_init"])
pmb.helpers.run.user(["./pmbootstrap.py", "shutdown"])
# Link everything from work (except for "packages") to the tmpdir
for path in get_context().config.work.glob("*"):
if os.path.basename(path) != "packages":
pmb.helpers.run.user(["ln", "-s", path, tmpdir + "/"])
# Copy testdata and selected device aport
for folder in ["device/testing", "main"]:
pmb.helpers.run.user(["mkdir", "-p", args.aports, tmpdir +
"/_aports/" + folder])
path_original = pmb.helpers.pmaports.find(f"device-{args.devicesdhbfvhubsud}")
pmb.helpers.run.user(["cp", "-r", path_original,
f"{tmpdir}/_aports/device/testing"])
for pkgname in ["testlib", "testapp", "testsubpkg"]:
pmb.helpers.run.user(["cp", "-r",
"test/testdata/pkgrel_bump/aports/"
f"{pkgname}",
f"{tmpdir}/_aports/main/{pkgname}"])
# Copy pmaports.cfg
pmb.helpers.run.user(["cp", args.aports / "pmaports.cfg", tmpdir +
"/_aports"])
# Empty packages folder
channel = pmb.config.pmaports.read_config()["channel"]
packages_path = f"{tmpdir}/packages/{channel}"
pmb.helpers.run.user(["mkdir", "-p", packages_path])
pmb.helpers.run.user(["chmod", "777", packages_path])
# Copy over the pmbootstrap config
pmb.helpers.run.user(["cp", args.config, tmpdir +
"/_pmbootstrap.cfg"])
def verify_pkgrels(tmpdir, pkgrel_testlib, pkgrel_testapp,
pkgrel_testsubpkg):
"""
Verify the pkgrels of the three test APKBUILDs ("testlib", "testapp",
"testsubpkg").
"""
pmb.helpers.other.cache["apkbuild"] = {}
mapping = {"testlib": pkgrel_testlib,
"testapp": pkgrel_testapp,
"testsubpkg": pkgrel_testsubpkg}
for pkgname, pkgrel in mapping.items():
# APKBUILD path
path = tmpdir + "/_aports/main/" + pkgname + "/APKBUILD"
# Parse and verify
apkbuild = pmb.parse.apkbuild(path)
assert pkgrel == int(apkbuild["pkgrel"])
def test_pkgrel_bump_high_level(args: PmbArgs, tmpdir):
# Tempdir setup
tmpdir = str(tmpdir)
setup_work(args, tmpdir)
# Make sure we don't try and cross compile
pmbootstrap(args, tmpdir, ["config", "build_default_device_arch", "False"])
# Let pkgrel_bump exit normally
pmbootstrap(args, tmpdir, ["build", "testlib", "testapp", "testsubpkg"])
pmbootstrap(args, tmpdir, ["pkgrel_bump", "--dry", "--auto"])
verify_pkgrels(tmpdir, 0, 0, 0)
# Increase soname (testlib soname changes with the pkgrel)
pmbootstrap(args, tmpdir, ["pkgrel_bump", "testlib"])
verify_pkgrels(tmpdir, 1, 0, 0)
pmbootstrap(args, tmpdir, ["build", "testlib"])
pmbootstrap(args, tmpdir, ["pkgrel_bump", "--dry", "--auto"])
verify_pkgrels(tmpdir, 1, 0, 0)
# Delete package with previous soname (--auto-dry exits with >0 now)
channel = pmb.config.pmaports.read_config()["channel"]
arch = pmb.config.arch_native
apk_path = f"{tmpdir}/packages/{channel}/{arch}/testlib-1.0-r0.apk"
pmb.helpers.run.root(["rm", apk_path])
pmbootstrap(args, tmpdir, ["index"])
pmbootstrap(args, tmpdir, ["pkgrel_bump", "--dry", "--auto"], False)
verify_pkgrels(tmpdir, 1, 0, 0)
# Bump pkgrel and build testapp/testsubpkg
pmbootstrap(args, tmpdir, ["pkgrel_bump", "--auto"])
verify_pkgrels(tmpdir, 1, 1, 1)
pmbootstrap(args, tmpdir, ["build", "testapp", "testsubpkg"])
# After rebuilding, pkgrel_bump --auto-dry exits with 0
pmbootstrap(args, tmpdir, ["pkgrel_bump", "--dry", "--auto"])
verify_pkgrels(tmpdir, 1, 1, 1)
# Test running with specific package names
pmbootstrap(args, tmpdir, ["pkgrel_bump", "invalid_package_name"], False)
pmbootstrap(args, tmpdir, ["pkgrel_bump", "--dry", "testlib"], False)
verify_pkgrels(tmpdir, 1, 1, 1)
# Clean up
pmbootstrap(args, tmpdir, ["shutdown"])
pmb.helpers.run.root(["rm", "-rf", tmpdir])

View file

@ -1,52 +0,0 @@
# Copyright 2024 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
""" Test preserving HTTP_PROXY and other proxy env vars with all pmbootstrap
run functions. """
import os
from pmb.types import PmbArgs
import pytest
import sys
import pmb_test # noqa
import pmb.chroot.run
import pmb.helpers.run
import pmb.helpers.run_core
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_proxy_user(args: PmbArgs, monkeypatch):
func = pmb.helpers.run.user
monkeypatch.setattr(os, "environ", {"HTTP_PROXY": "testproxy"})
ret = func(args, ["sh", "-c", 'echo "$HTTP_PROXY"'], output_return=True)
assert ret == "testproxy\n"
def test_proxy_root(args: PmbArgs, monkeypatch):
func = pmb.helpers.run.root
monkeypatch.setattr(os, "environ", {"HTTP_PROXY": "testproxy"})
ret = func(args, ["sh", "-c", 'echo "$HTTP_PROXY"'], output_return=True)
assert ret == "testproxy\n"
def test_proxy_chroot_user(args: PmbArgs, monkeypatch):
func = pmb.chroot.user
monkeypatch.setattr(os, "environ", {"HTTP_PROXY": "testproxy"})
ret = func(args, ["sh", "-c", 'echo "$HTTP_PROXY"'], output_return=True)
assert ret == "testproxy\n"
def test_proxy_chroot_root(args: PmbArgs, monkeypatch):
func = pmb.chroot.run
monkeypatch.setattr(os, "environ", {"HTTP_PROXY": "testproxy"})
ret = func(args, ["sh", "-c", 'echo "$HTTP_PROXY"'], output_return=True)
assert ret == "testproxy\n"

View file

@ -1,192 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
"""
This file runs various installations and boots into them with QEMU, then checks
via SSH if expected processes are running.
We use an extra config file (based on ~/.config/pmbootstrap.cfg), because we
need to change it a lot (e.g. UI, username, ...).
"""
from pmb.types import PmbArgs
import pytest
import sys
import shutil
import shlex
import time
import pmb_test # noqa
import pmb.chroot.apk_static
import pmb.parse.apkindex
import pmb.helpers.logging
import pmb.helpers.run
import pmb.parse.bootimg
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def ssh_create_askpass_script(args: PmbArgs):
"""Create /tmp/y.sh, which we need to automatically login via SSH."""
with open(get_context().config.work / "chroot_native/tmp/y.sh", "w") as handle:
handle.write("#!/bin/sh\necho y\n")
pmb.chroot.root(["chmod", "+x", "/tmp/y.sh"])
def pmbootstrap_run(args: PmbArgs, config, parameters, output="log"):
"""Execute pmbootstrap.py with a test pmbootstrap.conf."""
return pmb.helpers.run.user(["./pmbootstrap.py", "-c", config] +
parameters, working_dir=pmb.config.pmb_src,
output=output)
def pmbootstrap_yes(args: PmbArgs, config, parameters):
"""
Execute pmbootstrap.py with a test pmbootstrap.conf, and pipe "yes" into it
(so we can do a fully automated installation, using "y" as password
everywhere). Use --details-to-stdout to avoid the pmbootstrap process from
looking like it is hanging, when downloading packages with apk (otherwise
it would write no output, and get killed by the timeout).
"""
command = ("yes | ./pmbootstrap.py --details-to-stdout -c " +
shlex.quote(config))
for parameter in parameters:
command += " " + shlex.quote(parameter)
return pmb.helpers.run.user(["/bin/sh", "-c", command],
working_dir=pmb.config.pmb_src)
class QEMU(object):
def __init__(self, request):
self.process = None
request.addfinalizer(self.terminate)
def terminate(self):
if self.process:
self.process.terminate()
else:
print("WARNING: The QEMU process wasn't set, so it could not be"
" terminated.")
def run(self, args, tmpdir, ui="none"):
# Copy and adjust user's pmbootstrap.cfg
config = str(tmpdir) + "/pmbootstrap.cfg"
shutil.copyfile(args.config, config)
pmbootstrap_run(args, config, ["config", "device", "qemu-amd64"])
pmbootstrap_run(args, config, ["config", "kernel", "virt"])
pmbootstrap_run(args, config, ["config", "extra_packages", "none"])
pmbootstrap_run(args, config, ["config", "user", "testuser"])
pmbootstrap_run(args, config, ["config", "ui", ui])
# Prepare native chroot
pmbootstrap_run(args, config, ["-y", "zap"])
pmb.chroot.apk.install(["openssh-client"])
ssh_create_askpass_script(args)
# Create and run rootfs
pmbootstrap_yes(args, config, ["install"])
self.process = pmbootstrap_run(args, config, ["qemu", "--display",
"none"], "background")
@pytest.fixture
def qemu(request):
return QEMU(request)
def ssh_run(args: PmbArgs, command):
"""
Run a command in the QEMU VM on localhost via SSH.
:param command: flat string of the command to execute, e.g. "ps au"
:returns: the result from the SSH server
"""
ret = pmb.chroot.user(["SSH_ASKPASS=/tmp/y.sh", "DISPLAY=", "ssh",
"-o", "ConnectTimeout=10",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "StrictHostKeyChecking=no",
"-p", "2222", "testuser@localhost", "--",
command], output_return=True, check=False)
return ret
def is_running(args: PmbArgs, programs, timeout=300, sleep_before_retry=1):
"""
Simple check that looks for program names in the output of "ps ax".
This is error-prone, only use it with programs that have a unique name.
With defaults timeout and sleep_before_retry values, it will try keep
trying for 5 minutes, but not more than once per second.
:param programs: list of programs to check for, e.g. ["xfce4-desktop"]
:param timeout: approximate time in seconds until timeout
:param sleep_before_retry: time in seconds to sleep before trying again
"""
print(f"Looking for programs to appear in the VM (timeout: {timeout}): " +
", ".join(programs))
ssh_works = False
end = time.monotonic() + timeout
last_try = 0.0
while last_try < end:
# Sleep only when last try exited immediately
sleep = last_try - time.monotonic() + sleep_before_retry
if sleep > 0:
time.sleep(sleep)
last_try = time.monotonic()
# Get running programs via SSH
all = ssh_run(args, "ps ax")
if not all:
continue
ssh_works = True
# Missing programs
missing = []
for program in programs:
if program not in all:
missing.append(program)
if not missing:
return True
# Not found
print("ERROR: Timeout reached!")
if ssh_works:
print("Programs not running: " + ", ".join(missing))
else:
print("Could not connect to the VM via SSH")
return False
@pytest.mark.skip_ci
def test_none(args: PmbArgs, tmpdir, qemu):
qemu.run(args, tmpdir)
# Check that at least SSH works (no special process running)
assert is_running(args, [])
# self-test of is_running() - invalid-process should not be detected as
# running
assert is_running(args, ["invalid-process"], 1) is False
@pytest.mark.skip_ci
def test_xfce4(args: PmbArgs, tmpdir, qemu):
qemu.run(args, tmpdir, "xfce4")
assert is_running(args, ["xfce4-session", "xfdesktop", "xfce4-panel",
"Thunar", "dbus-daemon", "xfwm4"])
@pytest.mark.skip_ci
def test_plasma_mobile(args: PmbArgs, tmpdir, qemu):
# NOTE: Once we have plasma mobile running properly without GL, we can
# check for more processes
qemu.run(args, tmpdir, "plasma-mobile")
assert is_running(args, ["polkitd"])

View file

@ -1,270 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
from pmb.helpers import logging
import os
from pmb.types import PmbArgs
import pytest
import sys
import pmb_test
import pmb_test.const
import pmb.aportgen.device
import pmb.config
import pmb.config.init
import pmb.helpers.logging
import pmb.parse.deviceinfo
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
cfg = f"{pmb_test.const.testdata}/channels.cfg"
sys.argv = ["pmbootstrap.py", "--config-channels", cfg, "init"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def fake_answers(monkeypatch, answers):
"""
Patch pmb.helpers.cli.ask() function to return defined answers instead of
asking the user for an answer.
:param answers: list of answer strings, e.g. ["y", "n", "invalid-device"].
In this example, the first question is answered with "y",
the second question with "n" and so on.
"""
def fake_ask(question="Continue?", choices=["y", "n"], default="n",
lowercase_answer=True, validation_regex=None, complete=None):
answer = answers.pop(0)
logging.info("pmb.helpers.cli.ask() fake answer: " + answer)
return answer
monkeypatch.setattr(pmb.helpers.cli, "ask", fake_ask)
def test_fake_answers_selftest(monkeypatch):
fake_answers(monkeypatch, ["first", "second"])
assert pmb.helpers.cli.ask() == "first"
assert pmb.helpers.cli.ask() == "second"
def test_questions_booleans(args: PmbArgs, monkeypatch):
functions = [pmb.aportgen.device.ask_for_keyboard,
pmb.aportgen.device.ask_for_external_storage]
for func in functions:
fake_answers(monkeypatch, ["y", "n"])
assert func(args) is True
assert func(args) is False
def test_questions_strings(args: PmbArgs, monkeypatch):
functions = [pmb.aportgen.device.ask_for_manufacturer]
for func in functions:
fake_answers(monkeypatch, ["Simple string answer"])
assert func() == "Simple string answer"
def test_questions_name(args: PmbArgs, monkeypatch):
func = pmb.aportgen.device.ask_for_name
# Manufacturer should get added automatically, but not twice
fake_answers(monkeypatch, ["Amazon Thor"])
assert func("Amazon") == "Amazon Thor"
fake_answers(monkeypatch, ["Thor"])
assert func("Amazon") == "Amazon Thor"
# Don't add the manufacturer when it starts with "Google"
fake_answers(monkeypatch, ["Google Nexus 12345"])
assert func("Amazon") == "Google Nexus 12345"
def test_questions_arch(args: PmbArgs, monkeypatch):
fake_answers(monkeypatch, ["invalid_arch", "aarch64"])
assert pmb.aportgen.device.ask_for_architecture() == "aarch64"
def test_questions_bootimg(args: PmbArgs, monkeypatch):
func = pmb.aportgen.device.ask_for_bootimg
fake_answers(monkeypatch, ["invalid_path", ""])
assert func(args) is None
bootimg_path = pmb_test.const.testdata + "/bootimg/normal-boot.img"
fake_answers(monkeypatch, [bootimg_path])
output = {"header_version": "0",
"base": "0x80000000",
"kernel_offset": "0x00008000",
"ramdisk_offset": "0x04000000",
"second_offset": "0x00f00000",
"tags_offset": "0x0e000000",
"pagesize": "2048",
"cmdline": "bootopt=64S3,32S1,32S1",
"qcdt": "false",
"dtb_second": "false"}
assert func(args) == output
def test_questions_device(args: PmbArgs, monkeypatch):
# Prepare args
args.aports = pmb_test.const.testdata + "/init_questions_device/aports"
args.devicesdhbfvhubsud = "lg-mako"
args.kernel = "downstream"
# Do not generate aports
def fake_generate(args: PmbArgs, pkgname):
return
monkeypatch.setattr(pmb.aportgen, "generate", fake_generate)
# Existing device (without non-free components so we have defaults there)
func = pmb.config.init.ask_for_device
fake_answers(monkeypatch, ["lg", "mako"])
kernel = args.kernel
assert func(args) == ("lg-mako", True, kernel)
# Non-existing vendor, go back, existing vendor+device
fake_answers(monkeypatch, ["whoops", "n", "lg", "mako"])
assert func(args) == ("lg-mako", True, kernel)
# Existing vendor, new device, go back, existing vendor+device
fake_answers(monkeypatch, ["lg", "nonexistent", "n", "lg", "mako"])
assert func(args) == ("lg-mako", True, kernel)
# New vendor and new device (new port)
fake_answers(monkeypatch, ["new", "y", "device", "y"])
assert func(args) == ("new-device", False, kernel)
# Existing vendor, new device (new port)
fake_answers(monkeypatch, ["lg", "nonexistent", "y"])
assert func(args) == ("lg-nonexistent", False, kernel)
def test_questions_device_kernel(args: PmbArgs, monkeypatch):
# Prepare args
args.aports = pmb_test.const.testdata + "/init_questions_device/aports"
args.kernel = "downstream"
# Kernel hardcoded in depends
func = pmb.config.init.ask_for_device_kernel
device = "lg-mako"
assert func(args, device) == args.kernel
# Choose "mainline"
device = "sony-amami"
fake_answers(monkeypatch, ["mainline"])
assert func(args, device) == "mainline"
# Choose "downstream"
fake_answers(monkeypatch, ["downstream"])
assert func(args, device) == "downstream"
def test_questions_flash_methods(args: PmbArgs, monkeypatch):
func = pmb.aportgen.device.ask_for_flash_method
fake_answers(monkeypatch, ["invalid_flash_method", "fastboot"])
assert func() == "fastboot"
fake_answers(monkeypatch, ["0xffff"])
assert func() == "0xffff"
fake_answers(monkeypatch, ["heimdall", "invalid_type", "isorec"])
assert func() == "heimdall-isorec"
fake_answers(monkeypatch, ["heimdall", "bootimg"])
assert func() == "heimdall-bootimg"
def test_questions_keymaps(args: PmbArgs, monkeypatch):
func = pmb.config.init.ask_for_keymaps
fake_answers(monkeypatch, ["invalid_keymap", "us/rx51_us"])
assert func(args, pmb.parse.deviceinfo(args, "nokia-n900")) == "us/rx51_us"
assert func(args, pmb.parse.deviceinfo(args, "lg-mako")) == ""
def test_questions_ui(args: PmbArgs, monkeypatch):
args.aports = pmb_test.const.testdata + "/init_questions_device/aports"
device = "lg-mako"
info = pmb.parse.deviceinfo(args, device)
fake_answers(monkeypatch, ["none"])
assert pmb.config.init.ask_for_ui(args, info) == "none"
fake_answers(monkeypatch, ["invalid_UI", "weston"])
assert pmb.config.init.ask_for_ui(args, info) == "weston"
def test_questions_ui_extras(args: PmbArgs, monkeypatch):
args.aports = pmb_test.const.testdata + "/init_questions_device/aports"
assert not pmb.config.init.ask_for_ui_extras(args, "none")
fake_answers(monkeypatch, ["n"])
assert not pmb.config.init.ask_for_ui_extras(args, "weston")
fake_answers(monkeypatch, ["y"])
assert pmb.config.init.ask_for_ui_extras(args, "weston")
def test_questions_work_path(args: PmbArgs, monkeypatch, tmpdir):
# Existing paths (triggering various errors)
func = pmb.config.init.ask_for_work_path
tmpdir = str(tmpdir)
fake_answers(monkeypatch, ["/dev/null", os.path.dirname(__file__),
pmb.config.pmb_src, tmpdir])
assert func(args) == (tmpdir, True)
# Non-existing path
work = tmpdir + "/non_existing_subfolder"
fake_answers(monkeypatch, [work])
assert func(args) == (work, False)
def test_questions_additional_options(args: PmbArgs, monkeypatch):
func = pmb.config.init.ask_for_additional_options
cfg = {"pmbootstrap": {}}
# Skip changing anything
fake_answers(monkeypatch, ["n"])
func(args, cfg)
assert cfg == {"pmbootstrap": {}}
# Answer everything
fake_answers(monkeypatch, ["y", "128", "64", "5", "2G", "n", "y", "1",
"n"])
func(args, cfg)
mirror = pmb.config.defaults["mirrors_postmarketos"]
assert cfg == {"pmbootstrap": {"extra_space": "128",
"boot_size": "64",
"jobs": "5",
"ccache_size": "2G",
"sudo_timer": "False",
"mirrors_postmarketos": mirror}}
def test_questions_hostname(args: PmbArgs, monkeypatch):
func = pmb.config.init.ask_for_hostname
device = "test-device"
# Valid hostname
fake_answers(monkeypatch, ["valid"])
assert func(args, device) == "valid"
# Hostname too long ("aaaaa...")
fake_answers(monkeypatch, ["a" * 64, "a" * 63])
assert func(args, device) == "a" * 63
# Fail the regex
fake_answers(monkeypatch, ["$invalid", "valid"])
assert func(args, device) == "valid"
# Begins or ends with minus
fake_answers(monkeypatch, ["-invalid", "invalid-", "valid"])
assert func(args, device) == "valid"
# Device name: empty string
fake_answers(monkeypatch, [device])
assert func(args, device) == ""
def test_questions_channel(args: PmbArgs, monkeypatch):
fake_answers(monkeypatch, ["invalid-channel", "v20.05"])
assert pmb.config.init.ask_for_channel(args) == "v20.05"

View file

@ -1,171 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
""" Test pmb.helpers.run_core """
from typing import Sequence
from pmb.types import PmbArgs
import pytest
import re
import subprocess
import sys
import time
import pmb_test # noqa
import pmb.helpers.run_core
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_sanity_checks():
func = pmb.helpers.run_core.sanity_checks
# Invalid output
with pytest.raises(RuntimeError) as e:
func("invalid-output")
assert str(e.value).startswith("Invalid output value")
# Background and check
func("background", check=None)
for check in [True, False]:
with pytest.raises(RuntimeError) as e:
func("background", check=check)
assert str(e.value).startswith("Can't use check with")
# output_return
func("log", output_return=True)
with pytest.raises(RuntimeError) as e:
func("tui", output_return=True)
assert str(e.value).startswith("Can't use output_return with")
def test_background(args: PmbArgs):
# Sleep in background
process = pmb.helpers.run_core.background(["sleep", "1"], "/")
# Check if it is still running
assert process.poll() is None
def test_pipe(args: PmbArgs):
# Sleep in background
process = pmb.helpers.run_core.pipe(["sleep", "1"], "/")
# Check if it is still running
assert process.poll() is None
# Print output in background
process = pmb.helpers.run_core.pipe(["echo", "-n", "hello"], "/")
# Read output
assert process.communicate()[0].decode('utf-8') == "hello"
def test_foreground_pipe(args: PmbArgs):
func = pmb.helpers.run_core.foreground_pipe
cmd: Sequence[str] = ["echo", "test"]
# Normal run
assert func(args, cmd) == (0, "")
# Return output
assert func(args, cmd, output_return=True) == (0, "test\n")
# Kill with output timeout
cmd = ["sh", "-c", "echo first; sleep 2; echo second"]
args.timeout = 0.3
ret = func(args, cmd, output_return=True, output_timeout=True)
assert ret == (-9, "first\n")
# Kill with output timeout as root
cmd = pmb.config.sudo(["sh", "-c", "printf first; sleep 2; printf second"])
args.timeout = 0.3
ret = func(args, cmd, output_return=True, output_timeout=True,
sudo=True)
assert ret == (-9, "first")
# Finish before timeout
cmd = ["sh", "-c", "echo first; sleep 0.1; echo second; sleep 0.1;"
"echo third; sleep 0.1; echo fourth"]
args.timeout = 0.2
ret = func(args, cmd, output_return=True, output_timeout=True)
assert ret == (0, "first\nsecond\nthird\nfourth\n")
# Check if all child processes are killed after timeout.
# The first command uses ps to get its process group id (pgid) and echo it
# to stdout. All of the test commands will be running under that pgid.
cmd = pmb.config.sudo([
"sh", "-c",
"pgid=$(ps -o pgid= | grep ^${1:-$$});echo $pgid | tr -d '\n';"
"sleep 10 | sleep 20 | sleep 30"
])
args.timeout = 0.3
ret = func(args, cmd, output_return=True, output_timeout=True,
sudo=True)
pgid = str(ret[1])
cmd = ["ps", "-e", "-o", "pgid,comm"]
ret = subprocess.run(cmd, check=True, stdout=subprocess.PIPE)
procs = str(ret.stdout.decode("utf-8")).rstrip().split('\n')[1:]
child_procs = []
for process in procs:
items = process.split(maxsplit=1)
if len(items) != 2:
continue
if pgid == items[0] and "sleep" in items[1]:
child_procs.append(items)
assert len(child_procs) == 0
def test_foreground_tui():
func = pmb.helpers.run_core.foreground_tui
assert func(["echo", "test"]) == 0
def test_core(args: PmbArgs, monkeypatch):
# Background
func = pmb.helpers.run_core.core
msg = "test"
process = func(args, msg, ["sleep", "1"], output="background")
assert process.poll() is None
# Foreground (TUI)
ret = func(args, msg, ["echo", "test"], output="tui")
assert ret == 0
# Foreground (pipe)
ret = func(args, msg, ["echo", "test"], output="log")
assert ret == 0
# Return output
ret = func(args, msg, ["echo", "test"], output="log", output_return=True)
assert ret == "test\n"
# Check the return code
with pytest.raises(RuntimeError) as e:
func(args, msg, ["false"], output="log")
assert re.search(r"^Command failed \(exit code -?\d*\): ", str(e.value))
# Kill with timeout
args.timeout = 0.2
with pytest.raises(RuntimeError) as e:
func(args, msg, ["sleep", "1"], output="log")
assert re.search(r"^Command failed \(exit code -?\d*\): ", str(e.value))
@pytest.mark.skip_ci
def test_sudo_timer(args: PmbArgs):
pmb.helpers.run.root(["whoami"])
time.sleep(300)
out = pmb.helpers.run.root(["whoami"])
assert out == 0

View file

@ -1,112 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import sys
from typing import Any
from pmb.types import Env, PmbArgs
import pytest
import pmb_test # noqa
import pmb.chroot.run
import pmb.helpers.run
import pmb.helpers.run_core
import pmb.helpers.logging
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_shell_escape(args: PmbArgs):
cmds = {"test\n": ["echo", "test"],
"test && test\n": ["echo", "test", "&&", "test"],
"test ; test\n": ["echo", "test", ";", "test"],
"'test\"test\\'\n": ["echo", "'test\"test\\'"],
"*\n": ["echo", "*"],
"$PWD\n": ["echo", "$PWD"],
"hello world\n": ["printf", "%s world\n", "hello"]}
for expected, cmd in cmds.items():
copy = list(cmd)
core = pmb.helpers.run_core.core(str(cmd), cmd,
output_return=True)
assert expected == core
assert cmd == copy
user = pmb.helpers.run.user(cmd, output_return=True)
assert expected == user
assert cmd == copy
root = pmb.helpers.run.root(cmd, output_return=True)
assert expected == root
assert cmd == copy
chroot_root = pmb.chroot.run(args, cmd, output_return=True)
assert expected == chroot_root
assert cmd == copy
chroot_user = pmb.chroot.user(cmd, output_return=True)
assert expected == chroot_user
assert cmd == copy
def test_shell_escape_env(args: PmbArgs):
key = "PMBOOTSTRAP_TEST_ENVIRONMENT_VARIABLE"
value = "long value with spaces and special characters: '\"\\!$test"
env: Env = {key: value}
cmd = ["sh", "-c", "env | grep " + key + " | grep -v SUDO_COMMAND"]
ret = key + "=" + value + "\n"
copy = list(cmd)
func: Any = pmb.helpers.run.user
assert func(args, cmd, output_return=True, env=env) == ret
assert cmd == copy
func = pmb.helpers.run.root
assert func(args, cmd, output_return=True, env=env) == ret
assert cmd == copy
func = pmb.chroot.run
assert func(args, cmd, output_return=True, env=env) == ret
assert cmd == copy
func = pmb.chroot.user
assert func(args, cmd, output_return=True, env=env) == ret
assert cmd == copy
def test_flat_cmd_simple():
func = pmb.helpers.run_core.flat_cmd
cmd = ["echo", "test"]
ret = "echo test"
env: Env = {}
assert func(cmd, env=env) == ret
def test_flat_cmd_wrap_shell_string_with_spaces():
func = pmb.helpers.run_core.flat_cmd
cmd = ["echo", "string with spaces"]
ret = "echo 'string with spaces'"
env: Env = {}
assert func(cmd, env=env) == ret
def test_flat_cmd_wrap_env_simple():
func = pmb.helpers.run_core.flat_cmd
cmd = ["echo", "test"]
ret = "JOBS=5 echo test"
env: Env = {"JOBS": "5"}
assert func(cmd, env=env) == ret
def test_flat_cmd_wrap_env_spaces():
func = pmb.helpers.run_core.flat_cmd
cmd = ["echo", "test"]
ret = "JOBS=5 TEST='spaces string' echo test"
env: Env = {"JOBS": "5", "TEST": "spaces string"}
assert func(cmd, env=env) == ret

View file

@ -1,71 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import sys
from pmb.types import PmbArgs
import pytest
import pmb_test
import pmb_test.const
import pmb.helpers.git
import pmb.helpers.logging
import pmb.parse.version
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_version(args: PmbArgs):
# Fail after the first error or print a grand total of failures
keep_going = False
# Iterate over the version tests from apk-tools
path = pmb_test.const.testdata + "/version/version.data"
mapping = {-1: "<", 0: "=", 1: ">"}
count = 0
errors = []
with open(path) as handle:
for line in handle:
split = line.split(" ")
a = split[0]
b = split[2].split("#")[0].rstrip()
expected = split[1]
print("(#" + str(count) + ") " + line.rstrip())
result = pmb.parse.version.compare(a, b)
real = mapping[result]
count += 1
if real != expected:
if keep_going:
errors.append(line.rstrip() + " (got: '" + real + "')")
else:
assert real == expected
print("---")
print("total: " + str(count))
print("errors: " + str(len(errors)))
print("---")
for error in errors:
print(error)
assert errors == []
def test_version_check_string():
func = pmb.parse.version.check_string
assert func("3.2.4", ">=0.0.0") is True
assert func("3.2.4", ">=3.2.4") is True
assert func("3.2.4", "<4.0.0") is True
assert func("0.0.0", ">=0.0.1") is False
assert func("4.0.0", "<4.0.0") is False
assert func("4.0.1", "<4.0.0") is False
assert func("5.2.0_rc3", "<5.2.0") is False
assert func("5.2.0_rc3", ">=5.2.0") is True

View file

@ -1,16 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import pmb_test # noqa
import pmb.parse.version
def test_version_validate():
func = pmb.parse.version.validate
assert func("6.0_1") is False
assert func("6.0_invalidsuffix1") is False
assert func("6.0.0002") is True
assert func("6.0.234") is True
# Issue #1144
assert func("6.0_0002") is False

View file

@ -1,70 +0,0 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
# This file has a _zzz_ prefix so it runs last, because it tends to fail on
# sourcehut currently. Related to some CDN caching issue probably.
import os
import sys
from pmb.types import PmbArgs
import pytest
import glob
import filecmp
import pmb_test # noqa
import pmb.parse.apkindex
import pmb.helpers.logging
import pmb.config
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.log = get_context().config.work / "log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_keys(args: PmbArgs):
# Get the alpine-keys apk filename
pmb.chroot.init(args)
version = pmb.parse.apkindex.package("alpine-keys")["version"]
pattern = (get_context().config.work / "cache_apk_" + pmb.config.arch_native +
"/alpine-keys-" + version + ".*.apk")
filename = os.path.basename(glob.glob(pattern)[0])
# Extract it to a temporary folder
temp = "/tmp/test_keys_extract"
temp_outside = get_context().config.work / "chroot_native" + temp
if os.path.exists(temp_outside):
pmb.chroot.root(["rm", "-r", temp])
pmb.chroot.user(["mkdir", "-p", temp])
pmb.chroot.user(["tar", "xvf", "/var/cache/apk/" + filename],
working_dir=temp)
# Get all relevant key file names as {"filename": "full_outside_path"}
keys_upstream = {}
for arch in pmb.config.build_device_architectures + ["x86_64"]:
pattern = temp_outside + "/usr/share/apk/keys/" + arch + "/*.pub"
for path in glob.glob(pattern):
keys_upstream[os.path.basename(path)] = path
assert len(keys_upstream)
# Check if the keys are mirrored correctly
mirror_path_keys = pmb.config.apk_keys_path
for key, original_path in keys_upstream.items():
mirror_path = mirror_path_keys + "/" + key
assert filecmp.cmp(mirror_path, original_path, False)
# Find postmarketOS keys
keys_pmos = ["build.postmarketos.org.rsa.pub"]
for key in keys_pmos:
assert os.path.exists(mirror_path_keys + "/" + key)
# Find outdated keys, which need to be removed
glob_result = glob.glob(mirror_path_keys + "/*.pub")
assert len(glob_result)
for path in glob_result:
key = os.path.basename(key)
assert key in keys_pmos or key in keys_upstream

View file

@ -1,8 +0,0 @@
pkgname="depends-in-depends"
pkgver="1.0.0"
pkgrel=0
arch="armhf"
depends="first"
depends="$depends second"
depends="${depends} third"
pkgdesc="depends-in-depends test"

View file

@ -1,33 +0,0 @@
# APKBUILD to test 'pmbootstrap lint', used by test/test_helpers_lint.py
# Maintainer: Oliver Smith <ollieparanoid@postmarketos.org>
# Co-Maintainer: Hello World <hello@world>
pkgname=hello-world
pkgver=1
pkgrel=5
pkgdesc="hello world program to be built in the testsuite"
url="https://en.wikipedia.org/wiki/%22Hello,_World!%22_program"
arch="all"
license="MIT"
source="main.c Makefile"
# has pmbootstrap specific options (https://postmarketos.org/apkbuild-options)
options="!tracedeps pmb:cross-native pmb:strict !archcheck"
build() {
cd "$srcdir"
make
}
check() {
cd "$srcdir"
printf 'hello, world!\n' > expected
./hello-world > real
diff -q expected real
}
package() {
install -D -m755 "$srcdir"/hello-world \
"$pkgdir"/usr/bin/hello-world
}
sha512sums="62385af6a68cd4e0c03b15992bb9f1d20b8d6c8a33724ca2d28629a139e95016d0502257f8a3a8be53eef30e11b3e372a2469cb1989dbd387ebea4464a9273ee main.c
80c32948d3254f5e4f9084d73754824e7d7d7d117770b041a1a13baf056773de265153fe518cc3e735db55b638411aa6fbd0e17b5b674dfc89e69a9391fbd3bb Makefile"

View file

@ -1,20 +0,0 @@
pkgname="linux-envkernel-test"
package() {
install -Dm644 "$srcdir"/build/arch/arm/boot/dt.img \
"$pkgdir"/boot/dt.img
install -Dm644 "$srcdir"/build/arch/arm/boot/zImage-dtb \
"$pkgdir"/boot/vmlinuz-$_flavor
install -D "$srcdir"/build/include/config/kernel.release \
"$pkgdir"/usr/share/kernel/$_flavor/kernel.release
cd "$srcdir"/build
unset LDFLAGS
echo "--[ Installing modules ]--"
make ARCH="$_carch" CC="${CC:-gcc}" \
KBUILD_BUILD_VERSION="$((pkgrel + 1))-Alpine" CONFIG_NO_ERROR_ON_MISMATCH=y \
INSTALL_MOD_PATH="$pkgdir" INSTALL_MOD_STRIP=1 modules_install
}

View file

@ -1,10 +0,0 @@
# Reference: <https://postmarketos.org/devicepkg>
# Archived: This is broken!
pkgname="missing-pkgdesc-in-subpackage"
arch="noarch"
subpackages="$pkgname-subpackage invalid-function:does_not_exist"
subpackage() {
# this function does not have a pkgdesc
mkdir "$subpkgdir"
}

View file

@ -1,17 +0,0 @@
pkgname="subpackages"
arch="noarch"
subpackages="simple custom:custom_function different_arch::x86_64"
depends="postmarketos-base"
simple() {
mkdir "$subpkgdir"
}
custom_function() {
pkgdesc="This is one of the custom $pkgname"
depends="$depends glibc"
}
different_arch() {
pkgdesc="This has a different architecture than the other $pkgname"
}

View file

@ -1,13 +0,0 @@
pkgname="variable-replacements"
pkgver="1.0.0"
pkgrel=0
arch="armhf"
pkgdesc="$pkgdesc$pkgname test"
_custom_var="1234" # this variable is not known to pmbootstrap
url="${pkgname/variable-} ${pkgname/-replacements/} ${pkgname/variable/string} $_custom_var"
subpackages="${pkgdesc#variable-}:test_subpkg_func"
pkgdesc="this should not affect variable replacement"
test_subpkg_func() {
mkdir "$subpkgdir"
}

View file

@ -1,8 +0,0 @@
pkgname=dart-stage0
pkgver=3.0.0_alpha369-r0
pkgrel=1
pkgdesc="Dart is a client-optimized language for fast apps on any platform (temporary bootstrap package)"
url="https://dart.dev/"
arch="aarch64 armv7 x86_64"
license="BSD-3-Clause"
options="!check"

View file

@ -1,20 +0,0 @@
C:Q1XaZzCVZ9mvH8djPyEb5aUYhG3r4=
P:hello-world
V:2-r0
A:x86_64
S:2897
I:20480
T:hello world program to be built in the testsuite
U:https://en.wikipedia.org/wiki/%22Hello,_World!%22_program
L:MIT
o:hello-world
t:1500000000
c:
D:!conflict so:libc.musl-x86_64.so.1
p:cmd:hello-world
F:usr
F:usr/bin
R:hello-world
a:0:0:755
Z:Q1ZjTpsnMchSsSwEPB1cTjihYuJvo=

View file

@ -1,23 +0,0 @@
C:Q1gKkFdQUwKAmcUpGY8VaErq0uHNo=
P:musl
A:x86_64
S:357094
I:581632
T:the musl c library (libc) implementation
U:http://www.musl-libc.org/
L:MIT
o:musl
m:Timo Ter s <timo.teras@iki.fi>
t:1515217616
c:6cc1d4e6ac35607dd09003e4d013a0d9c4800c49
p:so:libc.musl-x86_64.so.1=1
F:lib
R:libc.musl-x86_64.so.1
a:0:0:777
Z:Q17yJ3JFNypA4mxhJJr0ou6CzsJVI=
R:ld-musl-x86_64.so.1
a:0:0:755
Z:Q1DadJ0cqdT+ImyeY5FgTdZWaLnyQ=
F:usr
F:usr/lib

View file

@ -1,25 +0,0 @@
C:Q1gKkFdQUwKAmcUpGY8VaErq0uHNo=
P:musl
V:1.1.18-r5
V:1.1.18-r5
A:x86_64
S:357094
I:581632
T:the musl c library (libc) implementation
U:http://www.musl-libc.org/
L:MIT
o:musl
m:Timo Ter s <timo.teras@iki.fi>
t:1515217616
c:6cc1d4e6ac35607dd09003e4d013a0d9c4800c49
p:so:libc.musl-x86_64.so.1=1
F:lib
R:libc.musl-x86_64.so.1
a:0:0:777
Z:Q17yJ3JFNypA4mxhJJr0ou6CzsJVI=
R:ld-musl-x86_64.so.1
a:0:0:755
Z:Q1DadJ0cqdT+ImyeY5FgTdZWaLnyQ=
F:usr
F:usr/lib

View file

@ -1,23 +0,0 @@
C:Q1gKkFdQUwKAmcUpGY8VaErq0uHNo=
P:musl
V:1.1.18-r5
A:x86_64
S:357094
I:581632
T:the musl c library (libc) implementation
U:http://www.musl-libc.org/
L:MIT
o:musl
m:Timo Ter s <timo.teras@iki.fi>
t:1515217616
c:6cc1d4e6ac35607dd09003e4d013a0d9c4800c49
p:so:libc.musl-x86_64.so.1=1
F:lib
R:libc.musl-x86_64.so.1
a:0:0:777
Z:Q17yJ3JFNypA4mxhJJr0ou6CzsJVI=
R:ld-musl-x86_64.so.1
a:0:0:755
Z:Q1DadJ0cqdT+ImyeY5FgTdZWaLnyQ=
F:usr
F:usr/lib

View file

@ -1,45 +0,0 @@
C:Q1gKkFdQUwKAmcUpGY8VaErq0uHNo=
P:musl
V:1.1.18-r5
A:x86_64
S:357094
I:581632
T:the musl c library (libc) implementation
U:http://www.musl-libc.org/
L:MIT
o:musl
m:Timo Ter s <timo.teras@iki.fi>
t:1515217616
c:6cc1d4e6ac35607dd09003e4d013a0d9c4800c49
p:so:libc.musl-x86_64.so.1=1
F:lib
R:libc.musl-x86_64.so.1
a:0:0:777
Z:Q17yJ3JFNypA4mxhJJr0ou6CzsJVI=
R:ld-musl-x86_64.so.1
a:0:0:755
Z:Q1DadJ0cqdT+ImyeY5FgTdZWaLnyQ=
F:usr
F:usr/lib
C:Q1iundrWyXyQtSTZ9h2qqh44cZcYA=
P:curl
V:7.57.0-r0
A:x86_64
S:118233
I:217088
T:An URL retrieval utility and library
U:http://curl.haxx.se
L:MIT
o:curl
m:Natanael Copa <ncopa@alpinelinux.org>
t:1512030418
c:d19c5b26c70a3055c5d6c7d2f15587f62a33a1fe
D:ca-certificates so:libc.musl-x86_64.so.1 so:libcurl.so.4 so:libz.so.1
p:cmd:curl
F:usr
F:usr/bin
R:curl
a:0:0:755
Z:Q1tlqDmZcIJJXo+ScFT6Nd31EPrBM=

View file

@ -1,31 +0,0 @@
C:Q1XaZzCVZ9mvH8djPyEb5aUYhG3r4=
P:hello-world
V:2-r0
A:x86_64
S:2897
I:20480
T:hello world program to be built in the testsuite
U:https://en.wikipedia.org/wiki/%22Hello,_World!%22_program
L:MIT
o:hello-world
t:1500000000
c:
D:so:libc.musl-x86_64.so.1
p:cmd:hello-world
F:usr
F:usr/bin
R:hello-world
a:0:0:755
Z:Q1ZjTpsnMchSsSwEPB1cTjihYuJvo=
C:Q127l1Ui9vzedbeR3BMelZnSa4pwY=
P:.pmbootstrap
V:0
A:noarch
S:0
I:0
T:virtual meta package
U:
L:
D:hello-world

View file

@ -1,143 +0,0 @@
# Contributor: Natanael Copa <ncopa@alpinelinux.org>
# Maintainer: Ariadne Conill <ariadne@dereferenced.org>
pkgname=binutils
pkgver=2.39
pkgrel=1
pkgdesc="Tools necessary to build programs"
url="https://www.gnu.org/software/binutils/"
makedepends_build="bison flex texinfo"
makedepends_host="zlib-dev"
makedepends="$makedepends_build $makedepends_host"
arch="all"
license="GPL-2.0 GPL-3.0-or-later LGPL-2.0 BSD"
subpackages="$pkgname-dev $pkgname-doc"
source="https://ftp.gnu.org/gnu/binutils/binutils-$pkgver.tar.xz
binutils-ld-fix-static-linking.patch
gold-mips.patch
ld-bfd-mips.patch
0001-Revert-PR25882-.gnu.attributes-are-not-checked-for-s.patch
binutils-mips-disable-assert.patch
"
builddir="$srcdir/$pkgname-$pkgver"
if [ "$CHOST" = "$CBUILD" ] && [ "$CBUILD" = "$CTARGET" ] && [ "$CTARGET_ARCH" != "riscv64" ]; then
subpackages="$subpackages $pkgname-gold"
fi
if [ "$CHOST" != "$CTARGET" ]; then
pkgname="$pkgname-$CTARGET_ARCH"
subpackages=""
sonameprefix="$pkgname:"
fi
# secfixes:
# 2.35.2-r1:
# - CVE-2021-3487
# 2.32-r0:
# - CVE-2018-19931
# - CVE-2018-19932
# - CVE-2018-20002
# - CVE-2018-20712
# 2.28-r1:
# - CVE-2017-7614
build() {
local _sysroot=/
local _cross_configure="--enable-install-libiberty --enable-shared"
local _arch_configure=""
local _gold_configure="--disable-gold"
local _plugin_configure="--enable-plugins"
if [ "$CHOST" != "$CTARGET" ]; then
_sysroot="$CBUILDROOT"
_cross_configure="--disable-install-libiberty"
_plugin_configure="--disable-plugins"
fi
if [ "$CHOST" = "$CBUILD" ] && [ "$CBUILD" = "$CTARGET" ] && [ "$CTARGET_ARCH" != "riscv64" ]; then
_gold_configure="--enable-gold"
fi
if [ "$CTARGET_ARCH" = "x86_64" ]; then
_arch_configure="--enable-targets=x86_64-pep"
fi
if [ "$CTARGET_ARCH" = "riscv64" ]; then
_gold_configure="--disable-gold"
fi
case "$CTARGET_ARCH" in
mips*) _hash_style_configure="--enable-default-hash-style=sysv" ;;
*) _hash_style_configure="--enable-default-hash-style=gnu" ;;
esac
./configure \
--build=$CBUILD \
--host=$CHOST \
--target=$CTARGET \
--with-build-sysroot="$CBUILDROOT" \
--with-sysroot=$_sysroot \
--prefix=/usr \
--mandir=/usr/share/man \
--infodir=/usr/share/info \
--disable-multilib \
--disable-gprofng \
--enable-ld=default \
$_gold_configure \
--enable-64-bit-bfd \
$_plugin_configure \
--enable-relro \
--enable-deterministic-archives \
--enable-default-execstack=no \
$_cross_configure \
$_arch_configure \
$_hash_style_configure \
--with-pic \
--disable-werror \
--disable-nls \
--with-mmap \
--with-system-zlib
make
}
package() {
make install DESTDIR="$pkgdir"
if [ -d "$pkgdir"/usr/lib64 ]; then
mv "$pkgdir"/usr/lib64/* "$pkgdir"/usr/lib/
rmdir "$pkgdir"/usr/lib64
fi
if [ "$CHOST" != "$CTARGET" ]; then
# creating cross tools: remove any files that would conflict
# with the native tools, or other cross tools
rm -r "${pkgdir:?}"/usr/share
rm -f "$pkgdir"/usr/lib/libiberty.a
rm -r "${pkgdir:?}"/usr/lib/bfd-plugins
fi
}
libs() {
pkgdesc="Runtime libraries from binutils - libbfd and libopcodes"
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/lib*.so "$subpkgdir"/usr/lib/
}
gold() {
pkgdesc="GNU binutils - gold linker"
if [ -e "$pkgdir"/usr/bin/ld.gold ]; then
mkdir -p "$subpkgdir"/usr/bin
mv "$pkgdir"/usr/bin/ld.gold "$subpkgdir"/usr/bin
fi
mkdir -p "$subpkgdir"/usr/$CTARGET/bin
mv "$pkgdir"/usr/$CTARGET/bin/ld.gold "$subpkgdir"/usr/$CTARGET/bin/ld.gold
}
sha512sums="
68e038f339a8c21faa19a57bbc447a51c817f47c2e06d740847c6e9cc3396c025d35d5369fa8c3f8b70414757c89f0e577939ddc0d70f283182504920f53b0a3 binutils-2.39.tar.xz
ecee33b0e435aa704af1c334e560f201638ff79e199aa11ed78a72f7c9b46f85fbb227af5748e735fd681d1965fcc42ac81b0c8824e540430ce0c706c81e8b49 binutils-ld-fix-static-linking.patch
f55cf2e0bf82f97583a1abe10710e4013ecf7d64f1da2ef8659a44a06d0dd8beaf58dab98a183488ea137f03e32d62efc878d95f018f836f8cec870bc448556f gold-mips.patch
314d2ef9071c89940aa6c8118e8a1e2f191a5d0a4bf596da1ad9cc84f884d8bc7dea8bd7b9fc3f8f1bddd3fd41c6eb017e1e804044b3bf084df1ed9e6e095e2d ld-bfd-mips.patch
70ec22bd72ef6dddecfd970613387dd4a8cdc8730dd3cbf03d5a0c3a7c4d839383167bb06dad21bf7c235329fd44b5dc4aefe762f68544f17155cf002bf1be4a 0001-Revert-PR25882-.gnu.attributes-are-not-checked-for-s.patch
609cd90d8b334eb309f586b17b9d335a08d3dbb6def7c3eb5c010028fcb681674031e5b9d853aa7a39a50304356a86afc184b85562b3f228f8197f4d29395c8f binutils-mips-disable-assert.patch
"

View file

@ -1,792 +0,0 @@
# Contributor: Natanael Copa <ncopa@alpinelinux.org>
# Contributor: Sören Tempel <soeren+alpine@soeren-tempel.net>
# Maintainer: Ariadne Conill <ariadne@dereferenced.org>
pkgname=gcc
_pkgbase=12.2.1 # must match gcc/BASE-VER
_pkgsnap=20220924
pkgver=${_pkgbase}_git${_pkgsnap}
[ "$BOOTSTRAP" = "nolibc" ] && pkgname="gcc-pass2"
[ "$CBUILD" != "$CHOST" ] && _cross="-$CARCH" || _cross=""
[ "$CHOST" != "$CTARGET" ] && _target="-$CTARGET_ARCH" || _target=""
pkgname="$pkgname$_target"
pkgrel=1
pkgdesc="The GNU Compiler Collection"
url="https://gcc.gnu.org"
arch="all"
license="GPL-2.0-or-later LGPL-2.1-or-later"
_gccrel=$pkgver-r$pkgrel
depends="binutils$_target"
makedepends_build="gcc$_cross g++$_cross bison flex texinfo gawk zip gmp-dev mpfr-dev mpc1-dev zlib-dev"
makedepends_host="linux-headers gmp-dev mpfr-dev mpc1-dev isl-dev zlib-dev !gettext-dev libucontext-dev"
subpackages=" "
[ "$CHOST" = "$CTARGET" ] && subpackages="gcc-doc$_target"
replaces="libstdc++ binutils"
: "${LANG_CXX:=true}"
: "${LANG_D:=true}"
: "${LANG_OBJC:=true}"
: "${LANG_GO:=true}"
: "${LANG_FORTRAN:=true}"
: "${LANG_ADA:=true}"
: "${LANG_JIT:=true}"
_libgomp=true
_libgcc=true
_libatomic=true
_libitm=true
if [ "$CHOST" != "$CTARGET" ]; then
if [ "$BOOTSTRAP" = nolibc ]; then
LANG_CXX=false
LANG_ADA=false
_libgcc=false
_builddir="$srcdir/build-cross-pass2"
else
_builddir="$srcdir/build-cross-final"
fi
LANG_OBJC=false
LANG_GO=false
LANG_FORTRAN=false
LANG_D=false
LANG_JIT=false
_libgomp=false
_libatomic=false
_libitm=false
# reset target flags (should be set in crosscreate abuild)
# fixup flags. seems gcc treats CPPFLAGS as global without
# _FOR_xxx variants. wrap it in CFLAGS and CXXFLAGS.
export CFLAGS="$CPPFLAGS $CFLAGS"
export CXXFLAGS="$CPPFLAGS $CXXFLAGS"
unset CPPFLAGS
export CFLAGS_FOR_TARGET=" "
export CXXFLAGS_FOR_TARGET=" "
export LDFLAGS_FOR_TARGET=" "
STRIP_FOR_TARGET="$CTARGET-strip"
elif [ "$CBUILD" != "$CHOST" ]; then
# fixup flags. seems gcc treats CPPFLAGS as global without
# _FOR_xxx variants. wrap it in CFLAGS and CXXFLAGS.
export CFLAGS="$CPPFLAGS $CFLAGS"
export CXXFLAGS="$CPPFLAGS $CXXFLAGS"
unset CPPFLAGS
# reset flags and cc for build
export CC_FOR_BUILD="gcc"
export CXX_FOR_BUILD="g++"
export CFLAGS_FOR_BUILD=" "
export CXXFLAGS_FOR_BUILD=" "
export LDFLAGS_FOR_BUILD=" "
export CFLAGS_FOR_TARGET=" "
export CXXFLAGS_FOR_TARGET=" "
export LDFLAGS_FOR_TARGET=" "
# Languages that do not need bootstrapping
LANG_OBJC=false
LANG_GO=false
LANG_FORTRAN=false
LANG_D=false
LANG_JIT=false
STRIP_FOR_TARGET=${CROSS_COMPILE}strip
_builddir="$srcdir/build-cross-native"
else
STRIP_FOR_TARGET=${CROSS_COMPILE}strip
_builddir="$srcdir/build"
fi
case "$CARCH" in
# GDC hasn't been ported to PowerPC
# See libphobos/configure.tgt in GCC sources for supported targets
# riscv fails with: error: static assert "unimplemented"
ppc64le|riscv64) LANG_D=false ;;
# GDC does currently not work on 32-bit musl architectures.
# This is a known upstream issue.
# See: https://github.com/dlang/druntime/pull/3383
armhf|armv7|x86) LANG_D=false ;;
esac
# libitm has TEXTRELs in ARM build, so disable for now
case "$CTARGET_ARCH" in
arm*) _libitm=false ;;
mips*) _libitm=false ;;
riscv64) _libitm=false ;;
esac
# Internal libffi fails to build on MIPS at the moment, need to
# investigate further. We disable LANG_GO on mips64 as it requires
# the internal libffi.
case "$CTARGET_ARCH" in
mips*) LANG_GO=false ;;
esac
# Fortran uses libquadmath if toolchain has __float128
# currently on x86, x86_64 and ia64
_libquadmath=$LANG_FORTRAN
case "$CTARGET_ARCH" in
x86 | x86_64) _libquadmath=$LANG_FORTRAN ;;
*) _libquadmath=false ;;
esac
# libatomic is a dependency for openvswitch
$_libatomic && subpackages="$subpackages libatomic::$CTARGET_ARCH"
$_libgcc && subpackages="$subpackages libgcc::$CTARGET_ARCH"
$_libquadmath && subpackages="$subpackages libquadmath::$CTARGET_ARCH"
if $_libgomp; then
depends="$depends libgomp=$_gccrel"
subpackages="$subpackages libgomp::$CTARGET_ARCH"
fi
case "$CARCH" in
riscv64)
LANG_ADA=false;;
esac
_languages=c
if $LANG_CXX; then
subpackages="$subpackages libstdc++:libcxx:$CTARGET_ARCH libstdc++-dev$_target:libcxx_dev g++$_target:gpp"
_languages="$_languages,c++"
fi
if $LANG_D; then
subpackages="$subpackages libgphobos::$CTARGET_ARCH gcc-gdc$_target:gdc"
_languages="$_languages,d"
makedepends_build="$makedepends_build libucontext-dev gcc-gdc-bootstrap"
fi
if $LANG_OBJC; then
subpackages="$subpackages libobjc::$CTARGET_ARCH gcc-objc$_target:objc"
_languages="$_languages,objc"
fi
if $LANG_GO; then
subpackages="$subpackages libgo::$CTARGET_ARCH gcc-go$_target:go"
_languages="$_languages,go"
fi
if $LANG_FORTRAN; then
subpackages="$subpackages libgfortran::$CTARGET_ARCH gfortran$_target:gfortran"
_languages="$_languages,fortran"
fi
if $LANG_ADA; then
subpackages="$subpackages gcc-gnat$_target:gnat"
_languages="$_languages,ada"
if [ "$CBUILD" = "$CTARGET" ]; then
makedepends_build="$makedepends_build gcc-gnat-bootstrap"
subpackages="$subpackages libgnat-static:libgnatstatic:$CTARGET_ARCH libgnat::$CTARGET_ARCH"
else
subpackages="$subpackages libgnat::$CTARGET_ARCH"
makedepends_build="$makedepends_build gcc-gnat gcc-gnat$_cross"
fi
fi
if $LANG_JIT; then
subpackages="$subpackages libgccjit:jit libgccjit-dev:jitdev"
fi
makedepends="$makedepends_build $makedepends_host"
# when using upstream releases, use this URI template
# https://gcc.gnu.org/pub/gcc/releases/gcc-${_pkgbase:-$pkgver}/gcc-${_pkgbase:-$pkgver}.tar.xz
#
# right now, we are using a git snapshot. snapshots are taken from gcc.gnu.org/pub/gcc/snapshots.
# However, since they are periodically deleted from the GCC mirrors the utilized snapshots are
# mirrored on dev.alpinelinux.org. Please ensure that the snapshot Git commit (as stated in the
# README) matches the base commit on the version-specific branch in the Git repository below.
#
# PLEASE submit all patches to gcc to https://gitlab.alpinelinux.org/kaniini/alpine-gcc-patches,
# so that they can be properly tracked and easily rebased if needed.
source="https://dev.alpinelinux.org/archive/gcc/${_pkgbase%%.*}-${_pkgsnap}/gcc-${_pkgbase%%.*}-${_pkgsnap}.tar.xz
0001-posix_memalign.patch
0002-gcc-poison-system-directories.patch
0003-specs-turn-on-Wl-z-now-by-default.patch
0004-Turn-on-D_FORTIFY_SOURCE-2-by-default-for-C-C-ObjC-O.patch
0005-On-linux-targets-pass-as-needed-by-default-to-the-li.patch
0006-Enable-Wformat-and-Wformat-security-by-default.patch
0007-Enable-Wtrampolines-by-default.patch
0008-Disable-ssp-on-nostdlib-nodefaultlibs-and-ffreestand.patch
0009-Ensure-that-msgfmt-doesn-t-encounter-problems-during.patch
0010-Don-t-declare-asprintf-if-defined-as-a-macro.patch
0011-libiberty-copy-PIC-objects-during-build-process.patch
0012-libitm-disable-FORTIFY.patch
0013-libgcc_s.patch
0014-nopie.patch
0015-dlang-use-libucontext-on-mips64.patch
0016-ada-fix-shared-linking.patch
0017-build-fix-CXXFLAGS_FOR_BUILD-passing.patch
0018-add-fortify-headers-paths.patch
0019-Alpine-musl-package-provides-libssp_nonshared.a.-We-.patch
0020-DP-Use-push-state-pop-state-for-gold-as-well-when-li.patch
0021-mips64-disable-multilib-support.patch
0022-aarch64-disable-multilib-support.patch
0023-s390x-disable-multilib-support.patch
0024-ppc64-le-disable-multilib-support.patch
0025-x86_64-disable-multilib-support.patch
0026-riscv-disable-multilib-support.patch
0027-always-build-libgcc_eh.a.patch
0028-ada-libgnarl-compatibility-for-musl.patch
0029-ada-musl-support-fixes.patch
0033-gcc-go-link-to-libucontext.patch
0034-Use-generic-errstr.go-implementation-on-musl.patch
0035-configure-Add-enable-autolink-libatomic-use-in-LINK_.patch
0036-configure-fix-detection-of-atomic-builtins-in-libato.patch
0037-libgo-Recognize-off64_t-and-loff_t-definitions-of-mu.patch
0039-gcc-go-Use-int64-type-as-offset-argument-for-mmap.patch
0041-go-gospec-forcibly-disable-fsplit-stack-support.patch
0042-gcc-go-fix-build-error-with-SYS_SECCOMP.patch
0043-libstdc-do-not-throw-exceptions-for-non-C-locales-on.patch
0044-gdc-unconditionally-link-libgphobos-against-libucont.patch
0045-druntime-link-against-libucontext-on-all-platforms.patch
0049-libgo-adjust-name-of-union-in-sigevent-struct.patch
0050-libphobos-don-t-define-__mode_t-twice-on-musl-target.patch
0051-libgo-Explicitly-define-SYS_timer_settime-for-32-bit.patch
0052-libgnat-time_t-is-always-64-bit-on-musl-libc.patch
0053-libgo-make-match.sh-POSIX-shell-compatible.patch
"
# we build out-of-tree
_gccdir="$srcdir"/gcc-${_pkgbase%%.*}-${_pkgsnap}
_gcclibdir="/usr/lib/gcc/$CTARGET/${_pkgbase:-$pkgver}"
_gcclibexec="/usr/libexec/gcc/$CTARGET/${_pkgbase:-$pkgver}"
prepare() {
cd "$_gccdir"
_err=
for i in $source; do
case "$i" in
*.patch)
msg "Applying $i"
patch -p1 -i "$srcdir"/$i || _err="$_err $i"
;;
esac
done
if [ -n "$_err" ]; then
error "The following patches failed:"
for i in $_err; do
echo " $i"
done
return 1
fi
echo ${_pkgbase:-$pkgver} > gcc/BASE-VER
}
build() {
local _arch_configure=
local _libc_configure=
local _cross_configure=
local _bootstrap_configure=
local _symvers=
local _jit_configure=
cd "$_gccdir"
case "$CTARGET" in
aarch64-*-*-*) _arch_configure="--with-arch=armv8-a --with-abi=lp64";;
armv5-*-*-*eabi) _arch_configure="--with-arch=armv5te --with-tune=arm926ej-s --with-float=soft --with-abi=aapcs-linux";;
armv6-*-*-*eabihf) _arch_configure="--with-arch=armv6zk --with-tune=arm1176jzf-s --with-fpu=vfp --with-float=hard --with-abi=aapcs-linux";;
armv7-*-*-*eabihf) _arch_configure="--with-arch=armv7-a --with-tune=generic-armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-abi=aapcs-linux --with-mode=thumb";;
mips-*-*-*) _arch_configure="--with-arch=mips32 --with-mips-plt --with-float=soft --with-abi=32";;
mips64-*-*-*) _arch_configure="--with-arch=mips3 --with-tune=mips64 --with-mips-plt --with-float=soft --with-abi=64";;
mips64el-*-*-*) _arch_configure="--with-arch=mips3 --with-tune=mips64 --with-mips-plt --with-float=soft --with-abi=64";;
mipsel-*-*-*) _arch_configure="--with-arch=mips32 --with-mips-plt --with-float=soft --with-abi=32";;
powerpc-*-*-*) _arch_configure="--enable-secureplt --enable-decimal-float=no";;
powerpc64*-*-*-*) _arch_configure="--with-abi=elfv2 --enable-secureplt --enable-decimal-float=no --enable-targets=powerpcle-linux";;
i486-*-*-*) _arch_configure="--with-arch=i486 --with-tune=generic --enable-cld";;
i586-*-*-*) _arch_configure="--with-arch=i586 --with-tune=generic --enable-cld";;
s390x-*-*-*) _arch_configure="--with-arch=z196 --with-tune=zEC12 --with-zarch --with-long-double-128 --enable-decimal-float";;
riscv64-*-*-*) _arch_configure="--with-arch=rv64gc --with-abi=lp64d --enable-autolink-libatomic";;
esac
case "$CTARGET_ARCH" in
mips*) _hash_style_configure="--with-linker-hash-style=sysv" ;;
*) _hash_style_configure="--with-linker-hash-style=gnu" ;;
esac
case "$CTARGET_LIBC" in
musl)
# musl does not support mudflap, or libsanitizer
# libmpx uses secure_getenv and struct _libc_fpstate not present in musl
# alpine musl provides libssp_nonshared.a, so we don't need libssp either
_libc_configure="--disable-libssp --disable-libmpx --disable-libmudflap --disable-libsanitizer"
_symvers="--disable-symvers"
export libat_cv_have_ifunc=no
;;
esac
[ "$CBUILD" != "$CHOST" ] && _cross_configure="--disable-bootstrap"
[ "$CHOST" != "$CTARGET" ] && _cross_configure="--disable-bootstrap --with-sysroot=$CBUILDROOT"
case "$BOOTSTRAP" in
nolibc) _bootstrap_configure="--with-newlib --disable-shared --enable-threads=no" ;;
*) _bootstrap_configure="--enable-shared --enable-threads --enable-tls" ;;
esac
$_libgomp || _bootstrap_configure="$_bootstrap_configure --disable-libgomp"
$_libatomic || _bootstrap_configure="$_bootstrap_configure --disable-libatomic"
$_libitm || _bootstrap_configure="$_bootstrap_configure --disable-libitm"
$_libquadmath || _arch_configure="$_arch_configure --disable-libquadmath"
msg "Building the following:"
echo ""
echo " CBUILD=$CBUILD"
echo " CHOST=$CHOST"
echo " CTARGET=$CTARGET"
echo " CTARGET_ARCH=$CTARGET_ARCH"
echo " CTARGET_LIBC=$CTARGET_LIBC"
echo " languages=$_languages"
echo " arch_configure=$_arch_configure"
echo " libc_configure=$_libc_configure"
echo " cross_configure=$_cross_configure"
echo " bootstrap_configure=$_bootstrap_configure"
echo " hash_style_configure=$_hash_style_configure"
echo ""
export CFLAGS="$CFLAGS -O2"
export CXXFLAGS="$CXXFLAGS -O2"
export CPPFLAGS="$CPPFLAGS -O2"
local version="Alpine $pkgver-r$pkgrel"
local gccconfiguration="
--prefix=/usr
--mandir=/usr/share/man
--infodir=/usr/share/info
--build=${CBUILD}
--host=${CHOST}
--target=${CTARGET}
--enable-checking=release
--disable-fixed-point
--disable-libstdcxx-pch
--disable-multilib
--disable-nls
--disable-werror
$_symvers
--enable-__cxa_atexit
--enable-default-pie
--enable-default-ssp
--enable-cloog-backend
--enable-languages=$_languages
$_arch_configure
$_libc_configure
$_cross_configure
$_bootstrap_configure
--with-bugurl=https://gitlab.alpinelinux.org/alpine/aports/-/issues
--with-system-zlib
$_hash_style_configure
"
mkdir -p "$_builddir"
cd "$_builddir"
"$_gccdir"/configure $gccconfiguration \
--with-pkgversion="$version"
msg "building gcc"
make
# we build gccjit separate to not build all of gcc with --enable-host-shared
# as doing so slows it down a few %, so for some quick if's here we gain
# free performance
if $LANG_JIT; then
mkdir -p "$_builddir"/libgccjit-build
cd "$_builddir"/libgccjit-build
"$_gccdir"/configure $gccconfiguration \
--disable-bootstrap \
--enable-host-shared \
--enable-languages=jit \
--with-pkgversion="$version"
msg "building libgccjit"
make all-gcc
fi
}
package() {
cd "$_builddir"
make DESTDIR="$pkgdir" install
ln -s gcc "$pkgdir"/usr/bin/cc
if $LANG_JIT; then
make -C "$_builddir"/libgccjit-build/gcc DESTDIR="$pkgdir" jit.install-common
fi
# we dont support gcj -static
# and saving 35MB is not bad.
find "$pkgdir" \( -name libgtkpeer.a \
-o -name libgjsmalsa.a \
-o -name libgij.a \) \
-delete
# strip debug info from some static libs
find "$pkgdir" \( -name libgfortran.a -o -name libobjc.a -o -name libgomp.a \
-o -name libgphobos.a -o -name libgdruntime.a \
-o -name libmudflap.a -o -name libmudflapth.a \
-o -name libgcc.a -o -name libgcov.a -o -name libquadmath.a \
-o -name libitm.a -o -name libgo.a -o -name libcaf\*.a \
-o -name libatomic.a -o -name libasan.a -o -name libtsan.a \) \
-a -type f \
-exec ${STRIP_FOR_TARGET} -g {} +
if $_libgomp; then
mv "$pkgdir"/usr/lib/libgomp.spec "$pkgdir"/$_gcclibdir
fi
if $_libitm; then
mv "$pkgdir"/usr/lib/libitm.spec "$pkgdir"/$_gcclibdir
fi
# remove ffi
rm -f "$pkgdir"/usr/lib/libffi* "$pkgdir"/usr/share/man/man3/ffi*
find "$pkgdir" -name 'ffi*.h' -delete
local gdblib=${_target:+$CTARGET/}lib
if [ -d "$pkgdir"/usr/$gdblib/ ]; then
for i in $(find "$pkgdir"/usr/$gdblib/ -type f -maxdepth 1 -name "*-gdb.py"); do
mkdir -p "$pkgdir"/usr/share/gdb/python/auto-load/usr/$gdblib
mv "$i" "$pkgdir"/usr/share/gdb/python/auto-load/usr/$gdblib/
done
fi
# move ada runtime libs
if $LANG_ADA; then
for i in $(find "$pkgdir"/$_gcclibdir/adalib/ -type f -maxdepth 1 -name "libgna*.so"); do
mv "$i" "$pkgdir"/usr/lib/
ln -s ../../../../${i##*/} $i
done
if [ "$CHOST" = "$CTARGET" ]; then
for i in $(find "$pkgdir"/$_gcclibdir/adalib/ -type f -maxdepth 1 -name "libgna*.a"); do
mv "$i" "$pkgdir"/usr/lib/
ln -s ../../../../${i##*/} $i
done
fi
fi
if [ "$CHOST" != "$CTARGET" ]; then
# cross-gcc: remove any files that would conflict with the
# native gcc package
rm -rf "$pkgdir"/usr/bin/cc "$pkgdir"/usr/include "${pkgdir:?}"/usr/share
# libcc1 does not depend on target, don't ship it
rm -rf "$pkgdir"/usr/lib/libcc1.so*
# fixup gcc library symlinks to be linker scripts so
# linker finds the libs from relocated sysroot
for so in "$pkgdir"/usr/"$CTARGET"/lib/*.so; do
if [ -h "$so" ]; then
local _real=$(basename "$(readlink "$so")")
rm -f "$so"
echo "GROUP ($_real)" > "$so"
fi
done
else
# add c89/c99 wrapper scripts
cat >"$pkgdir"/usr/bin/c89 <<'EOF'
#!/bin/sh
_flavor="-std=c89"
for opt; do
case "$opt" in
-ansi|-std=c89|-std=iso9899:1990) _flavor="";;
-std=*) echo "$(basename $0) called with non ANSI/ISO C option $opt" >&2
exit 1;;
esac
done
exec gcc $_flavor ${1+"$@"}
EOF
cat >"$pkgdir"/usr/bin/c99 <<'EOF'
#!/bin/sh
_flavor="-std=c99"
for opt; do
case "$opt" in
-std=c99|-std=iso9899:1999) _flavor="";;
-std=*) echo "$(basename $0) called with non ISO C99 option $opt" >&2
exit 1;;
esac
done
exec gcc $_flavor ${1+"$@"}
EOF
chmod 755 "$pkgdir"/usr/bin/c?9
# install lto plugin so regular binutils may use it
mkdir -p "$pkgdir"/usr/lib/bfd-plugins
ln -s /$_gcclibexec/liblto_plugin.so "$pkgdir/usr/lib/bfd-plugins/"
fi
}
libatomic() {
pkgdesc="GCC Atomic library"
depends=
replaces="gcc"
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/${_target:+$CTARGET/}lib/libatomic.so.* "$subpkgdir"/usr/lib/
}
libcxx() {
pkgdesc="GNU C++ standard runtime library"
depends=
if [ "$CHOST" = "$CTARGET" ]; then
# verify that we are using clock_gettime rather than doing direct syscalls
# so we dont break 32 bit arches due to time64.
nm -D "$pkgdir"/usr/lib/libstdc++.so.* | grep clock_gettime
fi
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/${_target:+$CTARGET/}lib/libstdc++.so.* "$subpkgdir"/usr/lib/
}
libcxx_dev() {
pkgdesc="GNU C++ standard runtime library (development files)"
depends=
replaces="g++"
amove usr/${_target:+$CTARGET/}lib/libstdc++.a \
usr/${_target:+$CTARGET/}lib/libstdc++.so \
usr/${_target:+$CTARGET/}lib/libstdc++fs.a \
usr/${_target:+$CTARGET/}lib/libsupc++.a \
usr/${_target:+$CTARGET/}include/c++
}
gpp() {
pkgdesc="GNU C++ standard library and compiler"
depends="libstdc++=$_gccrel libstdc++-dev$_target=$_gccrel gcc$_target=$_gccrel libc-dev"
mkdir -p "$subpkgdir/$_gcclibexec" \
"$subpkgdir"/usr/bin \
"$subpkgdir"/usr/${_target:+$CTARGET/}include \
"$subpkgdir"/usr/${_target:+$CTARGET/}lib \
mv "$pkgdir/$_gcclibexec/cc1plus" "$subpkgdir/$_gcclibexec/"
mv "$pkgdir"/usr/bin/*++ "$subpkgdir"/usr/bin/
}
jit() {
pkgdesc="GCC JIT Library"
depends=
amove usr/lib/libgccjit.so*
}
jitdev() {
pkgdesc="GCC JIT Library (development files)"
depends="libgccjit"
amove usr/include/libgccjit*.h
}
libobjc() {
pkgdesc="GNU Objective-C runtime"
replaces="objc"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/${_target:+$CTARGET/}lib/libobjc.so.* "$subpkgdir"/usr/lib/
}
objc() {
pkgdesc="GNU Objective-C"
replaces="gcc"
depends="libc-dev gcc=$_gccrel libobjc=$_gccrel"
mkdir -p "$subpkgdir/$_gcclibexec" \
"$subpkgdir"/$_gcclibdir/include \
"$subpkgdir"/usr/lib
mv "$pkgdir/$_gcclibexec/cc1obj" "$subpkgdir/$_gcclibexec/"
mv "$pkgdir"/$_gcclibdir/include/objc "$subpkgdir"/$_gcclibdir/include/
mv "$pkgdir"/usr/lib/libobjc.so "$pkgdir"/usr/lib/libobjc.a \
"$subpkgdir"/usr/lib/
}
libgcc() {
pkgdesc="GNU C compiler runtime libraries"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/${_target:+$CTARGET/}lib/libgcc_s.so.* "$subpkgdir"/usr/lib/
}
libgomp() {
pkgdesc="GCC shared-memory parallel programming API library"
depends=
replaces="gcc"
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/${_target:+$CTARGET/}lib/libgomp.so.* "$subpkgdir"/usr/lib/
}
libgphobos() {
pkgdesc="D programming language standard library for GCC"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/libgdruntime.so.* "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/lib/libgphobos.so.* "$subpkgdir"/usr/lib/
}
gdc() {
pkgdesc="GCC-based D language compiler"
depends="gcc=$_gccrel libgphobos=$_gccrel musl-dev"
depends="$depends libucontext-dev"
provides="gcc-gdc-bootstrap=$_gccrel"
mkdir -p "$subpkgdir/$_gcclibexec" \
"$subpkgdir"/$_gcclibdir/include/d/ \
"$subpkgdir"/usr/lib \
"$subpkgdir"/usr/bin
# Copy: The installed '.d' files, the static lib, the binary itself
# The shared libs are part of 'libgphobos' so one can run program
# without installing the compiler
mv "$pkgdir/$_gcclibexec/d21" "$subpkgdir/$_gcclibexec/"
mv "$pkgdir"/$_gcclibdir/include/d/* "$subpkgdir"/$_gcclibdir/include/d/
mv "$pkgdir"/usr/lib/libgdruntime.a "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/lib/libgdruntime.so "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/lib/libgphobos.a "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/lib/libgphobos.so "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/lib/libgphobos.spec "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/bin/$CTARGET-gdc "$subpkgdir"/usr/bin/
mv "$pkgdir"/usr/bin/gdc "$subpkgdir"/usr/bin/
}
libgo() {
pkgdesc="Go runtime library for GCC"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/libgo.so.* "$subpkgdir"/usr/lib/
}
go() {
pkgdesc="Go support for GCC"
depends="gcc=$_gccrel libgo=$_gccrel !go"
mkdir -p "$subpkgdir"/$_gcclibexec \
"$subpkgdir"/usr/lib \
"$subpkgdir"/usr/bin
mv "$pkgdir"/usr/lib/go "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/bin/*gccgo "$subpkgdir"/usr/bin/
mv "$pkgdir"/usr/bin/*go "$subpkgdir"/usr/bin
mv "$pkgdir"/usr/bin/*gofmt "$subpkgdir"/usr/bin
mv "$pkgdir"/$_gcclibexec/go1 "$subpkgdir"/$_gcclibexec/
mv "$pkgdir"/$_gcclibexec/cgo "$subpkgdir"/$_gcclibexec/
mv "$pkgdir"/$_gcclibexec/buildid "$subpkgdir"/$_gcclibexec/
mv "$pkgdir"/$_gcclibexec/test2json "$subpkgdir"/$_gcclibexec/
mv "$pkgdir"/$_gcclibexec/vet "$subpkgdir"/$_gcclibexec/
mv "$pkgdir"/usr/lib/libgo.a \
"$pkgdir"/usr/lib/libgo.so \
"$pkgdir"/usr/lib/libgobegin.a \
"$pkgdir"/usr/lib/libgolibbegin.a \
"$subpkgdir"/usr/lib/
}
libgfortran() {
pkgdesc="Fortran runtime library for GCC"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/libgfortran.so.* "$subpkgdir"/usr/lib/
}
libquadmath() {
replaces="gcc"
pkgdesc="128-bit math library for GCC"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/libquadmath.so.* "$subpkgdir"/usr/lib/
}
gfortran() {
pkgdesc="GNU Fortran Compiler"
depends="gcc=$_gccrel libgfortran=$_gccrel"
$_libquadmath && depends="$depends libquadmath=$_gccrel"
replaces="gcc"
mkdir -p "$subpkgdir"/$_gcclibexec \
"$subpkgdir"/$_gcclibdir \
"$subpkgdir"/usr/lib \
"$subpkgdir"/usr/bin
mv "$pkgdir"/usr/bin/*gfortran "$subpkgdir"/usr/bin/
mv "$pkgdir"/usr/lib/libgfortran.a \
"$pkgdir"/usr/lib/libgfortran.so \
"$subpkgdir"/usr/lib/
if $_libquadmath; then
mv "$pkgdir"/usr/lib/libquadmath.a \
"$pkgdir"/usr/lib/libquadmath.so \
"$subpkgdir"/usr/lib/
fi
mv "$pkgdir"/$_gcclibdir/finclude "$subpkgdir"/$_gcclibdir/
mv "$pkgdir"/$_gcclibexec/f951 "$subpkgdir"/$_gcclibexec
mv "$pkgdir"/usr/lib/libgfortran.spec "$subpkgdir"/$_gcclibdir
}
libgnat() {
pkgdesc="GNU Ada runtime shared libraries"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/libgna*.so "$subpkgdir"/usr/lib/
}
libgnatstatic() {
pkgdesc="GNU Ada static libraries"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/libgna*.a "$subpkgdir"/usr/lib/
}
gnat() {
pkgdesc="Ada support for GCC"
depends="gcc=$_gccrel"
provides="$pkgname-gnat-bootstrap=$_gccrel"
[ "$CHOST" = "$CTARGET" ] && depends="$depends libgnat=$_gccrel"
mkdir -p "$subpkgdir"/$_gcclibexec \
"$subpkgdir"/$_gcclibdir \
"$subpkgdir"/usr/bin
mv "$pkgdir"/$_gcclibexec/*gnat* "$subpkgdir"/$_gcclibexec/
mv "$pkgdir"/$_gcclibdir/*ada* "$subpkgdir"/$_gcclibdir/
mv "$pkgdir"/usr/bin/*gnat* "$subpkgdir"/usr/bin/
}
sha512sums="
ba4d9e73d108088da26fbefe18d9b245b76771ffe752c2b4b31bdf38a2d0b638fbc115c377526c27311d4d7ffd4e0d236a5af5016bd364ccaa11a4989d1401e8 gcc-12-20220924.tar.xz
41cbb4d69218006cf9e0cdb6c86212ef451f8decd52a50a7dbb4d34726009da7a4e0261c852b46cb584db253a4bae2f31dc485c506cb545e64a7d26e0ba6c2b6 0001-posix_memalign.patch
531155055cda7f119bcac6479bcae73af9201cd596af9cf1616850bbcf4393b91c5de9f2fbbc1cde6e158fb4df7237b033146f662dff5fa0ea12151cc514adb8 0002-gcc-poison-system-directories.patch
c1275d77b5269386a2ec683933570810f5a2ba1208c161ed887797eb9aee3cb82ef08a8964635902614e6a6e83f3065ba0801c9355d85dd8d60cb1fa20bdf687 0003-specs-turn-on-Wl-z-now-by-default.patch
a54e45bff4484a35d3826435a414d909281453f5605f4081cf3be1f15336cceed93a1d8a54e92e2fa97188623e3030ca1323d7749141e228a7db73795230d86a 0004-Turn-on-D_FORTIFY_SOURCE-2-by-default-for-C-C-ObjC-O.patch
ad132ddbd0c33a3983e3de4f74d8fdb8cb1ddf53ef54de0a5c12efb49e42014ed117165d43f396bcf3455ecfe2c8620e0326e73b4160a370a4cc92d213329c34 0005-On-linux-targets-pass-as-needed-by-default-to-the-li.patch
0b9ce0f130a7b797770f3d58a5200575f20e5663c86c0c5710718b7bffd3416cc2f05861613d9c258428e9541c6e0b9837d01f0c99d383e2c3de0503a988e861 0006-Enable-Wformat-and-Wformat-security-by-default.patch
e7813acc7ead61373c212cefbe53eb020b4c5bd8f0f35ee972e0524060713f911624f5a1a871feada642e1f3f5e48c8508125ca2da09de351d544bedf1d44ada 0007-Enable-Wtrampolines-by-default.patch
d0d0566a11e4828bdd6f53346a9a6b9841f3066d3f4a05ee2b6fe97aeb4552654170e7662318ea18fc777c3e75c88a067097478fc4e880a3f9c134b8a3af2277 0008-Disable-ssp-on-nostdlib-nodefaultlibs-and-ffreestand.patch
f75e63d9d933874f18fb7f55b135c60dfa0377abafa8e0edb91b85d5f00f4f072d0a338ba5d9baec18494211dbbda8068782830dbafbb37068936f76aede270f 0009-Ensure-that-msgfmt-doesn-t-encounter-problems-during.patch
afa4daba222a19569588736a8276dc7c12223a7c222f3dd3795dc3f1cd90f40b90518971ae27b358020354f89562c9680ec8b8e24e85e6d4f8e54e79d185359b 0010-Don-t-declare-asprintf-if-defined-as-a-macro.patch
79dac82249fb573ec477e1451a33883302eb63a5110853faed117f5021221f2153e2ec845dd5a0043b1bf9f0e5736ef0c89743ff2d771774a281c8b24542803a 0011-libiberty-copy-PIC-objects-during-build-process.patch
b035f85c1703b45d15c1d1ffe7d23400e01625e5d403504911cc92f740b02586447de2a9d66a9f80f12b9c227bc193e2a43942c8af2bdb42cdeff8272bbe6068 0012-libitm-disable-FORTIFY.patch
9fb4d396a9493d2d68fe829ce075ba4c5df148b1d6aaab315a6f8ccbdd70d0e052a5dc50369adc2dab005b4a3becd1504b182faed6e82c86accb95f5bc2b9f50 0013-libgcc_s.patch
f82ac22961d842c9f8e731a601bb255918cc160969888363ad2d83e2ccf08b19114a200d46bcf99d097bf530f470c2b1e71e46828bc1b9fff5469ff945f541d8 0014-nopie.patch
6527dc9d250db48d56cf01e9299461bf22a838ffda96c40d448e18f457b206cec2322275d2d5abbbaf3c6573c5e7eba12724c9691b601f118ff7520e19726373 0015-dlang-use-libucontext-on-mips64.patch
6c3ce0ccd68b19e2c76172d8f24b0747ee0af2b8de7af692f2f699848267d7fc42fec8e5c303102fe05be7e934b56f21eea17ce47c8aca20570590830d88e9b0 0016-ada-fix-shared-linking.patch
7089a96aaec8e0b222cb3fa7301d71bb2e328a24dec33e15ea9e3e7695bcae919308249b9a3be5ea2f3b1f069f9fd1739066f31d12317fcdab0596dba9ca54a4 0017-build-fix-CXXFLAGS_FOR_BUILD-passing.patch
b7ebdeee0b143052fdd6e3efa070ea8621d4fb729312cbc787d618e666b593990a20cd9044a786265970d8e09ec13da03b797009543d0b657b0fe924f2dcaa68 0018-add-fortify-headers-paths.patch
8e682893d6367732ab8c490b915112a68d98855deec3bd8db91dc0d9bf486b8c044b13ee2b95c4806da7ac17c41034e081b7a66861018274cb33fdb2fd6df04a 0019-Alpine-musl-package-provides-libssp_nonshared.a.-We-.patch
a14c5f98ade5af8cd6e3a0244752674d9c4f6dadb4260f98f1949bff51ac1211a3f8319e0f933f776e98998d2c7221004f92413f97ccc2e966f8462ed6d33597 0020-DP-Use-push-state-pop-state-for-gold-as-well-when-li.patch
28c1d477da79aa212ac79e4b02cf865d8b9c31cec6c42f41b4268e3f3c49bf67fb51e54180abe543a54e550788bb472bfcf1b4bc38d072a792d7403dbbee178a 0021-mips64-disable-multilib-support.patch
0920e31c46bf937b47a0602766f042d45adb71abf332ee84399c665c12298ef115cff945fe26d646b0276bfdfdd04913970e6f1f8784a11c26e15111c854643d 0022-aarch64-disable-multilib-support.patch
e4c6bf7ec40f2798c8e5b40a543aecffd5591a2805546b3b97aaa4fbe4df6ce4330a60973a9ddfbca9890590606d5204e7f653ab2b6e4b2c13feeb595b68e63a 0023-s390x-disable-multilib-support.patch
0e956d793c94283ce5af7fe84bfcbb655585a9573608e9bf497fa7b726e12daa391e44977d0a8c97fb460aba89b1773b91e036b0ee1ef4d6263a3943cb63d9cd 0024-ppc64-le-disable-multilib-support.patch
95917fcb60dbc0a8134db9beb583f3c9ea61128499c214f594c434ec8246641ec41e245ce2d1d9b85ffd40ea0e5764f7a33c5522b2547145814245ac0fa25025 0025-x86_64-disable-multilib-support.patch
b40d7e4712c035674c993bbb55475290ec14523b3f0fd05493514bac4e9adaa6641faf815fc40ffc00119d9fd64be28218ee874c289ec7430eeef05ab2fcae5e 0026-riscv-disable-multilib-support.patch
674360ce2ee9f704d0632cc98756f9fe8dd8ca30064fb9d3423b437f7e679c1c51e765b15e535dcb278cd2769583690acb3395b91e4fd5f6f4e3b97879fcc313 0027-always-build-libgcc_eh.a.patch
f060687adcd5297124e4000f1ba1e3fd5d7d124da04d948cbd0d4a6c69a90a2b29a4a0dbbe13a83ab6950724f434de012b681bdbcdf53c0100b40fe3d00f2f2f 0028-ada-libgnarl-compatibility-for-musl.patch
5160bae68e20a1966c1f6d655ee98af759e9b9ee842718ae6007d467b418e1cf3b307528a0841477b5259671ce868521b06c0f2e947b7b8f3a398c53dd978252 0029-ada-musl-support-fixes.patch
3c04b26554a78096296ca9542c77a91219bd26044dd2cb2006db4c1944889a97c215900b3828ba7e8c675162406db543605a815bdfbd915bf810663b1b253bdd 0033-gcc-go-link-to-libucontext.patch
699dc3641099da6136dd3689f06c6553c03b3a85acf83a3fce1beb5425065b3e378535ca9e9100a120fdbafc34871d61c063fd5328a49cd87a15a989ed51706d 0034-Use-generic-errstr.go-implementation-on-musl.patch
d9ba710f770e053c8f212e821817c188091a829658050b9ab5906388553ec60fec37943ea43c270e92a9014902949f3c98fc4639032d92b8145b375bb29e193e 0035-configure-Add-enable-autolink-libatomic-use-in-LINK_.patch
ab90d8fdd977d6cd3da096a1c76d77be3e89a020b2127247771711a32eb608cceed21834ef488ab4b69bb0f408b098fdfb61630819e3d1a1e57d5af67800ee74 0036-configure-fix-detection-of-atomic-builtins-in-libato.patch
8bc6823f0b3c66f7b73d7ddb64ffa6930463285c2e9a14a2bc1882bcc4271144eaa1107d713294699caf9481648163cbf43921a2b8e4ac0d55c78a804bae8a3d 0037-libgo-Recognize-off64_t-and-loff_t-definitions-of-mu.patch
e9699f4721778869eb3a8fef2c679208ef5b98584892f30b0e1cb5dc1669f8158198d7792659b1b56c381baf62247d21990dcced9178547affd5d6bfb2d12548 0039-gcc-go-Use-int64-type-as-offset-argument-for-mmap.patch
d6dc1bfb881a313d167aaa5658790b0f55eea4336c408cfc6613dd5783440dafd0d37c43031a5f3e69be40f632e38371cd4fb6e5f0494ac4ea4d7d5025d2ae02 0041-go-gospec-forcibly-disable-fsplit-stack-support.patch
684c6a6d52512b973429b6e709966439ac1e174f9e79a33d4a638b452245b457b34752b4b4034ba983f6a712f86522e7adf715bab00a6603f64a12139c5b1e39 0042-gcc-go-fix-build-error-with-SYS_SECCOMP.patch
25014dfa99d96ee70ce0ad22e9f7974f0a51cc50b3b9c2db49df50774c8cd29e497ceed120486bee50be83bfb07f2009ed310eb9b0543f2795bd7359b87eadd2 0043-libstdc-do-not-throw-exceptions-for-non-C-locales-on.patch
75fd83ac05ab0a08d5f48547b08810f9934209bc78b5db59d65f33887b382af7ec24d8a29d40f86325c05af40c1ae1ec6466c839f646af90afc895a13073d07b 0044-gdc-unconditionally-link-libgphobos-against-libucont.patch
13e047153076d6e1fc40c9f5b6bfe5699c0e5460248f3d2b35ae36677cb960525af7b0b025997e5000a8492cec5e77a86828d66b4058c0d7f89fde0ab3890142 0045-druntime-link-against-libucontext-on-all-platforms.patch
c33ca2553642c2dbd1c65cd97046548f08775785a3db06d761e3bbe61398c37bc382fe132c0c3fa2101dfd4eea2a6d48bf4fae899a0ddb811c81abd7be35c122 0049-libgo-adjust-name-of-union-in-sigevent-struct.patch
179cd15d629884a66e954fd76066675efa594686b970facbb12ad50769e5d70b5530d7f61e77120e26d1c3dfc701cfc5295f341f635db998df73c41bc8e62172 0050-libphobos-don-t-define-__mode_t-twice-on-musl-target.patch
c82d7c8d340a76df3d796565a79b0ccc04ddffef39927620e1f3719bf2dc1db101ba13aef24b46c5bc95b7bf1e31c8bda4ab0936ba4c9c5e5047ba08826c982c 0051-libgo-Explicitly-define-SYS_timer_settime-for-32-bit.patch
eb403d8ea665fd5dc2c11faf43b055e6a3bf480a397ceee3e0ca1e38ec7d2392315f2694ed9a34ffbc99e464f2873fbbf91be8646ea4dea5d3636e3ea22fefa0 0052-libgnat-time_t-is-always-64-bit-on-musl-libc.patch
22fb6edf1ed0387e2b93839ffe6e82a7fee420950af90e91199c3488d966702fdeb1a3396d22be0c73a4051525da9349c93d070a0d83b724c83f2b268da6483f 0053-libgo-make-match.sh-POSIX-shell-compatible.patch
"

View file

@ -1,810 +0,0 @@
# Automatically generated aport, do not edit!
# Generator: pmbootstrap aportgen gcc-armhf
# Based on: main/gcc (from Alpine)
CTARGET_ARCH=armhf
CTARGET="$(arch_to_hostspec ${CTARGET_ARCH})"
LANG_D=false
LANG_OBJC=false
LANG_JAVA=false
LANG_GO=false
LANG_FORTRAN=false
LANG_ADA=false
options="!strip"
# abuild doesn't try to tries to install "build-base-$CTARGET_ARCH"
# when this variable matches "no*"
BOOTSTRAP="nobuildbase"
# abuild will only cross compile when this variable is set, but it
# needs to find a valid package database in there for dependency
# resolving, so we set it to /.
CBUILDROOT="/"
_cross_configure="--disable-bootstrap --with-sysroot=/usr/$CTARGET"
pkgname=gcc-armhf
_pkgbase=12.2.1 # must match gcc/BASE-VER
_pkgsnap=20220924
pkgver=${_pkgbase}_git${_pkgsnap}
[ "$BOOTSTRAP" = "nolibc" ] && pkgname="gcc-pass2"
[ "$CBUILD" != "$CHOST" ] && _cross="-$CARCH" || _cross=""
[ "$CHOST" != "$CTARGET" ] && _target="-$CTARGET_ARCH" || _target=""
pkgname=gcc-armhf
pkgrel=1
pkgdesc="Stage2 cross-compiler for armhf"
url="https://gcc.gnu.org"
arch="x86_64"
license="GPL-2.0-or-later LGPL-2.1-or-later"
_gccrel=$pkgver-r$pkgrel
depends="binutils-armhf mpc1"
makedepends_build="gcc g++ bison flex texinfo gawk zip gmp-dev mpfr-dev mpc1-dev zlib-dev"
makedepends_host="linux-headers gmp-dev mpfr-dev mpc1-dev isl-dev zlib-dev musl-dev-armhf binutils-armhf"
subpackages="g++-armhf:gpp libstdc++-dev-armhf:libcxx_dev"
[ "$CHOST" = "$CTARGET" ] && subpackages="gcc-doc$_target"
replaces="libstdc++ binutils"
: "${LANG_CXX:=true}"
: "${LANG_D:=true}"
: "${LANG_OBJC:=true}"
: "${LANG_GO:=true}"
: "${LANG_FORTRAN:=true}"
: "${LANG_ADA:=true}"
: "${LANG_JIT:=true}"
_libgomp=true
_libgcc=false
_libatomic=true
_libitm=true
if [ "$CHOST" != "$CTARGET" ]; then
if [ "$BOOTSTRAP" = nolibc ]; then
LANG_CXX=false
LANG_ADA=false
_libgcc=false
_builddir="$srcdir/build-cross-pass2"
else
_builddir="$srcdir/build-cross-final"
fi
LANG_OBJC=false
LANG_GO=false
LANG_FORTRAN=false
LANG_D=false
LANG_JIT=false
_libgomp=false
_libatomic=false
_libitm=false
# reset target flags (should be set in crosscreate abuild)
# fixup flags. seems gcc treats CPPFLAGS as global without
# _FOR_xxx variants. wrap it in CFLAGS and CXXFLAGS.
export CFLAGS="$CPPFLAGS $CFLAGS"
export CXXFLAGS="$CPPFLAGS $CXXFLAGS"
unset CPPFLAGS
export CFLAGS_FOR_TARGET=" "
export CXXFLAGS_FOR_TARGET=" "
export LDFLAGS_FOR_TARGET=" "
STRIP_FOR_TARGET="$CTARGET-strip"
elif [ "$CBUILD" != "$CHOST" ]; then
# fixup flags. seems gcc treats CPPFLAGS as global without
# _FOR_xxx variants. wrap it in CFLAGS and CXXFLAGS.
export CFLAGS="$CPPFLAGS $CFLAGS"
export CXXFLAGS="$CPPFLAGS $CXXFLAGS"
unset CPPFLAGS
# reset flags and cc for build
export CC_FOR_BUILD="gcc"
export CXX_FOR_BUILD="g++"
export CFLAGS_FOR_BUILD=" "
export CXXFLAGS_FOR_BUILD=" "
export LDFLAGS_FOR_BUILD=" "
export CFLAGS_FOR_TARGET=" "
export CXXFLAGS_FOR_TARGET=" "
export LDFLAGS_FOR_TARGET=" "
# Languages that do not need bootstrapping
LANG_OBJC=false
LANG_GO=false
LANG_FORTRAN=false
LANG_D=false
LANG_JIT=false
STRIP_FOR_TARGET=${CROSS_COMPILE}strip
_builddir="$srcdir/build-cross-native"
else
STRIP_FOR_TARGET=${CROSS_COMPILE}strip
_builddir="$srcdir/build"
fi
case "$CARCH" in
# GDC hasn't been ported to PowerPC
# See libphobos/configure.tgt in GCC sources for supported targets
# riscv fails with: error: static assert "unimplemented"
ppc64le|riscv64) LANG_D=false ;;
# GDC does currently not work on 32-bit musl architectures.
# This is a known upstream issue.
# See: https://github.com/dlang/druntime/pull/3383
armhf|armv7|x86) LANG_D=false ;;
esac
# libitm has TEXTRELs in ARM build, so disable for now
case "$CTARGET_ARCH" in
arm*) _libitm=false ;;
mips*) _libitm=false ;;
riscv64) _libitm=false ;;
esac
# Internal libffi fails to build on MIPS at the moment, need to
# investigate further. We disable LANG_GO on mips64 as it requires
# the internal libffi.
case "$CTARGET_ARCH" in
mips*) LANG_GO=false ;;
esac
# Fortran uses libquadmath if toolchain has __float128
# currently on x86, x86_64 and ia64
_libquadmath=$LANG_FORTRAN
case "$CTARGET_ARCH" in
x86 | x86_64) _libquadmath=$LANG_FORTRAN ;;
*) _libquadmath=false ;;
esac
# libatomic is a dependency for openvswitch
$_libatomic && subpackages="$subpackages libatomic::$CTARGET_ARCH"
$_libgcc && subpackages="$subpackages libgcc::$CTARGET_ARCH"
$_libquadmath && subpackages="$subpackages libquadmath::$CTARGET_ARCH"
if $_libgomp; then
depends="$depends libgomp=$_gccrel"
subpackages="$subpackages libgomp::$CTARGET_ARCH"
fi
case "$CARCH" in
riscv64)
LANG_ADA=false;;
esac
_languages=c
if $LANG_CXX; then
_languages="$_languages,c++"
fi
if $LANG_D; then
subpackages="$subpackages libgphobos::$CTARGET_ARCH gcc-gdc$_target:gdc"
_languages="$_languages,d"
makedepends_build="$makedepends_build libucontext-dev gcc-gdc-bootstrap"
fi
if $LANG_OBJC; then
subpackages="$subpackages libobjc::$CTARGET_ARCH gcc-objc$_target:objc"
_languages="$_languages,objc"
fi
if $LANG_GO; then
subpackages="$subpackages libgo::$CTARGET_ARCH gcc-go$_target:go"
_languages="$_languages,go"
fi
if $LANG_FORTRAN; then
subpackages="$subpackages libgfortran::$CTARGET_ARCH gfortran$_target:gfortran"
_languages="$_languages,fortran"
fi
if $LANG_ADA; then
subpackages="$subpackages gcc-gnat$_target:gnat"
_languages="$_languages,ada"
if [ "$CBUILD" = "$CTARGET" ]; then
makedepends_build="$makedepends_build gcc-gnat-bootstrap"
subpackages="$subpackages libgnat-static:libgnatstatic:$CTARGET_ARCH libgnat::$CTARGET_ARCH"
else
subpackages="$subpackages libgnat::$CTARGET_ARCH"
makedepends_build="$makedepends_build gcc-gnat gcc-gnat$_cross"
fi
fi
if $LANG_JIT; then
subpackages="$subpackages libgccjit:jit libgccjit-dev:jitdev"
fi
makedepends="$makedepends_build $makedepends_host"
# when using upstream releases, use this URI template
# https://gcc.gnu.org/pub/gcc/releases/gcc-${_pkgbase:-$pkgver}/gcc-${_pkgbase:-$pkgver}.tar.xz
#
# right now, we are using a git snapshot. snapshots are taken from gcc.gnu.org/pub/gcc/snapshots.
# However, since they are periodically deleted from the GCC mirrors the utilized snapshots are
# mirrored on dev.alpinelinux.org. Please ensure that the snapshot Git commit (as stated in the
# README) matches the base commit on the version-specific branch in the Git repository below.
#
# PLEASE submit all patches to gcc to https://gitlab.alpinelinux.org/kaniini/alpine-gcc-patches,
# so that they can be properly tracked and easily rebased if needed.
source="https://dev.alpinelinux.org/archive/gcc/${_pkgbase%%.*}-${_pkgsnap}/gcc-${_pkgbase%%.*}-${_pkgsnap}.tar.xz
0001-posix_memalign.patch
0002-gcc-poison-system-directories.patch
0003-specs-turn-on-Wl-z-now-by-default.patch
0004-Turn-on-D_FORTIFY_SOURCE-2-by-default-for-C-C-ObjC-O.patch
0005-On-linux-targets-pass-as-needed-by-default-to-the-li.patch
0006-Enable-Wformat-and-Wformat-security-by-default.patch
0007-Enable-Wtrampolines-by-default.patch
0008-Disable-ssp-on-nostdlib-nodefaultlibs-and-ffreestand.patch
0009-Ensure-that-msgfmt-doesn-t-encounter-problems-during.patch
0010-Don-t-declare-asprintf-if-defined-as-a-macro.patch
0011-libiberty-copy-PIC-objects-during-build-process.patch
0012-libitm-disable-FORTIFY.patch
0013-libgcc_s.patch
0014-nopie.patch
0015-dlang-use-libucontext-on-mips64.patch
0016-ada-fix-shared-linking.patch
0017-build-fix-CXXFLAGS_FOR_BUILD-passing.patch
0018-add-fortify-headers-paths.patch
0019-Alpine-musl-package-provides-libssp_nonshared.a.-We-.patch
0020-DP-Use-push-state-pop-state-for-gold-as-well-when-li.patch
0021-mips64-disable-multilib-support.patch
0022-aarch64-disable-multilib-support.patch
0023-s390x-disable-multilib-support.patch
0024-ppc64-le-disable-multilib-support.patch
0025-x86_64-disable-multilib-support.patch
0026-riscv-disable-multilib-support.patch
0027-always-build-libgcc_eh.a.patch
0028-ada-libgnarl-compatibility-for-musl.patch
0029-ada-musl-support-fixes.patch
0033-gcc-go-link-to-libucontext.patch
0034-Use-generic-errstr.go-implementation-on-musl.patch
0035-configure-Add-enable-autolink-libatomic-use-in-LINK_.patch
0036-configure-fix-detection-of-atomic-builtins-in-libato.patch
0037-libgo-Recognize-off64_t-and-loff_t-definitions-of-mu.patch
0039-gcc-go-Use-int64-type-as-offset-argument-for-mmap.patch
0041-go-gospec-forcibly-disable-fsplit-stack-support.patch
0042-gcc-go-fix-build-error-with-SYS_SECCOMP.patch
0043-libstdc-do-not-throw-exceptions-for-non-C-locales-on.patch
0044-gdc-unconditionally-link-libgphobos-against-libucont.patch
0045-druntime-link-against-libucontext-on-all-platforms.patch
0049-libgo-adjust-name-of-union-in-sigevent-struct.patch
0050-libphobos-don-t-define-__mode_t-twice-on-musl-target.patch
0051-libgo-Explicitly-define-SYS_timer_settime-for-32-bit.patch
0052-libgnat-time_t-is-always-64-bit-on-musl-libc.patch
0053-libgo-make-match.sh-POSIX-shell-compatible.patch
"
# we build out-of-tree
_gccdir="$srcdir"/gcc-${_pkgbase%%.*}-${_pkgsnap}
_gcclibdir="/usr/lib/gcc/$CTARGET/${_pkgbase:-$pkgver}"
_gcclibexec="/usr/libexec/gcc/$CTARGET/${_pkgbase:-$pkgver}"
prepare() {
cd "$_gccdir"
_err=
for i in $source; do
case "$i" in
*.patch)
msg "Applying $i"
patch -p1 -i "$srcdir"/$i || _err="$_err $i"
;;
esac
done
if [ -n "$_err" ]; then
error "The following patches failed:"
for i in $_err; do
echo " $i"
done
return 1
fi
echo ${_pkgbase:-$pkgver} > gcc/BASE-VER
}
build() {
local _arch_configure=
local _libc_configure=
local _bootstrap_configure=
local _symvers=
local _jit_configure=
cd "$_gccdir"
case "$CTARGET" in
aarch64-*-*-*) _arch_configure="--with-arch=armv8-a --with-abi=lp64";;
armv5-*-*-*eabi) _arch_configure="--with-arch=armv5te --with-tune=arm926ej-s --with-float=soft --with-abi=aapcs-linux";;
armv6-*-*-*eabihf) _arch_configure="--with-arch=armv6zk --with-tune=arm1176jzf-s --with-fpu=vfp --with-float=hard --with-abi=aapcs-linux";;
armv7-*-*-*eabihf) _arch_configure="--with-arch=armv7-a --with-tune=generic-armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-abi=aapcs-linux --with-mode=thumb";;
mips-*-*-*) _arch_configure="--with-arch=mips32 --with-mips-plt --with-float=soft --with-abi=32";;
mips64-*-*-*) _arch_configure="--with-arch=mips3 --with-tune=mips64 --with-mips-plt --with-float=soft --with-abi=64";;
mips64el-*-*-*) _arch_configure="--with-arch=mips3 --with-tune=mips64 --with-mips-plt --with-float=soft --with-abi=64";;
mipsel-*-*-*) _arch_configure="--with-arch=mips32 --with-mips-plt --with-float=soft --with-abi=32";;
powerpc-*-*-*) _arch_configure="--enable-secureplt --enable-decimal-float=no";;
powerpc64*-*-*-*) _arch_configure="--with-abi=elfv2 --enable-secureplt --enable-decimal-float=no --enable-targets=powerpcle-linux";;
i486-*-*-*) _arch_configure="--with-arch=i486 --with-tune=generic --enable-cld";;
i586-*-*-*) _arch_configure="--with-arch=i586 --with-tune=generic --enable-cld";;
s390x-*-*-*) _arch_configure="--with-arch=z196 --with-tune=zEC12 --with-zarch --with-long-double-128 --enable-decimal-float";;
riscv64-*-*-*) _arch_configure="--with-arch=rv64gc --with-abi=lp64d --enable-autolink-libatomic";;
esac
case "$CTARGET_ARCH" in
mips*) _hash_style_configure="--with-linker-hash-style=sysv" ;;
*) _hash_style_configure="--with-linker-hash-style=gnu" ;;
esac
case "$CTARGET_LIBC" in
musl)
# musl does not support mudflap, or libsanitizer
# libmpx uses secure_getenv and struct _libc_fpstate not present in musl
# alpine musl provides libssp_nonshared.a, so we don't need libssp either
_libc_configure="--disable-libssp --disable-libmpx --disable-libmudflap --disable-libsanitizer"
_symvers="--disable-symvers"
export libat_cv_have_ifunc=no
;;
esac
case "$BOOTSTRAP" in
nolibc) _bootstrap_configure="--with-newlib --disable-shared --enable-threads=no" ;;
*) _bootstrap_configure="--enable-shared --enable-threads --enable-tls" ;;
esac
$_libgomp || _bootstrap_configure="$_bootstrap_configure --disable-libgomp"
$_libatomic || _bootstrap_configure="$_bootstrap_configure --disable-libatomic"
$_libitm || _bootstrap_configure="$_bootstrap_configure --disable-libitm"
$_libquadmath || _arch_configure="$_arch_configure --disable-libquadmath"
msg "Building the following:"
echo ""
echo " CBUILD=$CBUILD"
echo " CHOST=$CHOST"
echo " CTARGET=$CTARGET"
echo " CTARGET_ARCH=$CTARGET_ARCH"
echo " CTARGET_LIBC=$CTARGET_LIBC"
echo " languages=$_languages"
echo " arch_configure=$_arch_configure"
echo " libc_configure=$_libc_configure"
echo " cross_configure=$_cross_configure"
echo " bootstrap_configure=$_bootstrap_configure"
echo " hash_style_configure=$_hash_style_configure"
echo ""
export CFLAGS="$CFLAGS -O2"
export CXXFLAGS="$CXXFLAGS -O2"
export CPPFLAGS="$CPPFLAGS -O2"
local version="Alpine $pkgver-r$pkgrel"
local gccconfiguration="
--prefix=/usr
--mandir=/usr/share/man
--infodir=/usr/share/info
--build=${CBUILD}
--host=${CHOST}
--target=${CTARGET}
--enable-checking=release
--disable-fixed-point
--disable-libstdcxx-pch
--disable-multilib
--disable-nls
--disable-werror
$_symvers
--enable-__cxa_atexit
--enable-default-pie
--enable-default-ssp
--enable-cloog-backend
--enable-languages=$_languages
$_arch_configure
$_libc_configure
$_cross_configure
$_bootstrap_configure
--with-bugurl=https://gitlab.alpinelinux.org/alpine/aports/-/issues
--with-system-zlib
$_hash_style_configure
"
mkdir -p "$_builddir"
cd "$_builddir"
"$_gccdir"/configure $gccconfiguration \
--with-pkgversion="$version"
msg "building gcc"
make
# we build gccjit separate to not build all of gcc with --enable-host-shared
# as doing so slows it down a few %, so for some quick if's here we gain
# free performance
if $LANG_JIT; then
mkdir -p "$_builddir"/libgccjit-build
cd "$_builddir"/libgccjit-build
"$_gccdir"/configure $gccconfiguration \
--disable-bootstrap \
--enable-host-shared \
--enable-languages=jit \
--with-pkgversion="$version"
msg "building libgccjit"
make all-gcc
fi
}
package() {
cd "$_builddir"
make DESTDIR="$pkgdir" install
ln -s gcc "$pkgdir"/usr/bin/cc
if $LANG_JIT; then
make -C "$_builddir"/libgccjit-build/gcc DESTDIR="$pkgdir" jit.install-common
fi
# we dont support gcj -static
# and saving 35MB is not bad.
find "$pkgdir" \( -name libgtkpeer.a \
-o -name libgjsmalsa.a \
-o -name libgij.a \) \
-delete
# strip debug info from some static libs
find "$pkgdir" \( -name libgfortran.a -o -name libobjc.a -o -name libgomp.a \
-o -name libgphobos.a -o -name libgdruntime.a \
-o -name libmudflap.a -o -name libmudflapth.a \
-o -name libgcc.a -o -name libgcov.a -o -name libquadmath.a \
-o -name libitm.a -o -name libgo.a -o -name libcaf\*.a \
-o -name libatomic.a -o -name libasan.a -o -name libtsan.a \) \
-a -type f \
-exec ${STRIP_FOR_TARGET} -g {} +
if $_libgomp; then
mv "$pkgdir"/usr/lib/libgomp.spec "$pkgdir"/$_gcclibdir
fi
if $_libitm; then
mv "$pkgdir"/usr/lib/libitm.spec "$pkgdir"/$_gcclibdir
fi
# remove ffi
rm -f "$pkgdir"/usr/lib/libffi* "$pkgdir"/usr/share/man/man3/ffi*
find "$pkgdir" -name 'ffi*.h' -delete
local gdblib=${_target:+$CTARGET/}lib
if [ -d "$pkgdir"/usr/$gdblib/ ]; then
for i in $(find "$pkgdir"/usr/$gdblib/ -type f -maxdepth 1 -name "*-gdb.py"); do
mkdir -p "$pkgdir"/usr/share/gdb/python/auto-load/usr/$gdblib
mv "$i" "$pkgdir"/usr/share/gdb/python/auto-load/usr/$gdblib/
done
fi
# move ada runtime libs
if $LANG_ADA; then
for i in $(find "$pkgdir"/$_gcclibdir/adalib/ -type f -maxdepth 1 -name "libgna*.so"); do
mv "$i" "$pkgdir"/usr/lib/
ln -s ../../../../${i##*/} $i
done
if [ "$CHOST" = "$CTARGET" ]; then
for i in $(find "$pkgdir"/$_gcclibdir/adalib/ -type f -maxdepth 1 -name "libgna*.a"); do
mv "$i" "$pkgdir"/usr/lib/
ln -s ../../../../${i##*/} $i
done
fi
fi
if [ "$CHOST" != "$CTARGET" ]; then
# cross-gcc: remove any files that would conflict with the
# native gcc package
rm -rf "$pkgdir"/usr/bin/cc "$pkgdir"/usr/include "${pkgdir:?}"/usr/share
# libcc1 does not depend on target, don't ship it
rm -rf "$pkgdir"/usr/lib/libcc1.so*
# fixup gcc library symlinks to be linker scripts so
# linker finds the libs from relocated sysroot
for so in "$pkgdir"/usr/"$CTARGET"/lib/*.so; do
if [ -h "$so" ]; then
local _real=$(basename "$(readlink "$so")")
rm -f "$so"
echo "GROUP ($_real)" > "$so"
fi
done
else
# add c89/c99 wrapper scripts
cat >"$pkgdir"/usr/bin/c89 <<'EOF'
#!/bin/sh
_flavor="-std=c89"
for opt; do
case "$opt" in
-ansi|-std=c89|-std=iso9899:1990) _flavor="";;
-std=*) echo "$(basename $0) called with non ANSI/ISO C option $opt" >&2
exit 1;;
esac
done
exec gcc $_flavor ${1+"$@"}
EOF
cat >"$pkgdir"/usr/bin/c99 <<'EOF'
#!/bin/sh
_flavor="-std=c99"
for opt; do
case "$opt" in
-std=c99|-std=iso9899:1999) _flavor="";;
-std=*) echo "$(basename $0) called with non ISO C99 option $opt" >&2
exit 1;;
esac
done
exec gcc $_flavor ${1+"$@"}
EOF
chmod 755 "$pkgdir"/usr/bin/c?9
# install lto plugin so regular binutils may use it
mkdir -p "$pkgdir"/usr/lib/bfd-plugins
ln -s /$_gcclibexec/liblto_plugin.so "$pkgdir/usr/lib/bfd-plugins/"
fi
}
libatomic() {
pkgdesc="GCC Atomic library"
depends=
replaces="gcc"
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/${_target:+$CTARGET/}lib/libatomic.so.* "$subpkgdir"/usr/lib/
}
libcxx() {
pkgdesc="GNU C++ standard runtime library"
depends=
if [ "$CHOST" = "$CTARGET" ]; then
# verify that we are using clock_gettime rather than doing direct syscalls
# so we dont break 32 bit arches due to time64.
nm -D "$pkgdir"/usr/lib/libstdc++.so.* | grep clock_gettime
fi
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/${_target:+$CTARGET/}lib/libstdc++.so.* "$subpkgdir"/usr/lib/
}
libcxx_dev() {
pkgdesc="GNU C++ standard runtime library (development files)"
depends=
replaces="g++"
amove usr/${_target:+$CTARGET/}lib/libstdc++.a \
usr/${_target:+$CTARGET/}lib/libstdc++.so \
usr/${_target:+$CTARGET/}lib/libstdc++fs.a \
usr/${_target:+$CTARGET/}lib/libsupc++.a \
usr/${_target:+$CTARGET/}include/c++
}
gpp() {
pkgdesc="GNU C++ standard library and compiler"
depends="libstdc++=$_gccrel libstdc++-dev$_target=$_gccrel gcc$_target=$_gccrel libc-dev"
mkdir -p "$subpkgdir/$_gcclibexec" \
"$subpkgdir"/usr/bin \
"$subpkgdir"/usr/${_target:+$CTARGET/}include \
"$subpkgdir"/usr/${_target:+$CTARGET/}lib \
mv "$pkgdir/$_gcclibexec/cc1plus" "$subpkgdir/$_gcclibexec/"
mv "$pkgdir"/usr/bin/*++ "$subpkgdir"/usr/bin/
}
jit() {
pkgdesc="GCC JIT Library"
depends=
amove usr/lib/libgccjit.so*
}
jitdev() {
pkgdesc="GCC JIT Library (development files)"
depends="libgccjit"
amove usr/include/libgccjit*.h
}
libobjc() {
pkgdesc="GNU Objective-C runtime"
replaces="objc"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/${_target:+$CTARGET/}lib/libobjc.so.* "$subpkgdir"/usr/lib/
}
objc() {
pkgdesc="GNU Objective-C"
replaces="gcc"
depends="libc-dev gcc=$_gccrel libobjc=$_gccrel"
mkdir -p "$subpkgdir/$_gcclibexec" \
"$subpkgdir"/$_gcclibdir/include \
"$subpkgdir"/usr/lib
mv "$pkgdir/$_gcclibexec/cc1obj" "$subpkgdir/$_gcclibexec/"
mv "$pkgdir"/$_gcclibdir/include/objc "$subpkgdir"/$_gcclibdir/include/
mv "$pkgdir"/usr/lib/libobjc.so "$pkgdir"/usr/lib/libobjc.a \
"$subpkgdir"/usr/lib/
}
libgcc() {
pkgdesc="GNU C compiler runtime libraries"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/${_target:+$CTARGET/}lib/libgcc_s.so.* "$subpkgdir"/usr/lib/
}
libgomp() {
pkgdesc="GCC shared-memory parallel programming API library"
depends=
replaces="gcc"
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/${_target:+$CTARGET/}lib/libgomp.so.* "$subpkgdir"/usr/lib/
}
libgphobos() {
pkgdesc="D programming language standard library for GCC"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/libgdruntime.so.* "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/lib/libgphobos.so.* "$subpkgdir"/usr/lib/
}
gdc() {
pkgdesc="GCC-based D language compiler"
depends="gcc=$_gccrel libgphobos=$_gccrel musl-dev"
depends="$depends libucontext-dev"
provides="gcc-gdc-bootstrap=$_gccrel"
mkdir -p "$subpkgdir/$_gcclibexec" \
"$subpkgdir"/$_gcclibdir/include/d/ \
"$subpkgdir"/usr/lib \
"$subpkgdir"/usr/bin
# Copy: The installed '.d' files, the static lib, the binary itself
# The shared libs are part of 'libgphobos' so one can run program
# without installing the compiler
mv "$pkgdir/$_gcclibexec/d21" "$subpkgdir/$_gcclibexec/"
mv "$pkgdir"/$_gcclibdir/include/d/* "$subpkgdir"/$_gcclibdir/include/d/
mv "$pkgdir"/usr/lib/libgdruntime.a "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/lib/libgdruntime.so "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/lib/libgphobos.a "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/lib/libgphobos.so "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/lib/libgphobos.spec "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/bin/$CTARGET-gdc "$subpkgdir"/usr/bin/
mv "$pkgdir"/usr/bin/gdc "$subpkgdir"/usr/bin/
}
libgo() {
pkgdesc="Go runtime library for GCC"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/libgo.so.* "$subpkgdir"/usr/lib/
}
go() {
pkgdesc="Go support for GCC"
depends="gcc=$_gccrel libgo=$_gccrel !go"
mkdir -p "$subpkgdir"/$_gcclibexec \
"$subpkgdir"/usr/lib \
"$subpkgdir"/usr/bin
mv "$pkgdir"/usr/lib/go "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/bin/*gccgo "$subpkgdir"/usr/bin/
mv "$pkgdir"/usr/bin/*go "$subpkgdir"/usr/bin
mv "$pkgdir"/usr/bin/*gofmt "$subpkgdir"/usr/bin
mv "$pkgdir"/$_gcclibexec/go1 "$subpkgdir"/$_gcclibexec/
mv "$pkgdir"/$_gcclibexec/cgo "$subpkgdir"/$_gcclibexec/
mv "$pkgdir"/$_gcclibexec/buildid "$subpkgdir"/$_gcclibexec/
mv "$pkgdir"/$_gcclibexec/test2json "$subpkgdir"/$_gcclibexec/
mv "$pkgdir"/$_gcclibexec/vet "$subpkgdir"/$_gcclibexec/
mv "$pkgdir"/usr/lib/libgo.a \
"$pkgdir"/usr/lib/libgo.so \
"$pkgdir"/usr/lib/libgobegin.a \
"$pkgdir"/usr/lib/libgolibbegin.a \
"$subpkgdir"/usr/lib/
}
libgfortran() {
pkgdesc="Fortran runtime library for GCC"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/libgfortran.so.* "$subpkgdir"/usr/lib/
}
libquadmath() {
replaces="gcc"
pkgdesc="128-bit math library for GCC"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/libquadmath.so.* "$subpkgdir"/usr/lib/
}
gfortran() {
pkgdesc="GNU Fortran Compiler"
depends="gcc=$_gccrel libgfortran=$_gccrel"
$_libquadmath && depends="$depends libquadmath=$_gccrel"
replaces="gcc"
mkdir -p "$subpkgdir"/$_gcclibexec \
"$subpkgdir"/$_gcclibdir \
"$subpkgdir"/usr/lib \
"$subpkgdir"/usr/bin
mv "$pkgdir"/usr/bin/*gfortran "$subpkgdir"/usr/bin/
mv "$pkgdir"/usr/lib/libgfortran.a \
"$pkgdir"/usr/lib/libgfortran.so \
"$subpkgdir"/usr/lib/
if $_libquadmath; then
mv "$pkgdir"/usr/lib/libquadmath.a \
"$pkgdir"/usr/lib/libquadmath.so \
"$subpkgdir"/usr/lib/
fi
mv "$pkgdir"/$_gcclibdir/finclude "$subpkgdir"/$_gcclibdir/
mv "$pkgdir"/$_gcclibexec/f951 "$subpkgdir"/$_gcclibexec
mv "$pkgdir"/usr/lib/libgfortran.spec "$subpkgdir"/$_gcclibdir
}
libgnat() {
pkgdesc="GNU Ada runtime shared libraries"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/libgna*.so "$subpkgdir"/usr/lib/
}
libgnatstatic() {
pkgdesc="GNU Ada static libraries"
depends=
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/libgna*.a "$subpkgdir"/usr/lib/
}
gnat() {
pkgdesc="Ada support for GCC"
depends="gcc=$_gccrel"
provides="$pkgname-gnat-bootstrap=$_gccrel"
[ "$CHOST" = "$CTARGET" ] && depends="$depends libgnat=$_gccrel"
mkdir -p "$subpkgdir"/$_gcclibexec \
"$subpkgdir"/$_gcclibdir \
"$subpkgdir"/usr/bin
mv "$pkgdir"/$_gcclibexec/*gnat* "$subpkgdir"/$_gcclibexec/
mv "$pkgdir"/$_gcclibdir/*ada* "$subpkgdir"/$_gcclibdir/
mv "$pkgdir"/usr/bin/*gnat* "$subpkgdir"/usr/bin/
}
sha512sums="
ba4d9e73d108088da26fbefe18d9b245b76771ffe752c2b4b31bdf38a2d0b638fbc115c377526c27311d4d7ffd4e0d236a5af5016bd364ccaa11a4989d1401e8 gcc-12-20220924.tar.xz
41cbb4d69218006cf9e0cdb6c86212ef451f8decd52a50a7dbb4d34726009da7a4e0261c852b46cb584db253a4bae2f31dc485c506cb545e64a7d26e0ba6c2b6 0001-posix_memalign.patch
531155055cda7f119bcac6479bcae73af9201cd596af9cf1616850bbcf4393b91c5de9f2fbbc1cde6e158fb4df7237b033146f662dff5fa0ea12151cc514adb8 0002-gcc-poison-system-directories.patch
c1275d77b5269386a2ec683933570810f5a2ba1208c161ed887797eb9aee3cb82ef08a8964635902614e6a6e83f3065ba0801c9355d85dd8d60cb1fa20bdf687 0003-specs-turn-on-Wl-z-now-by-default.patch
a54e45bff4484a35d3826435a414d909281453f5605f4081cf3be1f15336cceed93a1d8a54e92e2fa97188623e3030ca1323d7749141e228a7db73795230d86a 0004-Turn-on-D_FORTIFY_SOURCE-2-by-default-for-C-C-ObjC-O.patch
ad132ddbd0c33a3983e3de4f74d8fdb8cb1ddf53ef54de0a5c12efb49e42014ed117165d43f396bcf3455ecfe2c8620e0326e73b4160a370a4cc92d213329c34 0005-On-linux-targets-pass-as-needed-by-default-to-the-li.patch
0b9ce0f130a7b797770f3d58a5200575f20e5663c86c0c5710718b7bffd3416cc2f05861613d9c258428e9541c6e0b9837d01f0c99d383e2c3de0503a988e861 0006-Enable-Wformat-and-Wformat-security-by-default.patch
e7813acc7ead61373c212cefbe53eb020b4c5bd8f0f35ee972e0524060713f911624f5a1a871feada642e1f3f5e48c8508125ca2da09de351d544bedf1d44ada 0007-Enable-Wtrampolines-by-default.patch
d0d0566a11e4828bdd6f53346a9a6b9841f3066d3f4a05ee2b6fe97aeb4552654170e7662318ea18fc777c3e75c88a067097478fc4e880a3f9c134b8a3af2277 0008-Disable-ssp-on-nostdlib-nodefaultlibs-and-ffreestand.patch
f75e63d9d933874f18fb7f55b135c60dfa0377abafa8e0edb91b85d5f00f4f072d0a338ba5d9baec18494211dbbda8068782830dbafbb37068936f76aede270f 0009-Ensure-that-msgfmt-doesn-t-encounter-problems-during.patch
afa4daba222a19569588736a8276dc7c12223a7c222f3dd3795dc3f1cd90f40b90518971ae27b358020354f89562c9680ec8b8e24e85e6d4f8e54e79d185359b 0010-Don-t-declare-asprintf-if-defined-as-a-macro.patch
79dac82249fb573ec477e1451a33883302eb63a5110853faed117f5021221f2153e2ec845dd5a0043b1bf9f0e5736ef0c89743ff2d771774a281c8b24542803a 0011-libiberty-copy-PIC-objects-during-build-process.patch
b035f85c1703b45d15c1d1ffe7d23400e01625e5d403504911cc92f740b02586447de2a9d66a9f80f12b9c227bc193e2a43942c8af2bdb42cdeff8272bbe6068 0012-libitm-disable-FORTIFY.patch
9fb4d396a9493d2d68fe829ce075ba4c5df148b1d6aaab315a6f8ccbdd70d0e052a5dc50369adc2dab005b4a3becd1504b182faed6e82c86accb95f5bc2b9f50 0013-libgcc_s.patch
f82ac22961d842c9f8e731a601bb255918cc160969888363ad2d83e2ccf08b19114a200d46bcf99d097bf530f470c2b1e71e46828bc1b9fff5469ff945f541d8 0014-nopie.patch
6527dc9d250db48d56cf01e9299461bf22a838ffda96c40d448e18f457b206cec2322275d2d5abbbaf3c6573c5e7eba12724c9691b601f118ff7520e19726373 0015-dlang-use-libucontext-on-mips64.patch
6c3ce0ccd68b19e2c76172d8f24b0747ee0af2b8de7af692f2f699848267d7fc42fec8e5c303102fe05be7e934b56f21eea17ce47c8aca20570590830d88e9b0 0016-ada-fix-shared-linking.patch
7089a96aaec8e0b222cb3fa7301d71bb2e328a24dec33e15ea9e3e7695bcae919308249b9a3be5ea2f3b1f069f9fd1739066f31d12317fcdab0596dba9ca54a4 0017-build-fix-CXXFLAGS_FOR_BUILD-passing.patch
b7ebdeee0b143052fdd6e3efa070ea8621d4fb729312cbc787d618e666b593990a20cd9044a786265970d8e09ec13da03b797009543d0b657b0fe924f2dcaa68 0018-add-fortify-headers-paths.patch
8e682893d6367732ab8c490b915112a68d98855deec3bd8db91dc0d9bf486b8c044b13ee2b95c4806da7ac17c41034e081b7a66861018274cb33fdb2fd6df04a 0019-Alpine-musl-package-provides-libssp_nonshared.a.-We-.patch
a14c5f98ade5af8cd6e3a0244752674d9c4f6dadb4260f98f1949bff51ac1211a3f8319e0f933f776e98998d2c7221004f92413f97ccc2e966f8462ed6d33597 0020-DP-Use-push-state-pop-state-for-gold-as-well-when-li.patch
28c1d477da79aa212ac79e4b02cf865d8b9c31cec6c42f41b4268e3f3c49bf67fb51e54180abe543a54e550788bb472bfcf1b4bc38d072a792d7403dbbee178a 0021-mips64-disable-multilib-support.patch
0920e31c46bf937b47a0602766f042d45adb71abf332ee84399c665c12298ef115cff945fe26d646b0276bfdfdd04913970e6f1f8784a11c26e15111c854643d 0022-aarch64-disable-multilib-support.patch
e4c6bf7ec40f2798c8e5b40a543aecffd5591a2805546b3b97aaa4fbe4df6ce4330a60973a9ddfbca9890590606d5204e7f653ab2b6e4b2c13feeb595b68e63a 0023-s390x-disable-multilib-support.patch
0e956d793c94283ce5af7fe84bfcbb655585a9573608e9bf497fa7b726e12daa391e44977d0a8c97fb460aba89b1773b91e036b0ee1ef4d6263a3943cb63d9cd 0024-ppc64-le-disable-multilib-support.patch
95917fcb60dbc0a8134db9beb583f3c9ea61128499c214f594c434ec8246641ec41e245ce2d1d9b85ffd40ea0e5764f7a33c5522b2547145814245ac0fa25025 0025-x86_64-disable-multilib-support.patch
b40d7e4712c035674c993bbb55475290ec14523b3f0fd05493514bac4e9adaa6641faf815fc40ffc00119d9fd64be28218ee874c289ec7430eeef05ab2fcae5e 0026-riscv-disable-multilib-support.patch
674360ce2ee9f704d0632cc98756f9fe8dd8ca30064fb9d3423b437f7e679c1c51e765b15e535dcb278cd2769583690acb3395b91e4fd5f6f4e3b97879fcc313 0027-always-build-libgcc_eh.a.patch
f060687adcd5297124e4000f1ba1e3fd5d7d124da04d948cbd0d4a6c69a90a2b29a4a0dbbe13a83ab6950724f434de012b681bdbcdf53c0100b40fe3d00f2f2f 0028-ada-libgnarl-compatibility-for-musl.patch
5160bae68e20a1966c1f6d655ee98af759e9b9ee842718ae6007d467b418e1cf3b307528a0841477b5259671ce868521b06c0f2e947b7b8f3a398c53dd978252 0029-ada-musl-support-fixes.patch
3c04b26554a78096296ca9542c77a91219bd26044dd2cb2006db4c1944889a97c215900b3828ba7e8c675162406db543605a815bdfbd915bf810663b1b253bdd 0033-gcc-go-link-to-libucontext.patch
699dc3641099da6136dd3689f06c6553c03b3a85acf83a3fce1beb5425065b3e378535ca9e9100a120fdbafc34871d61c063fd5328a49cd87a15a989ed51706d 0034-Use-generic-errstr.go-implementation-on-musl.patch
d9ba710f770e053c8f212e821817c188091a829658050b9ab5906388553ec60fec37943ea43c270e92a9014902949f3c98fc4639032d92b8145b375bb29e193e 0035-configure-Add-enable-autolink-libatomic-use-in-LINK_.patch
ab90d8fdd977d6cd3da096a1c76d77be3e89a020b2127247771711a32eb608cceed21834ef488ab4b69bb0f408b098fdfb61630819e3d1a1e57d5af67800ee74 0036-configure-fix-detection-of-atomic-builtins-in-libato.patch
8bc6823f0b3c66f7b73d7ddb64ffa6930463285c2e9a14a2bc1882bcc4271144eaa1107d713294699caf9481648163cbf43921a2b8e4ac0d55c78a804bae8a3d 0037-libgo-Recognize-off64_t-and-loff_t-definitions-of-mu.patch
e9699f4721778869eb3a8fef2c679208ef5b98584892f30b0e1cb5dc1669f8158198d7792659b1b56c381baf62247d21990dcced9178547affd5d6bfb2d12548 0039-gcc-go-Use-int64-type-as-offset-argument-for-mmap.patch
d6dc1bfb881a313d167aaa5658790b0f55eea4336c408cfc6613dd5783440dafd0d37c43031a5f3e69be40f632e38371cd4fb6e5f0494ac4ea4d7d5025d2ae02 0041-go-gospec-forcibly-disable-fsplit-stack-support.patch
684c6a6d52512b973429b6e709966439ac1e174f9e79a33d4a638b452245b457b34752b4b4034ba983f6a712f86522e7adf715bab00a6603f64a12139c5b1e39 0042-gcc-go-fix-build-error-with-SYS_SECCOMP.patch
25014dfa99d96ee70ce0ad22e9f7974f0a51cc50b3b9c2db49df50774c8cd29e497ceed120486bee50be83bfb07f2009ed310eb9b0543f2795bd7359b87eadd2 0043-libstdc-do-not-throw-exceptions-for-non-C-locales-on.patch
75fd83ac05ab0a08d5f48547b08810f9934209bc78b5db59d65f33887b382af7ec24d8a29d40f86325c05af40c1ae1ec6466c839f646af90afc895a13073d07b 0044-gdc-unconditionally-link-libgphobos-against-libucont.patch
13e047153076d6e1fc40c9f5b6bfe5699c0e5460248f3d2b35ae36677cb960525af7b0b025997e5000a8492cec5e77a86828d66b4058c0d7f89fde0ab3890142 0045-druntime-link-against-libucontext-on-all-platforms.patch
c33ca2553642c2dbd1c65cd97046548f08775785a3db06d761e3bbe61398c37bc382fe132c0c3fa2101dfd4eea2a6d48bf4fae899a0ddb811c81abd7be35c122 0049-libgo-adjust-name-of-union-in-sigevent-struct.patch
179cd15d629884a66e954fd76066675efa594686b970facbb12ad50769e5d70b5530d7f61e77120e26d1c3dfc701cfc5295f341f635db998df73c41bc8e62172 0050-libphobos-don-t-define-__mode_t-twice-on-musl-target.patch
c82d7c8d340a76df3d796565a79b0ccc04ddffef39927620e1f3719bf2dc1db101ba13aef24b46c5bc95b7bf1e31c8bda4ab0936ba4c9c5e5047ba08826c982c 0051-libgo-Explicitly-define-SYS_timer_settime-for-32-bit.patch
eb403d8ea665fd5dc2c11faf43b055e6a3bf480a397ceee3e0ca1e38ec7d2392315f2694ed9a34ffbc99e464f2873fbbf91be8646ea4dea5d3636e3ea22fefa0 0052-libgnat-time_t-is-always-64-bit-on-musl-libc.patch
22fb6edf1ed0387e2b93839ffe6e82a7fee420950af90e91199c3488d966702fdeb1a3396d22be0c73a4051525da9349c93d070a0d83b724c83f2b268da6483f 0053-libgo-make-match.sh-POSIX-shell-compatible.patch
"

View file

@ -1,143 +0,0 @@
# Forked from Alpine INSERT-REASON-HERE (CHANGEME!)
pkgname=binutils
pkgver=2.39
pkgrel=1
pkgdesc="Tools necessary to build programs"
url="https://www.gnu.org/software/binutils/"
makedepends_build="bison flex texinfo"
makedepends_host="zlib-dev"
makedepends="$makedepends_build $makedepends_host"
arch="all"
license="GPL-2.0 GPL-3.0-or-later LGPL-2.0 BSD"
subpackages="$pkgname-dev $pkgname-doc"
source="https://ftp.gnu.org/gnu/binutils/binutils-$pkgver.tar.xz
binutils-ld-fix-static-linking.patch
gold-mips.patch
ld-bfd-mips.patch
0001-Revert-PR25882-.gnu.attributes-are-not-checked-for-s.patch
binutils-mips-disable-assert.patch
"
builddir="$srcdir/$pkgname-$pkgver"
if [ "$CHOST" = "$CBUILD" ] && [ "$CBUILD" = "$CTARGET" ] && [ "$CTARGET_ARCH" != "riscv64" ]; then
subpackages="$subpackages $pkgname-gold"
fi
if [ "$CHOST" != "$CTARGET" ]; then
pkgname="$pkgname-$CTARGET_ARCH"
subpackages=""
sonameprefix="$pkgname:"
fi
# secfixes:
# 2.35.2-r1:
# - CVE-2021-3487
# 2.32-r0:
# - CVE-2018-19931
# - CVE-2018-19932
# - CVE-2018-20002
# - CVE-2018-20712
# 2.28-r1:
# - CVE-2017-7614
build() {
local _sysroot=/
local _cross_configure="--enable-install-libiberty --enable-shared"
local _arch_configure=""
local _gold_configure="--disable-gold"
local _plugin_configure="--enable-plugins"
if [ "$CHOST" != "$CTARGET" ]; then
_sysroot="$CBUILDROOT"
_cross_configure="--disable-install-libiberty"
_plugin_configure="--disable-plugins"
fi
if [ "$CHOST" = "$CBUILD" ] && [ "$CBUILD" = "$CTARGET" ] && [ "$CTARGET_ARCH" != "riscv64" ]; then
_gold_configure="--enable-gold"
fi
if [ "$CTARGET_ARCH" = "x86_64" ]; then
_arch_configure="--enable-targets=x86_64-pep"
fi
if [ "$CTARGET_ARCH" = "riscv64" ]; then
_gold_configure="--disable-gold"
fi
case "$CTARGET_ARCH" in
mips*) _hash_style_configure="--enable-default-hash-style=sysv" ;;
*) _hash_style_configure="--enable-default-hash-style=gnu" ;;
esac
./configure \
--build=$CBUILD \
--host=$CHOST \
--target=$CTARGET \
--with-build-sysroot="$CBUILDROOT" \
--with-sysroot=$_sysroot \
--prefix=/usr \
--mandir=/usr/share/man \
--infodir=/usr/share/info \
--disable-multilib \
--disable-gprofng \
--enable-ld=default \
$_gold_configure \
--enable-64-bit-bfd \
$_plugin_configure \
--enable-relro \
--enable-deterministic-archives \
--enable-default-execstack=no \
$_cross_configure \
$_arch_configure \
$_hash_style_configure \
--with-pic \
--disable-werror \
--disable-nls \
--with-mmap \
--with-system-zlib
make
}
package() {
make install DESTDIR="$pkgdir"
if [ -d "$pkgdir"/usr/lib64 ]; then
mv "$pkgdir"/usr/lib64/* "$pkgdir"/usr/lib/
rmdir "$pkgdir"/usr/lib64
fi
if [ "$CHOST" != "$CTARGET" ]; then
# creating cross tools: remove any files that would conflict
# with the native tools, or other cross tools
rm -r "${pkgdir:?}"/usr/share
rm -f "$pkgdir"/usr/lib/libiberty.a
rm -r "${pkgdir:?}"/usr/lib/bfd-plugins
fi
}
libs() {
pkgdesc="Runtime libraries from binutils - libbfd and libopcodes"
mkdir -p "$subpkgdir"/usr/lib
mv "$pkgdir"/usr/lib/lib*.so "$subpkgdir"/usr/lib/
}
gold() {
pkgdesc="GNU binutils - gold linker"
if [ -e "$pkgdir"/usr/bin/ld.gold ]; then
mkdir -p "$subpkgdir"/usr/bin
mv "$pkgdir"/usr/bin/ld.gold "$subpkgdir"/usr/bin
fi
mkdir -p "$subpkgdir"/usr/$CTARGET/bin
mv "$pkgdir"/usr/$CTARGET/bin/ld.gold "$subpkgdir"/usr/$CTARGET/bin/ld.gold
}
sha512sums="
68e038f339a8c21faa19a57bbc447a51c817f47c2e06d740847c6e9cc3396c025d35d5369fa8c3f8b70414757c89f0e577939ddc0d70f283182504920f53b0a3 binutils-2.39.tar.xz
ecee33b0e435aa704af1c334e560f201638ff79e199aa11ed78a72f7c9b46f85fbb227af5748e735fd681d1965fcc42ac81b0c8824e540430ce0c706c81e8b49 binutils-ld-fix-static-linking.patch
f55cf2e0bf82f97583a1abe10710e4013ecf7d64f1da2ef8659a44a06d0dd8beaf58dab98a183488ea137f03e32d62efc878d95f018f836f8cec870bc448556f gold-mips.patch
314d2ef9071c89940aa6c8118e8a1e2f191a5d0a4bf596da1ad9cc84f884d8bc7dea8bd7b9fc3f8f1bddd3fd41c6eb017e1e804044b3bf084df1ed9e6e095e2d ld-bfd-mips.patch
70ec22bd72ef6dddecfd970613387dd4a8cdc8730dd3cbf03d5a0c3a7c4d839383167bb06dad21bf7c235329fd44b5dc4aefe762f68544f17155cf002bf1be4a 0001-Revert-PR25882-.gnu.attributes-are-not-checked-for-s.patch
609cd90d8b334eb309f586b17b9d335a08d3dbb6def7c3eb5c010028fcb681674031e5b9d853aa7a39a50304356a86afc184b85562b3f228f8197f4d29395c8f binutils-mips-disable-assert.patch
"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,31 +0,0 @@
pkgname=hello-world
pkgver=1
pkgrel=0
pkgdesc="hello world program for testing 'pmbootstrap build --src'"
url="https://en.wikipedia.org/wiki/%22Hello,_World!%22_program"
arch="all"
license="MIT"
depends=""
makedepends=""
subpackages=""
source="non-existing-file.c" # this will be overridden by --src
options=""
build() {
cd "$builddir"
make
}
check() {
cd "$builddir"
printf 'hello, world!\n' > expected
./hello-world > real
diff -q expected real
}
package() {
install -D -m755 "$builddir"/hello-world \
"$pkgdir"/usr/bin/hello-world
}
# These will be overridden as well
sha512sums="d5ad91600d9be3e53be4cb6e5846b0757786c947b2c0d10f612f67262fc91c148e8d73621623e259ca9dcd5e2c8ec7069cebec44165e203ea8c0133669d3382d invalid-file.c"

View file

@ -1,22 +0,0 @@
# Reference: https://postmarketos.org/channels.cfg
[channels.cfg]
recommended=edge
[edge]
description=Rolling release channel
branch_pmaports=master
branch_aports=master
mirrordir_alpine=edge
# Legacy channel name, gets translated to v20.05
[stable]
description=For workgroups
branch_pmaports=v20.05
branch_aports=3.11-stable
mirrordir_alpine=v3.11
[v21.03]
description=Second beta release
branch_pmaports=v21.03
branch_aports=3.13-stable
mirrordir_alpine=v3.13

View file

@ -1,29 +0,0 @@
pkgname=device-multiple-kernels
pkgver=5
pkgrel=1
pkgdesc="Device with multiple kernels"
url="https://postmarketos.org"
arch="noarch"
license="MIT"
depends=""
makedepends=""
install=""
source=""
options=""
subpackages="
$pkgname-kernel-downstream:kernel_downstream
$pkgname-kernel-mainline:kernel_mainline
$pkgname-kernel-mainline-modem:kernel_mainline_modem
"
kernel_downstream() {
pkgdesc="Downstream kernel"
}
kernel_mainline() {
pkgdesc="Close to mainline kernel"
}
kernel_mainline_modem() {
pkgdesc="Close to mainline kernel (with some modem stuff)"
}

View file

@ -1,7 +0,0 @@
deviceinfo_codename="multiple-kernels"
deviceinfo_chassis="handset"
deviceinfo_arch="aarch64"
deviceinfo_append_dtb="yes"
deviceinfo_dtb_mainline="mainline-dtb"
deviceinfo_dtb_mainline_modem="mainline-modem-dtb"
deviceinfo_dtb_downstream="downstream-dtb"

View file

@ -1,11 +0,0 @@
pkgname=postmarketos-ui-plasma-mobile
pkgver=42
pkgrel=0
pkgdesc="cool pkgdesc"
url="https://postmarketos.org"
arch="noarch !armhf"
license="GPL-3.0-or-later"
package() {
mkdir "$pkgdir"
}

View file

@ -1 +0,0 @@
../../pmaports.cfg

View file

@ -1,16 +0,0 @@
# This is not a real aport, it's for the "pmbootstrap init" questions test
pkgname=device-lg-mako
pkgver=2
pkgrel=16
pkgdesc="Google Nexus 4"
url="https://postmarketos.org"
arch="noarch"
license="MIT"
depends="linux-lg-mako mkbootimg mesa-dri-swrast"
makedepends=""
install=""
subpackages="$pkgname-weston"
source=""
options="!check"

View file

@ -1,25 +0,0 @@
# Reference: <https://postmarketos.org/deviceinfo>
# Please use double quotes only. You can source this file in shell scripts.
deviceinfo_format_version="0"
deviceinfo_name="Google Nexus 4"
deviceinfo_manufacturer="LG"
deviceinfo_codename="lg-mako"
deviceinfo_year="2012"
deviceinfo_dtb=""
deviceinfo_external_storage="false"
deviceinfo_flash_method="fastboot"
deviceinfo_arch="armhf"
# Device related
deviceinfo_chassis="handset"
deviceinfo_keyboard="false"
deviceinfo_dev_touchscreen="/dev/input/event2"
# Fastboot related
deviceinfo_generate_bootimg="true"
deviceinfo_flash_offset_kernel="0x80208000"
deviceinfo_flash_offset_ramdisk="0x81800000"
deviceinfo_flash_offset_second="0x81100000"
deviceinfo_flash_offset_tags="0x80200100"
deviceinfo_flash_pagesize="2048"

View file

@ -1,33 +0,0 @@
# Reference: <https://postmarketos.org/devicepkg>
pkgname="device-nonfree-firmware-and-userland"
pkgdesc="Test device for nonfree questions"
pkgver=0.1
pkgrel=0
url="https://postmarketos.org"
license="MIT"
arch="noarch"
options="!check"
depends="mesa-dri-swrast"
makedepends="devicepkg-dev"
source="deviceinfo"
subpackages="$pkgname-nonfree-firmware:nonfree_firmware $pkgname-nonfree-userland:nonfree_userland"
build() {
devicepkg_build $startdir $pkgname
}
package() {
devicepkg_package $startdir $pkgname
}
nonfree_firmware() {
pkgdesc="firmware description"
mkdir "$subpkgdir"
}
nonfree_userland() {
pkgdesc="userland description"
mkdir "$subpkgdir"
}
sha512sums="71c640728d3ade4bea402523c1cdb30e0edac585948cfae987bac9f001a0eb572e5be9ea2babef4eb8f9f6437a3677ce3e7be398e00865a6d3f781a8d4b3bf5d deviceinfo"

View file

@ -1,28 +0,0 @@
# Reference: <https://postmarketos.org/devicepkg>
pkgname="device-nonfree-firmware"
pkgdesc="Test device for nonfree questions"
pkgver=0.1
pkgrel=0
url="https://postmarketos.org"
license="MIT"
arch="noarch"
options="!check"
depends="mesa-dri-swrast"
makedepends="devicepkg-dev"
source="deviceinfo"
subpackages="$pkgname-nonfree-firmware:nonfree_firmware"
build() {
devicepkg_build $startdir $pkgname
}
package() {
devicepkg_package $startdir $pkgname
}
nonfree_firmware() {
pkgdesc="firmware description"
mkdir "$subpkgdir"
}
sha512sums="71c640728d3ade4bea402523c1cdb30e0edac585948cfae987bac9f001a0eb572e5be9ea2babef4eb8f9f6437a3677ce3e7be398e00865a6d3f781a8d4b3bf5d deviceinfo"

View file

@ -1,20 +0,0 @@
# Reference: <https://postmarketos.org/devicepkg>
pkgname="device-nonfree-userland"
pkgdesc="Test device for nonfree questions"
pkgver=0.1
pkgrel=0
url="https://postmarketos.org"
license="MIT"
arch="noarch"
options="!check"
depends="mesa-dri-swrast"
makedepends="devicepkg-dev"
source="deviceinfo"
subpackages="$pkgname-nonfree-userland:nonfree_userland"
nonfree_userland() {
pkgdesc="userland description"
mkdir "$subpkgdir"
}
sha512sums="71c640728d3ade4bea402523c1cdb30e0edac585948cfae987bac9f001a0eb572e5be9ea2babef4eb8f9f6437a3677ce3e7be398e00865a6d3f781a8d4b3bf5d deviceinfo"

View file

@ -1,45 +0,0 @@
pkgname=device-sony-amami
pkgver=2
pkgrel=0
pkgdesc="Sony Xperia Z1 Compact"
url="https://postmarketos.org"
arch="noarch"
license="MIT"
depends="postmarketos-base mkbootimg mdss-fb-init-hack mesa-dri-swrast"
makedepends=""
install=""
subpackages="
$pkgname-kernel-downstream:kernel_downstream
$pkgname-kernel-mainline:kernel_mainline
$pkgname-nonfree-firmware:nonfree_firmware
"
source="deviceinfo 90-android-touch-dev.rules"
options="!check"
package() {
install -D -m644 "$srcdir/deviceinfo" \
"$pkgdir/usr/share/deviceinfo"
install -D -m644 "$srcdir"/90-android-touch-dev.rules \
"$pkgdir"/etc/udev/rules.d/90-android-touch-dev.rules
}
kernel_downstream() {
pkgdesc="Downstream description"
depends="linux-sony-amami"
mkdir "$subpkgdir"
}
kernel_mainline() {
pkgdesc="Mainline description"
depends="linux-postmarketos-mainline"
mkdir "$subpkgdir"
}
nonfree_firmware() {
pkgdesc="Wifi firmware"
depends="firmware-sony-amami"
mkdir "$subpkgdir"
}
sha512sums="e6daf310a259483da1e1e8be66693dea876f8d1fa6db001c37035d913d7de6e5f1be4a40fae7dcaff404d1953b4c5a58b31d8e6b593b72b56b64ba78f859717c deviceinfo
8b6034c0338ab4c7d648f47983aad6da07e427e7dba47baabf85a1b3ddeeda47c8d7fbcd547a302c9a759b2943ee30d3e82c3b368d8582833a058e4671638a9e 90-android-touch-dev.rules"

View file

@ -1,60 +0,0 @@
# Reference: <https://postmarketos.org/devicepkg>
pkgname="device-wileyfox-crackling"
pkgdesc="Wileyfox Swift"
pkgver=2
pkgrel=0
url="https://postmarketos.org"
license="MIT"
arch="aarch64"
options="!check !archcheck"
depends="postmarketos-base mkbootimg"
makedepends="devicepkg-dev"
subpackages="
$pkgname-kernel-mainline:kernel_mainline
$pkgname-kernel-mainline-modem:kernel_mainline_modem
$pkgname-kernel-downstream:downstream
$pkgname-nonfree-firmware:nonfree_firmware
$pkgname-nonfree-firmware-modem:nonfree_firmware_modem
"
source="deviceinfo"
build() {
devicepkg_build $startdir $pkgname
}
package() {
devicepkg_package $startdir $pkgname
}
kernel_mainline() {
pkgdesc="Mainline kernel (no modem)"
depends="linux-postmarketos-qcom-msm8916 soc-qcom-msm8916"
devicepkg_subpackage_kernel $startdir $pkgname $subpkgname
}
kernel_mainline_modem() {
pkgdesc="Mainline kernel (with modem)"
depends="linux-postmarketos-qcom-msm8916 soc-qcom-msm8916 soc-qcom-msm8916-modem"
devicepkg_subpackage_kernel $startdir $pkgname $subpkgname
}
# This is renamed to test the APKBUILD parser. In reality they should always use proper names.
downstream() {
pkgdesc="Downstream kernel"
depends="linux-wileyfox-crackling mesa-dri-swrast mdss-fb-init-hack"
devicepkg_subpackage_kernel $startdir $pkgname $subpkgname
}
nonfree_firmware() {
pkgdesc="GPU/WiFi/BT/Video firmware"
depends="linux-firmware-qcom firmware-wileyfox-crackling-venus firmware-wileyfox-crackling-wcnss"
mkdir "$subpkgdir"
}
nonfree_firmware_modem() {
pkgdesc="Modem firmware"
depends="firmware-wileyfox-crackling-modem"
install_if="$pkgname-nonfree-firmware $pkgname-kernel-mainline-modem"
mkdir "$subpkgdir"
}

View file

@ -1,16 +0,0 @@
pkgname=postmarketos-ui-weston
pkgver=42
pkgrel=0
pkgdesc="(Wayland) Reference compositor (demo, not a phone interface)"
url="https://postmarketos.org"
arch="noarch"
license="GPL-3.0-or-later"
subpackages="$pkgname-extras"
package() {
mkdir "$pkgdir"
}
extras() {
pkgdesc="Super cool extras you will definitely (not?) need"
}

View file

@ -1,29 +0,0 @@
pkgname=testapp
pkgver=1.0
pkgrel=0
pkgdesc="program using the testlib (for testing soname bumps)"
url="https://postmarketos.org"
arch="all"
license="MIT"
depends="testlib"
makedepends=""
subpackages=""
source="testapp.c"
options=""
build() {
cd "$srcdir"
$CC testapp.c -o testapp -L/usr/lib/ -ltestlib
}
check() {
cd "$srcdir"
printf 'hello, world from testlib!\n' > expected
./testapp > real
diff -q expected real
}
package() {
install -Dm755 "$srcdir/testapp" "$pkgdir/usr/bin/testapp"
}
sha512sums="73b167575dc0082a1277b0430f095509885c7aaf55e59bad148825a9879f91fe41c6479bb7f34c0cdd15284b0aadd904a5ba2c1ea85fb8bfb061e1cbf4322d76 testapp.c"

View file

@ -1,7 +0,0 @@
#include <stdio.h>
#include <testlib.h>
int main(int argc, char **argv) {
testlib_hello();
return 0;
}

View file

@ -1,38 +0,0 @@
pkgname=testlib
pkgver=1.0
pkgrel=0
pkgdesc="testing soname bumps (soname changes with pkgrel!)"
url="https://postmarketos.org"
arch="all"
license="MIT"
depends=""
makedepends=""
subpackages=""
source="testlib.c testlib.h"
options="!check"
build() {
cd "$srcdir"
local major="$pkgrel"
local minor="0"
local soname="libtestlib.so.$major"
local realname="libtestlib.so.$minor.$major"
$CC -fPIC -c -g -Wall testlib.c -o libtestlib.o
$CC -shared -Wl,-soname,$soname -o $realname libtestlib.o
ln -sf $realname $soname
ln -sf $soname "libtestlib.so"
}
package() {
cd "$srcdir"
install -Dm755 testlib.h "$pkgdir/usr/include/testlib.h"
mkdir -p "$pkgdir/usr/lib/"
local i
for i in *.so*; do
cp -a "$i" "$pkgdir/usr/lib/$i"
done
}
sha512sums="15c671462a2f043e798b2998e8706f3ac119648c3d3ae946a0115c1f1aec567537f44e7e778bc77d3af4cd05a2d684677dabd56bb35799fca5939c6c087b4e27 testlib.c
16be61567995052e20f9436c6834c2ca2afcfb04fea15c5d02eb576ecfdc9ef4fed8d977468b2564bbe934d098d111837d96cc323dae3f4dd033aa1d061063ee testlib.h"

View file

@ -1,5 +0,0 @@
#include <stdio.h>
void testlib_hello() {
printf("hello, world from testlib!\n");
}

View file

@ -1,3 +0,0 @@
#pragma once
void testlib_hello();

View file

@ -1,33 +0,0 @@
pkgname=testsubpkg
pkgver=1.0
pkgrel=0
pkgdesc="subpackage using the testlib (for testing soname bumps)"
url="https://postmarketos.org"
arch="all"
license="MIT"
depends=""
makedepends="testlib"
subpackages="$pkgname-app"
source="testapp.c"
options=""
build() {
cd "$srcdir"
$CC testapp.c -o testapp -L/usr/lib/ -ltestlib
}
check() {
cd "$srcdir"
printf 'hello, world from testlib!\n' > expected
./testapp > real
diff -q expected real
}
package() {
mkdir -p "$pkgdir"
}
app() {
install -Dm755 "$srcdir/testapp" "$subpkgdir/usr/bin/testapp"
}
sha512sums="73b167575dc0082a1277b0430f095509885c7aaf55e59bad148825a9879f91fe41c6479bb7f34c0cdd15284b0aadd904a5ba2c1ea85fb8bfb061e1cbf4322d76 testapp.c"

View file

@ -1,7 +0,0 @@
#include <stdio.h>
#include <testlib.h>
int main(int argc, char **argv) {
testlib_hello();
return 0;
}

View file

@ -1,5 +0,0 @@
# Reference: https://postmarketos.org/pmaports.cfg
[pmaports]
version=9999
pmbootstrap_min_version=1.18.0
channel=edge

View file

@ -1,13 +0,0 @@
pkgname=postmarketos-ui-test
pkgver=1
pkgrel=0
license="GPL-3.0-or-later"
depends=""
subpackages="$pkgname-extras"
arch="all"
_pmb_groups="feedbackd"
extras() {
_pmb_groups="extra"
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more