This commit is contained in:
VXTLS 2026-03-22 17:09:45 +00:00 committed by GitHub
commit df21b034b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
167 changed files with 13246 additions and 217 deletions

108
Payload_img_design.md Normal file
View file

@ -0,0 +1,108 @@
# live-bootstrap
This repository uses [`README.rst`](./README.rst) as the canonical main documentation.
## Kernel-bootstrap raw `external.img`
`external.img` is a raw container disk used in kernel-bootstrap mode when
`--external-sources` is set and `--repo` is unset.
### Why not put everything in the initial image?
In kernel-bootstrap mode, the first boot image is consumed by very early
runtime code before the system reaches the normal bash-based build stage.
That early stage has tight assumptions about memory layout and file table usage.
When too many distfiles are packed into the initial image, those assumptions can
be exceeded, which leads to unstable handoff behavior (for example, failures
around the Fiwix transition in QEMU or on bare metal).
So the design is intentionally split:
- Initial image: only what is required to reach `improve: import_payload`
- `external.img`: the rest of distfiles
This is not a patch-style workaround. It is a two-phase transport design that
keeps early boot deterministic and moves bulk data import to a stage where the
runtime is robust enough to process it safely.
### Why import from an external image and copy into main filesystem?
Because the bootstrap still expects distfiles to end up under the normal local
path (`/external/distfiles`) for later steps. `external.img` is used as a
transport medium only.
The flow is:
1. Boot minimal initial image.
2. Reach `improve: import_payload`.
3. Detect the external container disk by magic (`LBPAYLD1`) across detected block devices.
4. Copy payload files into `/external/distfiles`.
5. Continue the build exactly as if files had been present locally all along.
### Format
- Magic: `LBPAYLD1` (8 bytes)
- Then: little-endian `u64` file count
- Repeated entries:
- little-endian `u64` name length
- little-endian `u64` file size
- file name string, encoded as UTF-8 bytes (no terminator)
- file bytes
`name length` is the number of bytes in the UTF-8 encoded file name (not the number of Unicode code points).
The importer probes detected block devices and selects the one with magic `LBPAYLD1`.
### Manual creation without Python
Prepare `external.list` as:
```text
<archive-name> <absolute-path-to-archive>
```
Then:
```sh
cat > make-payload.sh <<'SH'
#!/bin/sh
set -e
out="${1:-external.img}"
list="${2:-external.list}"
write_u64le() {
v="$1"
printf '%016x' "$v" | sed -E 's/(..)(..)(..)(..)(..)(..)(..)(..)/\8\7\6\5\4\3\2\1/' | xxd -r -p
}
count="$(wc -l < "${list}" | tr -d ' ')"
: > "${out}"
printf 'LBPAYLD1' >> "${out}"
write_u64le "${count}" >> "${out}"
while read -r name path; do
[ -n "${name}" ] || continue
size="$(wc -c < "${path}" | tr -d ' ')"
name_len="$(printf '%s' "${name}" | wc -c | tr -d ' ')"
write_u64le "${name_len}" >> "${out}"
write_u64le "${size}" >> "${out}"
printf '%s' "${name}" >> "${out}"
cat "${path}" >> "${out}"
done < "${list}"
SH
chmod +x make-payload.sh
./make-payload.sh external.img external.list
```
Attach `external.img` as an extra raw disk in QEMU, or as the second disk on bare metal.
### When it is used
- Used in kernel-bootstrap with `--external-sources` and without `--repo`.
- Not used with `--repo` (that path still uses an ext filesystem disk).
- Without `--external-sources` and without `--repo`, there is no second disk:
the initial image only includes distfiles needed before `improve: get_network`,
and later distfiles are downloaded from mirrors.
- `--extra-builds=guix` increases container contents (includes post-early `steps-guix`
sources), but does not change the mechanism.

View file

@ -63,17 +63,86 @@ Without using Python:
* *Only* copy distfiles listed in ``sources`` files for ``build:`` steps
manifested before ``improve: get_network`` into this disk.
* Optionally (if you don't do this, distfiles will be network downloaded):
* In kernel-bootstrap mode with ``--external-sources`` (and no ``--repo``),
use the second image as ``external.img``.
``external.img`` is a raw container (not a filesystem) used to carry the
distfiles that are not needed before ``improve: import_payload``.
In other words, the first image only carries the minimal set needed to
reach the importer; the rest of the distfiles live in ``external.img``.
* On the second image, create an MSDOS partition table and one ext3
partition.
* Copy ``distfiles/`` into this disk.
* Run QEMU, with 4+G RAM, optionally SMP (multicore), both drives (in the
order introduced above), a NIC with model E1000
* Header magic: ``LBPAYLD1`` (8 bytes).
* Then: little-endian ``u64`` file count.
* Repeated for each file: little-endian ``u64`` name length,
little-endian ``u64`` file size, UTF-8 encoded file name bytes
(no terminator), raw file bytes.
* ``name length`` is the number of UTF-8 bytes (not Unicode code points).
* With ``--repo``, the second disk remains an ext3 distfiles/repo disk.
* Without ``--external-sources`` and without ``--repo``, no second disk is
used: the initial image includes only pre-network distfiles, and later
distfiles are downloaded from configured mirrors after networking starts.
* Run QEMU, with 4+G RAM, optionally SMP (multicore), both drives (main
builder image plus external image, when a second image is used), a NIC with model E1000
(``-nic user,model=e1000``), and ``-machine kernel-irqchip=split``.
c. **Bare metal:** Follow the same steps as QEMU, but the disks need to be
two different *physical* disks, and boot from the first disk.
Manual raw ``external.img`` preparation
---------------------------------------
The following script creates a raw ``external.img`` from a manually prepared
file list. This is equivalent to what ``rootfs.py`` does for kernel-bootstrap
with ``--external-sources`` (and no ``--repo``).
1. Prepare an ``external.list`` with one file per line, formatted as:
``<archive-name> <absolute-path-to-archive>``.
2. Run:
::
cat > make-payload.sh <<'EOF'
#!/bin/sh
set -e
out="${1:-external.img}"
list="${2:-external.list}"
write_u64le() {
v="$1"
printf '%016x' "$v" | sed -E 's/(..)(..)(..)(..)(..)(..)(..)(..)/\8\7\6\5\4\3\2\1/' | xxd -r -p
}
count="$(wc -l < "${list}" | tr -d ' ')"
: > "${out}"
printf 'LBPAYLD1' >> "${out}"
write_u64le "${count}" >> "${out}"
while read -r name path; do
[ -n "${name}" ] || continue
size="$(wc -c < "${path}" | tr -d ' ')"
name_len="$(printf '%s' "${name}" | wc -c | tr -d ' ')"
write_u64le "${name_len}" >> "${out}"
write_u64le "${size}" >> "${out}"
printf '%s' "${name}" >> "${out}"
cat "${path}" >> "${out}"
done < "${list}"
EOF
chmod +x make-payload.sh
./make-payload.sh external.img external.list
3. Attach ``external.img`` as an additional raw disk when booting in QEMU, or
as the second physical disk on bare metal.
Notes:
* ``external.img`` raw container mode is used with ``--external-sources`` (and
no ``--repo``). With ``--extra-builds=guix``, the container content is larger
because it also includes post-early sources from ``steps-guix``.
* Without ``--external-sources`` and without ``--repo``, there is no second
image. The initial image only includes distfiles needed before
``improve: get_network``; later distfiles are downloaded from mirrors.
* The runtime importer identifies the correct disk by checking the magic
``LBPAYLD1`` on each detected block device, not by assuming a device name.
Mirrors
-------

View file

@ -12,6 +12,7 @@ import hashlib
import os
import random
import shutil
import struct
import tarfile
import traceback
@ -25,16 +26,34 @@ class Generator():
git_dir = os.path.join(os.path.dirname(os.path.join(__file__)), '..')
distfiles_dir = os.path.join(git_dir, 'distfiles')
raw_container_magic = b'LBPAYLD1'
# pylint: disable=too-many-arguments,too-many-positional-arguments
def __init__(self, arch, external_sources, early_preseed, repo_path, mirrors):
def __init__(self, arch, external_sources, early_preseed, repo_path, mirrors,
extra_builds=None):
self.arch = arch
self.early_preseed = early_preseed
self.external_sources = external_sources
self.repo_path = repo_path
self.mirrors = mirrors
self.source_manifest = self.get_source_manifest(not self.external_sources)
self.early_source_manifest = self.get_source_manifest(True)
self.extra_builds = list(extra_builds or [])
self.pre_network_source_manifest = self.get_source_manifest(
stop_before_improve="get_network",
extra_builds=[],
)
self.pre_import_source_manifest = self.get_source_manifest(
stop_before_improve="import_payload",
extra_builds=[],
)
# Only raw-external mode needs full upfront availability for container generation.
if self.external_sources and not self.repo_path:
self.source_manifest = self.get_source_manifest(extra_builds=self.extra_builds)
else:
self.source_manifest = self.pre_network_source_manifest
self.bootstrap_source_manifest = self.source_manifest
self.external_source_manifest = []
self.external_image = None
self.kernel_bootstrap_mode = None
self.target_dir = None
self.external_dir = None
@ -46,6 +65,115 @@ class Generator():
self.external_dir = os.path.join(self.target_dir, 'external')
self.distfiles()
def _select_kernel_bootstrap_mode(self):
"""
Select how kernel-bootstrap should transport distfiles.
"""
if self.repo_path:
# Keep second-disk staging outside init image for ext3 repo mode.
self.external_dir = os.path.join(os.path.dirname(self.target_dir), 'external')
self.kernel_bootstrap_mode = "repo"
self.external_source_manifest = []
return
if self.external_sources:
# Raw external container mode keeps early distfiles inside init image.
self.external_dir = os.path.join(self.target_dir, 'external')
self.kernel_bootstrap_mode = "raw_external"
self._prepare_kernel_bootstrap_external_manifests()
return
# Network-only mode keeps pre-network distfiles inside init image.
self.external_dir = os.path.join(self.target_dir, 'external')
self.kernel_bootstrap_mode = "network_only"
self.bootstrap_source_manifest = self.pre_network_source_manifest
self.external_source_manifest = []
def _prepare_kernel_bootstrap_external_manifests(self):
"""
Split distfiles between init image and external raw container.
"""
# Keep the early builder image small: include only sources needed
# before improve: import_payload runs, so external.img is the primary
# carrier for the remaining distfiles.
self.bootstrap_source_manifest = self.pre_import_source_manifest
full_manifest = self.get_source_manifest(extra_builds=self.extra_builds)
if self.bootstrap_source_manifest == full_manifest:
raise ValueError("steps/manifest must include `improve: import_payload` in kernel-bootstrap mode.")
bootstrap_set = set(self.bootstrap_source_manifest)
self.external_source_manifest = [entry for entry in full_manifest if entry not in bootstrap_set]
def _kernel_bootstrap_init_manifest(self):
"""
Return the exact manifest that is allowed inside init image.
"""
mode_to_manifest = {
"network_only": self.pre_network_source_manifest, # up to get_network
"raw_external": self.bootstrap_source_manifest, # up to import_payload
"repo": self.pre_network_source_manifest, # up to get_network
}
manifest = mode_to_manifest.get(self.kernel_bootstrap_mode)
if manifest is None:
raise ValueError(f"Unexpected kernel bootstrap mode: {self.kernel_bootstrap_mode}")
return manifest
def _copy_manifest_distfiles(self, out_dir, manifest):
os.makedirs(out_dir, exist_ok=True)
for entry in manifest:
file_name = entry[3].strip()
shutil.copy2(os.path.join(self.distfiles_dir, file_name),
os.path.join(out_dir, file_name))
def _ensure_manifest_distfiles(self, manifest):
for entry in manifest:
checksum, directory, url, file_name = entry
distfile_path = os.path.join(directory, file_name)
if not os.path.isfile(distfile_path):
self.download_file(url, directory, file_name)
self.check_file(distfile_path, checksum)
def _create_raw_container_image(self, target_path, manifest, image_name="external.img"):
if manifest is None:
manifest = []
if manifest:
# Guarantee all payload distfiles exist and match checksums.
self._ensure_manifest_distfiles(manifest)
files_by_name = {}
for checksum, _, _, file_name in manifest:
if file_name in files_by_name and files_by_name[file_name] != checksum:
raise ValueError(
f"Conflicting container file with same name but different hash: {file_name}"
)
files_by_name[file_name] = checksum
container_path = os.path.join(target_path, image_name)
ordered_names = sorted(files_by_name.keys())
with open(container_path, "wb") as container:
container.write(self.raw_container_magic)
if len(ordered_names) > 0xFFFFFFFFFFFFFFFF:
raise ValueError("Too many files for raw container format.")
container.write(struct.pack("<Q", len(ordered_names)))
for file_name in ordered_names:
file_name_bytes = file_name.encode("utf_8")
if len(file_name_bytes) > 0xFFFFFFFFFFFFFFFF:
raise ValueError(f"Container file name too long: {file_name}")
src_path = os.path.join(self.distfiles_dir, file_name)
file_size = os.path.getsize(src_path)
if file_size > 0xFFFFFFFFFFFFFFFF:
raise ValueError(f"Container file too large for raw container format: {file_name}")
container.write(struct.pack("<QQ", len(file_name_bytes), file_size))
container.write(file_name_bytes)
with open(src_path, "rb") as src_file:
shutil.copyfileobj(src_file, container, 1024 * 1024)
return container_path
def prepare(self, target, using_kernel=False, kernel_bootstrap=False, target_size=0):
"""
Prepare basic media of live-bootstrap.
@ -55,6 +183,10 @@ class Generator():
"""
self.target_dir = target.path
self.external_dir = os.path.join(self.target_dir, 'external')
self.external_image = None
self.external_source_manifest = []
self.bootstrap_source_manifest = self.source_manifest
self.kernel_bootstrap_mode = None
# We use ext3 here; ext4 actually has a variety of extensions that
# have been added with varying levels of recency
@ -67,9 +199,7 @@ class Generator():
if kernel_bootstrap:
self.target_dir = os.path.join(self.target_dir, 'init')
os.mkdir(self.target_dir)
if not self.repo_path and not self.external_sources:
self.external_dir = os.path.join(self.target_dir, 'external')
self._select_kernel_bootstrap_mode()
elif using_kernel:
self.target_dir = os.path.join(self.target_dir, 'disk')
self.external_dir = os.path.join(self.target_dir, 'external')
@ -101,9 +231,17 @@ class Generator():
if kernel_bootstrap:
self.create_builder_hex0_disk_image(self.target_dir + '.img', target_size)
if self.repo_path or self.external_sources:
if self.kernel_bootstrap_mode == "repo":
mkfs_args = ['-d', os.path.join(target.path, 'external')]
target.add_disk("external", filesystem="ext3", mkfs_args=mkfs_args)
elif self.kernel_bootstrap_mode == "raw_external":
# external.img is a raw container, imported at improve: import_payload.
self.external_image = self._create_raw_container_image(
target.path,
self.external_source_manifest,
image_name="external.img",
)
target.add_existing_disk("external", self.external_image)
elif using_kernel:
mkfs_args = ['-F', '-d', os.path.join(target.path, 'disk')]
target.add_disk("disk",
@ -117,6 +255,18 @@ class Generator():
self.get_packages()
shutil.copytree(os.path.join(self.git_dir, 'steps'), os.path.join(self.target_dir, 'steps'))
for extra_build in self.extra_builds:
steps_extra = f"steps-{extra_build}"
steps_extra_dir = os.path.join(self.git_dir, steps_extra)
if not os.path.isdir(steps_extra_dir):
raise ValueError(
f"{steps_extra} directory does not exist while --extra-builds includes {extra_build}."
)
if not os.path.isfile(os.path.join(steps_extra_dir, 'manifest')):
raise ValueError(
f"{steps_extra}/manifest does not exist while --extra-builds includes {extra_build}."
)
shutil.copytree(steps_extra_dir, os.path.join(self.target_dir, steps_extra))
def stage0_posix(self, kernel_bootstrap=False):
"""Copy in all of the stage0-posix"""
@ -147,26 +297,25 @@ class Generator():
def distfiles(self):
"""Copy in distfiles"""
def copy_no_network_distfiles(out, early):
# Note that "no disk" implies "no network" for kernel bootstrap mode
manifest = self.early_source_manifest if early else self.source_manifest
for file in manifest:
file = file[3].strip()
shutil.copy2(os.path.join(self.distfiles_dir, file),
os.path.join(out, file))
distfile_dir = os.path.join(self.external_dir, 'distfiles')
early_distfile_dir = os.path.join(self.target_dir, 'external', 'distfiles')
main_distfile_dir = os.path.join(self.external_dir, 'distfiles')
if self.kernel_bootstrap_mode is not None:
# Kernel bootstrap always copies a bounded manifest, never full distfiles tree.
init_manifest = self._kernel_bootstrap_init_manifest()
init_distfile_dir = os.path.join(self.target_dir, 'external', 'distfiles')
self._copy_manifest_distfiles(init_distfile_dir, init_manifest)
if early_distfile_dir != main_distfile_dir:
os.makedirs(early_distfile_dir, exist_ok=True)
copy_no_network_distfiles(early_distfile_dir, True)
if self.kernel_bootstrap_mode == "repo":
# Repo mode also stages the same bounded set for the second ext3 disk.
staged_distfile_dir = distfile_dir
if staged_distfile_dir != init_distfile_dir:
self._copy_manifest_distfiles(staged_distfile_dir, init_manifest)
return
if self.external_sources:
shutil.copytree(self.distfiles_dir, main_distfile_dir, dirs_exist_ok=True)
shutil.copytree(self.distfiles_dir, distfile_dir, dirs_exist_ok=True)
else:
os.mkdir(main_distfile_dir)
copy_no_network_distfiles(main_distfile_dir, False)
self._copy_manifest_distfiles(distfile_dir, self.bootstrap_source_manifest)
@staticmethod
def output_dir(srcfs_file, dirpath):
@ -344,43 +493,60 @@ this script the next time")
self.check_file(path, line[0])
@classmethod
def get_source_manifest(cls, pre_network=False):
def get_source_manifest(cls, stop_before_improve=None, extra_builds=None):
"""
Generate a source manifest for the system.
"""
entries = []
directory = os.path.relpath(cls.distfiles_dir, cls.git_dir)
extra_builds = list(extra_builds or [])
# Find all source files
steps_dir = os.path.join(cls.git_dir, 'steps')
with open(os.path.join(steps_dir, 'manifest'), 'r', encoding="utf_8") as file:
for line in file:
if pre_network and line.strip().startswith("improve: ") and "network" in line:
break
manifests = [os.path.join(cls.git_dir, 'steps')]
for extra_build in extra_builds:
steps_extra = f"steps-{extra_build}"
steps_extra_dir = os.path.join(cls.git_dir, steps_extra)
if not os.path.isdir(steps_extra_dir):
raise ValueError(
f"{steps_extra} directory does not exist while --extra-builds includes {extra_build}."
)
manifests.append(steps_extra_dir)
if not line.strip().startswith("build: "):
continue
for steps_dir in manifests:
manifest_path = os.path.join(steps_dir, 'manifest')
if not os.path.isfile(manifest_path):
raise ValueError(f"Missing manifest: {manifest_path}")
step = line.split(" ")[1].split("#")[0].strip()
sourcef = os.path.join(steps_dir, step, "sources")
if os.path.exists(sourcef):
# Read sources from the source file
with open(sourcef, "r", encoding="utf_8") as sources:
for source in sources.readlines():
source = source.strip().split(" ")
with open(manifest_path, 'r', encoding="utf_8") as file:
for line in file:
stripped = line.strip()
if stop_before_improve and stripped.startswith("improve: "):
improve_step = stripped.split(" ")[1].split("#")[0].strip()
if improve_step == stop_before_improve:
break
if source[0] == "g" or source[0] == "git":
source[1:] = source[2:]
if not stripped.startswith("build: "):
continue
if len(source) > 3:
file_name = source[3]
else:
# Automatically determine file name based on URL.
file_name = os.path.basename(source[1])
step = line.split(" ")[1].split("#")[0].strip()
sourcef = os.path.join(steps_dir, step, "sources")
if os.path.exists(sourcef):
# Read sources from the source file
with open(sourcef, "r", encoding="utf_8") as sources:
for source in sources.readlines():
source = source.strip().split(" ")
entry = (source[2], directory, source[1], file_name)
if entry not in entries:
entries.append(entry)
if source[0] == "g" or source[0] == "git":
source[1:] = source[2:]
if len(source) > 3:
file_name = source[3]
else:
# Automatically determine file name based on URL.
file_name = os.path.basename(source[1])
entry = (source[2], directory, source[1], file_name)
if entry not in entries:
entries.append(entry)
return entries

View file

@ -12,7 +12,7 @@ class SimpleMirror(socketserver.TCPServer):
"""Simple HTTP mirror from a directory"""
def __init__(self, directory: str):
self.directory = directory
super().__init__(("localhost", 0), self._handler)
super().__init__(("0.0.0.0", 0), self._handler)
@property
def port(self):

View file

@ -59,3 +59,7 @@ class Target:
def get_disk(self, name):
"""Get the path to a device of a disk"""
return self._disks.get(name)
def add_existing_disk(self, name, path):
"""Register an existing disk image path."""
self._disks[name] = os.path.abspath(path)

View file

@ -186,7 +186,8 @@ do_file() {
esac
}
for src in steps/*/sources; do
for src in steps/*/sources steps-*/*/sources; do
[ -f "${src}" ] || continue
while read -r line; do
# shellcheck disable=SC2086
do_file ${line}

838
rootfs.py
View file

@ -17,6 +17,8 @@ you can run bootstap inside chroot.
import argparse
import os
import signal
import shutil
import tempfile
import threading
from lib.generator import Generator, stage0_arch_map
@ -24,6 +26,503 @@ from lib.simple_mirror import SimpleMirror
from lib.target import Target
from lib.utils import run, run_as_root
def parse_internal_ci_break_after(value):
"""
Parse INTERNAL_CI break directive in the form '<scope>:<step>'.
"""
if not value:
return None, None
scope, separator, step_name = value.partition(":")
scope = scope.strip()
step_name = step_name.strip()
if (
separator != ":"
or not _is_valid_manifest_scope(scope)
or not step_name
):
raise ValueError(
"--internal-ci-break-after must be in the form "
"'steps:<name>' or 'steps-<extra>:<name>'."
)
return scope, step_name
def _is_valid_extra_build_name(name):
if not name:
return False
return all(ch.isalnum() or ch in ("-", "_") for ch in name)
def parse_extra_builds(value):
"""
Parse comma-separated extra build namespaces (e.g. 'guix,gentoo').
"""
if not value:
return []
builds = []
for raw_name in value.split(","):
name = raw_name.strip()
if not name:
continue
if not _is_valid_extra_build_name(name):
raise ValueError(
"--extra-builds must be a comma-separated list of names using "
"letters, digits, '-' or '_'."
)
if name not in builds:
builds.append(name)
return builds
def _scope_for_extra_build(extra_build):
return f"steps-{extra_build}"
def _is_valid_manifest_scope(scope):
if scope == "steps":
return True
if not scope.startswith("steps-"):
return False
return _is_valid_extra_build_name(scope[len("steps-"):])
def _parse_build_step_name(line):
"""
Extract the package name from a manifest build directive.
"""
stripped = line.strip()
if not stripped.startswith("build: "):
return None
payload = stripped[len("build: "):].split("#", 1)[0].strip()
if not payload:
return None
return payload.split()[0]
_INIT_MOUNT_MARKER = "# LB_STAGE0_EARLY_MOUNTS"
_INIT_REGEN_MARKER = "# LB_STAGE0_REGENERATE_SCRIPTS"
_RESUME_NEXT_PATH = "/steps/.lb-resume-next"
_RESUME_NEXT_SCOPE_VAR = "LB_RESUME_NEXT_SCOPE"
_RESUME_NEXT_PACKAGE_VAR = "LB_RESUME_NEXT_PACKAGE"
_INIT_LEGACY_NETWORK_BLOCK = (
'if [ "${CHROOT}" = False ] && command -v dhcpcd >/dev/null 2>&1; then\n'
'dhcpcd --waitip=4 || true\n'
'fi\n'
)
_INIT_GATED_NETWORK_BLOCK = (
'if [ -f /steps/env ]; then\n'
'. /steps/env\n'
'fi\n'
'if [ "${CHROOT}" = False ] && [ "${NETWORK_READY}" = True ] && command -v dhcpcd >/dev/null 2>&1; then\n'
'dhcpcd --waitip=4 || true\n'
'fi\n'
)
_INIT_MOUNT_BLOCK = (
_INIT_MOUNT_MARKER + "\n"
+ "mount | grep ' on /dev ' >/dev/null 2>&1 || (mkdir -p /dev; mount -t devtmpfs devtmpfs /dev)\n"
+ "mount | grep ' on /proc ' >/dev/null 2>&1 || (mkdir -p /proc; mount -t proc proc /proc)\n"
)
_INIT_REGEN_BLOCK = (
_INIT_REGEN_MARKER + "\n"
+ "# Regenerate scripts from current manifests so resume runs stay deterministic.\n"
+ 'resume_entry=""\n'
+ 'resume_root=""\n'
+ 'resume_pkg=""\n'
+ 'resume_next_scope=""\n'
+ 'resume_next_pkg=""\n'
+ 'if [ -f "$0" ]; then\n'
+ 'resume_entry="$(sed -n "s/.*bash \\(\\/steps[^ ]*\\/[0-9][0-9]*\\.sh\\).*/\\1/p" "$0" | head -n1)"\n'
+ 'fi\n'
+ 'if [ -n "${resume_entry}" ]; then\n'
+ 'resume_root="$(dirname "${resume_entry}")"\n'
+ 'if [ -f "${resume_entry}" ]; then\n'
+ 'resume_pkg="$(sed -n "s/^build \\([^ ]*\\) .*/\\1/p" "${resume_entry}" | head -n1)"\n'
+ 'fi\n'
+ 'fi\n'
+ f'if [ -f "{_RESUME_NEXT_PATH}" ]; then\n'
+ f'resume_next_scope="$(sed -n "s/^scope=//p" "{_RESUME_NEXT_PATH}" | head -n1)"\n'
+ f'resume_next_pkg="$(sed -n "s/^package=//p" "{_RESUME_NEXT_PATH}" | head -n1)"\n'
+ 'if [ "${resume_next_scope}" = "steps" ]; then\n'
+ 'resume_root="/steps"\n'
+ 'elif echo "${resume_next_scope}" | grep -Eq "^steps-[A-Za-z0-9_-]+$"; then\n'
+ 'resume_root="/${resume_next_scope}"\n'
+ 'fi\n'
+ 'if [ -n "${resume_next_pkg}" ]; then\n'
+ 'resume_pkg="${resume_next_pkg}"\n'
+ 'fi\n'
+ f'rm -f "{_RESUME_NEXT_PATH}"\n'
+ 'fi\n'
+ 'if [ -x /script-generator ] && [ -f /steps/manifest ]; then\n'
+ '/script-generator /steps/manifest\n'
+ 'fi\n'
+ 'for extra_manifest in /steps-*/manifest; do\n'
+ 'if [ ! -f "${extra_manifest}" ]; then\n'
+ 'continue\n'
+ 'fi\n'
+ 'if [ -x /script-generator ]; then\n'
+ '/script-generator "${extra_manifest}" /steps\n'
+ 'fi\n'
+ 'done\n'
+ 'if [ -n "${resume_pkg}" ] && [ -d "${resume_root}" ]; then\n'
+ 'mapped_entry="$(grep -F -l "build ${resume_pkg} " "${resume_root}"/[0-9]*.sh 2>/dev/null | head -n1 || true)"\n'
+ 'if [ -n "${mapped_entry}" ]; then\n'
+ 'resume_entry="${mapped_entry}"\n'
+ 'fi\n'
+ 'fi\n'
+ 'if [ -n "${resume_entry}" ] && [ -f "${resume_entry}" ] && [ "${resume_entry}" != "$0" ]; then\n'
+ 'bash "${resume_entry}"\n'
+ 'exit "$?"\n'
+ 'fi\n'
)
def _find_next_build_after(manifest_lines, break_step, context_label):
"""
Return the next build step after break_step within the same manifest.
"""
found_break = False
for line in manifest_lines:
step_name = _parse_build_step_name(line)
if step_name is None:
continue
if found_break:
return step_name
if step_name == break_step:
found_break = True
if not found_break:
raise ValueError(
"INTERNAL_CI_BREAK_AFTER target not found in "
+ context_label
+ ": "
+ break_step
)
return None
def _insert_internal_ci_break(manifest_lines, break_step, internal_ci, context_label):
inserted = False
break_line = f"jump: break ( INTERNAL_CI == {internal_ci} )\n"
output_lines = []
for line in manifest_lines:
output_lines.append(line)
if inserted:
continue
step_name = _parse_build_step_name(line)
if step_name is None:
continue
if step_name == break_step:
output_lines.append(break_line)
inserted = True
if not inserted:
raise ValueError(
"INTERNAL_CI_BREAK_AFTER target not found in "
+ context_label
+ ": "
+ break_step
)
return output_lines
def _copytree_replace(src, dst):
if os.path.isdir(dst):
shutil.copytree(src, dst, dirs_exist_ok=True)
else:
shutil.copytree(src, dst)
def _inject_block_after_shebang(content, marker, block):
if marker in content:
return content
first_newline = content.find("\n")
if first_newline == -1:
return content
return content[: first_newline + 1] + block + content[first_newline + 1 :]
def _patch_resume_init_scripts(mountpoint):
for init_name in os.listdir(mountpoint):
if init_name != "init" and not init_name.startswith("init."):
continue
init_path = os.path.join(mountpoint, init_name)
if not os.path.isfile(init_path):
continue
with open(init_path, "r", encoding="utf-8", errors="ignore") as init_file:
init_content = init_file.read()
init_content = _inject_block_after_shebang(
init_content,
_INIT_MOUNT_MARKER,
_INIT_MOUNT_BLOCK,
)
if (
_INIT_LEGACY_NETWORK_BLOCK in init_content
and _INIT_GATED_NETWORK_BLOCK not in init_content
):
init_content = init_content.replace(
_INIT_LEGACY_NETWORK_BLOCK,
_INIT_GATED_NETWORK_BLOCK,
)
init_content = _inject_block_after_shebang(
init_content,
_INIT_REGEN_MARKER,
_INIT_REGEN_BLOCK,
)
with open(init_path, "w", encoding="utf-8") as init_file:
init_file.write(init_content)
def _update_stage0_tree(mountpoint,
steps_dir,
extra_builds,
mirrors,
internal_ci,
break_scope,
break_step):
"""
Apply all resume updates directly to a mounted stage0 filesystem tree.
"""
old_config_path = os.path.join(mountpoint, "steps", "bootstrap.cfg")
if not os.path.isfile(old_config_path):
raise SystemExit(f"Missing config in stage0 image: {old_config_path}")
old_env_path = os.path.join(mountpoint, "steps", "env")
old_env_content = None
break_output_lines = None
break_manifest_relpath = None
next_step = None
if os.path.isfile(old_env_path):
with open(old_env_path, "rb") as env_file:
old_env_content = env_file.read()
with open(old_config_path, "r", encoding="utf-8") as cfg:
lines = [
line for line in cfg
if not line.startswith("EXTRA_BUILDS=")
and not line.startswith("INTERNAL_CI=")
and not line.startswith(_RESUME_NEXT_SCOPE_VAR + "=")
and not line.startswith(_RESUME_NEXT_PACKAGE_VAR + "=")
and not line.startswith("MIRRORS=")
and not line.startswith("MIRRORS_LEN=")
and not line.startswith("PAYLOAD_REQUIRED=")
]
dest_steps = os.path.join(mountpoint, "steps")
_copytree_replace(steps_dir, dest_steps)
env_path = os.path.join(dest_steps, "env")
if old_env_content is not None:
with open(env_path, "wb") as env_file:
env_file.write(old_env_content)
if os.path.isfile(env_path):
with open(env_path, "r", encoding="utf-8", errors="ignore") as env_file:
env_content = env_file.read()
else:
env_content = ""
if "NETWORK_READY=" not in env_content:
with open(env_path, "a", encoding="utf-8") as env_file:
if env_content and not env_content.endswith("\n"):
env_file.write("\n")
env_file.write("NETWORK_READY=False\n")
if break_scope and break_step:
if internal_ci in ("", "False", None):
raise SystemExit("INTERNAL_CI must be set when INTERNAL_CI_BREAK_AFTER is used.")
if break_scope == "steps":
source_manifest_path = os.path.join(steps_dir, "manifest")
else:
allowed_scopes = {_scope_for_extra_build(extra) for extra in extra_builds}
if break_scope not in allowed_scopes:
raise SystemExit(
f"INTERNAL_CI_BREAK_AFTER scope '{break_scope}' is not enabled by EXTRA_BUILDS."
)
source_manifest_path = os.path.join(
os.path.dirname(steps_dir),
break_scope,
"manifest",
)
if not os.path.isfile(source_manifest_path):
raise SystemExit(f"Missing manifest for INTERNAL_CI_BREAK_AFTER: {source_manifest_path}")
with open(source_manifest_path, "r", encoding="utf-8") as manifest_file:
manifest_lines = manifest_file.readlines()
next_step = _find_next_build_after(
manifest_lines,
break_step,
f"{break_scope}/manifest",
)
break_output_lines = _insert_internal_ci_break(
manifest_lines,
break_step,
internal_ci,
f"{break_scope}/manifest",
)
break_manifest_relpath = os.path.join(break_scope, "manifest")
if next_step:
lines.append(f"{_RESUME_NEXT_SCOPE_VAR}={break_scope}\n")
lines.append(f"{_RESUME_NEXT_PACKAGE_VAR}={next_step}\n")
config_path = os.path.join(dest_steps, "bootstrap.cfg")
if extra_builds:
lines.append("EXTRA_BUILDS=" + ",".join(extra_builds) + "\n")
if mirrors:
lines.append(f'MIRRORS="{" ".join(mirrors)}"\n')
lines.append(f"MIRRORS_LEN={len(mirrors)}\n")
lines.append(f"INTERNAL_CI={internal_ci}\n")
lines.append("PAYLOAD_REQUIRED=False\n")
with open(config_path, "w", encoding="utf-8") as cfg:
cfg.writelines(lines)
_patch_resume_init_scripts(mountpoint)
for extra_build in extra_builds:
extra_scope = _scope_for_extra_build(extra_build)
source_steps_extra = os.path.join(os.path.dirname(steps_dir), extra_scope)
dest_steps_extra = os.path.join(mountpoint, extra_scope)
_copytree_replace(source_steps_extra, dest_steps_extra)
if break_output_lines is not None and break_manifest_relpath is not None:
manifest_path = os.path.join(mountpoint, break_manifest_relpath)
if not os.path.isfile(manifest_path):
raise SystemExit(f"Missing manifest for INTERNAL_CI_BREAK_AFTER: {manifest_path}")
with open(manifest_path, "w", encoding="utf-8") as manifest_file:
manifest_file.writelines(break_output_lines)
def _stage0_update_cli(argv):
"""
Internal entrypoint executed as root for mutating mounted stage0 trees.
"""
if len(argv) < 6:
raise SystemExit("stage0 update cli expects at least 6 arguments")
mountpoint = argv[0]
steps_dir = argv[1]
extra_builds = parse_extra_builds(argv[2])
internal_ci = argv[3]
break_scope = argv[4]
break_step = argv[5]
mirrors = argv[6:]
_update_stage0_tree(
mountpoint,
steps_dir,
extra_builds,
mirrors,
internal_ci,
break_scope,
break_step,
)
def apply_internal_ci_break_to_tree(tree_root, break_scope, break_step, internal_ci):
"""
Inject INTERNAL_CI break jump after a build step in a prepared steps tree.
"""
if not break_scope or not break_step:
return
if internal_ci in ("", "False", None):
raise ValueError("INTERNAL_CI must be set when INTERNAL_CI_BREAK_AFTER is used.")
manifest_path = os.path.join(tree_root, break_scope, "manifest")
if not os.path.isfile(manifest_path):
raise ValueError(f"Missing manifest for INTERNAL_CI_BREAK_AFTER: {manifest_path}")
with open(manifest_path, "r", encoding="utf-8") as manifest_file:
manifest_lines = manifest_file.readlines()
output_lines = _insert_internal_ci_break(
manifest_lines,
break_step,
internal_ci,
f"{break_scope}/manifest",
)
with open(manifest_path, "w", encoding="utf-8") as manifest_file:
manifest_file.writelines(output_lines)
def update_stage0_image(image_path,
extra_builds=None,
mirrors=None,
internal_ci=False,
internal_ci_break_after=None):
"""
Update an existing stage0 image by refreshing step sources from the working
tree and patching bootstrap config / optional extra build handoff bits.
"""
if extra_builds is None:
extra_builds = []
if mirrors is None:
mirrors = []
steps_dir = os.path.abspath("steps")
steps_manifest = os.path.join(steps_dir, "manifest")
if not os.path.isdir(steps_dir) or not os.path.isfile(steps_manifest):
raise ValueError("steps/manifest does not exist.")
for extra_build in extra_builds:
extra_scope = _scope_for_extra_build(extra_build)
extra_steps_dir = os.path.abspath(extra_scope)
manifest = os.path.join(extra_steps_dir, "manifest")
if not os.path.isdir(extra_steps_dir) or not os.path.isfile(manifest):
raise ValueError(
f"{extra_scope}/manifest does not exist while --extra-builds includes {extra_build}."
)
break_scope, break_step = parse_internal_ci_break_after(internal_ci_break_after)
mountpoint = tempfile.mkdtemp(prefix="lb-stage0-", dir="/tmp")
mounted = False
try:
run_as_root(
"mount",
"-t", "ext4",
"-o", "loop,offset=1073741824",
image_path,
mountpoint,
)
mounted = True
loader = (
"import importlib.util, sys;"
"spec=importlib.util.spec_from_file_location('lb_rootfs', sys.argv[1]);"
"mod=importlib.util.module_from_spec(spec);"
"spec.loader.exec_module(mod);"
"mod._stage0_update_cli(sys.argv[2:])"
)
run_as_root(
"python3",
"-c",
loader,
os.path.abspath(__file__),
mountpoint,
steps_dir,
",".join(extra_builds),
str(internal_ci) if internal_ci else "False",
break_scope or "",
break_step or "",
*mirrors,
)
finally:
if mounted:
run_as_root("umount", mountpoint)
os.rmdir(mountpoint)
def prepare_stage0_work_image(base_image,
output_dir,
extra_builds,
mirrors=None,
internal_ci=False,
internal_ci_break_after=None):
"""
Copy stage0 base image to a disposable work image and refresh steps/config.
"""
work_image = os.path.join(output_dir, "stage0-work.img")
shutil.copy2(base_image, work_image)
update_stage0_image(work_image,
extra_builds=extra_builds,
mirrors=mirrors,
internal_ci=internal_ci,
internal_ci_break_after=internal_ci_break_after)
return work_image
def create_configuration_file(args):
"""
Creates bootstrap.cfg file which would contain options used to
@ -31,6 +530,8 @@ def create_configuration_file(args):
"""
config_path = os.path.join('steps', 'bootstrap.cfg')
with open(config_path, "w", encoding="utf_8") as config:
kernel_bootstrap = ((args.bare_metal or args.qemu) and not args.kernel)
payload_required = kernel_bootstrap and args.external_sources and not args.repo
config.write(f"ARCH={args.arch}\n")
config.write(f"ARCH_DIR={stage0_arch_map.get(args.arch, args.arch)}\n")
config.write(f"FORCE_TIMESTAMPS={args.force_timestamps}\n")
@ -41,13 +542,13 @@ def create_configuration_file(args):
config.write(f"FINAL_JOBS={args.cores}\n")
config.write(f"INTERNAL_CI={args.internal_ci or False}\n")
config.write(f"INTERACTIVE={args.interactive}\n")
config.write(f"PAYLOAD_REQUIRED={payload_required}\n")
config.write(f"QEMU={args.qemu}\n")
config.write(f"BARE_METAL={args.bare_metal or (args.qemu and args.interactive)}\n")
if (args.bare_metal or args.qemu) and not args.kernel:
if args.repo or args.external_sources:
config.write("DISK=sdb1\n")
else:
config.write("DISK=sda\n")
if args.extra_builds:
config.write("EXTRA_BUILDS=" + ",".join(args.extra_builds) + "\n")
if kernel_bootstrap:
config.write("DISK=sdb1\n" if args.repo else "DISK=sda\n")
config.write("KERNEL_BOOTSTRAP=True\n")
else:
config.write("DISK=sda1\n")
@ -95,6 +596,9 @@ def main():
parser.add_argument("--build-kernels",
help="Also build kernels in chroot and bwrap builds",
action="store_true")
parser.add_argument("--extra-builds",
help="Comma-separated extra build namespaces to run after main steps "
"(e.g. guix or guix,gentoo,azl3).")
parser.add_argument("--no-create-config",
help="Do not automatically create config file",
action="store_true")
@ -112,6 +616,10 @@ def main():
parser.add_argument("--early-preseed",
help="Skip early stages of live-bootstrap", nargs=None)
parser.add_argument("--internal-ci", help="INTERNAL for github CI")
parser.add_argument("--internal-ci-break-after",
help="Insert a temporary jump: break after a build step using "
"'steps:<name>' or 'steps-<extra>:<name>' "
"for --stage0-image resume runs and fresh --qemu kernel-bootstrap runs.")
parser.add_argument("-s", "--swap", help="Swap space to allocate in Linux",
default=0)
@ -125,11 +633,14 @@ def main():
parser.add_argument("-qs", "--target-size", help="Size of the target image (for QEMU only)",
default="16G")
parser.add_argument("-qk", "--kernel", help="Custom early kernel to use")
parser.add_argument("--stage0-image",
help="Boot an existing stage0 image (target/init.img) directly in QEMU")
parser.add_argument("-b", "--bare-metal", help="Build images for bare metal",
action="store_true")
args = parser.parse_args()
args.extra_builds = parse_extra_builds(args.extra_builds)
# Mode validation
def check_types():
@ -179,9 +690,34 @@ def main():
args.swap = 0
# Validate mirrors
if not args.mirrors:
if not args.mirrors and not args.stage0_image:
raise ValueError("At least one mirror must be provided.")
if args.internal_ci_break_after:
if not args.internal_ci:
raise ValueError("--internal-ci-break-after requires --internal-ci (e.g. pass2).")
break_scope, _ = parse_internal_ci_break_after(args.internal_ci_break_after)
if break_scope != "steps":
extra_build = break_scope[len("steps-"):]
if extra_build not in args.extra_builds:
raise ValueError(
f"--internal-ci-break-after {break_scope}:* requires --extra-builds include "
f"{extra_build}."
)
if not args.qemu:
raise ValueError("--internal-ci-break-after currently requires --qemu.")
if args.kernel:
raise ValueError("--internal-ci-break-after cannot be used with --kernel.")
if args.stage0_image:
if not args.qemu:
raise ValueError("--stage0-image can only be used with --qemu.")
if args.kernel:
raise ValueError("--stage0-image cannot be combined with --kernel.")
if not os.path.isfile(args.stage0_image):
raise ValueError(f"Stage0 image does not exist: {args.stage0_image}")
args.stage0_image = os.path.abspath(args.stage0_image)
# Set constant umask
os.umask(0o022)
@ -199,15 +735,16 @@ def main():
mirror_servers.append(server)
# bootstrap.cfg
try:
os.remove(os.path.join('steps', 'bootstrap.cfg'))
except FileNotFoundError:
pass
if not args.no_create_config:
create_configuration_file(args)
else:
with open(os.path.join('steps', 'bootstrap.cfg'), 'a', encoding='UTF-8'):
if not args.stage0_image:
try:
os.remove(os.path.join('steps', 'bootstrap.cfg'))
except FileNotFoundError:
pass
if not args.no_create_config:
create_configuration_file(args)
else:
with open(os.path.join('steps', 'bootstrap.cfg'), 'a', encoding='UTF-8'):
pass
# target
target = Target(path=args.target)
@ -223,120 +760,185 @@ def main():
server.shutdown()
signal.signal(signal.SIGINT, cleanup)
generator = Generator(arch=args.arch,
external_sources=args.external_sources,
repo_path=args.repo,
early_preseed=args.early_preseed,
mirrors=args.mirrors)
generator = None
if not args.stage0_image:
generator = Generator(arch=args.arch,
external_sources=args.external_sources,
repo_path=args.repo,
early_preseed=args.early_preseed,
mirrors=args.mirrors,
extra_builds=args.extra_builds)
bootstrap(args, generator, target, args.target_size, cleanup)
cleanup()
def _bootstrap_chroot(args, generator, target, cleanup):
find_chroot = """
import shutil
print(shutil.which('chroot'))
"""
chroot_binary = run_as_root(
'python3',
'-c',
find_chroot,
capture_output=True,
).stdout.decode().strip()
generator.prepare(target, using_kernel=False)
arch = stage0_arch_map.get(args.arch, args.arch)
init = os.path.join(os.sep, 'bootstrap-seeds', 'POSIX', arch, 'kaem-optional-seed')
run_as_root('env', '-i', 'PATH=/bin', chroot_binary, generator.target_dir, init, cleanup=cleanup)
def _bootstrap_bwrap(args, generator, target, cleanup):
init = '/init'
if not args.internal_ci or args.internal_ci == "pass1":
generator.prepare(target, using_kernel=False)
arch = stage0_arch_map.get(args.arch, args.arch)
init = os.path.join(os.sep, 'bootstrap-seeds', 'POSIX', arch, 'kaem-optional-seed')
else:
generator.reuse(target)
run('env', '-i', 'bwrap', '--unshare-user',
'--uid', '0',
'--gid', '0',
'--unshare-net' if args.external_sources else None,
'--setenv', 'PATH', '/usr/bin',
'--bind', generator.target_dir, '/',
'--dir', '/dev',
'--dev-bind', '/dev/null', '/dev/null',
'--dev-bind', '/dev/zero', '/dev/zero',
'--dev-bind', '/dev/random', '/dev/random',
'--dev-bind', '/dev/urandom', '/dev/urandom',
'--dev-bind', '/dev/ptmx', '/dev/ptmx',
'--dev-bind', '/dev/tty', '/dev/tty',
'--tmpfs', '/dev/shm',
'--proc', '/proc',
'--bind', '/sys', '/sys',
'--tmpfs', '/tmp',
init,
cleanup=cleanup)
def _bootstrap_bare_metal(args, generator, target, size):
if args.kernel:
generator.prepare(target, using_kernel=True, target_size=size)
path = os.path.join(args.target, os.path.relpath(generator.target_dir, args.target))
print("Please:")
print(f" 1. Take {path}/initramfs and your kernel, boot using this.")
print(f" 2. Take {path}/disk.img and put this on a writable storage medium.")
return
generator.prepare(target, kernel_bootstrap=True, target_size=size)
path = os.path.join(args.target, os.path.relpath(generator.target_dir, args.target))
print("Please:")
print(f" 1. Take {path}.img and write it to a boot drive and then boot it.")
external_disk = target.get_disk("external")
if external_disk is None:
return
external_path = os.path.join(args.target, os.path.relpath(external_disk, args.target))
if args.repo:
print(" 2. Take " + f"{external_path} and attach it as a second disk (/dev/sdb preferred).")
else:
print(" 2. Take " + f"{external_path} and attach it as a second raw container disk (/dev/sdb preferred).")
def _qemu_arg_list_for_stage0_image(args, target):
work_image = prepare_stage0_work_image(
args.stage0_image,
target.path,
args.extra_builds,
mirrors=args.mirrors,
internal_ci=args.internal_ci,
internal_ci_break_after=args.internal_ci_break_after,
)
return [
'-enable-kvm',
'-m', str(args.qemu_ram) + 'M',
'-smp', str(args.cores),
'-drive', 'file=' + work_image + ',format=raw',
'-machine', 'kernel-irqchip=split',
'-nic', 'user,ipv6=off,model=e1000',
]
def _qemu_arg_list_for_kernel(args, generator, target, size):
generator.prepare(target, using_kernel=True, target_size=size)
arg_list = [
'-enable-kvm',
'-m', str(args.qemu_ram) + 'M',
'-smp', str(args.cores),
'-drive', 'file=' + target.get_disk("disk") + ',format=raw',
]
if target.get_disk("external") is not None:
arg_list += [
'-drive', 'file=' + target.get_disk("external") + ',format=raw',
]
arg_list += [
'-nic', 'user,ipv6=off,model=e1000',
'-kernel', args.kernel,
'-append',
]
if args.interactive:
arg_list += ['consoleblank=0 earlyprintk=vga root=/dev/sda1 init=/init rw']
else:
arg_list += ['console=ttyS0 earlycon=uart8250,io,0x3f8,115200n8 root=/dev/sda1 init=/init rw']
return arg_list
def _qemu_arg_list_for_kernel_bootstrap(args, generator, target, size):
generator.prepare(target, kernel_bootstrap=True, target_size=size)
if args.internal_ci_break_after:
break_scope, break_step = parse_internal_ci_break_after(args.internal_ci_break_after)
apply_internal_ci_break_to_tree(
generator.target_dir,
break_scope,
break_step,
args.internal_ci,
)
os.remove(generator.target_dir + '.img')
generator.create_builder_hex0_disk_image(generator.target_dir + '.img', size)
arg_list = [
'-enable-kvm',
'-m', str(args.qemu_ram) + 'M',
'-smp', str(args.cores),
'-drive', 'file=' + generator.target_dir + '.img' + ',format=raw',
]
if target.get_disk("external") is not None:
arg_list += [
'-drive', 'file=' + target.get_disk("external") + ',format=raw',
]
arg_list += [
'-machine', 'kernel-irqchip=split',
'-nic', 'user,ipv6=off,model=e1000',
]
return arg_list
def bootstrap(args, generator, target, size, cleanup):
"""Kick off bootstrap process."""
print(f"Bootstrapping {args.arch}", flush=True)
if args.chroot:
find_chroot = """
import shutil
print(shutil.which('chroot'))
"""
chroot_binary = run_as_root('python3', '-c', find_chroot,
capture_output=True).stdout.decode().strip()
generator.prepare(target, using_kernel=False)
arch = stage0_arch_map.get(args.arch, args.arch)
init = os.path.join(os.sep, 'bootstrap-seeds', 'POSIX', arch, 'kaem-optional-seed')
run_as_root('env', '-i', 'PATH=/bin', chroot_binary, generator.target_dir, init,
cleanup=cleanup)
elif args.bwrap:
init = '/init'
if not args.internal_ci or args.internal_ci == "pass1":
generator.prepare(target, using_kernel=False)
arch = stage0_arch_map.get(args.arch, args.arch)
init = os.path.join(os.sep, 'bootstrap-seeds', 'POSIX', arch, 'kaem-optional-seed')
else:
generator.reuse(target)
run('env', '-i', 'bwrap', '--unshare-user',
'--uid', '0',
'--gid', '0',
'--unshare-net' if args.external_sources else None,
'--setenv', 'PATH', '/usr/bin',
'--bind', generator.target_dir, '/',
'--dir', '/dev',
'--dev-bind', '/dev/null', '/dev/null',
'--dev-bind', '/dev/zero', '/dev/zero',
'--dev-bind', '/dev/random', '/dev/random',
'--dev-bind', '/dev/urandom', '/dev/urandom',
'--dev-bind', '/dev/ptmx', '/dev/ptmx',
'--dev-bind', '/dev/tty', '/dev/tty',
'--tmpfs', '/dev/shm',
'--proc', '/proc',
'--bind', '/sys', '/sys',
'--tmpfs', '/tmp',
init,
cleanup=cleanup)
elif args.bare_metal:
if args.kernel:
generator.prepare(target, using_kernel=True, target_size=size)
path = os.path.join(args.target, os.path.relpath(generator.target_dir, args.target))
print("Please:")
print(f" 1. Take {path}/initramfs and your kernel, boot using this.")
print(f" 2. Take {path}/disk.img and put this on a writable storage medium.")
else:
generator.prepare(target, kernel_bootstrap=True, target_size=size)
path = os.path.join(args.target, os.path.relpath(generator.target_dir, args.target))
print("Please:")
print(f" 1. Take {path}.img and write it to a boot drive and then boot it.")
_bootstrap_chroot(args, generator, target, cleanup)
return
if args.bwrap:
_bootstrap_bwrap(args, generator, target, cleanup)
return
if args.bare_metal:
_bootstrap_bare_metal(args, generator, target, size)
return
if args.stage0_image:
arg_list = _qemu_arg_list_for_stage0_image(args, target)
elif args.kernel:
arg_list = _qemu_arg_list_for_kernel(args, generator, target, size)
else:
if args.kernel:
generator.prepare(target, using_kernel=True, target_size=size)
arg_list = [
'-enable-kvm',
'-m', str(args.qemu_ram) + 'M',
'-smp', str(args.cores),
'-drive', 'file=' + target.get_disk("disk") + ',format=raw'
]
if target.get_disk("external") is not None:
arg_list += [
'-drive', 'file=' + target.get_disk("external") + ',format=raw',
]
arg_list += [
'-nic', 'user,ipv6=off,model=e1000',
'-kernel', args.kernel,
'-append',
]
if args.interactive:
arg_list += ['consoleblank=0 earlyprintk=vga root=/dev/sda1 '
'rootfstype=ext3 init=/init rw']
else:
arg_list += ['console=ttyS0 earlycon=uart8250,io,0x3f8,115200n8 '
'root=/dev/sda1 rootfstype=ext3 init=/init rw']
else:
generator.prepare(target, kernel_bootstrap=True, target_size=size)
arg_list = [
'-enable-kvm',
'-m', str(args.qemu_ram) + 'M',
'-smp', str(args.cores),
'-drive', 'file=' + generator.target_dir + '.img' + ',format=raw'
]
if target.get_disk("external") is not None:
arg_list += [
'-drive', 'file=' + target.get_disk("external") + ',format=raw',
]
arg_list += [
'-machine', 'kernel-irqchip=split',
'-nic', 'user,ipv6=off,model=e1000'
]
if not args.interactive:
arg_list += ['-no-reboot', '-nographic']
run(args.qemu_cmd, *arg_list, cleanup=cleanup)
arg_list = _qemu_arg_list_for_kernel_bootstrap(args, generator, target, size)
if not args.interactive:
arg_list += ['-no-reboot', '-nographic']
run(args.qemu_cmd, *arg_list, cleanup=cleanup)
if __name__ == "__main__":
main()

View file

@ -32,6 +32,48 @@ struct Directive {
};
typedef struct Directive Directive;
char *steps_root = "/steps";
char *config_root = "/steps";
char *join_path(const char *base, const char *suffix) {
char *out = calloc(MAX_STRING, sizeof(char));
strcpy(out, base);
if (strlen(out) > 0 && out[strlen(out) - 1] != '/') {
strcat(out, "/");
}
while (*suffix == '/') {
suffix += 1;
}
strcat(out, suffix);
return out;
}
char *config_path(const char *suffix) {
return join_path(config_root, suffix);
}
char *dirname_from_path(const char *path) {
char *slash = strrchr(path, '/');
char *out = calloc(MAX_STRING, sizeof(char));
if (slash == NULL) {
strcpy(out, ".");
return out;
}
if (slash == path) {
strcpy(out, "/");
return out;
}
strncpy(out, path, slash - path);
return out;
}
void write_steps_prefix(FILE *out) {
fputs(steps_root, out);
if (steps_root[strlen(steps_root) - 1] != '/') {
fputs("/", out);
}
}
/* Tokenizer. */
/* Skip over a comment. */
@ -120,10 +162,11 @@ typedef struct Variable Variable;
Variable *variables;
Variable *load_config() {
FILE *config = fopen("/steps/bootstrap.cfg", "r");
/* File does not exist check. */
char *config_file = config_path("bootstrap.cfg");
FILE *config = fopen(config_file, "r");
if (config == NULL) {
return NULL;
fputs("Unable to open bootstrap.cfg\n", stderr);
exit(1);
}
char *line = calloc(MAX_STRING, sizeof(char));
@ -392,9 +435,12 @@ Directive *interpreter(Directive *directives) {
/* Script generator. */
FILE *start_script(int id, int bash_build) {
/* Create the file /steps/$id.sh */
/* Create the file ${steps_root}/$id.sh */
char *filename = calloc(MAX_STRING, sizeof(char));
strcpy(filename, "/steps/");
strcpy(filename, steps_root);
if (filename[strlen(filename) - 1] != '/') {
strcat(filename, "/");
}
strcat(filename, int2str(id, 10, 0));
strcat(filename, ".sh");
@ -407,28 +453,47 @@ FILE *start_script(int id, int bash_build) {
}
if (bash_build) {
char *bootstrap_file = config_path("bootstrap.cfg");
char *env_file = config_path("env");
char *helpers_file = join_path(steps_root, "helpers.sh");
fputs("#!/bin/bash\n", out);
if (strcmp(get_var("INTERACTIVE"), "True") == 0) {
if (bash_build != 1) {
fputs("set -eEo pipefail\ntrap 'env PS1=\"[TRAP] \\w # \" bash -i' ERR\n", out);
} else {
/* FIXME early bash has buggy ERR trap handling */
fputs("set -e\ntrap 'bash -c '\"'\"'while true; do printf \""
"[TRAP - use Ctrl+D] $(pwd) # \"; eval \"$(cat)\"; done'\"'\"'' EXIT\n",
out);
fputs("set -e\ntrap 'status=$?; if [ \"${status}\" -ne 0 ]; then env PS1=\"[TRAP] \\w # \" bash -i; fi' EXIT\n", out);
}
} else {
fputs("set -e\n", out);
}
fputs("cd /steps\n", out);
fputs(". ./bootstrap.cfg\n", out);
fputs(". ./env\n", out);
fputs(". ./helpers.sh\n", out);
fputs("cd ", out);
fputs(steps_root, out);
fputs("\n", out);
fputs(". ", out);
fputs(bootstrap_file, out);
fputs("\n", out);
fputs(". ", out);
fputs(env_file, out);
fputs("\n", out);
fputs("SRCDIR=", out);
fputs(steps_root, out);
fputs("\n", out);
fputs(". ", out);
fputs(helpers_file, out);
fputs("\n", out);
} else {
char *env_file = config_path("env");
fputs("set -ex\n", out);
fputs("cd /steps\n", out);
fputs("cd ", out);
fputs(steps_root, out);
fputs("\n", out);
output_config(out);
FILE *env = fopen("/steps/env", "r");
FILE *env = fopen(env_file, "r");
if (env == NULL) {
fputs("Unable to open env\n", stderr);
exit(1);
}
char *line = calloc(MAX_STRING, sizeof(char));
while (fgets(line, MAX_STRING, env) != 0) {
/* Weird M2-Planet behaviour. */
@ -454,7 +519,7 @@ void output_call_script(FILE *out, char *type, char *name, int bash_build, int s
} else {
fputs("kaem --file ", out);
}
fputs("/steps/", out);
write_steps_prefix(out);
if (strlen(type) != 0) {
fputs(type, out);
fputs("/", out);
@ -463,6 +528,23 @@ void output_call_script(FILE *out, char *type, char *name, int bash_build, int s
fputs(".sh\n", out);
}
void output_resume_network_init(FILE *out) {
fputs("if [ -f ", out);
write_steps_prefix(out);
fputs("helpers.sh ]; then\n", out);
fputs(". ", out);
write_steps_prefix(out);
fputs("helpers.sh\n", out);
fputs("resume_network_init \"", out);
fputs(config_root, out);
fputs("\"\n", out);
fputs("fi\n", out);
}
void output_init_call_script(FILE *out, char *name, int bash_build) {
output_call_script(out, "", name, bash_build, 0);
}
void output_build(FILE *out, Directive *directive, int pass_no, int bash_build) {
if (bash_build) {
fputs("build ", out);
@ -486,7 +568,8 @@ void generate_preseed_jump(int id) {
FILE *out = fopen("/preseed-jump.kaem", "w");
fputs("set -ex\n", out);
fputs("PATH=/usr/bin\n", out);
fputs("bash /steps/", out);
fputs("bash ", out);
write_steps_prefix(out);
fputs(int2str(id, 10, 0), out);
fputs(".sh\n", out);
fclose(out);
@ -503,8 +586,14 @@ void generate(Directive *directives) {
int counter = 0;
/* Initially, we use kaem, not bash. */
/*
* Default /steps manifests start in kaem.
* Alternative step roots (for example /steps-guix) start in bash.
*/
int bash_build = 0;
if (strcmp(steps_root, "/steps") != 0) {
bash_build = 2;
}
FILE *out = start_script(counter, bash_build);
counter += 1;
@ -576,6 +665,7 @@ void generate(Directive *directives) {
exit(1);
}
fputs("#!/bin/bash\n", out);
output_resume_network_init(out);
} else {
out = fopen(filename, "w");
if (out == NULL) {
@ -584,7 +674,7 @@ void generate(Directive *directives) {
}
fputs("set -ex\n", out);
}
output_call_script(out, "", int2str(counter, 10, 0), bash_build, 0);
output_init_call_script(out, int2str(counter, 10, 0), bash_build);
fclose(out);
out = start_script(counter, bash_build);
counter += 1;
@ -598,8 +688,8 @@ void generate(Directive *directives) {
}
void main(int argc, char **argv) {
if (argc != 2) {
fputs("Usage: script-generator <script>\n", stderr);
if (argc != 2 && argc != 3) {
fputs("Usage: script-generator <script> [config-root]\n", stderr);
exit(1);
}
@ -608,12 +698,18 @@ void main(int argc, char **argv) {
fputs("Error opening input file\n", stderr);
exit(1);
}
steps_root = dirname_from_path(argv[1]);
config_root = steps_root;
if (argc == 3) {
config_root = argv[2];
}
Directive *directives = tokenizer(in);
fclose(in);
load_config();
directives = interpreter(directives);
generate(directives);
FILE *config = fopen("/steps/bootstrap.cfg", "w");
char *config_file = config_path("bootstrap.cfg");
FILE *config = fopen(config_file, "w");
output_config(config);
fclose(config);
}

View file

@ -1 +1 @@
fbec25d987c89e66fd7dd89d780be0629bab84f78ebf1878fd2528fca9e46c45 script-generator
3c136337e679e39407701dee9d65402c8b538ae786af850b8430370cb07df25d script-generator

View file

@ -0,0 +1,38 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Build argp-standalone for the kernel toolchain sysroot. This is used by
# later kernel-side dependencies (for example elfutils).
: "${KERNEL_SYSROOT:=/kernel-toolchain}"
src_prepare() {
default
autoreconf -fi
}
src_configure() {
mkdir build
cd build
# argp-standalone's testsuite expects argp.h from source root even when
# building out-of-tree.
CPPFLAGS="-I${PWD}/.." \
CC=gcc \
AR=ar \
RANLIB=ranlib \
../configure \
--prefix="${KERNEL_SYSROOT}" \
--libdir="${KERNEL_SYSROOT}/lib"
}
src_compile() {
default_src_compile
}
src_install() {
mkdir -p "${DESTDIR}${KERNEL_SYSROOT}/include"
mkdir -p "${DESTDIR}${KERNEL_SYSROOT}/lib"
# noinst_HEADERS/noinst_LIBRARIES: install artifacts explicitly.
install -m644 ../argp.h "${DESTDIR}${KERNEL_SYSROOT}/include/argp.h"
install -m644 libargp.a "${DESTDIR}${KERNEL_SYSROOT}/lib/libargp.a"
}

View file

@ -0,0 +1 @@
g https://github.com/ericonr/argp-standalone.git~743004c68e7358fb9cd4737450f2d9a34076aadf https://github.com/ericonr/argp-standalone/archive/743004c68e7358fb9cd4737450f2d9a34076aadf.tar.gz a79f2a6fd6c68a423063ee53bc4afb6a5633a296a25764e5cc368c1e323a0997 argp-standalone-743004c6.tar.gz

View file

@ -0,0 +1,54 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
}
src_configure() {
local host_triplet pkg_config_path
host_triplet="$(gcc -dumpmachine)"
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG_PATH="${pkg_config_path}" \
PKG_CONFIG_LIBDIR="${pkg_config_path}" \
DBUS_CFLAGS="$(pkg-config --cflags dbus-1)" \
DBUS_LIBS="$(pkg-config --libs dbus-1)" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--includedir="${PREFIX}/include" \
--host="${host_triplet}" \
--build="${host_triplet}" \
--with-distro=lfs \
--disable-stack-protector \
--enable-gdbm \
--disable-dbm \
--enable-static \
--enable-shared \
--disable-glib \
--disable-gobject \
--disable-gtk \
--disable-gtk3 \
--disable-qt3 \
--disable-qt4 \
--disable-qt5 \
--disable-python \
--disable-python-dbus \
--disable-pygobject \
--disable-mono \
--disable-monodoc \
--disable-autoipd \
--disable-doxygen-doc \
--disable-manpages \
--disable-xmltoman \
--disable-tests
}
src_compile() {
default_src_compile
}
src_install() {
default_src_install
}

View file

@ -0,0 +1 @@
f https://github.com/avahi/avahi/releases/download/v0.8/avahi-0.8.tar.gz 060309d7a333d38d951bc27598c677af1796934dbd98e1024e7ad8de798fedda avahi-0.8.tar.gz

View file

@ -0,0 +1,29 @@
# SPDX-License-Identifier: GPL-3.0-or-later
SEED_PREFIX="/bootstrap-seeds/bash-5.3-1"
src_prepare() {
default
}
src_configure() {
./configure \
--prefix="${SEED_PREFIX}" \
--without-bash-malloc \
--disable-nls \
--enable-static-link \
--build="${TARGET}" \
bash_cv_dev_stdin=absent \
bash_cv_dev_fd=whacky
}
src_compile() {
make -j1
}
src_install() {
# Keep seed output for bootstrap artifact generation.
install -D -m 0755 bash "${DESTDIR}${SEED_PREFIX}/bin/bash"
# same as steps/bash
install -D -m 0755 bash "${DESTDIR}/usr/bin/bash"
}

View file

@ -0,0 +1 @@
f https://ftp.gnu.org/gnu/bash/bash-5.3.tar.gz 0d5cd86965f869a26cf64f4b71be7b96f90a3ba8b3d74e27e8e9d9d5550f31ba

View file

@ -0,0 +1,178 @@
# SPDX-FileCopyrightText: 2022 Dor Askayo <dor.askayo@gmail.com>
# SPDX-FileCopyrightText: 2021 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-FileCopyrightText: 2021 Paul Dersey <pdersey@gmail.com>
# SPDX-FileCopyrightText: 2023,2025 Samuel Tyler <samuel@samuelt.me>
#
# SPDX-License-Identifier: GPL-3.0-or-later
# This binutils build targets the 64-bit kernel toolchain.
: "${KERNEL_TARGET:=x86_64-unknown-linux-musl}"
: "${KERNEL_SYSROOT:=/kernel-toolchain}"
src_prepare() {
default
# Remove unused generated files
rm etc/Makefile.in etc/configure
# Remove unused parts
rm -r zlib
# intl/ Makefile is a bit broken because of new gettext
sed -i 's/@USE_INCLUDED_LIBINTL@/no/' intl/Makefile.in
# There is no way to add -all-static to libtool LDFLAGS (such a thing doesn't exist)
# -all-static is required for static binaries with libtool
sed -i 's:\(--mode=link $(CCLD)\):\1 -all-static:' {bfd,binutils,opcodes,ld,libctf,gas,gprof}/Makefile.in
# Rebuild bison files
touch -- */*.y
rm binutils/arparse.c binutils/arparse.h binutils/defparse.c \
binutils/defparse.h binutils/mcparse.c binutils/mcparse.h \
binutils/rcparse.c binutils/rcparse.h binutils/sysinfo.c \
binutils/sysinfo.h gas/config/bfin-parse.c gas/config/bfin-parse.h \
gas/config/loongarch-parse.c gas/config/loongarch-parse.h \
gas/config/m68k-parse.c gas/config/rl78-parse.c \
gas/config/rl78-parse.h gas/config/rx-parse.c gas/config/rx-parse.h \
gas/itbl-parse.c gas/itbl-parse.h gold/yyscript.c gold/yyscript.h \
intl/plural.c ld/deffilep.c ld/deffilep.h ld/ldgram.c ld/ldgram.h
# Rebuild flex generated files
touch -- */*.l */*/*.l
rm binutils/arlex.c binutils/deflex.c binutils/syslex.c \
gas/config/bfin-lex.c gas/config/loongarch-lex.c gas/itbl-lex.c \
ld/ldlex.c
# Remove prebuilt docs
find . -type f -name '*.info*' \
-not -wholename './binutils/sysroff.info' \
-delete
find . -type f \( -name '*.1' -or -name '*.man' \) -delete
rm libiberty/functions.texi
# Remove gettext translation files
find . -type f -name '*.gmo' -delete
# Remove pregenerated opcodes files
rm opcodes/i386-init.h opcodes/i386-tbl.h opcodes/i386-mnem.h \
opcodes/ia64-asmtab.c opcodes/z8k-opc.h opcodes/aarch64-asm-2.c \
opcodes/aarch64-opc-2.c opcodes/aarch64-dis-2.c \
opcodes/msp430-decode.c opcodes/rl78-decode.c opcodes/rx-decode.c
rm $(grep -l 'MACHINE GENERATED' opcodes/*.c opcodes/*.h)
# Various other blobs/generated headers
rm ld/emultempl/*.o_c
rm gprof/bsd_callg_bl.c gprof/flat_bl.c gprof/fsf_callg_bl.c
rm bfd/libcoff.h bfd/libbfd.h bfd/go32stub.h bfd/bfd-in2.h
# Generated testsuite stuff (xz-style attack)
rm libsframe/testsuite/libsframe.decode/DATA* \
ld/testsuite/ld-x86-64/*.obj.bz2 ld/testsuite/ld-sh/arch/*.s \
ld/testsuite/ld-sh/arch/arch_expected.txt \
ld/testsuite/ld-i386/pr27193a.o.bz2 \
gas/testsuite/gas/xstormy16/allinsn.sh \
gas/testsuite/gas/tic4x/opcodes.s gas/testsuite/gas/sh/arch/*.s \
gas/testsuite/gas/sh/arch/arch_expected.txt \
binutils/testsuite/binutils-all/x86-64/pr22451.o.bz2 \
binutils/testsuite/binutils-all/x86-64/pr26808.dwp.bz2 \
binutils/testsuite/binutils-all/x86-64/pr27708.exe.bz2 \
binutils/testsuite/binutils-all/nfp/*.nffw \
binutils/testsuite/binutils-all/pr26112.o.bz2 \
binutils/testsuite/binutils-all/pr26160.dwp.bz2
# Regenerate crc table in libiberty/crc32.c
cd libiberty
sed -n '/^ #include <stdio.h>/,/^ \}$/p' crc32.c > crcgen.c
gcc -o crcgen crcgen.c
sed '/crc_v3\.txt/{n; q}' crc32.c > crc32.c.new
./crcgen >> crc32.c.new
sed '1,/^};$/d' crc32.c >> crc32.c.new
mv crc32.c.new crc32.c
cd ..
# bfd-in2.h is required to run autoreconf, but we don't have it yet
cd bfd
cp configure.ac configure.ac.bak
sed -i "s/bfd-in3.h:bfd-in2.h //" configure.ac
AUTOPOINT=true ACLOCAL=aclocal-1.15 AUTOMAKE=automake-1.15 autoreconf-2.69 -fi
./configure
make headers
mv configure.ac.bak configure.ac
make distclean
cd ..
# Regenerate top-level (autogen + autotools)
autogen Makefile.def
ACLOCAL=aclocal-1.15 autoreconf-2.69 -fi
# Regenerate autoconf
for dir in bfd binutils gas gold gprof intl ld libctf libiberty libsframe opcodes; do
cd $dir
ACLOCAL=aclocal-1.15 AUTOMAKE=automake-1.15 autoreconf-2.69 -fi
cd ..
done
cd gprofng
# there is no libtool in gprofng, and libtoolize fails
LIBTOOLIZE=true ACLOCAL=aclocal-1.15 AUTOMAKE=automake-1.15 autoreconf-2.69 -fi
cd ..
# Rebuild dependencies in libiberty/Makefile.in
cd libiberty
./configure --enable-maintainer-mode
make maint-deps
make distclean
cd ..
# Regenerate MeP sections
./bfd/mep-relocs.pl
}
src_configure() {
mkdir build
cd build
LDFLAGS="-static" \
../configure \
--prefix="${KERNEL_SYSROOT}" \
--libdir="${KERNEL_SYSROOT}/lib" \
--build="${TARGET}" \
--host="${TARGET}" \
--target="${KERNEL_TARGET}" \
--enable-static \
--disable-nls \
--disable-multilib \
--disable-plugins \
--disable-gprofng \
--enable-threads \
--enable-64-bit-bfd \
--enable-gold \
--enable-ld=default \
--enable-install-libiberty \
--enable-deterministic-archives \
--enable-targets=x86_64-elf,i386-elf \
--with-system-zlib \
--program-prefix="" \
--with-sysroot="${KERNEL_SYSROOT}" \
--srcdir=..
}
src_compile() {
default_src_compile
}
src_install() {
make "${MAKEJOBS}" install \
DESTDIR="${DESTDIR}" \
prefix="${KERNEL_SYSROOT}" \
libdir="${KERNEL_SYSROOT}/lib"
# Create triplet symlinks
pushd "${DESTDIR}${KERNEL_SYSROOT}/bin"
for f in *; do
ln -sf "${KERNEL_SYSROOT}/bin/${f}" "${KERNEL_TARGET}-${f}"
done
popd
# FIXME: Binutils' manpages dates are not reproducible
rm -rf "${DESTDIR}${KERNEL_SYSROOT}/share/man"
}

View file

@ -0,0 +1,17 @@
SPDX-FileCopyrightText: 2023 Samuel Tyler <samuel@samuelt.me>
SPDX-License-Identifier: GPL-3.0-or-later
In new gettext external is required for AM_GNU_GETTEXT.
--- binutils-2.41/intl/configure.ac 2023-02-07 18:57:56.350832016 +1100
+++ binutils-2.41/intl/configure.ac 2023-02-07 18:58:07.310054484 +1100
@@ -4,7 +4,7 @@
AC_CONFIG_HEADER(config.h)
AC_CONFIG_MACRO_DIR(../config)
AM_GNU_GETTEXT_VERSION(0.12.1)
-AM_GNU_GETTEXT([], [need-ngettext])
+AM_GNU_GETTEXT([external], [need-ngettext])
# This replaces the extensive use of DEFS in the original Makefile.in.
AC_DEFINE(IN_LIBINTL, 1, [Define because this is libintl.])

View file

@ -0,0 +1,26 @@
SPDX-FileCopyrightText: 2023 Samuel Tyler <samuel@samuelt.me>
SPDX-License-Identifier: GPL-3.0-or-later
Ensure functions.texi dependencies are satisfied.
--- binutils-2.41/libiberty/Makefile.in 2023-12-08 15:18:57.985791235 +1100
+++ binutils-2.41/libiberty/Makefile.in 2023-12-08 15:19:15.391252344 +1100
@@ -368,12 +368,12 @@
libiberty.html : $(srcdir)/libiberty.texi $(TEXISRC)
$(MAKEINFO) --no-split --html -I$(srcdir) -o $@ $<
-@MAINT@$(srcdir)/functions.texi : stamp-functions
-@MAINT@ @true
+$(srcdir)/functions.texi : stamp-functions
+ @true
-@MAINT@stamp-functions : $(CFILES:%=$(srcdir)/%) $(TEXIFILES:%=$(srcdir)/%) $(srcdir)/gather-docs Makefile
-@MAINT@@HAVE_PERL@ $(PERL) $(srcdir)/gather-docs $(srcdir) $(srcdir)/functions.texi $(CFILES) $(TEXIFILES)
-@MAINT@ echo stamp > stamp-functions
+stamp-functions : $(CFILES:%=$(srcdir)/%) $(TEXIFILES:%=$(srcdir)/%) $(srcdir)/gather-docs Makefile
+@HAVE_PERL@ $(PERL) $(srcdir)/gather-docs $(srcdir) $(srcdir)/functions.texi $(CFILES) $(TEXIFILES)
+ echo stamp > stamp-functions
INSTALL_DEST = @INSTALL_DEST@
install: install_to_$(INSTALL_DEST) install-subdir

View file

@ -0,0 +1,18 @@
SPDX-FileCopyrightText: 2022 Dor Askayo <dor.askayo@gmail.com>
SPDX-FileCopyrightText: 2023 Samuel Tyler <samuel@samuelt.me>
SPDX-License-Identifier: GPL-3.0-or-later
Ensure i386-tbl.h dependencies are satisfied.
--- binutils-2.41/opcodes/Makefile.am 2023-12-08 17:13:05.669136957 +1100
+++ binutils-2.41/opcodes/Makefile.am 2023-12-08 17:13:18.410480026 +1100
@@ -540,7 +540,7 @@
# i386-gen will generate all headers in one go. Use a pattern rule to properly
# express this, with the inner dash ('-') arbitrarily chosen to be the stem.
$(srcdir)/i386%tbl.h $(srcdir)/i386%init.h $(srcdir)/i386%mnem.h: \
- @MAINT@ i386-gen$(EXEEXT_FOR_BUILD) i386-opc.tbl i386-reg.tbl i386-opc.h
+ i386-gen$(EXEEXT_FOR_BUILD) i386-opc.tbl i386-reg.tbl i386-opc.h
$(AM_V_GEN)$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) - \
< $(srcdir)/i386-opc.tbl \
| ./i386-gen$(EXEEXT_FOR_BUILD) --srcdir $(srcdir)

View file

@ -0,0 +1 @@
f https://mirrors.kernel.org/gnu/binutils/binutils-2.41.tar.xz ae9a5789e23459e59606e6714723f2d3ffc31c03174191ef0d015bdf06007450

View file

@ -0,0 +1,22 @@
# SPDX-License-Identifier: GPL-3.0-or-later
SEED_PREFIX="/bootstrap-seeds/bzip2-1.0.6"
SYSTEM_PREFIX="/usr"
src_configure() {
:
}
src_compile() {
make "${MAKEJOBS}" CFLAGS="-O2" LDFLAGS="-static"
}
src_install() {
# Upstream bzip2 Makefile does not support DESTDIR, so PREFIX must include it.
make CFLAGS="-O2" LDFLAGS="-static" PREFIX="${DESTDIR}${SYSTEM_PREFIX}" install
make CFLAGS="-O2" LDFLAGS="-static" PREFIX="${DESTDIR}${SEED_PREFIX}" install
# Fail early if either installed binary is not executable in this environment.
"${DESTDIR}${SYSTEM_PREFIX}/bin/bzip2" --help >/dev/null
"${DESTDIR}${SEED_PREFIX}/bin/bzip2" --help >/dev/null
}

View file

@ -0,0 +1 @@
f https://sourceware.org/pub/bzip2/bzip2-1.0.6.tar.gz a2848f34fcd5d6cf47def00461fcb528a0484d8edef8208d6d2e2909dc61d9cd

View file

@ -0,0 +1,24 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
}
src_configure() {
./bootstrap \
--prefix="${PREFIX}" \
--parallel="${JOBS}" \
--no-qt-gui \
-- \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_USE_OPENSSL=ON \
-DCMAKE_INSTALL_LIBDIR="${LIBDIR}"
}
src_compile() {
make "${MAKEJOBS}"
}
src_install() {
make install DESTDIR="${DESTDIR}"
}

View file

@ -0,0 +1 @@
f https://github.com/Kitware/CMake/releases/download/v4.2.3/cmake-4.2.3.tar.gz 7efaccde8c5a6b2968bad6ce0fe60e19b6e10701a12fce948c2bf79bac8a11e9

View file

@ -0,0 +1,23 @@
# SPDX-License-Identifier: GPL-3.0-or-later
SEED_PREFIX="/bootstrap-seeds/coreutils-8.30"
src_configure() {
FORCE_UNSAFE_CONFIGURE=1 ./configure \
--prefix="${SEED_PREFIX}" \
--disable-nls \
--disable-silent-rules \
--enable-no-install-program=stdbuf,libstdbuf.so \
CFLAGS="-Os -g0" \
LDFLAGS="-static -pthread" \
gl_cv_func_getcwd_path_max="no, but it is partly working" \
gl_cv_prog_perl="no"
}
src_compile() {
make "${MAKEJOBS}" MAKEINFO=true GPERF=true
}
src_install() {
make DESTDIR="${DESTDIR}" MAKEINFO=true install
}

View file

@ -0,0 +1 @@
f https://mirrors.kernel.org/gnu/coreutils/coreutils-8.30.tar.xz e831b3a86091496cdba720411f9748de81507798f6130adeaef872d206e1b057

View file

@ -0,0 +1,41 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
}
src_configure() {
local cmake_libdir
cmake_libdir="${LIBDIR#${PREFIX}/}"
if [ "${cmake_libdir}" = "${LIBDIR}" ]; then
cmake_libdir="${LIBDIR#/}"
fi
mkdir -p build
cd build
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="${PREFIX}" \
-DCMAKE_INSTALL_LIBDIR="${cmake_libdir}" \
-DCMAKE_INSTALL_INCLUDEDIR="include" \
-DCMAKE_PREFIX_PATH="${PREFIX}" \
-DCMAKE_INCLUDE_PATH="${PREFIX}/include" \
-DCMAKE_LIBRARY_PATH="${LIBDIR}:${PREFIX}/lib" \
-DBUILD_SHARED_LIBS=ON \
-DDBUS_BUILD_TESTS=OFF \
-DDBUS_ENABLE_XML_DOCS=OFF \
-DDBUS_ENABLE_DOXYGEN_DOCS=OFF \
-DDBUS_BUILD_X11=OFF \
-DDBUS_WITH_GLIB=OFF \
-DENABLE_SYSTEMD=OFF \
-DENABLE_USER_SESSION=OFF
}
src_compile() {
make "${MAKEJOBS}"
}
src_install() {
make install DESTDIR="${DESTDIR}"
}

View file

@ -0,0 +1 @@
f https://dbus.freedesktop.org/releases/dbus/dbus-1.16.2.tar.xz 0ba2a1a4b16afe7bceb2c07e9ce99a8c2c3508e5dec290dbb643384bd6beb7e2 dbus-1.16.2.tar.xz

View file

@ -0,0 +1,53 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Build elfutils against kernel-toolchain dependencies.
: "${KERNEL_SYSROOT:=/kernel-toolchain}"
src_prepare() {
default
# Regenerate autotools outputs from source metadata.
AUTOMAKE=automake-1.15 \
ACLOCAL=aclocal-1.15 \
AUTOCONF=autoconf-2.69 \
AUTOHEADER=autoheader-2.69 \
autoreconf-2.69 -fi
}
src_configure() {
mkdir build
cd build
PKG_CONFIG_PATH="${KERNEL_SYSROOT}/lib/pkgconfig:${KERNEL_SYSROOT}/share/pkgconfig" \
PKG_CONFIG_LIBDIR="${KERNEL_SYSROOT}/lib/pkgconfig:${KERNEL_SYSROOT}/share/pkgconfig" \
CPPFLAGS="-I${KERNEL_SYSROOT}/include" \
CFLAGS="-Wno-error=unused-but-set-variable" \
LDFLAGS="-L${KERNEL_SYSROOT}/lib" \
CC=gcc \
AR=ar \
RANLIB=ranlib \
../configure \
--prefix="${KERNEL_SYSROOT}" \
--libdir="${KERNEL_SYSROOT}/lib" \
--includedir="${KERNEL_SYSROOT}/include" \
--build="${TARGET}" \
--host="${TARGET}" \
--disable-textrelcheck \
--disable-debuginfod \
--disable-libdebuginfod
}
src_compile() {
LD_LIBRARY_PATH="${KERNEL_SYSROOT}/lib:${LD_LIBRARY_PATH}" \
make "${MAKEJOBS}" \
LDFLAGS="-L${KERNEL_SYSROOT}/lib -Wl,-rpath-link,${KERNEL_SYSROOT}/lib" \
LIBS="-lfts -lobstack -largp"
}
src_install() {
make "${MAKEJOBS}" install \
DESTDIR="${DESTDIR}" \
prefix="${KERNEL_SYSROOT}" \
libdir="${KERNEL_SYSROOT}/lib" \
includedir="${KERNEL_SYSROOT}/include"
}

View file

@ -0,0 +1,39 @@
--- elfutils-0.194/src/strip.c
+++ elfutils-0.194/src/strip.c
@@ -26,6 +26,10 @@
#include <endian.h>
#include <fcntl.h>
#include <fnmatch.h>
+#ifndef FNM_EXTMATCH
+#define FNM_EXTMATCH 0
+#endif
+
#include <gelf.h>
#include <libelf.h>
#include <locale.h>
--- elfutils-0.194/src/elfcompress.c
+++ elfutils-0.194/src/elfcompress.c
@@ -26,6 +26,10 @@
#include <locale.h>
#include <fcntl.h>
#include <fnmatch.h>
+#ifndef FNM_EXTMATCH
+#define FNM_EXTMATCH 0
+#endif
+
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
--- elfutils-0.194/debuginfod/debuginfod-client.c
+++ elfutils-0.194/debuginfod/debuginfod-client.c
@@ -106,6 +106,10 @@
#include <stdio.h>
#include <dwarf.h>
#include <fnmatch.h>
+#ifndef FNM_EXTMATCH
+#define FNM_EXTMATCH 0
+#endif
+
#include <json-c/json.h>
#include <stdlib.h>
#include <unistd.h>

View file

@ -0,0 +1 @@
f https://sourceware.org/elfutils/ftp/0.194/elfutils-0.194.tar.bz2 09e2ff033d39baa8b388a2d7fbc5390bfde99ae3b7c67c7daaf7433fbcf0f01e

View file

@ -0,0 +1,29 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
}
src_configure() {
local host_triplet
host_triplet="$(gcc -dumpmachine)"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG_PATH="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--includedir="${PREFIX}/include" \
--host="${host_triplet}" \
--build="${host_triplet}" \
--enable-static \
--enable-shared
}
src_compile() {
default_src_compile
}
src_install() {
default_src_install
}

View file

@ -0,0 +1 @@
f https://github.com/libexpat/libexpat/releases/download/R_2_7_4/expat-2.7.4.tar.gz 461ecc8aa98ab1a68c2db788175665d1a4db640dc05bf0e289b6ea17122144ec expat-2.7.4.tar.gz

View file

@ -0,0 +1,22 @@
# SPDX-License-Identifier: GPL-3.0-or-later
SEED_PREFIX="/bootstrap-seeds/gawk-4.2.1"
src_prepare() {
default
}
src_configure() {
CFLAGS="-O2" LDFLAGS="-static" ./configure \
--prefix="${SEED_PREFIX}" \
--disable-nls \
--disable-shared
}
src_compile() {
default_src_compile
}
src_install() {
make DESTDIR="${DESTDIR}" install
}

View file

@ -0,0 +1,26 @@
SPDX-License-Identifier: GPL-3.0-or-later
Fix legacy getopt declarations that conflict with modern libc headers.
--- gawk-4.2.1/support/getopt.c
+++ gawk-4.2.1/support/getopt.c
@@ -152,7 +152,7 @@
whose names are inconsistent. */
#ifndef getenv
-extern char *getenv ();
+extern char *getenv (const char *);
#endif
#endif /* not __GNU_LIBRARY__ */
--- gawk-4.2.1/support/getopt.h
+++ gawk-4.2.1/support/getopt.h
@@ -181,7 +181,7 @@
# endif
# endif
#else /* not __GNU_LIBRARY__ */
-extern int getopt ();
+extern int getopt (int, char *const *, const char *);
#endif /* __GNU_LIBRARY__ */
#ifndef __need_getopt

View file

@ -0,0 +1,15 @@
SPDX-License-Identifier: GPL-3.0-or-later
Fix MPFR callback pointer prototype for modern compilers.
--- gawk-4.2.1/mpfr.c
+++ gawk-4.2.1/mpfr.c
@@ -689,7 +689,7 @@
static inline NODE *
do_mpfr_func(const char *name,
- int (*mpfr_func)(), /* putting argument types just gets the compiler confused */
+ int (*mpfr_func)(mpfr_ptr, mpfr_srcptr, mpfr_rnd_t),
int nargs)
{
NODE *t1, *res;

View file

@ -0,0 +1,53 @@
SPDX-License-Identifier: GPL-3.0-or-later
Fix read_func prototype to use a modern typed function pointer.
--- gawk-4.2.1/gawkapi.h
+++ gawk-4.2.1/gawkapi.h
@@ -190,7 +190,7 @@
* No argument prototype on read_func to allow for older systems
* whose headers are not up to date.
*/
- ssize_t (*read_func)();
+ ssize_t (*read_func)(int, void *, size_t);
/*
* The close_func is called to allow the parser to free private data.
--- gawk-4.2.1/io.c
+++ gawk-4.2.1/io.c
@@ -310,7 +310,7 @@
static NODE *in_PROCINFO(const char *pidx1, const char *pidx2, NODE **full_idx);
static long get_read_timeout(IOBUF *iop);
-static ssize_t read_with_timeout(int fd, char *buf, size_t size);
+static ssize_t read_with_timeout(int fd, void *buf, size_t size);
static bool read_can_timeout = false;
static long read_timeout;
@@ -3340,7 +3340,7 @@
iop->public.fd = fd;
iop->public.name = name;
- iop->public.read_func = ( ssize_t(*)() ) read;
+ iop->public.read_func = (ssize_t (*)(int, void *, size_t)) read;
iop->valid = false;
iop->errcode = errno_val;
@@ -4318,7 +4318,7 @@
tmout = read_default_timeout; /* initialized from env. variable in init_io() */
/* overwrite read routine only if an extension has not done so */
- if ((iop->public.read_func == ( ssize_t(*)() ) read) && tmout > 0)
+ if ((iop->public.read_func == (ssize_t (*)(int, void *, size_t)) read) && tmout > 0)
iop->public.read_func = read_with_timeout;
return tmout;
@@ -4330,7 +4330,7 @@
*/
static ssize_t
-read_with_timeout(int fd, char *buf, size_t size)
+read_with_timeout(int fd, void *buf, size_t size)
{
#if ! defined(VMS)
fd_set readfds;

View file

@ -0,0 +1,64 @@
SPDX-License-Identifier: GPL-3.0-or-later
Use an explicit function pointer prototype for readfunc so gawk 4.2.1
builds with modern C compilers where an empty parameter list is treated
as a no-argument function.
--- gawk-4.2.1/awkgram.y
+++ gawk-4.2.1/awkgram.y
@@ -2870,22 +2870,17 @@
struct stat sbuf;
/*
- * No argument prototype on readfunc on purpose,
- * avoids problems with some ancient systems where
- * the types of arguments to read() aren't up to date.
+ * Use an explicit prototype so modern C compilers (C23 and newer)
+ * do not treat an empty parameter list as a no-argument function.
*/
- static ssize_t (*readfunc)() = 0;
+ static ssize_t (*readfunc)(int, void *, size_t) = NULL;
if (readfunc == NULL) {
char *cp = getenv("AWKREADFUNC");
/* If necessary, one day, test value for different functions. */
if (cp == NULL)
- /*
- * cast is to remove warnings on systems with
- * different return types for read.
- */
- readfunc = ( ssize_t(*)() ) read;
+ readfunc = read;
else
readfunc = read_one_line;
}
--- gawk-4.2.1/awkgram.c
+++ gawk-4.2.1/awkgram.c
@@ -5290,22 +5290,17 @@
struct stat sbuf;
/*
- * No argument prototype on readfunc on purpose,
- * avoids problems with some ancient systems where
- * the types of arguments to read() aren't up to date.
+ * Use an explicit prototype so modern C compilers (C23 and newer)
+ * do not treat an empty parameter list as a no-argument function.
*/
- static ssize_t (*readfunc)() = 0;
+ static ssize_t (*readfunc)(int, void *, size_t) = NULL;
if (readfunc == NULL) {
char *cp = getenv("AWKREADFUNC");
/* If necessary, one day, test value for different functions. */
if (cp == NULL)
- /*
- * cast is to remove warnings on systems with
- * different return types for read.
- */
- readfunc = ( ssize_t(*)() ) read;
+ readfunc = read;
else
readfunc = read_one_line;
}

View file

@ -0,0 +1,14 @@
SPDX-License-Identifier: GPL-3.0-or-later
Drop obsolete K&R-style strtod declaration in node.c.
--- gawk-4.2.1/node.c
+++ gawk-4.2.1/node.c
@@ -62,7 +62,6 @@ r_force_number(NODE *n)
char *cpend;
char save;
char *ptr;
- extern double strtod();
if ((n->flags & NUMCUR) != 0)
return n;

View file

@ -0,0 +1 @@
f https://mirrors.kernel.org/gnu/gawk/gawk-4.2.1.tar.xz d1119785e746d46a8209d28b2de404a57f983aa48670f4e225531d3bdc175551

View file

@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2021 Andrius Štikonas <andrius@stikonas.eu>
#
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
autoreconf-2.71 -fi
}
src_configure() {
# CFLAGS needed on musl
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--disable-shared \
CFLAGS='-D_GNU_SOURCE -DNO_GETCONTEXT -DSEARCH_FOR_DATA_START -DUSE_MMAP -DHAVE_DL_ITERATE_PHDR'
}

View file

@ -0,0 +1 @@
f https://github.com/bdwgc/bdwgc/releases/download/v8.2.12/gc-8.2.12.tar.gz 42e5194ad06ab6ffb806c83eb99c03462b495d979cda782f3c72c08af833cd4e

View file

@ -0,0 +1,59 @@
// SPDX-FileCopyrightText: 2007, 2009 Free Software Foundation, Inc.
// SPDX-License-Identifier: GPL-3.0-or-later
/* Conversion lookup tables for the decNumber C Library.
Copyright (C) 2007, 2009 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/* ------------------------------------------------------------------------ */
/* Binary Coded Decimal and Densely Packed Decimal conversion lookup tables */
/* [Automatically generated -- do not edit. 2008.06.21] */
/* ------------------------------------------------------------------------ */
/* For details, see DPDecimal.html on the General Decimal Arithmetic page. */
#include "decDPDSymbols.h"
/* This include file defines several DPD and BCD conversion tables: */
/* */
/* uint16_t BCD2DPD[2458]; -- BCD -> DPD (0x999 => 2457) */
/* uint16_t BIN2DPD[1000]; -- Bin -> DPD (999 => 2457) */
/* uint8_t BIN2CHAR[4001]; -- Bin -> CHAR (999 => '\3' '9' '9' '9') */
/* uint8_t BIN2BCD8[4000]; -- Bin -> bytes (999 => 9 9 9 3) */
/* uint16_t DPD2BCD[1024]; -- DPD -> BCD (0x3FF => 0x999) */
/* uint16_t DPD2BIN[1024]; -- DPD -> BIN (0x3FF => 999) */
/* uint32_t DPD2BINK[1024]; -- DPD -> BIN * 1000 (0x3FF => 999000) */
/* uint32_t DPD2BINM[1024]; -- DPD -> BIN * 1E+6 (0x3FF => 999000000) */
/* uint8_t DPD2BCD8[4096]; -- DPD -> bytes (x3FF => 9 9 9 3) */
/* */
/* In all cases the result (10 bits or 12 bits, or binary) is right-aligned */
/* in the table entry. BIN2CHAR entries are a single byte length (0 for */
/* value 0) followed by three digit characters; a trailing terminator is */
/* included to allow 4-char moves always. BIN2BCD8 and DPD2BCD8 entries */
/* are similar with the three BCD8 digits followed by a one-byte length */
/* (again, length=0 for value 0). */
/* */
/* To use a table, its name, prefixed with DEC_, must be defined with a */
/* value of 1 before this header file is included. For example: */
/* #define DEC_BCD2DPD 1 */
/* This mechanism allows software to only include tables that are needed. */
/* ------------------------------------------------------------------------ */

View file

@ -0,0 +1,228 @@
// SPDX-FileCopyrightText: 2025 Samuel Tyler <samuel@samuelt.me>
// SPDX-License-Identifier: GPL-3.0-or-later
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
/*
* Creates decDPD.h.
* Based upon the algorithm given on;
* https://web.archive.org/web/20080308073422/http://www2.hursley.ibm.com/decimal/DPDecimal.html
* originally written in the (obsolete) language Rexx.
*
* Is not bit-for-bit identical to the original decDPD.h, as we don't bother
* to follow the same formatting.
*
* The original Rexx code follows;
*/
// /* dpdGenerate.rex -- display Densely Packed Decimal table */
// /* mfc 2000.10.03; Rexx version with new equations 2007.02.01 */
//
// do i=0 to 999
// bcd=right(i, 3, 0) -- make three-digit hexadecimal string
// bit10=bcd2dpd(x2b(bcd)) -- compress
// bit12=dpd2bcd(bit10) -- expand
// say bcd bit10 bit12 -- display
// end i
// exit
//
// /* bcd2dpd -- Compress BCD to Densely Packed Decimal
// argument is a string of 12 characters, each 0 or 1, being 3 digits
// of 4 bits, each being a valid BCD digit (0000-1001)
// (for example, 923 is 100100100011)
// result is a string of 10 characters, each 0 or 1
// (for the example, this would be 1001010011)
// */
// bcd2dpd: procedure
// -- assign each bit to a variable, named as in the description
// parse arg a +1 b +1 c +1 d +1 e +1 f +1 g +1 h +1 i +1 j +1 k +1 m +1
//
// -- derive the result bits, using boolean expressions only
// -- [the operators are: '&'=AND, '|'=OR, '\'=NOT.]
// p=b | (a & j) | (a & f & i)
// q=c | (a & k) | (a & g & i)
// r=d
// s=(f & (\a | \i)) | (\a & e & j) | (e & i)
// t=g | (\a & e &k;) | (a & i)
// u=h
// v=a | e | i
// w=a | (e & i) | (\e & j)
// x=e | (a & i) | (\a & k)
// y=m
// -- concatenate the bits and return
// return p||q||r||s||t||u||v||w||x||y
//
// /* dpd2bcd -- Expand Densely Packed Decimal to BCD
// argument is a string of 10 characters, each 0 or 1; all 1024
// possibilities are accepted (non-canonicals -> 999)
// (for example, 1001010011)
// result is a string of 12 characters, each 0 or 1
// (for the example, 100100100011 -- 923)
// */
// dpd2bcd: procedure
// -- assign each bit to a variable, named as in the description
// parse arg p +1 q +1 r +1 s +1 t +1 u +1 v +1 w +1 x +1 y +1
//
// -- derive the result bits, using boolean expressions only
// a= (v & w) & (\s | t | \x)
// b=p & (\v | \w | (s & \t & x))
// c=q & (\v | \w | (s & \t & x))
// d=r
// e=v & ((\w & x) | (\t & x) | (s & x))
// f=(s & (\v | \x)) | (p & \s & t & v & w & x)
// g=(t & (\v | \x)) | (q & \s & t & w)
// h=u
// i=v & ((\w & \x) | (w & x & (s | t)))
// j=(\v & w) | (s & v & \w & x) | (p & w & (\x | (\s & \t)))
// k=(\v & x) | (t & \w & x) | (q & v & w & (\x | (\s & \t)))
// m=y
// -- concatenate the bits and return
// return a||b||c||d||e||f||g||h||i||j||k||m
void int2boolarr(uint32_t num, bool *arr, int bits) {
int j = 0;
for (int i = bits - 1; i >= 0; i--) {
arr[j++] = (num >> i) & 0x1;
}
}
uint32_t boolarr2int(bool *dpd, int bits) {
uint32_t num = 0;
int j = 0;
for (int i = bits - 1; i >= 0; i--) {
num |= dpd[j++] << i;
}
return num;
}
uint32_t bcd2dpd(uint16_t ibcd) {
bool bcd[12];
int2boolarr(ibcd, bcd, 12);
bool dpd[10];
dpd[0] = bcd[1] | (bcd[0] & bcd[9]) | (bcd[0] & bcd[5] & bcd[8]);
dpd[1] = bcd[2] | (bcd[0] & bcd[10]) | (bcd[0] & bcd[6] & bcd[8]);
dpd[2] = bcd[3];
dpd[3] = (bcd[5] & (~bcd[0] | ~bcd[8])) | (~bcd[0] & bcd[4] & bcd[9]) | (bcd[4] & bcd[8]);
dpd[4] = bcd[6] | (~bcd[0] & bcd[4] & bcd[10]) | (bcd[0] & bcd[8]);
dpd[5] = bcd[7];
dpd[6] = bcd[0] | bcd[4] | bcd[8];
dpd[7] = bcd[0] | (bcd[4] & bcd[8]) | (~bcd[4] & bcd[9]);
dpd[8] = bcd[4] | (bcd[0] & bcd[8]) | (~bcd[0] & bcd[10]);
dpd[9] = bcd[11];
return boolarr2int(dpd, 10);
}
uint32_t dpd2bcd(uint32_t idpd) {
bool dpd[10];
int2boolarr(idpd, dpd, 10);
bool bcd[12];
bcd[0] = (dpd[6] & dpd[7]) & (~dpd[3] | dpd[4] | ~dpd[8]);
bcd[1] = dpd[0] & (~dpd[6] | ~dpd[7] | (dpd[3] & ~dpd[4] & dpd[8]));
bcd[2] = dpd[1] & (~dpd[6] | ~dpd[7] | (dpd[3] & ~dpd[4] & dpd[8]));
bcd[3] = dpd[2];
bcd[4] = dpd[6] & ((~dpd[7] & dpd[8]) | (~dpd[4] & dpd[8]) | (dpd[3] & dpd[8]));
bcd[5] = (dpd[3] & (~dpd[6] | ~dpd[8])) | (dpd[0] & ~dpd[3] & dpd[4] & dpd[6] & dpd[7] & dpd[8]);
bcd[6] = (dpd[4] & (~dpd[6] | ~dpd[8])) | (dpd[1] & ~dpd[3] & dpd[4] & dpd[7]);
bcd[7] = dpd[5];
bcd[8] = dpd[6] & ((~dpd[7] & ~dpd[8]) | (dpd[7] & dpd[8] & (dpd[3] | dpd[4])));
bcd[9] = (~dpd[6] & dpd[7]) | (dpd[3] & dpd[6] & ~dpd[7] & dpd[8]) | (dpd[0] & dpd[7] & (~dpd[8] | (~dpd[3] & ~dpd[4])));
bcd[10] = (~dpd[6] & dpd[8]) | (dpd[4] & ~dpd[7] & dpd[8]) | (dpd[1] & dpd[6] & dpd[7] & (~dpd[8] | (~dpd[3] & ~dpd[4])));
bcd[11] = dpd[9];
return boolarr2int(bcd, 12);
}
uint8_t get_cntrl_char(uint8_t num) {
if (num == 0) {
return 0;
} else if (num < 10) {
return 1;
} else if (num < 100) {
return 2;
} else {
return 3;
}
}
void bin2char(uint8_t num, uint32_t str[4]) {
str[0] = get_cntrl_char(num);
str[1] = num / 100 + '0';
str[2] = (num % 100) / 10 + '0';
str[3] = num % 10 + '0';
}
void bin2bcd8(uint8_t num, char digit[4], uint32_t arr[4]) {
for (int i = 0; i < 3; i++) {
arr[i] = digit[i] - '0';
}
arr[3] = get_cntrl_char(num);
}
#define TABLES_COUNT 9
int main(void) {
uint32_t BCD2DPD[2458] = {0};
uint32_t BIN2DPD[1000] = {0};
uint32_t BIN2BCD8[4000];
uint32_t BIN2CHAR[4001];
uint32_t DPD2BCD[1024] = {0};
uint32_t DPD2BIN[1024] = {0};
uint32_t DPD2BINK[1024] = {0};
uint32_t DPD2BINM[1024] = {0};
uint32_t DPD2BCD8[4096];
for (int i = 0; i < 1000; i++) {
char digit[4];
snprintf(digit, 4, "%03d", i);
uint32_t bcd = 0;
for (int j = 0; j < 3; j++) {
bcd |= (digit[j] - '0') << (4 * (2 - j));
}
uint32_t dpd = bcd2dpd(bcd);
BCD2DPD[bcd] = dpd;
DPD2BCD[dpd] = bcd;
BIN2DPD[i] = dpd;
DPD2BIN[dpd] = i;
DPD2BINK[dpd] = i * 1000;
DPD2BINM[dpd] = i * 1E+6;
bin2char(i, BIN2CHAR + (4 * i));
bin2bcd8(i, digit, BIN2BCD8 + (4 * i));
bin2bcd8(i, digit, DPD2BCD8 + (4 * dpd));
}
BIN2CHAR[4000] = '\0';
char *names[] = {
"BCD2DPD", "BIN2DPD", "BIN2CHAR", "BIN2BCD8", "DPD2BCD", "DPD2BIN",
"DPD2BINK", "DPD2BINM", "DPD2BCD8",
};
char *types[] = {
"uint16_t", "uint16_t", "uint8_t", "uint8_t", "uint16_t", "uint16_t",
"uint32_t", "uint32_t", "uint8_t",
};
uint32_t *data[] = {
BCD2DPD, BIN2DPD, BIN2CHAR, BIN2BCD8, DPD2BCD, DPD2BIN,
DPD2BINK, DPD2BINM, DPD2BCD8,
};
int lengths[] = {2458, 1000, 4001, 4000, 1024, 1024, 1024, 1024, 4096};
for (int i = 0; i < TABLES_COUNT; i++) {
printf("#if defined(DEC_%s) && DEC_%s==1 && !defined(DEC%s)\n", names[i], names[i], names[i]);
printf("#define DEC%s\n", names[i]);
printf("const %s %s[%d] = {\n", types[i], names[i], lengths[i]);
for (int j = 0; j < lengths[i] / 16; j++) {
for (int k = j * 16; k < (j + 1) * 16 && k < lengths[i]; k++) {
printf("%s%d,", k == j * 16 ? "" : " ", data[i][k]);
}
printf("\n");
}
printf("};\n");
printf("#endif\n\n");
}
}

View file

@ -0,0 +1,286 @@
# SPDX-FileCopyrightText: 2023 Samuel Tyler <samuel@samuelt.me>
#
# SPDX-License-Identifier: GPL-3.0-or-later
# This gcc build targets the 64-bit kernel toolchain and keeps multilib enabled
# so the compiler can emit both 64-bit and 32-bit code.
: "${KERNEL_TARGET:=x86_64-unknown-linux-musl}"
: "${KERNEL_SYSROOT:=/kernel-toolchain}"
src_prepare() {
default
# Remove unused pregenerated files
rm libsanitizer/include/sanitizer/netbsd_syscall_hooks.h \
libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc
rm -r libgfortran/generated
rm gcc/testsuite/go.test/test/bench/go1/jsondata_test.go \
gcc/testsuite/go.test/test/bench/go1/parserdata_test.go \
gcc/testsuite/go.test/test/cmplxdivide1.go \
gcc/testsuite/go.test/test/fixedbugs/issue6866.go
rm gcc/testsuite/gcc.target/x86_64/abi/test_3_element_struct_and_unions.c \
gcc/testsuite/gcc.target/x86_64/abi/test_basic_returning.c \
gcc/testsuite/gcc.target/x86_64/abi/test_passing_floats.c \
gcc/testsuite/gcc.target/x86_64/abi/test_passing_integers.c \
gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/test_passing_floats.c \
gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/test_basic_returning.c \
gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/test_3_element_struct_and_unions.c \
gcc/testsuite/gcc.target/x86_64/abi/bf16/test_passing_floats.c \
gcc/testsuite/gcc.target/x86_64/abi/bf16/test_3_element_struct_and_unions.c
rm gcc/testsuite/c-c++-common/analyzer/flex-with-call-summaries.c \
gcc/testsuite/c-c++-common/analyzer/flex-without-call-summaries.c
rm gcc/testsuite/gdc.test/compilable/dtoh_windows.d
rm gcc/testsuite/sarif-replay.dg/2.1.0-valid/malloc-vs-local-4.c.sarif \
gcc/testsuite/sarif-replay.dg/2.1.0-valid/signal-1.c.sarif
rm gcc/testsuite/gm2/projects/pim/run/pass/tower/advflex.c \
gcc/testsuite/gm2/projects/pim/run/pass/tower/AdvParse.mod
rm -r gcc/testsuite/gdc.test/compilable
rm gcc/config/rs6000/rs6000-tables.opt \
gcc/config/rs6000/fusion.md \
gcc/config/h8300/mova.md \
gcc/config/aarch64/aarch64-tune.md \
gcc/config/riscv/t-elf-multilib \
gcc/config/riscv/t-linux-multilib \
gcc/config/arm/arm-tune.md \
gcc/config/arm/arm-tables.opt \
gcc/config/arm/ldmstm.md \
gcc/config/arc/t-multilib \
gcc/config/m68k/m68k-tables.opt \
gcc/config/c6x/c6x-mult.md \
gcc/config/c6x/c6x-tables.opt \
gcc/config/c6x/c6x-sched.md \
gcc/config/csky/csky_tables.opt \
gcc/config/mips/mips-tables.opt \
gcc/config/nvptx/nvptx-gen.opt \
gcc/config/nvptx/nvptx-gen.h
rm libphobos/src/std/internal/unicode_tables.d \
libphobos/src/std/internal/unicode_decomp.d \
libphobos/src/std/internal/unicode_grapheme.d \
libphobos/src/std/internal/unicode_norm.d
rm libgo/go/math/bits/example_test.go \
libgo/go/math/bits/bits_tables.go \
libgo/go/math/big/accuracy_string.go \
libgo/go/math/big/roundingmode_string.go \
libgo/go/strconv/isprint.go \
libgo/go/strconv/eisel_lemire.go \
libgo/go/sort/zfuncversion.go \
libgo/go/golang.org/x/net/route/zsys_*.go \
libgo/go/golang.org/x/net/idna/*.go \
libgo/go/golang.org/x/text/unicode/bidi/t*.go \
libgo/go/golang.org/x/text/unicode/norm/tables*.go \
libgo/go/golang.org/x/tools/internal/typeparams/typeterm.go \
libgo/go/golang.org/x/tools/internal/typeparams/termlist.go \
libgo/go/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go \
libgo/go/internal/syscall/windows/registry/zsyscall_windows.go \
libgo/go/internal/syscall/windows/zsyscall_windows.go \
libgo/go/encoding/gob/*_helpers.go \
libgo/go/index/suffixarray/sais2.go \
libgo/go/net/http/*_bundle.go \
libgo/go/runtime/sizeclasses.go \
libgo/go/runtime/fastlog2table.go \
libgo/go/html/template/*_string.go \
libgo/go/crypto/md5/md5block.go \
libgo/go/crypto/tls/common_string.go \
libgo/go/crypto/elliptic/internal/fiat/p*.go \
libgo/go/crypto/ed25519/internal/edwards25519/field/fe_amd64.go \
libgo/go/time/zoneinfo_abbrs_windows.go \
libgo/go/unicode/tables.go \
libgo/go/regexp/syntax/doc.go \
libgo/go/regexp/syntax/op_string.go \
libgo/go/regexp/syntax/perl_groups.go \
libgo/go/image/internal/imageutil/impl.go \
libgo/go/image/color/palette/palette.go \
libgo/go/cmd/internal/objabi/*_string.go \
libgo/go/cmd/go/internal/test/flagdefs.go \
libgo/go/debug/dwarf/*_string.go \
libgo/go/debug/macho/reloctype_string.go \
libgo/go/internal/goexperiment/exp_*.go \
libgo/go/time/tzdata/zipdata.go \
libgo/go/go/constant/kind_string.go
rm libgo/go/compress/bzip2/testdata/*.bin \
libgo/go/go/internal/gccgoimporter/testdata/v1reflect.gox \
libgo/go/go/internal/gccgoimporter/testdata/time.gox \
libgo/go/go/internal/gccgoimporter/testdata/unicode.gox \
libgo/go/go/internal/gccgoimporter/testdata/escapeinfo.gox \
libgo/go/go/internal/gccgoimporter/testdata/libimportsar.a \
libgo/go/go/internal/gcimporter/testdata/versions/*.a
rm -r libgo/go/compress/*/testdata \
libgo/go/runtime/pprof/testdata \
libgo/go/debug/*/testdata \
libgo/go/internal/trace/testdata \
libgo/go/time/testdata \
libgo/go/internal/xcoff/testdata \
libgo/go/archive/*/testdata
rm gcc/d/dmd/common/identifiertables.d
rm -r gcc/rust/checks/errors/borrowck/ffi-polonius/vendor \
libgrust/libformat_parser/vendor
find fixincludes/tests -name "*.h" -delete
rm gcc/m2/mc/mcp*.bnf
rm -r gcc/m2/pge-boot \
gcc/m2/mc-boot
# Partially generated unused files
rm libgcc/config/sh/lib1funcs.S \
libgcc/config/sh/lib1funcs-4-300.S \
libgcc/config/arc/lib1funcs.S
# Remove vendored zlib
rm -r zlib/
# gperf files
rm gcc/cp/cfns.h gcc/cp/std-name-hint.h
# Generate it now, because gcc doesn't regenerate it for some reason
# (taken directly from gcc/cp/Make-lang.in)
gperf -o -C -E -k '1-6,$' -j1 -D -N 'libc_name_p' -L C++ \
gcc/cp/cfns.gperf --output-file gcc/cp/cfns.h
# Regenerate autogen stuff
rm Makefile.in fixincludes/fixincl.x
autogen Makefile.def
pushd fixincludes
./genfixes
popd
# Regenerate autotools
# configure
find . -name configure | sed 's:/configure::' | while read d; do
pushd "${d}"
AUTOMAKE=automake-1.15 ACLOCAL=aclocal-1.15 autoreconf-2.69 -fiv
popd
done
# Because GCC is stupid, copy depcomp back in
cp "${PREFIX}/share/automake-1.15/depcomp" .
# A odd script
pushd gcc/m2/gm2-libs
autoconf-2.69 -f config-host.in > config-host
popd
# Makefile.in only
local BACK="${PWD}"
find . -type d \
-exec test -e "{}/Makefile.am" -a ! -e "{}/configure" \; \
-print | while read d; do
d="$(readlink -f "${d}")"
cd "${d}"
# Find the appropriate configure script for automake
while [ ! -e configure ]; do
cd ..
done
automake-1.15 -fai "${d}/Makefile"
cd "${BACK}"
done
# Remove bison generated files
rm gcc/cobol/parse.{cc,h}
rm gcc/cobol/cdf.{cc,h}
# Remove flex generated files
rm gcc/gengtype-lex.cc
rm gcc/cobol/scan.cc
# Regenerate crc table in libiberty/crc32.c
pushd libiberty
sed -n '/^ #include <stdio.h>/,/^ \}$/p' crc32.c > crcgen.c
gcc -o crcgen crcgen.c
sed '/crc_v3\.txt/{n; q}' crc32.c > crc32.c.new
./crcgen >> crc32.c.new
sed '1,/^};$/d' crc32.c >> crc32.c.new
mv crc32.c.new crc32.c
popd
# Regenerate decDPD.h
rm libdecnumber/decDPD.h
gcc -std=c99 -o decDPD_generate decDPD_generate.c
cp decDPD.h.preamble libdecnumber/decDPD.h
./decDPD_generate >> libdecnumber/decDPD.h
# Regenerate sarif-spec-urls.def
rm gcc/sarif-spec-urls.def
cp -t contrib ../sarif-v2.1.0-errata01-os-complete.html
pushd contrib
# windows-1252 is not supported by our Python build
sed -i "s/'windows-1252'/'latin-1'/g" regenerate-sarif-spec-index.py
python3 regenerate-sarif-spec-index.py
popd
# Regenerate box-drawing-chars.inc
rm gcc/text-art/box-drawing-chars.inc
python3 contrib/unicode/gen-box-drawing-chars.py > gcc/text-art/box-drawing-chars.inc
# Regenerate combining-chars.inc
rm libcpp/combining-chars.inc
python3 contrib/unicode/gen-combining-chars.py > libcpp/combining-chars.inc
# Regenerate printable-chars.inc
rm libcpp/printable-chars.inc
python3 contrib/unicode/gen-printable-chars.py > libcpp/printable-chars.inc
# Regenerate unicode-data.h
rm libstdc++-v3/include/bits/unicode-data.h
pushd contrib/unicode
python3 gen_libstdcxx_unicode_data.py > ../../libstdc++-v3/include/bits/unicode-data.h
popd
# Regenerate loongarch files
pushd gcc/config/loongarch
rm loongarch-evolution.{cc,h} loongarch-str.h loongarch.opt
./genopts/genstr.sh evolution_c > loongarch-evolution.cc
./genopts/genstr.sh evolution_h > loongarch-evolution.h
./genopts/genstr.sh header > loongarch-str.h
./genopts/genstr.sh opt > loongarch.opt
popd
# Regenerate gcn files
pushd gcc/config/gcn
rm gcn-tables.opt
awk -f gen-opt-tables.awk gcn-devices.def > gcn-tables.opt
popd
# Remove docs/translation
find . -name "*.gmo" -delete
find . -name "*.info" -delete
find . -type f -name '*.[1-9]' -delete
rm libiberty/functions.texi
# Sphinx-generated
rm gcc/jit/docs/conf.py
rm gcc/jit/docs/_build/texinfo/libgccjit.texi \
gcc/ada/gnat_rm.texi \
gcc/ada/gnat_ugn.texi
rm gcc/doc/avr-mmcu.texi
gcc -o gen-avr-mmcu-texi gcc/config/avr/gen-avr-mmcu-texi.cc
./gen-avr-mmcu-texi > gcc/doc/avr-mmcu.texi
}
src_configure() {
export PATH="${KERNEL_SYSROOT}/bin:${PATH}"
mkdir build
cd build
LDFLAGS="-static" \
../configure \
--target="${KERNEL_TARGET}" \
--prefix="${KERNEL_SYSROOT}" \
--disable-nls \
--enable-languages=c \
--without-headers \
--disable-threads \
--disable-shared \
--disable-libssp \
--disable-libsanitizer \
--disable-libquadmath \
--disable-libatomic \
--disable-libgomp \
--enable-multilib
}
src_compile() {
make "${MAKEJOBS}" all-gcc
make "${MAKEJOBS}" all-target-libgcc
}
src_install() {
make install-gcc DESTDIR="${DESTDIR}"
make install-target-libgcc DESTDIR="${DESTDIR}"
}

View file

@ -0,0 +1,2 @@
f https://mirrors.kernel.org/gnu/gcc/gcc-15.2.0/gcc-15.2.0.tar.xz 438fd996826b0c82485a29da03a72d71d6e3541a83ec702df4271f6fe025d24e
f https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html 835a4d043e4415a76668c8f38d5605f4e6f8ac2279dfab7e61c3f06e9228dd1c

View file

@ -0,0 +1,24 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
}
src_configure() {
PATH="${PREFIX}/bin:/usr/bin:/bin" \
CFLAGS="${CFLAGS:-} -std=gnu89" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--includedir="${PREFIX}/include" \
--enable-static \
--enable-shared
}
src_compile() {
default_src_compile
}
src_install() {
default_src_install
}

View file

@ -0,0 +1 @@
f https://ftp.gnu.org/gnu/gdbm/gdbm-1.8.3.tar.gz cc340338a2e28b40058ab9eb5354a21d53f88a1582ea21ba0bb185c37a281dc9 gdbm-1.8.3.tar.gz

View file

@ -0,0 +1,46 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
}
src_configure() {
local host_triplet curl_static_libs
host_triplet="$(gcc -dumpmachine)"
curl_static_libs="-lcurl -lssl -lcrypto -lz -pthread"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
LIBS="${curl_static_libs}" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--build="${host_triplet}" \
--host="${host_triplet}"
}
src_compile() {
local curl_static_libs
curl_static_libs="-lcurl -lssl -lcrypto -lz -pthread"
make "${MAKEJOBS}" \
NO_GETTEXT=YesPlease \
NO_TCLTK=YesPlease \
NO_PERL=YesPlease \
NO_PYTHON=YesPlease \
CURL_LDFLAGS="${curl_static_libs}"
}
src_install() {
local curl_static_libs
curl_static_libs="-lcurl -lssl -lcrypto -lz -pthread"
make install \
NO_GETTEXT=YesPlease \
NO_TCLTK=YesPlease \
NO_PERL=YesPlease \
NO_PYTHON=YesPlease \
CURL_LDFLAGS="${curl_static_libs}" \
DESTDIR="${DESTDIR}" \
prefix="${PREFIX}" \
libdir="${LIBDIR}"
}

View file

@ -0,0 +1,19 @@
--- git-2.53.0/configure
+++ git-2.53.0/configure
@@ -5582,7 +5582,7 @@
printf %s "(cached) " >&6
else case e in #(
e) ac_check_lib_save_LIBS=$LIBS
-LIBS="-lcurl $LIBS"
+LIBS="-lcurl -lssl -lcrypto -lz -pthread $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -5695,6 +5695,7 @@
fi
CURL_LDFLAGS=$($CURL_CONFIG $CURL_CONFIG_OPTS)
+ CURL_LDFLAGS="$CURL_LDFLAGS -lssl -lcrypto -lz -pthread"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Setting CURL_LDFLAGS to '$CURL_LDFLAGS'" >&5
printf "%s\n" "$as_me: Setting CURL_LDFLAGS to '$CURL_LDFLAGS'" >&6;}

View file

@ -0,0 +1 @@
f https://www.kernel.org/pub/software/scm/git/git-2.53.0.tar.xz 5818bd7d80b061bbbdfec8a433d609dc8818a05991f731ffc4a561e2ca18c653

View file

@ -0,0 +1,39 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
}
src_configure() {
local host_triplet
host_triplet="$(gcc -dumpmachine)"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG_PATH="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--includedir="${PREFIX}/include" \
--host="${host_triplet}" \
--build="${host_triplet}" \
--enable-shared \
--disable-static \
--disable-doc \
--disable-tests \
--disable-tools \
--disable-libdane \
--without-p11-kit \
--without-idn \
--without-zlib \
--without-brotli \
--without-tpm \
--without-tpm2
}
src_compile() {
default_src_compile
}
src_install() {
default_src_install
}

View file

@ -0,0 +1 @@
f https://www.gnupg.org/ftp/gcrypt/gnutls/v3.8/gnutls-3.8.12.tar.xz a7b341421bfd459acf7a374ca4af3b9e06608dcd7bd792b2bf470bea012b8e51 gnutls-3.8.0.tar.xz

View file

@ -0,0 +1,18 @@
# SPDX-License-Identifier: GPL-3.0-or-later
SEED_PREFIX="/bootstrap-seeds/grep-3.1"
src_configure() {
CFLAGS="-O2" LDFLAGS="-static" ./configure \
--prefix="${SEED_PREFIX}" \
--disable-perl-regexp \
--disable-shared
}
src_compile() {
default_src_compile
}
src_install() {
make DESTDIR="${DESTDIR}" install
}

View file

@ -0,0 +1 @@
f https://mirrors.kernel.org/gnu/grep/grep-3.1.tar.xz db625c7ab3bb3ee757b3926a5cfa8d9e1c3991ad24707a83dde8a5ef2bf7a07e

View file

@ -0,0 +1,46 @@
# SPDX-License-Identifier: GPL-3.0-or-later
SEED_PREFIX="/bootstrap-seeds/guile-2.2.4"
src_prepare() {
default
# Match Guix's static bootstrap Guile approach: force the final `guile`
# executable to be linked through libtool with -all-static.
sed -i \
-e 's|^guile_LDADD =.*$|guile_LDADD = libguile-@GUILE_EFFECTIVE_VERSION@.la -ldl|' \
-e 's|^guile_LDFLAGS =.*$|guile_LDFLAGS = -all-static|' \
libguile/Makefile.in
}
src_configure() {
local pkg_config_path libffi_cflags libffi_libs
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig"
libffi_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
pkg-config --cflags libffi)"
libffi_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
pkg-config --static --libs libffi)"
PKG_CONFIG_LIBDIR="${pkg_config_path}" \
PKG_CONFIG_PATH="${pkg_config_path}" \
LIBFFI_CFLAGS="${libffi_cflags}" \
LIBFFI_LIBS="${libffi_libs}" \
LDFLAGS="-ldl" \
./configure \
--prefix="${SEED_PREFIX}" \
--disable-shared \
--enable-static
}
src_compile() {
default_src_compile
}
src_install() {
local stage
stage="${DESTDIR}${SEED_PREFIX}"
make DESTDIR="${DESTDIR}" install
seed_make_repro_tar_xz "${stage}" "${DISTFILES}/guile-static-stripped-2.2.4-i686-linux.tar.xz"
}

View file

@ -0,0 +1,45 @@
--- guile-2.2.4/libguile/posix.c
+++ guile-2.2.4/libguile/posix.c
@@ -2356,6 +2356,8 @@
#endif
#ifdef WAIT_ANY
scm_c_define ("WAIT_ANY", scm_from_int (WAIT_ANY));
+#else
+ scm_c_define ("WAIT_ANY", scm_from_int (-1));
#endif
#ifdef WAIT_MYPGRP
scm_c_define ("WAIT_MYPGRP", scm_from_int (WAIT_MYPGRP));
@@ -2390,21 +2392,33 @@
#endif
#ifdef LC_PAPER
scm_c_define ("LC_PAPER", scm_from_int (LC_PAPER));
+#else
+ scm_c_define ("LC_PAPER", scm_from_int (7));
#endif
#ifdef LC_NAME
scm_c_define ("LC_NAME", scm_from_int (LC_NAME));
+#else
+ scm_c_define ("LC_NAME", scm_from_int (8));
#endif
#ifdef LC_ADDRESS
scm_c_define ("LC_ADDRESS", scm_from_int (LC_ADDRESS));
+#else
+ scm_c_define ("LC_ADDRESS", scm_from_int (9));
#endif
#ifdef LC_TELEPHONE
scm_c_define ("LC_TELEPHONE", scm_from_int (LC_TELEPHONE));
+#else
+ scm_c_define ("LC_TELEPHONE", scm_from_int (10));
#endif
#ifdef LC_MEASUREMENT
scm_c_define ("LC_MEASUREMENT", scm_from_int (LC_MEASUREMENT));
+#else
+ scm_c_define ("LC_MEASUREMENT", scm_from_int (11));
#endif
#ifdef LC_IDENTIFICATION
scm_c_define ("LC_IDENTIFICATION", scm_from_int (LC_IDENTIFICATION));
+#else
+ scm_c_define ("LC_IDENTIFICATION", scm_from_int (12));
#endif
#ifdef PIPE_BUF
scm_c_define ("PIPE_BUF", scm_from_long (PIPE_BUF));

View file

@ -0,0 +1,12 @@
diff -ru guile-2.2.4/libguile/filesys.c guile-2.2.4/libguile/filesys.c
--- guile-2.2.4/libguile/filesys.c
+++ guile-2.2.4/libguile/filesys.c
@@ -1135,7 +1135,7 @@
ssize_t result SCM_UNUSED;
size_t c_count, total = 0;
- scm_t_off c_offset;
+ off_t c_offset;
int in_fd, out_fd;
VALIDATE_FD_OR_PORT (out_fd, out, 1);

View file

@ -0,0 +1,53 @@
--- guile-2.2.4/module/rnrs/arithmetic/fixnums.scm
+++ guile-2.2.4/module/rnrs/arithmetic/fixnums.scm
@@ -242,50 +242,34 @@
(define (fxcopy-bit fx1 fx2 fx3)
(assert-fixnum fx1 fx2 fx3)
- (unless (and (<= 0 fx2) (< fx2 (fixnum-width)))
- (raise (make-assertion-violation)))
(bitwise-copy-bit fx1 fx2 fx3))
(define (fxbit-field fx1 fx2 fx3)
(assert-fixnum fx1 fx2 fx3)
- (unless (and (<= 0 fx2 fx3) (< fx3 (fixnum-width)))
- (raise (make-assertion-violation)))
(bitwise-bit-field fx1 fx2 fx3))
(define (fxcopy-bit-field fx1 fx2 fx3 fx4)
(assert-fixnum fx1 fx2 fx3 fx4)
- (unless (and (<= 0 fx2 fx3) (< fx3 (fixnum-width)))
- (raise (make-assertion-violation)))
(bitwise-copy-bit-field fx1 fx2 fx3 fx4))
(define (fxarithmetic-shift fx1 fx2)
(assert-fixnum fx1 fx2)
- (unless (< (abs fx2) (fixnum-width))
- (raise (make-assertion-violation)))
(ash fx1 fx2))
(define (fxarithmetic-shift-left fx1 fx2)
(assert-fixnum fx1 fx2)
- (unless (and (<= 0 fx2) (< fx2 (fixnum-width)))
- (raise (make-assertion-violation)))
(ash fx1 fx2))
(define (fxarithmetic-shift-right fx1 fx2)
(assert-fixnum fx1 fx2)
- (unless (and (<= 0 fx2) (< fx2 (fixnum-width)))
- (raise (make-assertion-violation)))
(ash fx1 (- fx2)))
(define (fxrotate-bit-field fx1 fx2 fx3 fx4)
(assert-fixnum fx1 fx2 fx3 fx4)
- (unless (and (<= 0 fx2 fx3) (< fx3 (fixnum-width)) (< fx4 (- fx3 fx2)))
- (raise (make-assertion-violation)))
(bitwise-rotate-bit-field fx1 fx2 fx3 fx4))
(define (fxreverse-bit-field fx1 fx2 fx3)
(assert-fixnum fx1 fx2 fx3)
- (unless (and (<= 0 fx2 fx3) (< fx3 (fixnum-width)))
- (raise (make-assertion-violation)))
(bitwise-reverse-bit-field fx1 fx2 fx3))
)

View file

@ -0,0 +1,111 @@
--- guile-2.2.4/libguile/simpos.c
+++ guile-2.2.4/libguile/simpos.c
@@ -24,7 +24,10 @@
#endif
#include <errno.h>
-#include <stdlib.h> /* for getenv, system, exit, free */
+#include <fcntl.h>
+#include <stdlib.h> /* for getenv, exit, free */
+#include <sys/types.h>
+#include <sys/wait.h>
#include <unistd.h> /* for _exit */
#include "libguile/_scm.h"
@@ -48,7 +51,11 @@
"indicating whether the command processor is available.")
#define FUNC_NAME s_scm_system
{
- int rv, eno;
+ int rv, eno, child_errno = 0;
+ int status;
+ int errpipe[2];
+ ssize_t nread;
+ pid_t pid;
char *c_cmd;
if (SCM_UNBNDP (cmd))
@@ -59,11 +66,78 @@
SCM_VALIDATE_STRING (1, cmd);
errno = 0;
c_cmd = scm_to_locale_string (cmd);
- rv = system (c_cmd);
- eno = errno; free (c_cmd); errno = eno;
- if (rv == -1 || (rv == 127 && errno != 0))
- SCM_SYSERROR;
- return scm_from_int (rv);
+
+ if (pipe (errpipe) < 0)
+ {
+ eno = errno; free (c_cmd); errno = eno;
+ SCM_SYSERROR;
+ }
+
+ if (fcntl (errpipe[1], F_SETFD, FD_CLOEXEC) == -1)
+ {
+ eno = errno;
+ close (errpipe[0]);
+ close (errpipe[1]);
+ free (c_cmd);
+ errno = eno;
+ SCM_SYSERROR;
+ }
+
+ pid = fork ();
+ if (pid == 0)
+ {
+ char *argv[] = { (char *) "sh", (char *) "-c", c_cmd, NULL };
+ close (errpipe[0]);
+ execvp ("sh", argv);
+ child_errno = errno;
+ if (write (errpipe[1], &child_errno, sizeof (child_errno)) < 0)
+ ;
+ _exit (127);
+ }
+ else if (pid < 0)
+ {
+ eno = errno;
+ close (errpipe[0]);
+ close (errpipe[1]);
+ free (c_cmd);
+ errno = eno;
+ SCM_SYSERROR;
+ }
+
+ close (errpipe[1]);
+ while ((nread = read (errpipe[0], &child_errno, sizeof (child_errno))) == -1
+ && errno == EINTR)
+ ;
+ close (errpipe[0]);
+ if (nread == -1)
+ {
+ eno = errno;
+ free (c_cmd);
+ errno = eno;
+ SCM_SYSERROR;
+ }
+ if (nread != sizeof (child_errno))
+ child_errno = 0;
+
+ while ((rv = waitpid (pid, &status, 0)) == -1 && errno == EINTR)
+ ;
+ if (rv == -1)
+ {
+ eno = errno;
+ free (c_cmd);
+ errno = eno;
+ SCM_SYSERROR;
+ }
+
+ free (c_cmd);
+
+ if (child_errno != 0)
+ {
+ errno = child_errno;
+ SCM_SYSERROR;
+ }
+
+ return scm_from_int (status);
}
#undef FUNC_NAME
#endif /* HAVE_SYSTEM */

View file

@ -0,0 +1 @@
f https://mirrors.kernel.org/gnu/guile/guile-2.2.4.tar.xz d9e8b94af7b206fcf52bec6501b921bd7d0bd7a31fb7e896a35ba8253678e31e

View file

@ -0,0 +1,89 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
autoreconf -fi
}
src_configure() {
local host_triplet pkg_config_path guile_cflags guile_libs
local avahi_cflags avahi_libs
host_triplet="$(gcc -dumpmachine)"
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
guile_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --cflags guile-3.0)"
guile_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs guile-3.0)"
avahi_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --cflags avahi-client)"
avahi_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs avahi-client)"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG="/usr/bin/pkg-config" \
PKG_CONFIG_LIBDIR="${pkg_config_path}" \
PKG_CONFIG_PATH="${pkg_config_path}" \
LD_LIBRARY_PATH="${LIBDIR}:${PREFIX}/lib:${LD_LIBRARY_PATH}" \
GUILE_CFLAGS="${guile_cflags}" \
GUILE_LDFLAGS="${guile_libs}" \
AVAHI_CFLAGS="${avahi_cflags}" \
AVAHI_LIBS="${avahi_libs}" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--host="${host_triplet}" \
--build="${host_triplet}" \
--enable-shared \
--disable-static \
'--with-guilemoduledir=$(datarootdir)/guile/site/$(GUILE_EFFECTIVE_VERSION)'
}
src_compile() {
local pkg_config_path guile_cflags guile_libs avahi_cflags avahi_libs gnutls_libs
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
guile_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --cflags guile-3.0)"
guile_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs guile-3.0)"
avahi_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --cflags avahi-client)"
avahi_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs avahi-client)"
gnutls_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs gnutls)"
CPPFLAGS="${guile_cflags} ${avahi_cflags} ${CPPFLAGS:-}" \
GUILE_CFLAGS="${guile_cflags}" \
GUILE_LDFLAGS="${guile_libs}" \
AVAHI_CFLAGS="${avahi_cflags}" \
AVAHI_LIBS="${avahi_libs}" \
GNUTLS_LIBS="${gnutls_libs}" \
default_src_compile
}
src_install() {
local pkg_config_path guile_cflags guile_libs avahi_cflags avahi_libs gnutls_libs
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
guile_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --cflags guile-3.0)"
guile_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs guile-3.0)"
avahi_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --cflags avahi-client)"
avahi_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs avahi-client)"
gnutls_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs gnutls)"
CPPFLAGS="${guile_cflags} ${avahi_cflags} ${CPPFLAGS:-}" \
GUILE_CFLAGS="${guile_cflags}" \
GUILE_LDFLAGS="${guile_libs}" \
AVAHI_CFLAGS="${avahi_cflags}" \
AVAHI_LIBS="${avahi_libs}" \
GNUTLS_LIBS="${gnutls_libs}" \
default_src_install
}
src_postprocess() {
default_src_postprocess
}

View file

@ -0,0 +1,171 @@
diff -urN guile-avahi-0.4.1/Makefile.am guile-avahi-0.4.1/Makefile.am
--- guile-avahi-0.4.1/Makefile.am 2023-01-15 17:29:00
+++ guile-avahi-0.4.1/Makefile.am 2026-03-08 10:22:35
@@ -37,6 +37,7 @@
EXTRA_DIST += \
src/make-enum-map.scm src/make-smob-types.scm \
src/make-enum-header.scm src/make-smob-header.scm \
+ src/guile-static-main.c \
src/make-callback-header.scm src/make-callback-trampolines.scm
# Files generated by (avahi build ...).
@@ -61,6 +62,11 @@
src/common.c.x src/watch.c.x src/client.c.x \
src/errors.c.x src/publish.c.x src/lookup.c.x
+guile_avahi_common_cflags = \
+ $(AVAHI_CFLAGS) $(GUILE_CFLAGS) $(AM_CFLAGS)
+
+if ENABLE_SHARED
+
nobase_guileextension_LTLIBRARIES = guile-avahi-v-0.la
# Use '-module' to build a "dlopenable module", in Libtool terms.
@@ -72,11 +78,29 @@
src/utils.c src/errors.c src/watch.c \
src/common.c src/client.c \
src/publish.c src/lookup.c
-guile_avahi_v_0_la_CFLAGS = \
- $(AVAHI_CFLAGS) $(GUILE_CFLAGS) $(AM_CFLAGS)
+guile_avahi_v_0_la_CFLAGS = $(guile_avahi_common_cflags)
+guile_avahi_v_0_la_DEPENDENCIES = $(BUILT_SOURCES)
guile_avahi_v_0_la_LIBADD = \
$(AVAHI_LIBS) $(GUILE_LDFLAGS)
+else
+lib_LIBRARIES = libguile-avahi-static.a
+libguile_avahi_static_a_SOURCES = \
+ src/utils.c src/errors.c src/watch.c \
+ src/common.c src/client.c \
+ src/publish.c src/lookup.c
+libguile_avahi_static_a_CPPFLAGS = $(AM_CPPFLAGS)
+libguile_avahi_static_a_CFLAGS = $(guile_avahi_common_cflags)
+libguile_avahi_static_a_DEPENDENCIES = $(BUILT_SOURCES)
+bin_PROGRAMS = guile
+guile_SOURCES = src/guile-static-main.c
+guile_CPPFLAGS = $(AM_CPPFLAGS)
+guile_CFLAGS = $(guile_avahi_common_cflags)
+guile_LDFLAGS = -static
+guile_LDADD = libguile-avahi-static.a $(GUILE_GNUTLS_STATIC_LIB) \
+ $(GUILE_LDFLAGS) $(AVAHI_LIBS) $(GNUTLS_LIBS) $(LIBS)
+endif
+
AM_CFLAGS = $(GCC_CFLAGS)
AM_CPPFLAGS = -I$(builddir)/src -I$(srcdir)/src \
-I$(top_srcdir)/lib -I$(top_builddir)/lib
@@ -173,6 +196,8 @@
gosubdir = $(godir)/avahi
goclientdir = $(gosubdir)/client
+if ENABLE_SHARED
+
nodist_go_DATA = \
modules/avahi.go
nodist_gosub_DATA = \
@@ -213,6 +238,7 @@
SUFFIXES += .go
CLEANFILES += $(GOBJECTS)
+endif ENABLE_SHARED
#
diff -urN guile-avahi-0.4.1/configure.ac guile-avahi-0.4.1/configure.ac
--- guile-avahi-0.4.1/configure.ac 2023-01-15 17:30:33
+++ guile-avahi-0.4.1/configure.ac 2026-03-08 10:22:35
@@ -27,7 +27,8 @@
# Libtool.
LT_PREREQ([2.2.6])
-LT_INIT([disable-static dlopen])
+LT_INIT([dlopen])
+AM_CONDITIONAL([ENABLE_SHARED], [test "x$enable_shared" != "xno"])
# Checks for programs.
AC_PROG_CC
diff -urN guile-avahi-0.4.1/modules/avahi.in guile-avahi-0.4.1/modules/avahi.in
--- guile-avahi-0.4.1/modules/avahi.in 2023-01-15 16:21:01
+++ guile-avahi-0.4.1/modules/avahi.in 2026-03-08 10:22:35
@@ -110,7 +110,8 @@
(string-append %libdir "/guile-avahi-v-0")
"guile-avahi-v-0"))
- (unless (getenv "AVAHI_GUILE_CROSS_COMPILING")
+ (unless (or (getenv "AVAHI_GUILE_CROSS_COMPILING")
+ (module-variable (current-module) 'watch?))
(load-extension %avahi-extension "scm_avahi_common_init")))
;; Optional bindings, depending on the configuration.
diff -urN guile-avahi-0.4.1/modules/avahi/client/lookup.scm guile-avahi-0.4.1/modules/avahi/client/lookup.scm
--- guile-avahi-0.4.1/modules/avahi/client/lookup.scm 2023-01-15 16:21:14
+++ guile-avahi-0.4.1/modules/avahi/client/lookup.scm 2026-03-08 10:22:35
@@ -63,7 +63,8 @@
resolver-event->string
resolver-event/found resolver-event/failure))
-(unless (getenv "AVAHI_GUILE_CROSS_COMPILING")
- (load-extension %avahi-extension "scm_avahi_lookup_init"))
+(unless (or (getenv "AVAHI_GUILE_CROSS_COMPILING")
+ (module-variable (current-module) 'domain-browser?))
+ (load-extension %avahi-extension "scm_avahi_lookup_init"))
;;; arch-tag: 9ab68bd4-4705-42e5-89c3-e02551be4d09
diff -urN guile-avahi-0.4.1/modules/avahi/client/publish.scm guile-avahi-0.4.1/modules/avahi/client/publish.scm
--- guile-avahi-0.4.1/modules/avahi/client/publish.scm 2023-01-15 16:21:20
+++ guile-avahi-0.4.1/modules/avahi/client/publish.scm 2026-03-08 10:22:35
@@ -39,7 +39,8 @@
publish-flag/no-cookie publish-flag/update
publish-flag/use-wide-area publish-flag/use-multicast))
-(unless (getenv "AVAHI_GUILE_CROSS_COMPILING")
- (load-extension %avahi-extension "scm_avahi_publish_init"))
+(unless (or (getenv "AVAHI_GUILE_CROSS_COMPILING")
+ (module-variable (current-module) 'entry-group?))
+ (load-extension %avahi-extension "scm_avahi_publish_init"))
;;; arch-tag: 36180c98-3262-40a6-a90c-eb8f283e628e
diff -urN guile-avahi-0.4.1/modules/avahi/client.scm guile-avahi-0.4.1/modules/avahi/client.scm
--- guile-avahi-0.4.1/modules/avahi/client.scm 2023-01-15 16:21:09
+++ guile-avahi-0.4.1/modules/avahi/client.scm 2026-03-08 10:22:35
@@ -29,8 +29,9 @@
client-flag->string
client-flag/ignore-user-config client-flag/no-fail))
-(unless (getenv "AVAHI_GUILE_CROSS_COMPILING")
- (load-extension %avahi-extension "scm_avahi_client_init"))
+(unless (or (getenv "AVAHI_GUILE_CROSS_COMPILING")
+ (module-variable (current-module) 'client?))
+ (load-extension %avahi-extension "scm_avahi_client_init"))
;; Optional bindings, depending on the configuration.
(if (defined? 'set-client-host-name!) (export set-client-host-name!))
diff -urN guile-avahi-0.4.1/src/guile-static-main.c guile-avahi-0.4.1/src/guile-static-main.c
--- guile-avahi-0.4.1/src/guile-static-main.c 1969-12-31 19:00:00
+++ guile-avahi-0.4.1/src/guile-static-main.c 2026-03-08 10:22:35
@@ -0,0 +1,26 @@
+#include <libguile.h>
+
+void scm_init_gnutls(void);
+void scm_avahi_common_init(void);
+void scm_avahi_client_init(void);
+void scm_avahi_lookup_init(void);
+void scm_avahi_publish_init(void);
+
+static void
+inner_main(void *closure, int argc, char **argv)
+{
+ (void) closure;
+ scm_init_gnutls();
+ scm_avahi_common_init();
+ scm_avahi_client_init();
+ scm_avahi_lookup_init();
+ scm_avahi_publish_init();
+ scm_shell(argc, argv);
+}
+
+int
+main(int argc, char **argv)
+{
+ scm_boot_guile(argc, argv, inner_main, NULL);
+ return 0;
+}

View file

@ -0,0 +1 @@
f https://download-mirror.savannah.gnu.org/releases/guile-avahi/guile-avahi-0.4.1.tar.gz db9de9e19df728b40d23c0381caa9f8eda2b175fa7f69f153be8f3f078044ca5 guile-avahi-0.4.1.tar.gz

View file

@ -0,0 +1,36 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
autoreconf -fi
}
src_configure() {
local host_triplet pkg_config_path
host_triplet="$(gcc -dumpmachine)"
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
mkdir -p build
cd build
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG="/usr/bin/pkg-config" \
PKG_CONFIG_LIBDIR="${pkg_config_path}" \
PKG_CONFIG_PATH="${pkg_config_path}" \
LD_LIBRARY_PATH="${LIBDIR}:${PREFIX}/lib:${LD_LIBRARY_PATH}" \
../configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--host="${host_triplet}" \
--build="${host_triplet}" \
--with-libgcrypt-prefix="${PREFIX}" \
--with-libgcrypt-libdir="${LIBDIR}"
}
src_compile() {
default_src_compile
}
src_install() {
default_src_install
}

View file

@ -0,0 +1 @@
f https://deb.debian.org/debian/pool/main/g/guile-gcrypt/guile-gcrypt_0.5.0.orig.tar.gz 59fafedf6bc23dce32d26400c957a4d7cd32be1fbb26d0c6992aa71777284fe3

View file

@ -0,0 +1,57 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
autoreconf -fi
}
src_configure() {
local host_triplet pkg_config_path libgit2_cflags libgit2_libs
host_triplet="$(gcc -dumpmachine)"
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
libgit2_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --cflags libgit2)"
libgit2_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs libgit2)"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG="/usr/bin/pkg-config" \
PKG_CONFIG_LIBDIR="${pkg_config_path}" \
PKG_CONFIG_PATH="${pkg_config_path}" \
CPPFLAGS="${libgit2_cflags} ${CPPFLAGS:-}" \
LIBS="${libgit2_libs}" \
LIBGIT2_CFLAGS="${libgit2_cflags}" \
LIBGIT2_LIBS="${libgit2_libs}" \
libgit2_CFLAGS="${libgit2_cflags}" \
libgit2_LIBS="${libgit2_libs}" \
LD_LIBRARY_PATH="${LIBDIR}:${PREFIX}/lib:${LD_LIBRARY_PATH}" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
'--with-guile-site-dir=$(datarootdir)/guile/site/$(GUILE_EFFECTIVE_VERSION)' \
'--with-guile-extension-dir=$(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/extensions' \
--host="${host_triplet}" \
--build="${host_triplet}"
}
src_compile() {
local pkg_config_path libgit2_cflags libgit2_libs
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
libgit2_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --cflags libgit2)"
libgit2_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs libgit2)"
CPPFLAGS="${libgit2_cflags} ${CPPFLAGS:-}" \
LIBS="${libgit2_libs}" \
LIBGIT2_CFLAGS="${libgit2_cflags}" \
LIBGIT2_LIBS="${libgit2_libs}" \
libgit2_CFLAGS="${libgit2_cflags}" \
libgit2_LIBS="${libgit2_libs}" \
default_src_compile
}
src_install() {
default_src_install
}

View file

@ -0,0 +1 @@
g https://gitlab.com/guile-git/guile-git.git~v0.10.0 https://gitlab.com/guile-git/guile-git/-/archive/v0.10.0/guile-git-v0.10.0.tar.gz 97966a8fb862bf50eb200c92a75039fc655e169a76dcb929e7e6ca3d81b493fc guile-git-v0.10.0.tar.gz

View file

@ -0,0 +1,68 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
autoreconf -fi
}
src_configure() {
local host_triplet pkg_config_path guile_cflags guile_libs gnutls_libs
host_triplet="$(gcc -dumpmachine)"
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
guile_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --cflags guile-3.0)"
guile_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs guile-3.0)"
gnutls_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs gnutls)"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG="/usr/bin/pkg-config" \
PKG_CONFIG_LIBDIR="${pkg_config_path}" \
PKG_CONFIG_PATH="${pkg_config_path}" \
CFLAGS="-fPIC" \
CXXFLAGS="-fPIC" \
LD_LIBRARY_PATH="${LIBDIR}:${PREFIX}/lib:${LD_LIBRARY_PATH}" \
GUILE_CFLAGS="${guile_cflags}" \
GUILE_LIBS="${guile_libs}" \
GNUTLS_LIBS="${gnutls_libs}" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--host="${host_triplet}" \
--build="${host_triplet}" \
--enable-shared \
--disable-static \
'--with-guile-site-dir=$(datarootdir)/guile/site/$(GUILE_EFFECTIVE_VERSION)' \
'--with-guile-site-ccache-dir=$(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/site-ccache' \
'--with-guile-extension-dir=$(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/extensions'
}
src_compile() {
local pkg_config_path guile_cflags guile_libs gnutls_cflags gnutls_libs
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
guile_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --cflags guile-3.0)"
guile_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs guile-3.0)"
gnutls_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --cflags gnutls)"
gnutls_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs gnutls)"
CPPFLAGS="${guile_cflags} ${gnutls_cflags} ${CPPFLAGS:-}" \
GUILE_CFLAGS="${guile_cflags}" \
GUILE_LDFLAGS="${guile_libs}" \
GNUTLS_CFLAGS="${gnutls_cflags}" \
GNUTLS_LIBS="${gnutls_libs}" \
default_src_compile
}
src_install() {
default_src_install
}
src_postprocess() {
default_src_postprocess
}

View file

@ -0,0 +1 @@
f https://ftp.gnu.org/gnu/gnutls/guile-gnutls-v5.0.1-src.tar.gz b190047cee068f6b22a5e8d49ca49a2425ad4593901b9ac8940f8842ba7f164f guile-gnutls-v5.0.1-src.tar.gz

View file

@ -0,0 +1,30 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
autoreconf -fi
}
src_configure() {
local host_triplet pkg_config_path
host_triplet="$(gcc -dumpmachine)"
pkg_config_path="${LIBDIR}/pkgconfig"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG_LIBDIR="${pkg_config_path}:${PREFIX}/lib/pkgconfig" \
PKG_CONFIG_PATH="${pkg_config_path}:${PREFIX}/lib/pkgconfig" \
LD_LIBRARY_PATH="${LIBDIR}:${LD_LIBRARY_PATH}" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--host="${host_triplet}" \
--build="${host_triplet}"
}
src_compile() {
default_src_compile
}
src_install() {
default_src_install
}

View file

@ -0,0 +1 @@
g https://github.com/aconchillo/guile-json.git~4.7.3 https://github.com/aconchillo/guile-json/archive/refs/tags/4.7.3.tar.gz 91485b2ac9453326e72d38ab4c0ffbe850597a4e3723993979d8aeb57d1ebb32 guile-json-v4.7.3.tar.gz

View file

@ -0,0 +1,34 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
autoreconf -fi
}
src_configure() {
local host_triplet pkg_config_path
host_triplet="$(gcc -dumpmachine)"
pkg_config_path="${LIBDIR}/pkgconfig"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG_LIBDIR="${pkg_config_path}" \
PKG_CONFIG_PATH="${pkg_config_path}:${PREFIX}/lib/pkgconfig" \
LD_LIBRARY_PATH="${LIBDIR}:${LD_LIBRARY_PATH}" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--host="${host_triplet}" \
--build="${host_triplet}"
}
src_compile() {
default_src_compile
}
src_install() {
default_src_install
}
src_postprocess() {
default_src_postprocess
}

View file

@ -0,0 +1,32 @@
SPDX-License-Identifier: GPL-3.0-or-later
Avoid requiring scm_gc_register_allocation to be exported from the
main Guile executable. Static Guile builds in this bootstrap do not
provide that symbol to dynamic-func, so fall back to a no-op.
--- guile-lzlib/lzlib.scm
+++ guile-lzlib/lzlib.scm
@@ -56,10 +56,15 @@
(define %liblz-handle
(delay (dynamic-link %liblz)))
-(define register-allocation
- ;; Let the GC know that an unmanaged heap allocation took place.
- (pointer->procedure void
- (dynamic-func "scm_gc_register_allocation"
- (dynamic-link))
- (list size_t)))
+(define register-allocation
+ ;; Let the GC know that an unmanaged heap allocation took place.
+ ;; Static Guile builds may not export this symbol from the main program.
+ (match (false-if-exception
+ (dynamic-func "scm_gc_register_allocation"
+ (dynamic-link)))
+ ((? pointer? proc)
+ (pointer->procedure void proc (list size_t)))
+ (#f
+ (lambda (_size)
+ #t))))
(define (lzlib-procedure ret name parameters)
"Return a procedure corresponding to C function NAME in liblz, or #f if

View file

@ -0,0 +1 @@
f https://deb.debian.org/debian/pool/main/g/guile-lzlib/guile-lzlib_0.3.0.orig.tar.gz a7f99c8d2a143e05ea22db2dc8b9ce6c27cae942162b45ee3015ed9027af0ff2 guile-lzlib_0.3.0.orig.tar.gz

View file

@ -0,0 +1,50 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
autoreconf -fi
}
src_configure() {
local host_triplet pkg_config_path
host_triplet="$(gcc -dumpmachine)"
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG="/usr/bin/pkg-config" \
PKG_CONFIG_LIBDIR="${pkg_config_path}:${PREFIX}/lib/pkgconfig" \
PKG_CONFIG_PATH="${pkg_config_path}:${PREFIX}/lib/pkgconfig" \
LD_LIBRARY_PATH="${LIBDIR}:${PREFIX}/lib:${LD_LIBRARY_PATH}" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--host="${host_triplet}" \
--build="${host_triplet}" \
'--with-guile-site-dir=$(datarootdir)/guile/site/$(GUILE_EFFECTIVE_VERSION)' \
'--with-guile-site-ccache-dir=$(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/site-ccache'
}
src_compile() {
default_src_compile
}
src_install() {
default_src_install
}
src_postprocess() {
local guile_site_path guile_site_ccache guile_core_ccache
default_src_postprocess
guile_site_path="${DESTDIR}${PREFIX}/share/guile/site/3.0:${PREFIX}/share/guile/site/3.0:${PREFIX}/share/guile/3.0"
guile_site_ccache="${DESTDIR}${LIBDIR}/guile/3.0/site-ccache:${LIBDIR}/guile/3.0/site-ccache"
guile_core_ccache="${LIBDIR}/guile/3.0/ccache"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
GUILE_LOAD_PATH="${guile_site_path}" \
GUILE_LOAD_COMPILED_PATH="${guile_site_ccache}:${guile_core_ccache}" \
GUILE_SYSTEM_PATH="${guile_site_path}" \
GUILE_SYSTEM_COMPILED_PATH="${guile_site_ccache}:${guile_core_ccache}" \
"${PREFIX}/bin/guile" -c '(use-modules (semver)) (display "semver-module-ok\n")'
}

View file

@ -0,0 +1 @@
g https://codeberg.org/daym/guile-semver.git~607ca84c24b8950fdb5aca73e9d53d924e49fc24 _ 914b5aaf3064dedcea8bb55de31e48ba564971ebac3f2e33968c030ecc40c51f guile-semver-607ca84c24b8950fdb5aca73e9d53d924e49fc24.tar.gz

View file

@ -0,0 +1,30 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
autoreconf -fi
}
src_configure() {
local host_triplet pkg_config_path
host_triplet="$(gcc -dumpmachine)"
pkg_config_path="${LIBDIR}/pkgconfig"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG_LIBDIR="${pkg_config_path}" \
PKG_CONFIG_PATH="${pkg_config_path}" \
LD_LIBRARY_PATH="${LIBDIR}:${LD_LIBRARY_PATH}" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--host="${host_triplet}" \
--build="${host_triplet}"
}
src_compile() {
default_src_compile
}
src_install() {
default_src_install
}

View file

@ -0,0 +1 @@
f https://deb.debian.org/debian/pool/main/g/guile-sqlite3/guile-sqlite3_0.1.3.orig.tar.gz 158cb82958c6329319f911412999ea125980f327f54185bf0dad271d6f8f45c2

View file

@ -0,0 +1,30 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
autoreconf -fi
}
src_configure() {
local host_triplet pkg_config_path
host_triplet="$(gcc -dumpmachine)"
pkg_config_path="${LIBDIR}/pkgconfig"
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG_LIBDIR="${pkg_config_path}" \
PKG_CONFIG_PATH="${pkg_config_path}:${PREFIX}/lib/pkgconfig" \
LD_LIBRARY_PATH="${LIBDIR}:${LD_LIBRARY_PATH}" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--host="${host_triplet}" \
--build="${host_triplet}"
}
src_compile() {
default_src_compile
}
src_install() {
default_src_install
}

View file

@ -0,0 +1 @@
f https://deb.debian.org/debian/pool/main/g/guile-zlib/guile-zlib_0.2.2.orig.tar.gz 6f6cca4b32ca79f3f4627cdb7ea68569a3cc38be60468991e2b5c085783e38c1 guile-zlib_0.2.2.orig.tar.gz

174
steps-guix/guix-1.5.0/pass2.sh Executable file
View file

@ -0,0 +1,174 @@
# SPDX-License-Identifier: GPL-3.0-or-later
: "${KERNEL_SYSROOT:=/kernel-toolchain}"
src_prepare() {
local patch_template rendered_patch
local mes_patch_template rendered_mes_patch
default
if [ ! -f /tmp/guix-bootstrap-seeds.env ]; then
echo "Missing /tmp/guix-bootstrap-seeds.env" >&2
false
fi
. /tmp/guix-bootstrap-seeds.env
patch_template="${base_dir}/patches/bootstrap-local-seeds.patch.in"
rendered_patch="/tmp/guix-bootstrap-local-seeds.patch"
mes_patch_template="${base_dir}/patches/bootstrap-local-mes-extra.patch.in"
rendered_mes_patch="/tmp/guix-bootstrap-local-mes-extra.patch"
sed \
-e "s|@EXEC_BASH_HASH@|${EXEC_BASH_HASH}|g" \
-e "s|@EXEC_MKDIR_HASH@|${EXEC_MKDIR_HASH}|g" \
-e "s|@EXEC_TAR_HASH@|${EXEC_TAR_HASH}|g" \
-e "s|@EXEC_XZ_HASH@|${EXEC_XZ_HASH}|g" \
-e "s|@STATIC_BINARIES_SEED_HASH@|${STATIC_BINARIES_SEED_HASH}|g" \
-e "s|@GUILE_SEED_HASH@|${GUILE_SEED_HASH}|g" \
-e "s|@MES_MINIMAL_SEED_HASH@|${MES_MINIMAL_SEED_HASH}|g" \
-e "s|@MESCC_TOOLS_SEED_HASH@|${MESCC_TOOLS_SEED_HASH}|g" \
"${patch_template}" > "${rendered_patch}"
sed \
-e "s|@MES_MINIMAL_SEED_HASH@|${MES_MINIMAL_SEED_HASH}|g" \
-e "s|@MESCC_TOOLS_SEED_HASH@|${MESCC_TOOLS_SEED_HASH}|g" \
"${mes_patch_template}" > "${rendered_mes_patch}"
patch -p1 < "${rendered_patch}"
patch -p1 < "${rendered_mes_patch}"
autoreconf -fi
}
probe_guile_module() {
local module_name debug_log
local guile_site_path guile_site_ccache guile_core_ccache guile_ext_path
local pkg_config_path probe_label probe_pkg_config probe_expression
local find_name find_module
module_name="$1"
debug_log="/tmp/${module_name}-guile-probe.log"
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
guile_site_path="${PREFIX}/share/guile/site/3.0:${PREFIX}/share/guile/3.0"
guile_site_ccache="${LIBDIR}/guile/3.0/site-ccache"
guile_core_ccache="${LIBDIR}/guile/3.0/ccache"
guile_ext_path="${LIBDIR}/guile/3.0/extensions"
case "${module_name}" in
git)
probe_label="git-related"
probe_pkg_config="libgit2"
find_name='libguile-git*'
find_module='git'
probe_expression="(use-modules (git)) (display \"git-module-ok\\n\")"
;;
gnutls)
probe_label="gnutls-related"
probe_pkg_config="gnutls"
find_name='libguile-gnutls*'
find_module='gnutls'
probe_expression="(use-modules (gnutls)) (if (module-variable (resolve-module '(gnutls)) 'make-session) (display \"gnutls-module-ok\\n\") (begin (display \"gnutls-make-session-missing\\n\") (exit 1)))"
;;
*)
probe_label="${module_name}-related"
probe_pkg_config=""
find_name="*${module_name}*"
find_module="${module_name}"
probe_expression="(use-modules (${module_name})) (display \"${module_name}-module-ok\\n\")"
;;
esac
rm -f "${debug_log}"
echo "guix: probing (${module_name}) before configure" >&2
echo "guix: GUILE_LOAD_PATH=${guile_site_path}" >&2
echo "guix: GUILE_LOAD_COMPILED_PATH=${guile_site_ccache}:${guile_core_ccache}" >&2
echo "guix: GUILE_EXTENSIONS_PATH=${guile_ext_path}" >&2
if [ -n "${probe_pkg_config}" ]; then
echo "guix: ${probe_pkg_config} pkg-config libs=$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" /usr/bin/pkg-config --libs "${probe_pkg_config}")" >&2
echo "guix: ${probe_pkg_config} pkg-config static-libs=$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" /usr/bin/pkg-config --static --libs "${probe_pkg_config}")" >&2
fi
if command -v find >/dev/null 2>&1; then
echo "guix: installed Guile ${probe_label} files:" >&2
find "${PREFIX}/share/guile" "${LIBDIR}/guile" -type f \
\( -path "*/${find_module}/*.scm" -o -path "*/${find_module}.scm" -o -path "*/${find_module}/*.go" -o -path "*/${find_module}.go" -o -name "${find_name}" \) \
2>/dev/null | LC_ALL=C sort >&2 || true
fi
if ! PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG="/usr/bin/pkg-config" \
PKG_CONFIG_LIBDIR="${pkg_config_path}" \
PKG_CONFIG_PATH="${pkg_config_path}" \
LD_LIBRARY_PATH="${LIBDIR}:${PREFIX}/lib:${LD_LIBRARY_PATH}" \
GUILE_LOAD_PATH="${guile_site_path}" \
GUILE_LOAD_COMPILED_PATH="${guile_site_ccache}:${guile_core_ccache}" \
GUILE_SYSTEM_PATH="${guile_site_path}" \
GUILE_SYSTEM_COMPILED_PATH="${guile_site_ccache}:${guile_core_ccache}" \
GUILE_EXTENSIONS_PATH="${guile_ext_path}" \
GNUTLS_GUILE_EXTENSION_DIR="${guile_ext_path}" \
"${PREFIX}/bin/guile" -c "${probe_expression}" \
>"${debug_log}" 2>&1; then
echo "guix: explicit (${module_name}) probe failed; raw Guile output follows:" >&2
cat "${debug_log}" >&2 || true
false
fi
}
src_configure() {
local host_triplet pkg_config_path guile_cflags guile_libs
local argp_cppflags argp_ldflags
local guile_site_path guile_site_ccache guile_core_ccache guile_ext_path
host_triplet="$(gcc -dumpmachine)"
pkg_config_path="${LIBDIR}/pkgconfig:${PREFIX}/lib/pkgconfig:${PREFIX}/share/pkgconfig"
guile_site_path="${PREFIX}/share/guile/site/3.0:${PREFIX}/share/guile/3.0"
guile_site_ccache="${LIBDIR}/guile/3.0/site-ccache"
guile_core_ccache="${LIBDIR}/guile/3.0/ccache"
guile_ext_path="${LIBDIR}/guile/3.0/extensions"
argp_cppflags="-I${KERNEL_SYSROOT}/include"
argp_ldflags="-L${KERNEL_SYSROOT}/lib"
guile_cflags="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --cflags guile-3.0)"
# Guix runtime loads Guile extensions such as guile-gnutls dynamically.
# Link against the shared libguile so those extensions reuse one runtime.
guile_libs="$(PKG_CONFIG_LIBDIR="${pkg_config_path}" PKG_CONFIG_PATH="${pkg_config_path}" \
/usr/bin/pkg-config --libs guile-3.0)"
probe_guile_module gnutls
probe_guile_module git
probe_guile_module zlib
probe_guile_module lzlib
probe_guile_module semver
PATH="${PREFIX}/bin:/usr/bin:/bin" \
PKG_CONFIG="/usr/bin/pkg-config" \
PKG_CONFIG_LIBDIR="${pkg_config_path}" \
PKG_CONFIG_PATH="${pkg_config_path}" \
LD_LIBRARY_PATH="${LIBDIR}:${PREFIX}/lib:${LD_LIBRARY_PATH}" \
GUILE_LOAD_PATH="${guile_site_path}" \
GUILE_LOAD_COMPILED_PATH="${guile_site_ccache}:${guile_core_ccache}" \
GUILE_SYSTEM_PATH="${guile_site_path}" \
GUILE_SYSTEM_COMPILED_PATH="${guile_site_ccache}:${guile_core_ccache}" \
GUILE_EXTENSIONS_PATH="${guile_ext_path}" \
GNUTLS_GUILE_EXTENSION_DIR="${guile_ext_path}" \
GUILE_CFLAGS="${guile_cflags}" \
GUILE_LIBS="${guile_libs}" \
CPPFLAGS="${argp_cppflags} ${CPPFLAGS:-}" \
LDFLAGS="${argp_ldflags} ${LDFLAGS:-}" \
LIBS="${LIBS:-} -largp" \
./configure \
--prefix="${PREFIX}" \
--libdir="${LIBDIR}" \
--sysconfdir=/etc \
--localstatedir=/var \
--host="${host_triplet}" \
--build="${host_triplet}"
}
src_compile() {
default_src_compile
}
src_install() {
default_src_install
}

View file

@ -0,0 +1,57 @@
--- a/gnu/packages/bootstrap.scm
+++ b/gnu/packages/bootstrap.scm
@@ -676,7 +676,45 @@
(substitute* '("bin/egrep" "bin/fgrep")
(("^exec grep") (string-append (getcwd) "/bin/grep"))))
(chmod "bin" #o555))))
+
+
+(define (bootstrap-mes-minimal-origin system)
+ (origin
+ (method url-fetch)
+ (uri (map (cut string-append <>
+ "/mes-minimal-stripped-0.19-i686-linux.tar.xz")
+ %bootstrap-base-urls))
+ (sha256
+ (match system
+ ((or "i686-linux" "x86_64-linux")
+ (base32 "@MES_MINIMAL_SEED_HASH@"))
+ (_
+ (base32 "@MES_MINIMAL_SEED_HASH@"))))))
+
+(define %bootstrap-mes-minimal
+ (package-from-tarball "mes-minimal-bootstrap"
+ bootstrap-mes-minimal-origin
+ "mes"
+ "Bootstrap Mes minimal binary seed"))
+
+(define (bootstrap-mescc-tools-origin system)
+ (origin
+ (method url-fetch)
+ (uri (map (cut string-append <>
+ "/mescc-tools-static-stripped-0.5.2-i686-linux.tar.xz")
+ %bootstrap-base-urls))
+ (sha256
+ (match system
+ ((or "i686-linux" "x86_64-linux")
+ (base32 "@MESCC_TOOLS_SEED_HASH@"))
+ (_
+ (base32 "@MESCC_TOOLS_SEED_HASH@"))))))
+(define %bootstrap-mescc-tools
+ (package-from-tarball "mescc-tools-bootstrap"
+ bootstrap-mescc-tools-origin
+ "M2-Planet"
+ "Bootstrap MesCC tools binary seed"))
(define-public %bootstrap-linux-libre-headers
(package-from-tarball
"linux-libre-headers-bootstrap"
@@ -1012,6 +1050,8 @@
("gcc" ,%bootstrap-gcc)
("binutils" ,%bootstrap-binutils)
("coreutils&co" ,%bootstrap-coreutils&co)
+ ("mes-minimal" ,%bootstrap-mes-minimal)
+ ("mescc-tools" ,%bootstrap-mescc-tools)
("bash" ,%bootstrap-coreutils&co)))
;;; bootstrap.scm ends here

View file

@ -0,0 +1,129 @@
--- a/gnu/packages/bootstrap.scm
+++ b/gnu/packages/bootstrap.scm
@@ -109,13 +109,13 @@
,(base32 "1cqqavghjfr0iwxqf61lrssv27wfigysgq2rs4rm1gkmn04yn1k3")))
("i686-linux"
("bash"
- ,(base32 "0rjaxyzjdllfkf1abczvgaf3cdcc7mmahyvdbkjmjzhgz92pv23g"))
+ ,(base32 "@EXEC_BASH_HASH@"))
("mkdir"
- ,(base32 "133ybmfpkmsnysrzbngwvbysqnsmfi8is8zifs7i7n6n600h4s1w"))
+ ,(base32 "@EXEC_MKDIR_HASH@"))
("tar"
- ,(base32 "07830bx29ad5i0l1ykj0g0b1jayjdblf01sr3ww9wbnwdbzinqms"))
+ ,(base32 "@EXEC_TAR_HASH@"))
("xz"
- ,(base32 "0i9kxdi17bm5gxfi2xzm0y73p3ii0cqxli1sbljm6rh2fjgyn90k")))
+ ,(base32 "@EXEC_XZ_HASH@")))
("i586-gnu"
("bash"
,(base32 "1as8649aqaibahhhrvkj10ci8shpi4hq5n7gnik8rhhy0dc1jarg"))
@@ -164,15 +164,12 @@
(define %bootstrap-executable-base-urls
;; This is where the bootstrap executables come from.
- '("https://ftpmirror.gnu.org/guix/bootstrap/"
- "https://git.savannah.gnu.org/cgit/guix.git/plain/gnu/packages/bootstrap/"
- "https://alpha.gnu.org/gnu/guix/bootstrap/"
- "http://flashner.co.il/guix/bootstrap/"
- "http://lilypond.org/janneke/guix/"))
+ '("http://127.0.0.1:38445/"))
(define (bootstrap-executable-file-name system program)
"Return the FILE-NAME part of url where PROGRAM can be found for SYSTEM."
(match system
+ ("i686-linux" (string-append "i686-linux/bootstrap-exec-" program "-i686-linux"))
("powerpc64le-linux" (string-append system "/20210106/" program))
("i586-gnu" (string-append system "/20200326/" program))
("x86_64-gnu" (string-append system "/20241122/" program))
@@ -388,15 +385,15 @@
("riscv64-linux"
"/20210725/guile-3.0.2.tar.xz")
(_
- "/20131110/guile-2.0.9.tar.xz"))))
+ "/guile-static-stripped-2.2.4-i686-linux.tar.xz"))))
(define (bootstrap-guile-hash system)
"Return the SHA256 hash of the Guile bootstrap tarball for SYSTEM."
(match system
("x86_64-linux"
- (base32 "1w2p5zyrglzzniqgvyn1b55vprfzhgk8vzbzkkbdgl5248si0yq3"))
+ (base32 "@GUILE_SEED_HASH@"))
("i686-linux"
- (base32 "0im800m30abgh7msh331pcbjvb4n02smz5cfzf1srv0kpx3csmxp"))
+ (base32 "@GUILE_SEED_HASH@"))
("mips64el-linux"
(base32 "0fzp93lvi0hn54acc0fpvhc7bvl0yc853k62l958cihk03q80ilr"))
("armhf-linux"
@@ -458,8 +455,8 @@
(lambda (p)
(format p "\
#!~a
-export GUILE_SYSTEM_PATH=~a/share/guile/2.0
-export GUILE_SYSTEM_COMPILED_PATH=~a/lib/guile/2.0/ccache
+export GUILE_SYSTEM_PATH=~a/share/guile/2.2
+export GUILE_SYSTEM_COMPILED_PATH=~a/lib/guile/2.2/ccache
exec -a \"~a0\" ~a \"~a@\"\n"
bash out out dollar guile-real dollar)))
(chmod guile #o555)
@@ -480,8 +477,8 @@
~a -dc < $GUILE_TARBALL | ~a xv
# Use the bootstrap guile to create its own wrapper to set the load path.
-GUILE_SYSTEM_PATH=$out/share/guile/2.0 \
-GUILE_SYSTEM_COMPILED_PATH=$out/lib/guile/2.0/ccache \
+GUILE_SYSTEM_PATH=$out/share/guile/2.2 \
+GUILE_SYSTEM_COMPILED_PATH=$out/lib/guile/2.2/ccache \
$out/bin/guile -c ~s $out ~a
# Sanity check.
@@ -625,16 +622,16 @@
("riscv64-linux"
"/20210725/static-binaries.tar.xz")
(_
- "/20131110/static-binaries.tar.xz")))
+ "/static-binaries-0-i686-linux.tar.xz")))
%bootstrap-base-urls))
(sha256
(match system
("x86_64-linux"
(base32
- "0c533p9dhczzcsa1117gmfq3pc8w362g4mx84ik36srpr7cx2bg4"))
+ "@STATIC_BINARIES_SEED_HASH@"))
("i686-linux"
(base32
- "0s5b3jb315n13m1k8095l0a5hfrsz8g0fv1b6riyc5hnxqyphlak"))
+ "@STATIC_BINARIES_SEED_HASH@"))
("armhf-linux"
(base32
"0gf0fn2kbpxkjixkmx5f4z6hv6qpmgixl69zgg74dbsfdfj8jdv5"))
@@ -989,11 +1022,15 @@
;; own packages.
(match (%current-system)
((or "i686-linux" "x86_64-linux")
- `(("linux-libre-headers" ,%bootstrap-linux-libre-headers)))
+ `(("linux-libre-headers" ,%bootstrap-linux-libre-headers)
+ ("mes-minimal" ,%bootstrap-mes-minimal)
+ ("mescc-tools" ,%bootstrap-mescc-tools)))
(_
`(("libc" ,%bootstrap-glibc)
("gcc" ,%bootstrap-gcc)
("binutils" ,%bootstrap-binutils)
("coreutils&co" ,%bootstrap-coreutils&co)
+ ("mes-minimal" ,%bootstrap-mes-minimal)
+ ("mescc-tools" ,%bootstrap-mescc-tools)
;; In gnu-build-system.scm, we rely on the availability of Bash.
("bash" ,%bootstrap-coreutils&co)))))
--- a/guix/channels.scm
+++ b/guix/channels.scm
@@ -194,8 +194,8 @@
(introduction %guix-channel-introduction)))
(define %default-channels
- ;; Default list of channels.
- (list %default-guix-channel))
+ ;; Offline bootstrap environment: require explicit channels.
+ '())
(define (guix-channel? channel)
"Return true if CHANNEL is the 'guix' channel."

View file

@ -0,0 +1,34 @@
--- guix-1.5.0/gnu/packages/bootstrap.scm
+++ guix-1.5.0/gnu/packages/bootstrap.scm
@@ -357,8 +357,9 @@
;;; Bootstrap packages.
;;;
-(define %bootstrap-base-urls
- ;; This is where the initial binaries come from.
+(define %bootstrap-linux-headers-base-urls
+ ;; Keep linux headers as an explicit exception: text headers can still come
+ ;; from the historical bootstrap mirrors.
'("https://ftpmirror.gnu.org/guix/bootstrap/"
"https://ftp.gnu.org/gnu/guix/bootstrap"
"https://alpha.gnu.org/gnu/guix/bootstrap"
@@ -369,6 +370,10 @@
"http://flashner.co.il/guix/bootstrap"
"http://lilypond.org/janneke/guix/"))
+(define %bootstrap-base-urls
+ ;; All bootstrap binaries must come from the local bootstrap mirror.
+ '("http://127.0.0.1:38445"))
+
(define (bootstrap-guile-url-path system)
"Return the URI for FILE."
(string-append "/" system
@@ -684,7 +689,7 @@
(uri (map (cute string-append <>
"/i686-linux/20190815/"
"linux-libre-headers-stripped-4.14.67-i686-linux.tar.xz")
- %bootstrap-base-urls))
+ %bootstrap-linux-headers-base-urls))
(sha256
(base32
"0sm2z9x4wk45bh6qfs94p0w1d6hsy6dqx9sw38qsqbvxwa1qzk8s"))))

View file

@ -0,0 +1,14 @@
--- guix-1.5.0/m4/guix.m4
+++ guix-1.5.0/m4/guix.m4
@@ -207,8 +207,9 @@
[guix_cv_have_recent_guile_gcrypt],
[GUILE_CHECK([retval],
[(use-modules (gcrypt hash))
- (equal? (hash-algorithm sha256)
- (lookup-hash-algorithm 'sha256))])
+ (let ((algorithm (lookup-hash-algorithm 'sha256)))
+ (and algorithm
+ (= 32 (hash-size algorithm))))])
if test "$retval" = 0; then
guix_cv_have_recent_guile_gcrypt="yes"
else

View file

@ -0,0 +1 @@
f https://ftpmirror.gnu.org/gnu/guix/guix-1.5.0.tar.gz df2102eed00aff0b17275654a42f094c8a1117ec065884eb1ff76005e47415c5

View file

@ -0,0 +1,570 @@
#define _POSIX_C_SOURCE 200809L
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define SHA256_BLOCK_SIZE 32
struct sha256_ctx {
uint8_t data[64];
uint32_t datalen;
uint64_t bitlen;
uint32_t state[8];
};
static const uint32_t k256[64] = {
0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U,
0x3956c25bU, 0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U,
0xd807aa98U, 0x12835b01U, 0x243185beU, 0x550c7dc3U,
0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U, 0xc19bf174U,
0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU,
0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU,
0x983e5152U, 0xa831c66dU, 0xb00327c8U, 0xbf597fc7U,
0xc6e00bf3U, 0xd5a79147U, 0x06ca6351U, 0x14292967U,
0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU, 0x53380d13U,
0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U,
0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U,
0xd192e819U, 0xd6990624U, 0xf40e3585U, 0x106aa070U,
0x19a4c116U, 0x1e376c08U, 0x2748774cU, 0x34b0bcb5U,
0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU, 0x682e6ff3U,
0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U,
0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U
};
#define ROTRIGHT(a, b) (((a) >> (b)) | ((a) << (32 - (b))))
#define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
#define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#define EP0(x) (ROTRIGHT((x), 2) ^ ROTRIGHT((x), 13) ^ ROTRIGHT((x), 22))
#define EP1(x) (ROTRIGHT((x), 6) ^ ROTRIGHT((x), 11) ^ ROTRIGHT((x), 25))
#define SIG0(x) (ROTRIGHT((x), 7) ^ ROTRIGHT((x), 18) ^ ((x) >> 3))
#define SIG1(x) (ROTRIGHT((x), 17) ^ ROTRIGHT((x), 19) ^ ((x) >> 10))
static void sha256_transform(struct sha256_ctx *ctx, const uint8_t data[]) {
uint32_t a, b, c, d, e, f, g, h;
uint32_t t1, t2, m[64];
uint32_t i;
for (i = 0; i < 16; ++i) {
m[i] = ((uint32_t)data[i * 4] << 24) |
((uint32_t)data[i * 4 + 1] << 16) |
((uint32_t)data[i * 4 + 2] << 8) |
((uint32_t)data[i * 4 + 3]);
}
for (; i < 64; ++i) {
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
}
a = ctx->state[0];
b = ctx->state[1];
c = ctx->state[2];
d = ctx->state[3];
e = ctx->state[4];
f = ctx->state[5];
g = ctx->state[6];
h = ctx->state[7];
for (i = 0; i < 64; ++i) {
t1 = h + EP1(e) + CH(e, f, g) + k256[i] + m[i];
t2 = EP0(a) + MAJ(a, b, c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
ctx->state[0] += a;
ctx->state[1] += b;
ctx->state[2] += c;
ctx->state[3] += d;
ctx->state[4] += e;
ctx->state[5] += f;
ctx->state[6] += g;
ctx->state[7] += h;
}
static void sha256_init(struct sha256_ctx *ctx) {
ctx->datalen = 0;
ctx->bitlen = 0;
ctx->state[0] = 0x6a09e667U;
ctx->state[1] = 0xbb67ae85U;
ctx->state[2] = 0x3c6ef372U;
ctx->state[3] = 0xa54ff53aU;
ctx->state[4] = 0x510e527fU;
ctx->state[5] = 0x9b05688cU;
ctx->state[6] = 0x1f83d9abU;
ctx->state[7] = 0x5be0cd19U;
}
static void sha256_update(struct sha256_ctx *ctx, const uint8_t *data, size_t len) {
size_t i;
for (i = 0; i < len; ++i) {
ctx->data[ctx->datalen] = data[i];
ctx->datalen++;
if (ctx->datalen == 64) {
sha256_transform(ctx, ctx->data);
ctx->bitlen += 512;
ctx->datalen = 0;
}
}
}
static void sha256_final(struct sha256_ctx *ctx, uint8_t hash[SHA256_BLOCK_SIZE]) {
uint32_t i;
i = ctx->datalen;
if (ctx->datalen < 56) {
ctx->data[i++] = 0x80;
while (i < 56) {
ctx->data[i++] = 0;
}
} else {
ctx->data[i++] = 0x80;
while (i < 64) {
ctx->data[i++] = 0;
}
sha256_transform(ctx, ctx->data);
memset(ctx->data, 0, 56);
}
ctx->bitlen += (uint64_t)ctx->datalen * 8;
ctx->data[63] = (uint8_t)(ctx->bitlen);
ctx->data[62] = (uint8_t)(ctx->bitlen >> 8);
ctx->data[61] = (uint8_t)(ctx->bitlen >> 16);
ctx->data[60] = (uint8_t)(ctx->bitlen >> 24);
ctx->data[59] = (uint8_t)(ctx->bitlen >> 32);
ctx->data[58] = (uint8_t)(ctx->bitlen >> 40);
ctx->data[57] = (uint8_t)(ctx->bitlen >> 48);
ctx->data[56] = (uint8_t)(ctx->bitlen >> 56);
sha256_transform(ctx, ctx->data);
for (i = 0; i < 4; ++i) {
hash[i] = (uint8_t)((ctx->state[0] >> (24 - i * 8)) & 0xff);
hash[i + 4] = (uint8_t)((ctx->state[1] >> (24 - i * 8)) & 0xff);
hash[i + 8] = (uint8_t)((ctx->state[2] >> (24 - i * 8)) & 0xff);
hash[i + 12] = (uint8_t)((ctx->state[3] >> (24 - i * 8)) & 0xff);
hash[i + 16] = (uint8_t)((ctx->state[4] >> (24 - i * 8)) & 0xff);
hash[i + 20] = (uint8_t)((ctx->state[5] >> (24 - i * 8)) & 0xff);
hash[i + 24] = (uint8_t)((ctx->state[6] >> (24 - i * 8)) & 0xff);
hash[i + 28] = (uint8_t)((ctx->state[7] >> (24 - i * 8)) & 0xff);
}
}
static void die_perror(const char *msg) {
fprintf(stderr, "%s: %s\n", msg, strerror(errno));
exit(1);
}
static void die_msg(const char *msg) {
fprintf(stderr, "%s\n", msg);
exit(1);
}
static void sha_update_u32le_in_8(struct sha256_ctx *ctx, uint32_t n) {
uint8_t b[8] = {0, 0, 0, 0, 0, 0, 0, 0};
b[0] = (uint8_t)(n & 0xffU);
b[1] = (uint8_t)((n >> 8) & 0xffU);
b[2] = (uint8_t)((n >> 16) & 0xffU);
b[3] = (uint8_t)((n >> 24) & 0xffU);
sha256_update(ctx, b, sizeof(b));
}
static void sha_update_u64le(struct sha256_ctx *ctx, uint64_t n) {
uint8_t b[8];
b[0] = (uint8_t)(n & 0xffU);
b[1] = (uint8_t)((n >> 8) & 0xffU);
b[2] = (uint8_t)((n >> 16) & 0xffU);
b[3] = (uint8_t)((n >> 24) & 0xffU);
b[4] = (uint8_t)((n >> 32) & 0xffU);
b[5] = (uint8_t)((n >> 40) & 0xffU);
b[6] = (uint8_t)((n >> 48) & 0xffU);
b[7] = (uint8_t)((n >> 56) & 0xffU);
sha256_update(ctx, b, sizeof(b));
}
static void nar_write_padding(struct sha256_ctx *ctx, size_t n) {
static const uint8_t zeros[8] = {0, 0, 0, 0, 0, 0, 0, 0};
size_t m = n % 8;
if (m != 0) {
sha256_update(ctx, zeros, 8 - m);
}
}
static void nar_write_string_n(struct sha256_ctx *ctx, const char *s, size_t n) {
if (n > UINT32_MAX) {
die_msg("string too long for NAR serialization");
}
sha_update_u32le_in_8(ctx, (uint32_t)n);
if (n > 0) {
sha256_update(ctx, (const uint8_t *)s, n);
}
nar_write_padding(ctx, n);
}
static void nar_write_string(struct sha256_ctx *ctx, const char *s) {
nar_write_string_n(ctx, s, strlen(s));
}
static void sha_update_from_fd(struct sha256_ctx *ctx, int fd, uint64_t *out_size) {
uint8_t buf[65536];
ssize_t n;
uint64_t total = 0;
for (;;) {
n = read(fd, buf, sizeof(buf));
if (n == 0) {
break;
}
if (n < 0) {
die_perror("read failed");
}
sha256_update(ctx, buf, (size_t)n);
total += (uint64_t)n;
}
if (out_size != NULL) {
*out_size = total;
}
}
static char *join_path(const char *dir, const char *name) {
size_t a = strlen(dir);
size_t b = strlen(name);
int need_slash = (a > 0 && dir[a - 1] != '/');
char *out = malloc(a + (size_t)need_slash + b + 1);
if (out == NULL) {
die_msg("out of memory");
}
memcpy(out, dir, a);
if (need_slash) {
out[a] = '/';
}
memcpy(out + a + (size_t)need_slash, name, b);
out[a + (size_t)need_slash + b] = '\0';
return out;
}
static int cmp_cstring_ptr(const void *a, const void *b) {
const char *const *sa = (const char *const *)a;
const char *const *sb = (const char *const *)b;
return strcmp(*sa, *sb);
}
static void nar_dump_path(struct sha256_ctx *ctx, const char *path);
static void nar_dump_directory(struct sha256_ctx *ctx, const char *path) {
DIR *dir;
struct dirent *de;
char **entries = NULL;
size_t count = 0;
size_t cap = 0;
size_t i;
dir = opendir(path);
if (dir == NULL) {
die_perror("opendir failed");
}
for (;;) {
errno = 0;
de = readdir(dir);
if (de == NULL) {
if (errno != 0) {
closedir(dir);
die_perror("readdir failed");
}
break;
}
if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) {
continue;
}
if (count == cap) {
size_t new_cap = (cap == 0) ? 16 : cap * 2;
char **new_entries = realloc(entries, new_cap * sizeof(char *));
if (new_entries == NULL) {
closedir(dir);
die_msg("out of memory");
}
entries = new_entries;
cap = new_cap;
}
entries[count] = strdup(de->d_name);
if (entries[count] == NULL) {
closedir(dir);
die_msg("out of memory");
}
count++;
}
if (closedir(dir) != 0) {
die_perror("closedir failed");
}
qsort(entries, count, sizeof(char *), cmp_cstring_ptr);
nar_write_string(ctx, "(");
nar_write_string(ctx, "type");
nar_write_string(ctx, "directory");
for (i = 0; i < count; ++i) {
char *child = join_path(path, entries[i]);
nar_write_string(ctx, "entry");
nar_write_string(ctx, "(");
nar_write_string(ctx, "name");
nar_write_string(ctx, entries[i]);
nar_write_string(ctx, "node");
nar_dump_path(ctx, child);
nar_write_string(ctx, ")");
free(child);
free(entries[i]);
}
free(entries);
nar_write_string(ctx, ")");
}
static void nar_dump_regular(struct sha256_ctx *ctx, const char *path, mode_t mode) {
int fd;
uint64_t size;
fd = open(path, O_RDONLY);
if (fd < 0) {
die_perror("open failed");
}
nar_write_string(ctx, "(");
nar_write_string(ctx, "type");
nar_write_string(ctx, "regular");
if ((mode & 0100) != 0) {
nar_write_string(ctx, "executable");
nar_write_string(ctx, "");
}
nar_write_string(ctx, "contents");
size = 0;
{
struct stat st;
if (fstat(fd, &st) != 0) {
close(fd);
die_perror("fstat failed");
}
size = (uint64_t)st.st_size;
}
sha_update_u64le(ctx, size);
sha_update_from_fd(ctx, fd, NULL);
nar_write_padding(ctx, (size_t)(size % 8));
if (close(fd) != 0) {
die_perror("close failed");
}
nar_write_string(ctx, ")");
}
static void nar_dump_symlink(struct sha256_ctx *ctx, const char *path) {
ssize_t n;
size_t buf_size = 256;
char *buf = NULL;
for (;;) {
char *new_buf = realloc(buf, buf_size);
if (new_buf == NULL) {
free(buf);
die_msg("out of memory");
}
buf = new_buf;
n = readlink(path, buf, buf_size);
if (n < 0) {
free(buf);
die_perror("readlink failed");
}
if ((size_t)n < buf_size) {
break;
}
buf_size *= 2;
}
nar_write_string(ctx, "(");
nar_write_string(ctx, "type");
nar_write_string(ctx, "symlink");
nar_write_string(ctx, "target");
nar_write_string_n(ctx, buf, (size_t)n);
nar_write_string(ctx, ")");
free(buf);
}
static void nar_dump_path(struct sha256_ctx *ctx, const char *path) {
struct stat st;
if (lstat(path, &st) != 0) {
die_perror("lstat failed");
}
if (S_ISDIR(st.st_mode)) {
nar_dump_directory(ctx, path);
return;
}
if (S_ISREG(st.st_mode)) {
nar_dump_regular(ctx, path, st.st_mode);
return;
}
if (S_ISLNK(st.st_mode)) {
nar_dump_symlink(ctx, path);
return;
}
fprintf(stderr, "unsupported file type: %s\n", path);
exit(1);
}
static void hash_flat_file(const char *path, uint8_t out[SHA256_BLOCK_SIZE]) {
struct sha256_ctx ctx;
int fd;
sha256_init(&ctx);
if (strcmp(path, "-") == 0) {
sha_update_from_fd(&ctx, STDIN_FILENO, NULL);
} else {
fd = open(path, O_RDONLY);
if (fd < 0) {
die_perror("open failed");
}
sha_update_from_fd(&ctx, fd, NULL);
if (close(fd) != 0) {
die_perror("close failed");
}
}
sha256_final(&ctx, out);
}
static void hash_nar_path(const char *path, uint8_t out[SHA256_BLOCK_SIZE]) {
struct sha256_ctx ctx;
sha256_init(&ctx);
nar_write_string(&ctx, "nix-archive-1");
nar_dump_path(&ctx, path);
sha256_final(&ctx, out);
}
static uint8_t bytevector_quintet_ref_right(const uint8_t *bv, size_t bv_len, size_t index) {
size_t offset = (index * 5) / 8;
uint8_t a = (offset < bv_len) ? bv[offset] : 0;
uint8_t b = ((offset + 1) < bv_len) ? bv[offset + 1] : 0;
switch (index % 8) {
case 0:
return a & 0x1fU;
case 1:
return (uint8_t)(((a >> 5) & 0x07U) | ((b & 0x03U) << 3));
case 2:
return (uint8_t)((a >> 2) & 0x1fU);
case 3:
return (uint8_t)(((a >> 7) & 0x01U) | ((b & 0x0fU) << 1));
case 4:
return (uint8_t)(((a >> 4) & 0x0fU) | ((b & 0x01U) << 4));
case 5:
return (uint8_t)((a >> 1) & 0x1fU);
case 6:
return (uint8_t)(((a >> 6) & 0x03U) | ((b & 0x07U) << 2));
case 7:
return (uint8_t)((a >> 3) & 0x1fU);
default:
return 0;
}
}
static void sha256_to_nix_base32(const uint8_t digest[SHA256_BLOCK_SIZE], char out[53]) {
static const char alphabet[] = "0123456789abcdfghijklmnpqrsvwxyz";
const size_t quintets = (SHA256_BLOCK_SIZE * 8 + 4) / 5;
size_t i;
for (i = 0; i < quintets; ++i) {
size_t idx = quintets - 1 - i;
uint8_t q = bytevector_quintet_ref_right(digest, SHA256_BLOCK_SIZE, idx);
out[i] = alphabet[q & 0x1fU];
}
out[quintets] = '\0';
}
static void usage(const char *prog) {
fprintf(stderr,
"Usage: %s [OPTION] FILE\n"
" -r, --recursive hash FILE using NAR serialization\n",
prog);
}
int main(int argc, char **argv) {
int recursive = 0;
int i;
int first_arg = 1;
for (i = 1; i < argc; ++i) {
if (strcmp(argv[i], "--") == 0) {
first_arg = i + 1;
break;
}
if (argv[i][0] != '-') {
first_arg = i;
break;
}
if (strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "--recursive") == 0) {
recursive = 1;
continue;
}
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
usage(argv[0]);
return 0;
}
fprintf(stderr, "unsupported option: %s\n", argv[i]);
usage(argv[0]);
return 1;
}
if (first_arg >= argc) {
fprintf(stderr, "no arguments specified\n");
usage(argv[0]);
return 1;
}
for (i = first_arg; i < argc; ++i) {
uint8_t digest[SHA256_BLOCK_SIZE];
char out[53];
if (recursive) {
hash_nar_path(argv[i], digest);
} else {
hash_flat_file(argv[i], digest);
}
sha256_to_nix_base32(digest, out);
puts(out);
}
return 0;
}

View file

@ -0,0 +1,24 @@
# SPDX-License-Identifier: GPL-3.0-or-later
src_prepare() {
default
}
src_configure() {
:
}
src_compile() {
gcc \
-O2 \
-std=c99 \
-Wall \
-Wextra \
-Werror \
-o guix-hash-compat \
guix-hash-compat.c
}
src_install() {
install -D -m 0755 guix-hash-compat "${DESTDIR}/usr/bin/guix-hash-compat"
}

View file

@ -0,0 +1 @@
f https://ftpmirror.gnu.org/gnu/guix/guix-1.5.0.tar.gz df2102eed00aff0b17275654a42f094c8a1117ec065884eb1ff76005e47415c5

View file

@ -0,0 +1,18 @@
# SPDX-License-Identifier: GPL-3.0-or-later
SEED_PREFIX="/bootstrap-seeds/gzip-1.9"
src_configure() {
CFLAGS="-O2" LDFLAGS="-static" ./configure \
--prefix="${SEED_PREFIX}" \
--disable-nls \
ac_cv_prog_LESS="less"
}
src_compile() {
default_src_compile
}
src_install() {
make DESTDIR="${DESTDIR}" install
}

View file

@ -0,0 +1 @@
f https://mirrors.kernel.org/gnu/gzip/gzip-1.9.tar.xz ae506144fc198bd8f81f1f4ad19ce63d5a2d65e42333255977cf1dcf1479089a

704
steps-guix/helpers.sh Executable file
View file

@ -0,0 +1,704 @@
#!/bin/bash -e
# SPDX-FileCopyrightText: 2021 Andrius Štikonas <andrius@stikonas.eu>
# SPDX-FileCopyrightText: 2021-22 Samuel Tyler <samuel@samuelt.me>
# SPDX-FileCopyrightText: 2021 Paul Dersey <pdersey@gmail.com>
# SPDX-FileCopyrightText: 2021 Melg Eight <public.melg8@gmail.com>
#
# SPDX-License-Identifier: GPL-3.0-or-later
# Set constant umask
umask 022
resume_network_init() {
local cfg_root
cfg_root="${1:-/steps}"
if [ -f "${cfg_root}/bootstrap.cfg" ]; then
# shellcheck source=/dev/null
. "${cfg_root}/bootstrap.cfg"
fi
if [ -f "${cfg_root}/env" ]; then
# shellcheck source=/dev/null
. "${cfg_root}/env"
fi
mount | grep ' on /dev ' >/dev/null 2>&1 || (mkdir -p /dev; mount -t devtmpfs devtmpfs /dev)
mount | grep ' on /proc ' >/dev/null 2>&1 || (mkdir -p /proc; mount -t proc proc /proc)
if [ "${CHROOT}" = False ] && [ "${NETWORK_READY}" = True ] && command -v dhcpcd >/dev/null 2>&1; then
dhcpcd --waitip=4 || true
fi
}
# Get a list of files
get_files() {
echo "."
_get_files "${1}"
}
_get_files() {
local prefix
prefix="${1}"
fs=
if [ -n "$(ls 2>/dev/null)" ]; then
fs=$(echo *)
fi
if [ -n "$(ls .[0-z]* 2>/dev/null)" ]; then
fs="${fs} $(echo .[0-z]*)"
fi
for f in ${fs}; do
# Archive symlinks to directories as symlinks
echo "${prefix}/${f}"
if [ -d "./${f}" ] && ! [ -h "./${f}" ]; then
cd "./${f}"
_get_files "${prefix}/${f}"
cd ..
fi
done
}
# Reset all timestamps to unix time 0
reset_timestamp() {
if command -v find >/dev/null 2>&1; then
# find does not error out on exec error
find . -print0 | xargs -0 touch -h -t 197001010000.00
else
# A rudimentary find implementation that does the trick
fs=
if [ -n "$(ls 2>/dev/null)" ]; then
fs=$(echo ./*)
fi
if [ -n "$(ls .[0-z]* 2>/dev/null)" ]; then
fs="${fs} $(echo .[0-z]*)"
fi
for f in ${fs}; do
touch -h -t 197001010000.00 "./${f}"
if [ -d "./${f}" ]; then
cd "./${f}"
reset_timestamp
cd ..
fi
done
fi
}
# Fake grep
_grep() {
local text="${1}"
local fname="${2}"
if command -v grep >/dev/null 2>&1; then
grep "${text}" "${fname}"
else
# shellcheck disable=SC2162
while read line; do
case "${line}" in *"${text}"*)
echo "${line}" ;;
esac
done < "${fname}"
fi
}
# Useful for perl extensions
get_perl_version() {
perl -v | sed -n -re 's/.*[ (]v([0-9\.]*)[ )].*/\1/p'
}
get_revision() {
local pkg=$1
local oldpwd="${PWD}"
cd "/external/repo"
# Get revision (n time this package has been built)
revision=$( (ls -1 "${pkg}"* 2>/dev/null || true) | wc -l | sed 's/ *//g')
cd "${oldpwd}"
}
# Installs binary packages from an earlier run
# This is useful to speed up development cycle
bin_preseed() {
if [ -d "/external/repo-preseeded" ]; then
get_revision "${pkg}"
cd "/external/repo-preseeded"
test -e "${pkg}_${revision}.tar.bz2" || return 1
if [ "${UPDATE_CHECKSUMS}" = "True" ] || src_checksum "${pkg}" $((revision)); then
echo "${pkg}: installing prebuilt package."
mv "${pkg}_${revision}.tar.bz2" /external/repo || return 1
cd "/external/repo"
rm -f /tmp/filelist.txt
src_apply "${pkg}" $((revision))
cd "${SRCDIR}"
return 0
fi
fi
return 1
}
# Removes either an existing package or file
uninstall() {
local in_fs in_pkg symlinks
while [ $# -gt 0 ]; do
removing="$1"
case "${removing}" in
/*)
# Removing a file
echo "removing file: ${removing}."
rm -f "${removing}"
;;
*)
echo "${removing}: uninstalling."
local oldpwd="${PWD}"
mkdir -p "/tmp/removing"
cd "/tmp/removing"
get_revision "${removing}"
local filename="/external/repo/${removing}_$((revision-1)).tar.bz2"
# Initial bzip2 built against meslibc has broken pipes
bzip2 -dc "${filename}" | tar -xf -
# reverse to have files before directories
if command -v find >/dev/null 2>&1; then
find . | sort -r > ../filelist
else
get_files . | tac > ../filelist
fi
# shellcheck disable=SC2162
while read file; do
if [ -d "${file}" ]; then
if [ -z "$(ls -A "/${file}")" ]; then
rmdir "/${file}"
fi
elif [ -h "${file}" ]; then
symlinks="${symlinks} ${file}"
else
# in some cases we might be uninstalling a file that has already been overwritten
# in this case we don't want to remove it
in_fs="$(sha256sum "${file}" 2>/dev/null | cut -d' ' -f1)"
in_pkg="$(sha256sum "/${file}" 2>/dev/null | cut -d' ' -f1)"
if [ "${in_fs}" = "${in_pkg}" ]; then
rm -f "/${file}"
fi
fi
done < ../filelist
rm -f ../filelist
for link in ${symlinks}; do
if [ ! -e "/${link}" ]; then
rm -f "/${link}"
fi
done
cd "${oldpwd}"
rm -rf "/tmp/removing"
;;
esac
shift
done
}
# Common build steps
# Build function provides a few common stages with default implementation
# that can be overridden on per package basis in the build script.
# build takes two arguments:
# 1) name-version of the package
# 2) optionally specify build script. Default is pass$((revision+1)).sh
# 3) optionally specify directory to cd into
build() {
pkg=$1
get_revision "${pkg}"
script_name=${2:-pass$((revision+1)).sh}
dirname=${3:-${pkg}}
# shellcheck disable=SC2015
bin_preseed && return || true # Normal build if preseed fails
cd "${SRCDIR}/${pkg}" || (echo "Cannot cd into ${pkg}!"; kill $$)
echo "${pkg}: beginning build using script ${script_name}"
base_dir="${PWD}"
if [ -e "${base_dir}/patches-$(basename "${script_name}" .sh)" ]; then
patch_dir="${base_dir}/patches-$(basename "${script_name}" .sh)"
else
patch_dir="${base_dir}/patches"
fi
mk_dir="${base_dir}/mk"
files_dir="${base_dir}/files"
rm -rf "build"
mkdir "build"
cd "build"
build_script="${base_dir}/${script_name}"
if test -e "${build_script}"; then
# shellcheck source=/dev/null
. "${build_script}"
fi
echo "${pkg}: getting sources."
build_stage=src_get
call $build_stage
echo "${pkg}: unpacking source."
build_stage=src_unpack
call $build_stage
unset EXTRA_DISTFILES
cd "${dirname}" || (echo "Cannot cd into build/${dirname}!"; kill $$)
echo "${pkg}: preparing source."
build_stage=src_prepare
call $build_stage
echo "${pkg}: configuring source."
build_stage=src_configure
call $build_stage
echo "${pkg}: compiling source."
build_stage=src_compile
call $build_stage
echo "${pkg}: install to fakeroot."
mkdir -p "${DESTDIR}"
build_stage=src_install
call $build_stage
echo "${pkg}: postprocess binaries."
build_stage=src_postprocess
call $build_stage
echo "${pkg}: creating package."
cd "${DESTDIR}"
src_pkg
src_checksum "${pkg}" "${revision}"
echo "${pkg}: cleaning up."
rm -rf "${SRCDIR}/${pkg}/build"
rm -rf "${DESTDIR}"
echo "${pkg}: installing package."
src_apply "${pkg}" "${revision}"
echo "${pkg}: build successful"
cd "${SRCDIR}"
unset -f src_get src_unpack src_prepare src_configure src_compile src_install src_postprocess
unset extract
}
# An inventive way to randomise with what we know we always have
randomize() {
if command -v shuf >/dev/null 2>&1; then
# shellcheck disable=SC2086
shuf -e ${1} | tr '\n' ' '
else
mkdir -p /tmp/random
for item in ${1}; do
touch --date=@${RANDOM} /tmp/random/"${item//\//~*~*}"
done
# cannot rely on find existing
# shellcheck disable=SC2012
ls -1 -t /tmp/random | sed 's:~\*~\*:/:g' | tr '\n' ' '
rm -r /tmp/random
fi
}
ensure_network_ready() {
if [ "${NETWORK_READY}" = "True" ]; then
return
fi
# Resumed QEMU boots (e.g. from stage0-work.img) can lose configured links.
# Bring the interface up deterministically before any source download.
if [ "${QEMU}" = "True" ] && [ "${CHROOT}" != "True" ]; then
dhcpcd --waitip=4
fi
NETWORK_READY=True
}
download_source_line() {
upstream_url="${1}"
checksum="${2}"
fname="${3}"
if ! [ -e "${fname}" ]; then
for mirror in $(randomize "${MIRRORS}"); do
# In qemu SimpleMirror is not running on the guest os, use qemu IP
case "${QEMU}-${mirror}" in 'True-http://127.0.0.1'*)
mirror="http://10.0.2.2${mirror#'http://127.0.0.1'}"
esac
mirror_url="${mirror}/${fname}"
echo "${mirror_url}"
curl --fail --retry 3 --location "${mirror_url}" --output "${fname}" || true && break
done
if ! [ -e "${fname}" ] && [ "${upstream_url}" != "_" ]; then
curl --fail --retry 3 --location "${upstream_url}" --output "${fname}" || true
fi
fi
}
check_source_line() {
url="${1}"
checksum="${2}"
fname="${3}"
if ! [ -e "${fname}" ]; then
echo "${fname} does not exist!"
false
fi
echo "${checksum} ${fname}" > "${fname}.sum"
sha256sum -c "${fname}.sum"
rm "${fname}.sum"
}
source_line_action() {
action="$1"
shift
type="$1"
shift
case $type in
"g" | "git")
shift
;;
esac
url="${1}"
checksum="${2}"
fname="${3}"
# Default to basename of url if not given
fname="${fname:-$(basename "${url}")}"
$action "$url" "$checksum" "$fname"
}
# Default get function that downloads source tarballs.
default_src_get() {
ensure_network_ready
# shellcheck disable=SC2153
cd "${DISTFILES}"
# shellcheck disable=SC2162
while read line; do
# This is intentional - we want to split out ${line} into separate arguments.
# shellcheck disable=SC2086
source_line_action download_source_line ${line}
done < "${base_dir}/sources"
# shellcheck disable=SC2162
while read line; do
# This is intentional - we want to split out ${line} into separate arguments.
# shellcheck disable=SC2086
source_line_action check_source_line ${line}
done < "${base_dir}/sources"
cd -
}
# Intelligently extracts a file based upon its filetype.
extract_file() {
f="${3:-$(basename "${1}")}"
# shellcheck disable=SC2154
case "${noextract}" in
*${f}*)
cp "${DISTFILES}/${f}" .
;;
*)
case "${f}" in
*.tar* | *.tgz)
# shellcheck disable=SC2153
if test -e "${PREFIX}/libexec/rmt"; then
# Again, we want to split out into words.
# shellcheck disable=SC2086
tar --no-same-owner -xf "${DISTFILES}/${f}" ${extract}
else
# shellcheck disable=SC2086
case "${f}" in
*.tar.gz) tar -xzf "${DISTFILES}/${f}" ${extract} ;;
*.tar.bz2)
# Initial bzip2 built against meslibc has broken pipes
bzip2 -dc "${DISTFILES}/${f}" | tar -xf - ${extract} ;;
*.tar.xz | *.tar.lzma)
if test -e "${PREFIX}/bin/xz"; then
tar -xf "${DISTFILES}/${f}" --use-compress-program=xz ${extract}
else
unxz --file "${DISTFILES}/${f}" | tar -xf - ${extract}
fi
;;
esac
fi
;;
*)
cp "${DISTFILES}/${f}" .
;;
esac
;;
esac
}
# Default unpacking function that unpacks all sources.
default_src_unpack() {
# Handle the first one differently
first_line=$(head -n 1 ../sources)
# Again, we want to split out into words.
# shellcheck disable=SC2086
source_line_action extract_file ${first_line}
# This assumes there is only one directory in the tarball
# Get the dirname "smartly"
if ! [ -e "${dirname}" ]; then
for i in *; do
if [ -d "${i}" ]; then
dirname="${i}"
break
fi
done
fi
if ! [ -e "${dirname}" ]; then
# there are no directories extracted
dirname=.
fi
# shellcheck disable=SC2162
tail -n +2 ../sources | while read line; do
# shellcheck disable=SC2086
source_line_action extract_file ${line}
done
}
# Default function to prepare source code.
# It applies all patches from patch_dir (at the moment only -p0 patches are supported).
# Patches are applied from the parent directory.
# Then it copies our custom makefile and any other custom files from files directory.
default_src_prepare() {
if test -d "${patch_dir}"; then
if ls "${patch_dir}"/*.patch >/dev/null 2>&1; then
for p in "${patch_dir}"/*.patch; do
echo "Applying patch: ${p}"
patch -d.. -Np0 < "${p}"
done
fi
fi
makefile="${mk_dir}/main.mk"
if test -e "${makefile}"; then
cp "${makefile}" Makefile
fi
if test -d "${files_dir}"; then
cp --no-preserve=mode "${files_dir}"/* "${PWD}/"
fi
}
# Default function for configuring source.
default_src_configure() {
:
}
# Default function for compiling source. It simply runs make without any parameters.
default_src_compile() {
make "${MAKEJOBS}" -f Makefile PREFIX="${PREFIX}"
}
# Default installing function. PREFIX should be set by run.sh script.
# Note that upstream makefiles might ignore PREFIX and have to be configured in configure stage.
default_src_install() {
make -f Makefile install PREFIX="${PREFIX}" DESTDIR="${DESTDIR}"
}
# Helper function for permissions
_do_strip() {
# shellcheck disable=SC2124
local f="${@: -1}"
if ! [ -w "${f}" ]; then
local perms
perms="$(stat -c %a "${f}")"
chmod u+w "${f}"
fi
strip "$@"
if [ -n "${perms}" ]; then
chmod "${perms}" "${f}"
fi
}
# Default function for postprocessing binaries.
default_src_postprocess() {
if (command -v find && command -v file && command -v strip) >/dev/null 2>&1; then
# Logic largely taken from void linux 06-strip-and-debug-pkgs.sh
# shellcheck disable=SC2162
find "${DESTDIR}" -type f | while read f; do
case "$(file -bi "${f}")" in
application/x-executable*) _do_strip "${f}" ;;
application/x-sharedlib*|application/x-pie-executable*)
machine_set="$(file -b "${f}")"
case "${machine_set}" in
*no\ machine*) ;; # don't strip ELF container-only
*) _do_strip --strip-unneeded "${f}" ;;
esac
;;
application/x-archive*) _do_strip --strip-debug "${f}" ;;
esac
done
fi
}
src_pkg() {
touch -t 197001010000.00 .
reset_timestamp
local tar_basename="${pkg}_${revision}.tar"
local dest_tar="/external/repo/${tar_basename}"
local filelist=/tmp/filelist.txt
cd /external/repo
# If grep is unavailable, then tar --sort is unavailable.
# So this does not need a command -v grep.
if tar --help | grep ' \-\-sort' >/dev/null 2>&1; then
tar -C "${DESTDIR}" --sort=name --hard-dereference \
--numeric-owner --owner=0 --group=0 --mode=go=rX,u+rw -cf "${dest_tar}" .
else
local olddir
olddir=$PWD
cd "${DESTDIR}"
local null
if command -v find >/dev/null 2>&1 && command -v sort >/dev/null 2>&1; then
find . -print0 | LC_ALL=C sort -z > "${filelist}"
null="--null"
elif command -v sort >/dev/null 2>&1; then
get_files . | LC_ALL=C sort > "${filelist}"
else
get_files . > ${filelist}
fi
tar --no-recursion ${null} --files-from "${filelist}" \
--numeric-owner --owner=0 --group=0 --mode=go=rX,u+rw -cf "${dest_tar}"
rm -f "$filelist"
cd "$olddir"
fi
touch -t 197001010000.00 "${tar_basename}"
bzip2 --best "${tar_basename}"
}
src_checksum() {
local pkg=$1 revision=$2
local rval=0
if ! [ "$UPDATE_CHECKSUMS" = True ] ; then
# We avoid using pipes as that is not supported by initial sha256sum from mescc-tools-extra
local checksum_file=/tmp/checksum
_grep "${pkg}_${revision}.tar.bz2" "${SRCDIR}/SHA256SUMS.pkgs" > "${checksum_file}" || true
# Check there is something in checksum_file
if ! [ -s "${checksum_file}" ]; then
echo "${pkg}: no checksum stored!"
false
fi
echo "${pkg}: checksumming created package."
sha256sum -c "${checksum_file}" || rval=$?
rm "${checksum_file}"
fi
return "${rval}"
}
src_apply() {
local pkg="${1}" revision="${2}"
local TAR_PREFIX BZIP2_PREFIX
# Make sure we have at least one copy of tar
if [[ "${pkg}" == tar-* ]]; then
mkdir -p /tmp
cp "${PREFIX}/bin/tar" "/tmp/tar"
TAR_PREFIX="/tmp/"
fi
# Bash does not like to be overwritten
if [[ "${pkg}" == bash-* ]]; then
rm "${PREFIX}/bin/bash"
fi
# Overwriting files is mega busted, so do it manually
# shellcheck disable=SC2162
if [ -e /tmp/filelist.txt ]; then
while IFS= read -d $'\0' file; do
rm -f "/${file}" >/dev/null 2>&1 || true
done < /tmp/filelist.txt
fi
# Bzip2 does not like to be overwritten
if [[ "${pkg}" == bzip2-* ]]; then
mkdir -p /tmp
mv "${PREFIX}/bin/bzip2" "/tmp/bzip2"
BZIP2_PREFIX="/tmp/"
fi
"${BZIP2_PREFIX}bzip2" -dc "/external/repo/${pkg}_${revision}.tar.bz2" | \
"${TAR_PREFIX}tar" -C / -xpf -
if [[ "${pkg}" == bzip2-* ]]; then
if ! "${PREFIX}/bin/bzip2" --help >/dev/null 2>&1; then
echo "${pkg}: installed ${PREFIX}/bin/bzip2 is not runnable." >&2
mv -f "/tmp/bzip2" "${PREFIX}/bin/bzip2" || true
false
fi
fi
rm -f "/tmp/bzip2" "/tmp/tar"
}
# Check if bash function exists
fn_exists() {
test "$(type -t "$1")" == 'function'
}
# Call package specific function or default implementation.
call() {
if fn_exists "$1"; then
$1
else
default_"${1}"
fi
}
# Call default build stage function
default() {
"default_${build_stage}"
}
# Reusable helpers for sysroot-oriented stages (e.g. kernel toolchain/kernel build).
sysroot_stage_init() {
: "${KERNEL_SYSROOT:=/kernel-toolchain}"
}
sysroot_src_install_default() {
# Generic install helper for packages that should install into a dedicated sysroot.
# Package-specific post-install actions stay in each package script.
sysroot_stage_init
make "${MAKEJOBS}" install \
DESTDIR="${DESTDIR}" \
prefix="${KERNEL_SYSROOT}" \
libdir="${KERNEL_SYSROOT}/lib"
}
seed_require_file() {
local path="$1"
if [ ! -e "${path}" ]; then
echo "Missing required seed input: ${path}" >&2
false
fi
}
seed_make_repro_tar_xz() {
local src_dir="$1"
local out_file="$2"
local tmp_dir
local tmp_tar
seed_require_file "${src_dir}"
mkdir -p "$(dirname "${out_file}")"
tmp_dir="$(mktemp -d /tmp/seed-tar.XXXXXX)"
tmp_tar="$(mktemp /tmp/seed-tarball.XXXXXX.tar)"
cp -a "${src_dir}/." "${tmp_dir}/"
(
cd "${tmp_dir}"
reset_timestamp
tar --sort=name --hard-dereference \
--numeric-owner --owner=0 --group=0 --mode=go=rX,u+rw \
-cf "${tmp_tar}" .
)
touch -t 197001010000.00 "${tmp_tar}"
xz -T1 -c "${tmp_tar}" > "${out_file}"
touch -t 197001010000.00 "${out_file}"
rm -rf "${tmp_dir}"
rm -f "${tmp_tar}"
}
seed_install_exec() {
local src="$1"
local dst="$2"
seed_require_file "${src}"
mkdir -p "$(dirname "${dst}")"
install -m 0755 "${src}" "${dst}"
}

View file

@ -0,0 +1,22 @@
#!/bin/sh
#
# SPDX-License-Identifier: GPL-3.0-or-later
set -e
. /steps/bootstrap.cfg
. /steps/env
if [ "${INTERACTIVE}" = True ]; then
env - PATH=${PREFIX}/bin PS1="\w # " setsid openvt -fec1 -- bash -i
fi
if [ "${CHROOT}" = False ]; then
# Ignore errors due to missing swap/fstab.
swapoff -a >/dev/null 2>&1 || true
sync
echo u > /proc/sysrq-trigger
mount -o remount,ro /
echo o > /proc/sysrq-trigger
while true; do sleep 1; done
fi

View file

@ -0,0 +1,11 @@
#!/bin/sh
#
# SPDX-License-Identifier: GPL-3.0-or-later
mkdir -p /proc /etc
if [ ! -r /proc/mounts ]; then
mount -t proc proc /proc
fi
ln -snf /proc/mounts /etc/mtab
. /steps/improve/finalize_fhs.sh

View file

@ -0,0 +1,4 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-or-later
dhcpcd --waitip=4

View file

@ -0,0 +1,76 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-or-later
set -e
dist="${DISTFILES:-/external/distfiles}"
env_out="/tmp/guix-bootstrap-seeds.env"
required_files="
${dist}/static-binaries-0-i686-linux.tar.xz
${dist}/guile-static-stripped-2.2.4-i686-linux.tar.xz
${dist}/mes-minimal-stripped-0.19-i686-linux.tar.xz
${dist}/mescc-tools-static-stripped-0.5.2-i686-linux.tar.xz
${dist}/bootstrap-exec-bash-i686-linux
${dist}/bootstrap-exec-mkdir-i686-linux
${dist}/bootstrap-exec-tar-i686-linux
${dist}/bootstrap-exec-xz-i686-linux
"
for f in ${required_files}; do
if [ ! -e "${f}" ]; then
echo "Missing required seed artifact: ${f}" >&2
exit 1
fi
done
if [ ! -x /usr/bin/guix-hash-compat ]; then
echo "Missing /usr/bin/guix-hash-compat" >&2
exit 1
fi
# Prepare file layout expected by bootstrap.scm for i686/x86_64.
mkdir -p "${dist}/i686-linux" "${dist}/x86_64-linux"
cp -f "${dist}/static-binaries-0-i686-linux.tar.xz" \
"${dist}/i686-linux/static-binaries-0-i686-linux.tar.xz"
cp -f "${dist}/static-binaries-0-i686-linux.tar.xz" \
"${dist}/x86_64-linux/static-binaries-0-i686-linux.tar.xz"
cp -f "${dist}/guile-static-stripped-2.2.4-i686-linux.tar.xz" \
"${dist}/i686-linux/guile-static-stripped-2.2.4-i686-linux.tar.xz"
cp -f "${dist}/guile-static-stripped-2.2.4-i686-linux.tar.xz" \
"${dist}/x86_64-linux/guile-static-stripped-2.2.4-i686-linux.tar.xz"
cp -f "${dist}/bootstrap-exec-bash-i686-linux" \
"${dist}/i686-linux/bootstrap-exec-bash-i686-linux"
cp -f "${dist}/bootstrap-exec-mkdir-i686-linux" \
"${dist}/i686-linux/bootstrap-exec-mkdir-i686-linux"
cp -f "${dist}/bootstrap-exec-tar-i686-linux" \
"${dist}/i686-linux/bootstrap-exec-tar-i686-linux"
cp -f "${dist}/bootstrap-exec-xz-i686-linux" \
"${dist}/i686-linux/bootstrap-exec-xz-i686-linux"
static_binaries_hash="$(/usr/bin/guix-hash-compat "${dist}/static-binaries-0-i686-linux.tar.xz")"
guile_seed_hash="$(/usr/bin/guix-hash-compat "${dist}/guile-static-stripped-2.2.4-i686-linux.tar.xz")"
mes_minimal_hash="$(/usr/bin/guix-hash-compat "${dist}/mes-minimal-stripped-0.19-i686-linux.tar.xz")"
mescc_tools_hash="$(/usr/bin/guix-hash-compat "${dist}/mescc-tools-static-stripped-0.5.2-i686-linux.tar.xz")"
exec_bash_hash="$(/usr/bin/guix-hash-compat -r "${dist}/bootstrap-exec-bash-i686-linux")"
exec_mkdir_hash="$(/usr/bin/guix-hash-compat -r "${dist}/bootstrap-exec-mkdir-i686-linux")"
exec_tar_hash="$(/usr/bin/guix-hash-compat -r "${dist}/bootstrap-exec-tar-i686-linux")"
exec_xz_hash="$(/usr/bin/guix-hash-compat -r "${dist}/bootstrap-exec-xz-i686-linux")"
cat > "${env_out}" <<ENVEOF
DISTFILES=${dist}
STATIC_BINARIES_SEED_FILE=static-binaries-0-i686-linux.tar.xz
STATIC_BINARIES_SEED_HASH=${static_binaries_hash}
GUILE_SEED_FILE=guile-static-stripped-2.2.4-i686-linux.tar.xz
GUILE_SEED_HASH=${guile_seed_hash}
MES_MINIMAL_SEED_FILE=mes-minimal-stripped-0.19-i686-linux.tar.xz
MES_MINIMAL_SEED_HASH=${mes_minimal_hash}
MESCC_TOOLS_SEED_FILE=mescc-tools-static-stripped-0.5.2-i686-linux.tar.xz
MESCC_TOOLS_SEED_HASH=${mescc_tools_hash}
EXEC_BASH_HASH=${exec_bash_hash}
EXEC_MKDIR_HASH=${exec_mkdir_hash}
EXEC_TAR_HASH=${exec_tar_hash}
EXEC_XZ_HASH=${exec_xz_hash}
ENVEOF
chmod 0644 "${env_out}"

View file

@ -0,0 +1,34 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-or-later
set -e
. /steps/bootstrap.cfg
. /steps/env
guix_localstate_dir="/var/guix"
daemon_socket="${guix_localstate_dir}/daemon-socket/socket"
out_dir="/external/guix-images"
export GUIX_DAEMON_SOCKET="${daemon_socket}"
if [ ! -S "${daemon_socket}" ]; then
echo "guix-daemon socket is missing: ${daemon_socket}" >&2
echo "Run improve/guix-daemon-and-pull.sh first." >&2
exit 1
fi
mkdir -p "${out_dir}"
iso_store_path="$(guix system image \
--system=x86_64-linux \
-t iso9660 \
-e '(@@ (gnu system install) installation-os)' \
--no-substitutes \
--disable-authentication)"
if [ ! -e "${iso_store_path}" ]; then
echo "guix system image did not return a valid path: ${iso_store_path}" >&2
exit 1
fi
ln -sfn "${iso_store_path}" "${out_dir}/guix-system-install-x86_64.iso"

View file

@ -0,0 +1,295 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-or-later
set -e
. /steps/bootstrap.cfg
. /steps/env
guix_localstate_dir="/var/guix"
daemon_socket="${guix_localstate_dir}/daemon-socket/socket"
channel_root="/var/lib/guix/local-channels"
channel_repo="${channel_root}/guix"
channel_work="/tmp/guix-local-channel-work"
channels_file="/root/.config/guix/channels.scm"
distfiles="${DISTFILES:-/external/distfiles}"
distfiles_http_host="127.0.0.1"
distfiles_http_port="38445"
distfiles_http_base_url="http://${distfiles_http_host}:${distfiles_http_port}"
distfiles_http_pid=""
distfiles_http_log="/tmp/distfiles-httpd.log"
guix_seed_helper="/steps-guix/improve/guix-1.5.0.sh"
guix_patch_dir="/steps-guix/guix-1.5.0/patches"
PATH="/usr/sbin:/sbin:${PATH}"
export GUIX_DAEMON_SOCKET="${daemon_socket}"
guile_site_path="${PREFIX}/share/guile/site/3.0:${PREFIX}/share/guile/3.0"
guile_site_ccache="${LIBDIR}/guile/3.0/site-ccache"
guile_core_ccache="${LIBDIR}/guile/3.0/ccache"
guile_ext_path="${LIBDIR}/guile/3.0/extensions"
# Keep Guile runtime lookup deterministic for both CLI and daemon-side Guile
# helpers.
export LD_LIBRARY_PATH="${LIBDIR}:${PREFIX}/lib:${LD_LIBRARY_PATH}"
export GUILE_LOAD_PATH="${guile_site_path}"
export GUILE_LOAD_COMPILED_PATH="${guile_site_ccache}:${guile_core_ccache}"
export GUILE_SYSTEM_PATH="${guile_site_path}"
export GUILE_SYSTEM_COMPILED_PATH="${guile_site_ccache}:${guile_core_ccache}"
export GUILE_EXTENSIONS_PATH="${guile_ext_path}"
export GNUTLS_GUILE_EXTENSION_DIR="${guile_ext_path}"
stop_distfiles_http_server() {
if [ -n "${distfiles_http_pid}" ] && kill -0 "${distfiles_http_pid}" >/dev/null 2>&1; then
kill "${distfiles_http_pid}" >/dev/null 2>&1 || true
wait "${distfiles_http_pid}" >/dev/null 2>&1 || true
fi
}
start_distfiles_http_server() {
if [ ! -d "${distfiles}" ]; then
echo "Distfiles directory is missing: ${distfiles}" >&2
exit 1
fi
if ! command -v python3 >/dev/null 2>&1; then
echo "python3 is required to serve local distfiles over HTTP." >&2
exit 1
fi
rm -f "${distfiles_http_log}"
echo "Starting local distfiles HTTP server at ${distfiles_http_base_url}"
python3 -m http.server "${distfiles_http_port}" \
--bind "${distfiles_http_host}" \
--directory "${distfiles}" \
>"${distfiles_http_log}" 2>&1 &
distfiles_http_pid="$!"
retry=0
while [ "${retry}" -lt 30 ]; do
if ! kill -0 "${distfiles_http_pid}" >/dev/null 2>&1; then
echo "Local distfiles HTTP server exited unexpectedly." >&2
cat "${distfiles_http_log}" >&2 || true
exit 1
fi
if python3 -c "import urllib.request; urllib.request.urlopen('${distfiles_http_base_url}/', timeout=2).read(1)" \
>/dev/null 2>&1; then
return
fi
retry=$((retry + 1))
sleep 1
done
echo "Timed out waiting for local distfiles HTTP server: ${distfiles_http_base_url}" >&2
cat "${distfiles_http_log}" >&2 || true
exit 1
}
trap stop_distfiles_http_server EXIT INT TERM HUP
have_group() {
if command -v getent >/dev/null 2>&1; then
getent group "$1" >/dev/null 2>&1
else
grep -q "^$1:" /etc/group
fi
}
have_user() {
if command -v getent >/dev/null 2>&1; then
getent passwd "$1" >/dev/null 2>&1
else
grep -q "^$1:" /etc/passwd
fi
}
have_tty_device() {
for dev in /dev/tty /dev/tty[0-9]* /dev/ttyS*; do
if [ -c "${dev}" ]; then
return 0
fi
done
return 1
}
verify_terminal_devices() {
mount | grep ' on /dev ' >/dev/null 2>&1 &&
mount | grep ' on /dev/pts ' >/dev/null 2>&1 &&
test -c /dev/ptmx &&
test -c /dev/pts/ptmx &&
have_tty_device
}
prepare_local_channel_checkout() {
rendered_patch="/tmp/guix-bootstrap-local-seeds.patch"
rendered_mes_patch="/tmp/guix-bootstrap-local-mes-extra.patch"
if [ ! -x "${guix_seed_helper}" ]; then
echo "Missing Guix seed helper: ${guix_seed_helper}" >&2
exit 1
fi
if [ ! -d "${guix_patch_dir}" ]; then
echo "Missing Guix patch directory: ${guix_patch_dir}" >&2
exit 1
fi
"${guix_seed_helper}"
if [ ! -f /tmp/guix-bootstrap-seeds.env ]; then
echo "Missing /tmp/guix-bootstrap-seeds.env" >&2
exit 1
fi
. /tmp/guix-bootstrap-seeds.env
sed \
-e "s|@EXEC_BASH_HASH@|${EXEC_BASH_HASH}|g" \
-e "s|@EXEC_MKDIR_HASH@|${EXEC_MKDIR_HASH}|g" \
-e "s|@EXEC_TAR_HASH@|${EXEC_TAR_HASH}|g" \
-e "s|@EXEC_XZ_HASH@|${EXEC_XZ_HASH}|g" \
-e "s|@STATIC_BINARIES_SEED_HASH@|${STATIC_BINARIES_SEED_HASH}|g" \
-e "s|@GUILE_SEED_HASH@|${GUILE_SEED_HASH}|g" \
-e "s|@MES_MINIMAL_SEED_HASH@|${MES_MINIMAL_SEED_HASH}|g" \
-e "s|@MESCC_TOOLS_SEED_HASH@|${MESCC_TOOLS_SEED_HASH}|g" \
"${guix_patch_dir}/bootstrap-local-seeds.patch.in" > "${rendered_patch}"
sed \
-e "s|@MES_MINIMAL_SEED_HASH@|${MES_MINIMAL_SEED_HASH}|g" \
-e "s|@MESCC_TOOLS_SEED_HASH@|${MESCC_TOOLS_SEED_HASH}|g" \
"${guix_patch_dir}/bootstrap-local-mes-extra.patch.in" > "${rendered_mes_patch}"
if grep -Eq '@[A-Z0-9_]+@' "${rendered_patch}" "${rendered_mes_patch}"; then
echo "Unexpanded placeholder found while rendering Guix channel patches." >&2
exit 1
fi
(
cd "${channel_repo}"
patch -p1 < "${guix_patch_dir}/enforce-local-bootstrap-binaries-except-linux-headers.patch"
patch -p1 < "${rendered_patch}"
patch -p1 < "${rendered_mes_patch}"
git init -q
git add -A
git -c user.name='guix-local' -c user.email='guix-local@example.invalid' commit -q -m 'local guix channel snapshot'
)
}
mkdir -p /proc /sys /dev "${guix_localstate_dir}/daemon-socket" /var/lib/guix /root/.config/guix
mount | grep ' on /proc ' >/dev/null 2>&1 || mount -t proc proc /proc
mount | grep ' on /sys ' >/dev/null 2>&1 || mount -t sysfs sysfs /sys
mount | grep ' on /dev ' >/dev/null 2>&1 || mount -t devtmpfs devtmpfs /dev
if ! mount | grep ' on /dev/pts ' >/dev/null 2>&1; then
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
fi
test -c /dev/tty || mknod -m 666 /dev/tty c 5 0
test -c /dev/ptmx || mknod -m 666 /dev/ptmx c 5 2
test -c /dev/tty0 || mknod -m 666 /dev/tty0 c 4 0
test -c /dev/tty1 || mknod -m 666 /dev/tty1 c 4 1
test -c /dev/tty2 || mknod -m 666 /dev/tty2 c 4 2
test -c /dev/ttyS0 || mknod -m 666 /dev/ttyS0 c 4 64
if ! verify_terminal_devices; then
echo "Missing terminal devices required for Guix: /dev/ptmx, /dev/pts/ptmx, or /dev/tty*" >&2
exit 1
fi
if ! have_group guixbuild; then
groupadd --system guixbuild
fi
nologin_bin="$(command -v nologin)"
i=1
while [ "${i}" -le 10 ]; do
idp="$(printf '%02d' "${i}")"
user="guixbuilder${idp}"
if ! have_user "${user}"; then
useradd -g guixbuild -G guixbuild \
-d /var/empty -s "${nologin_bin}" \
-c "Guix build user ${idp}" --system \
"${user}"
fi
i=$((i + 1))
done
if [ ! -S "${daemon_socket}" ]; then
guix-daemon \
--build-users-group=guixbuild \
--listen="${daemon_socket}" \
>/tmp/guix-daemon.log 2>&1 &
fi
retry=0
while [ "${retry}" -lt 60 ]; do
if [ -S "${daemon_socket}" ]; then
break
fi
retry=$((retry + 1))
sleep 1
done
if [ ! -S "${daemon_socket}" ]; then
echo "guix-daemon did not become ready: ${daemon_socket}" >&2
exit 1
fi
src_tar=""
for f in "${distfiles}"/guix-1.5.0*.tar.* "${distfiles}"/guix-v1.5.0*.tar.*; do
if [ -f "${f}" ]; then
src_tar="${f}"
break
fi
done
if [ -z "${src_tar}" ]; then
echo "Could not find Guix 1.5.0 source tarball in ${distfiles}" >&2
exit 1
fi
rm -rf "${channel_work}" "${channel_repo}"
mkdir -p "${channel_work}" "${channel_root}"
case "${src_tar}" in
*.tar.gz|*.tgz) tar -C "${channel_work}" -xzf "${src_tar}" ;;
*.tar.xz) tar -C "${channel_work}" -xJf "${src_tar}" ;;
*.tar.bz2) tar -C "${channel_work}" -xjf "${src_tar}" ;;
*.tar) tar -C "${channel_work}" -xf "${src_tar}" ;;
*)
echo "Unsupported tarball format: ${src_tar}" >&2
exit 1
;;
esac
src_dir="$(find "${channel_work}" -mindepth 1 -maxdepth 1 -type d | head -n 1)"
if [ -z "${src_dir}" ]; then
echo "Failed to unpack Guix source from ${src_tar}" >&2
exit 1
fi
mv "${src_dir}" "${channel_repo}"
prepare_local_channel_checkout
channel_commit="$(git -C "${channel_repo}" rev-parse HEAD)"
channel_branch="$(git -C "${channel_repo}" symbolic-ref --quiet --short HEAD)"
if [ -z "${channel_branch}" ]; then
echo "Failed to determine local Guix channel branch." >&2
exit 1
fi
cat > "${channels_file}" <<EOF
(use-modules (guix channels))
(list
(channel
(name 'guix)
(url "file://${channel_repo}")
(branch "${channel_branch}")
(commit "${channel_commit}")))
EOF
chmod 0644 "${channels_file}"
if ! guile -c '(use-modules (gnutls)) (if (module-variable (resolve-module (quote (gnutls))) (quote make-session)) (exit 0) (exit 1))'; then
echo "Guile GnuTLS bindings are incomplete: (gnutls) is missing make-session." >&2
exit 1
fi
start_distfiles_http_server
guix pull --bootstrap --no-substitutes --channels="${channels_file}" --disable-authentication

View file

@ -0,0 +1,5 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-or-later
. /steps/improve/open_console.sh

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