universalisos/docs/parity/RPM_PARITY_SPEC.md

450 lines
44 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UniversalisOS RPM Packaging Environment — Feature-Parity Specification
**Document:** `docs/parity/RPM_PARITY_SPEC.md`
**Status:** Analysis of mirrored PikeOS 5.0 packaging environment; design for the `uos-pkg` reimplementation.
**Sources analyzed:**
- `~/portugalfuturista/universalisos/pikeos-mirror/rpm/` (mirror of `src/rpm/`)
- `~/portugalfuturista/universalisos/pikeos-mirror/config/rpm/`
- Live execution of binaries in `~/portugalfuturista/universalisos/src/rpm/bin/` with `LD_LIBRARY_PATH=src/rpm/lib64`
> Naming note: the original vendor tree uses a two-character product abbreviation that is banned in UniversalisOS documentation and code. This spec uses "PikeOS" (the product) and the `uos_` prefix (the replica) exclusively. Where the original macro names contain the product name (e.g. `%_pikeos_prefix`), they are quoted verbatim because they are interface facts that `uos-pkg` must reproduce.
---
## 1. Tool Inventory (exact versions)
### 1.1 Binary tools — `src/rpm/bin/`
All ELF binaries are **x86-64, dynamically linked, stripped, built for GNU/Linux 2.6.26**, linking against the bundled `lib64/` shared objects (`librpm-4.2.so`, `librpmbuild-4.2.so`, `librpmdb-4.2.so`, `libpopt.so.0`, `libbeecrypt.so.2`). Verified by execution (`./rpm --version` → `RPM version 4.2`).
| Tool | Type | Version / facts | Evidence |
|---|---|---|---|
| `rpm` | ELF 78 432 B | **RPM 4.2** (Red Hat rpm-4.2 codebase, CVS `macros.in,v 1.138 2003/03/05`, `rpmrc.in,v 2.54 2003/01/10`). Modes: query (`-q`), verify (`-V`), install/upgrade/erase (`-i/-U/-e`), signature (`-K/--addsign/--resign/--import`), database (`--initdb/--rebuilddb`). 133 query tags (`--querytags`). Localized (pt, de, es, … locale catalogs in `share/locale/`). | `bin/rpm`; `--version`; `--help`; `--querytags` |
| `rpmbuild` | symlink → `lib/rpm/rpmb` (ELF 80 904 B) | **RPM 4.2** build front-end. Stages `-bp -bc -bi -bl -ba -bb -bs`, tarball variants `-t*`, `--rebuild/--recompile`, `--target=CPU-VENDOR-OS`, `--buildroot`, `--clean`, `--rmsource`, `--rmspec`, `--short-circuit`, `--nodirtokens`. | `bin/rpmbuild`; `--help` |
| `rpmquery` | symlink → `lib/rpm/rpmq` (71 168 B) | Query-only mode binary (same 4.2 CLI). | `bin/rpmquery` |
| `rpmi` / `rpmu` / `rpme` | `lib/rpm/rpmi` (73 376 B); `rpmu→rpmi`, `rpme→rpmi` | Install / upgrade / erase mode binaries. | `lib/rpm/` |
| `rpmsign` | symlink → `lib/rpm/rpmk` (71 584 B) | Signature mode binary. | `bin/rpmsign` |
| `rpmverify` | symlink → `lib/rpm/rpmv``rpmq` | Verify mode. | `bin/rpmverify` |
| `rpmdb` | symlink → `lib/rpm/rpmd` (70 272 B) | Database maintenance mode. | `bin/rpmdb` |
| `rpm2cpio` | ELF 87 872 B | RPM 4.2 payload extractor; supports **gzip and bzip2** payloads (bzip2 decompressor statically embedded, jseward bzip2 strings present). Usage: `rpm2cpio file.rpm > out.cpio`. | `bin/rpm2cpio`, `strings` |
| `rpmgraph` | ELF 70 496 B | RPM 4.2 dependency-graph tool; emits **graphviz `digraph`** of Requires/Provides from rpmdb or package files (`digraph XXX {` string, `rpmgraph.c`). Option `--nolegacy`. | `bin/rpmgraph`, `strings`, `--help` |
| `gendiff` | POSIX sh script, 386 B | `gendiff <directory> <diff-extension>` — finds `*<ext>` / `.*<ext>` files and emits unified diffs against the original (`-U0` for `ChangeLog<ext>`). Used to generate `PatchN:` files. | `bin/gendiff` |
### 1.2 Bundled libraries — `src/rpm/lib64/`
| Library | Version | Role |
|---|---|---|
| `librpm-4.2.so` | rpm 4.2 core | header/payload/signature/transaction engine; embeds zlib **1.1.4** inflate/deflate (Adler/Gailly 19952002 copyright strings) and reports zlib 1.2.7 via `zlibVersion` linkage; compiled-in defaults: prefix `/opt/pikeos-D5.0/rpm`, rpmdb `/opt/pikeos-D5.0/rpm/var/lib/rpm`, magic file `lib/rpm/magic` |
| `librpmbuild-4.2.so` | rpm 4.2 | spec parsing, build scriptlets, packaging |
| `librpmdb-4.2.so` | rpm 4.2 | rpmdb access; **Berkeley DB 4.1.24 (Sleepycat, 2002-09-13)** embedded (`db_version_rpmdb`) |
| `libpopt.so.0.0.0` | popt (rpm 4.2 era) | CLI parsing, alias/exec tables (`rpmpopt-4.2`) |
| `libbeecrypt.so.2.2.0` | **BeeCrypt 2.2.0** | DSA/RSA signature verification, entropy |
### 1.3 Auxiliary executables — `src/rpm/lib/rpm/`
| Tool | Kind | Purpose |
|---|---|---|
| `debugedit` | ELF 57 816 B | rewrites DWARF debug paths (`-b builddir -d /usr/src/debug`) for debuginfo packages |
| `rpmdeps` | ELF 66 816 B | internal dependency generator (`--provides/--requires`) |
| `rpmcache` | ELF 73 928 B | dependency-universe cache builder (rpmcache(8)) |
| `rpmfile` | ELF 73 200 B | file-classification helper (libmagic-based) |
| `rpmdb_dump`, `rpmdb_load`, `rpmdb_loadcvt`, `rpmdb_stat`, `rpmdb_svc`, `rpmdb_verify`, `rpmdb_deadlock` | ELF | Berkeley DB 4.1.24 utilities for the rpmdb |
| `rpmdiff`, `rpmdiff.cgi` | script + CGI | package-to-package diff reporting |
| `brp-compress`, `brp-strip`, `brp-strip-static-archive`, `brp-strip-comment-note`, `brp-strip-shared`, `brp-sparc64-linux`, `brp-redhat` | sh | **B**uild-**R**oot **P**olicy scripts run at end of `%install` (compress man pages, strip ELF) |
| `check-files` | sh | fails build on unpackaged files in `$RPM_BUILD_ROOT` (see `%__check_files`) |
| `check-prereqs` | sh | verifies build prerequisites |
| `config.guess`, `config.sub`, `config.site` | autotools | platform detection / site defaults for `%configure` |
| `cpanflute`, `cpanflute2` | perl | CPAN module → spec file generator |
| `find-provides`, `find-requires` (+`.perl` stubs), `find-prov.pl`, `find-req.pl`, `get_magic.pl`, `perl.prov`, `perl.req`, `perldeps.pl`, `sql.prov`, `sql.req`, `tcl.req` | sh/perl | automatic dependency extraction (ELF SONAMEs via `file`/`ldd`, shebang interpreters, perl modules, tcl, java) |
| `find-debuginfo.sh` | sh | creates `/usr/lib/debug` shadow tree + `debugfiles.list` (invokes `debugedit`, `eu-strip`) |
| `find-lang.sh` | sh | generates `%lang()` file lists from `share/locale/**/<name>.mo` |
| `getpo.sh` | sh | extracts translatable Summary/Group/Description into `.po` format via `rpm -qp --qf` |
| `rpm2cpio.sh` | sh | pure-sh rpm→cpio: parses lead (96 B) + signature header + header with `od`, then `dd … | gunzip` |
| `Specfile.pm` | perl module | `RPM::Specfile` v1.02 — programmatic spec generation (accessors for name/version/release/…, `generate_specfile`) |
| `convertrpmrc.sh` | sh | migrates legacy `/etc/rpmrc` key:value entries to `%_macro` form (translation table at lines 3872) |
| `u_pkg.sh` | sh | "universal package manager" abstraction: maps `list_all_packages`, `query_file`, … to `rpm -qa/-qf/…` on Linux, `pkginfo/pkgchk` on SunOS |
| `vpkg-provides.sh`, `vpkg-provides2.sh` | sh | build "virtual packages" that `Provides:` host OS libraries/interpreters (SunOS/HP-UX/AIX/IRIX/OSF1 shlib dirs) |
| `trpm`, `tgpg`, `rpm.daily`, `rpm.log`, `rpm.xinetd`, `cross-build` | misc | test/ops helpers; `cross-build` shows the cross-compile make invocation pattern |
### 1.4 Configuration files shipped with the tools
| File | Lines | Role |
|---|---|---|
| `lib/rpm/macros` | 1100 | master macro definitions (§3) |
| `lib/rpm/rpmrc` | 358 | arch/os canon tables, optflags per arch, **`macrofiles:` load list (line 355)** |
| `lib/rpm/rpmpopt-4.2` | 472 | popt aliases: `--scripts`, `--setperms`, `--setugids`, `--conflicts`, `--obsoletes`, `--provides`, `--requires`/`-R`, `--info`, `--changelog`, `--xml`, … |
| `lib/rpm/x86_64-linux/macros` | 66 | per-platform overrides (§3.5) |
| `lib/rpm/noarch-linux/macros` | ~60 | same for `noarch` builds |
| `var/lib/rpm/*` | — | rpmdb skeleton: Berkeley DB files `Packages, Name, Basenames, Group, Requirename, Providename, Conflictname?, Triggername, Dirnames, Requireversion, Provideversion, Installtid, Sigmd5, Sha1header, Filemd5s` + `__db.001003` environment. `Packages` is 0 bytes (empty template); secondary indexes retain ~1906 historical package-name keys (used in §2.3) |
---
## 2. The PikeOS Package Model
### 2.1 What a `.spec` + macros produce
A PikeOS package is a standard **RPM 4.2 binary package** (`name-version-release.arch.rpm`, name template `%_build_name_fmt` = `%{ARCH}/%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm`, `macros:575`) whose build is driven by the PikeOS macro layer in `config/rpm/`. The flow:
1. `rpmbuild -bb/--rebuild` loads the macro stack (§3.6): master `macros` → host file → target file → `common` → platform macros → user files.
2. `%prep` unpacks `SourceN:` into `%_builddir` (`%{_topdir}/BUILD`, topdir = `%{_usrsrc}/sysgo` = `/opt/pikeos-D5.0/rpm/src/sysgo`).
3. `%build` typically invokes PikeOS-aware macros from `config/rpm/common`: `%pikeos_build_package` (init devel project → `make var-value && make all && make install`) or `%pikeos_build_recipe` (`pikeos-build-recipe <name>.recipe`), with `PIKEOS_BUILD_ID="%{_pikeos_build_id}"` exported (`common:119129`).
4. `%install` populates `$RPM_BUILD_ROOT`; install-post hooks run `brp-compress/brp-strip/…` (platform macros) plus the SYSGO hooks `__sysgo_track_compile_post` and `__sysgo_check_files` (`common:194197`).
5. Packaging: `%files` list → cpio payload (gzip `w9.gzdio` default, bzip2 optional) → header with Requires/Provides (internal generator, `%_use_internal_dependency_generator 1`, `macros:326`) → written to `%_rpmdir` = `%{_topdir}/RPMS`.
6. Install: `rpmi`/`rpm -i` into the rpmdb at `%_dbpath` = `/opt/pikeos-D5.0/rpm/var/lib/rpm`, files landing under `/opt/pikeos-D5.0/…` (prefix `%_pikeos_prefix`, `common:1`).
**Vendor metadata** stamped into every header (`config/rpm/common:115`): `Vendor: SYSGO AG`, `Distribution: PikeOS D5.0`, `Packager: <support@pikeos.com>`, URL `http://www.pikeos.com/`, product version `D5.0`, build id `%{_pikeos_version}-%{_pikeos_mod_release}` (mod_release injected by the build system, `common:1719`).
### 2.2 Package naming scheme (from `config/rpm/targets/*` + `common`)
Name grammar (assembled by spec authors from these macros):
```
%{_pikeos_rpm_prefix} <component> [-<qualifier>…] [-%{_pikeos_target_arch}] (target packages)
%{_pikeos_rpm_prefix} <component> [-%{_pikeos_rpm_host}<host-ish>] (host packages)
```
- `%_pikeos_rpm_prefix` = **`pikeos-`** (`common:7`). Every product package starts with it.
- **Target suffix** `%_pikeos_target_arch` = `%{_pikeos_target_cpu}_%{_pikeos_target_proc}` (e.g. `arm_v7hf`, `ppc_e500mc-4g`; the `-diab` toolchain variants append `-diab`, `targets/ppc_e500mc-diab-linux:3`).
- **Tool prefix** `%_pikeos_tool_prefix` = `<arch>-` used for cross-tool binaries (`targets/*:4`).
- **Host infix** `%_pikeos_rpm_host`: `%nil` (empty) on Linux hosts, `cygwin-` / `win32-` on Windows hosts (`hosts/*:3`).
- Derived component renames (`common:7172`): `pikeos-psp-<board>-<arch>` → sources package `pikeos-sources-psp-<board>-<arch>` and config package `pikeos-config-psp-<board>-<arch>` (sed rewrites).
### 2.3 Observed package taxonomy (rpmdb `Name` index, 1906 unique names)
Recovered from `src/rpm/var/lib/rpm/Name` (secondary index keys). Representative families — the replica must accept/install all of these shapes:
| Family | Example | Meaning |
|---|---|---|
| `pikeos-kernel[-cert]-<arch>` | `pikeos-kernel-cert-ppc_e5500` | kernel binaries (cert = certification variant) |
| `pikeos-fusion-kernel-<board>-<arch>` | `pikeos-fusion-kernel-<qoriq-board>-e6500-l2-ppc_e500mc` | board-fused kernel images |
| `pikeos-bin-fusion-pssw-{standard,cert}-<arch>` | — | prebuilt PSSW fusion binaries |
| `pikeos-psp-<board>-<arch>` | `pikeos-psp-<qoriq-board>-e6500-ppc_e500mc` | Platform Support Package |
| `pikeos-sources-psp-<board>-<arch>` / `pikeos-config-psp-<board>-<arch>` | `pikeos-config-psp-imx6-arm_v7hf` | PSP source/config split (renames per `common:7172`) |
| `pikeos-bsp-…` | 29 names | board support packages |
| `pikeos-ddk-<drv>[-headers][-kdev][-cmp]-<arch>` | `pikeos-ddk-can-headers-ppc_e500mc`, `pikeos-pci_manager-kdev-x86_amd64` | Driver Development Kit modules; `-kdev` = kernel-device framework variant, `-cmp` = companion |
| `pikeos-posix[-smp]-pse51[-debug-instr]-<arch>` | `pikeos-posix-pse51-arm_v8hf` | POSIX PSE51 personality |
| `pikeos-personality-{native,integration}-<arch>` | — | personality runtimes |
| `pikeos-apex-…` / `pikeos-demo-…` | `pikeos-demo-apex-hello-smp` | ARINC-653 + demo projects (129 demo names) |
| `pikeos-gcc-<arch>`, `pikeos-binutils-…`, `pikeos-gdb-client-<arch>` | `pikeos-gcc-ppc_e500mc-4g` | cross toolchains (host packages, target in name) |
| `pikeos-lib{vp,spider,drv,imon,nfsrpc,util,gcc_cert,psp,ivm,gdbstub,fdt,debug,vm,acpica}-…` | `pikeos-libgcc_cert-ppc_e500` | libraries |
| `pikeos-{hlnet,hlser,hldio,hlclk,hlcan,hlblk}-<arch>` | — | high-level I/O stacks |
| `pikeos-{scov,coverage,profile,profileopt,mon,traceserver,sectick}-…` | 202 scov names | coverage/profiling/monitoring |
| `pikeos-{cenv,cppenv,tfw,errno,errcnt,anisfp,kextfp,enteremul}-…` | — | C/C++ environments, test framework |
| `pikeos-{virtio,veth,qport,muxa,sport,pci,dpaa}-…` | — | virtual/para-virtual devices |
| `pikeos-{boot,bootimage,cdk,target,devel,doc,releasenotes,licensing}-…` | `pikeos-boot-grub-noarch` | boot loaders, CDK, docs; `-noarch` suffix appears explicitly on some |
| `pikeos-{8250,e1000,pl011,lpuart,scif,xuartps,xemacps,tsec,cpsw,ravb,smc911x,smmu}-…` | — | device drivers |
| `pikeos-buildenv-babs`, `pikeos-babs-buildlogs`, `pikeos-rpmconfig`, `pikeos-scripts` | — | build-system integration (BaBS) |
| `host-provides`, `sbe-proxy-<pkg>` | — | proxy packages (§2.4) |
Target-suffix distribution in the index: `arm_v7hf` 276, `arm_v8hf` 243, `ppc_e500mc-4g` 232, `ppc_e500mc` 228, `ppc_e5500` 222, `ppc_e500` 216, `x86_amd64` 211, plus unsuffixed host/noarch packages.
### 2.4 Proxy packages (host-provides / buildenv-provides)
Two special package types let the rpmdb satisfy dependencies on material that is **not** rpm-managed:
1. **`host-provides`** (`rpm/host-provides/host-provides.spec`, 39 lines): `Name: host-provides`, `Version: 0.0`, `Release: 1`, `BuildArchitectures: noarch`, `AutoReqProv: no`, empty `%files`. The line `# PROVIDES GO HERE -- DON'T CHANGE!` (line 18) marks where `find-host-provides.sh` output is injected. That script (`find-host-provides.sh`, 113 lines):
- emits `Provides: /bin/sh`, `/usr/bin/env`, and interpreters `bash/perl/csh` found via `which` (lines 83100);
- scans `/lib /usr/lib` (or `/compat/linux/...` on BSD) for `lib*.so.[0-9]` and `ld-linux*.so.[0-9]`, and for each library emits `Provides: <SONAME>`, `Provides: <libname>(<VERDEF>)` for every version definition, suffixed `(64bit)` for ELF64 (lines 4473, 103112);
- Cygwin hosts skip library scanning.
2. **`sbe-proxy-<PKGNAME>`** (`rpm/buildenv-provides/buildenv-provides.spec.in`, 39 lines): template with `##PKGNAME##` placeholder (lines 1, 21); one proxy package per SYSGO Build Environment (`/opt/sbe-D3.1`, `%_sysgo_buildenv_prefix`, `common:9`) component, same noarch/AutoReqProv-no shape.
`uos-pkg` must generate and install both proxy types so that `Requires: libc.so.6(GLIBC_2.17)(64bit)`-style dependencies resolve against the host.
---
## 3. Macro Reference — `lib/rpm/macros` and `config/rpm/*`
241 distinct macro names in the master file (265 definition lines). Grouped below with file:line citations (`macros` = `src/rpm/lib/rpm/macros`, `common` = `pikeos-mirror/config/rpm/common`).
### 3.1 Path macros
| Macro | Value | Cite |
|---|---|---|
| `%nil` | empty (`%{!?nil}`) | macros:24 |
| `%_usr` | `/opt/pikeos-D5.0/rpm` | macros:29 |
| `%_usrsrc` | `%{_usr}/src` | macros:30 |
| `%_var` | `/opt/pikeos-D5.0/rpm/var` | macros:31 |
| `%_topdir` | `%{_usrsrc}/sysgo` | macros:170 |
| `%_builddir` / `%_sourcedir` / `%_specdir` / `%_rpmdir` / `%_srcrpmdir` | `%{_topdir}/{BUILD,SOURCES,SPECS,RPMS,SRPMS}` | macros:95,157,161,146,164 |
| `%_tmppath` | `/tmp` | macros:167 |
| `%_dbpath` / `%_dbpath_rebuild` | `%{_var}/lib/rpm` | macros:104,107 |
| `%_defaultdocdir` | `%{_usr}/doc` | macros:133 |
| `%_rpmfilename` / `%_build_name_fmt` | `%{ARCH}/%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm` | macros:150,575 |
| `%_repackage_dir` / `%_repackage_name_fmt` / `%_repackage_root` / `%_repackage_all_erasures` | `/var/spool/repackage`, `%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm`, empty, 0 | macros:604614 |
| `%_prefix` `%_exec_prefix` `%_bindir` `%_sbindir` `%_libexecdir` `%_datadir` `%_sysconfdir` `%_sharedstatedir` `%_localstatedir` `%_lib` `%_libdir` `%_includedir` `%_oldincludedir` `%_infodir` `%_mandir` | autoconf-style tree under `/opt/pikeos-D5.0/rpm` (`_lib`=lib) | macros:902916 |
| `%_javadir` / `%_javadocdir` | `%{_datadir}/java`, `%{_datadir}/javadoc` | macros:245246 |
| `%_install_script_path` | `/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin` | macros:231 |
| `%_cache_dbpath`, `%_bhpath`, `%_bhcoll`, `%_bhN`, `%_bhVR` (=SYSGO), `%_bhA` | rpmcache universe config | macros:703710 |
| Tool paths `%__awk … %__xz` (30 entries) | `gawk bzip2 cat chgrp chmod chown cp cpio file gpg grep gzip id install ln-s make mkdir mkdir-p mv patch perl pgp python rm rsh sed ssh tar unzip xz` | macros:3665 |
| Build tools `%__ar %__as %__cxx %__ld %__nm %__objcopy %__objdump %__ranlib %__remsh %__strip` + autotools set | `ar as g++ /usr/bin/ld /usr/bin/nm /usr/bin/objcopy /usr/bin/objdump ranlib %{__rsh} /usr/bin/strip`, `libtoolize aclocal autoheader automake autoconf` | macros:7086 |
### 3.2 Build macros
| Macro | Meaning | Cite |
|---|---|---|
| `%_buildshell` | `/bin/bash` — scriptlet interpreter | macros:98 |
| `%___build_shell/_args/_cmd/_pre/_post/_template` | scriptlet template machinery; `_pre` exports `RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS RPM_DOC_DIR RPM_PACKAGE_NAME/VERSION/RELEASE RPM_BUILD_ROOT`, `umask 022`, `cd %{u2p:%{_builddir}}` | macros:738773 |
| `%__spec_{prep,build,install,check,clean,rmbuild}_{shell,args,cmd,pre,body,post,template}` | per-stage instantiations of the template | macros:780880 |
| `%optflags` | `-O2` (generic); per-arch table in `rpmrc:1462` (e.g. `x86_64 -O2 -g`); platform file sets `-O2 -g` | macros:726; rpmrc:20; x86_64-linux/macros:11 |
| `%configure` | PLD-style: exports CFLAGS/CXXFLAGS/FFLAGS, runs `./configure --host=%{_host} --build=%{_build} --target=%{_target_platform} --program-prefix=… --prefix=… ` + 12 dir flags | macros:958977 |
| `%GNUconfigure(MCs:)` | regenerates autotools (libtoolize/gettextize/aclocal/autoheader/automake/autoconf) then configures; opts `-C` dir, `-M` mkdir, `-s` LDFLAGS | macros:10081052 |
| `%makeinstall` | `make prefix=%{buildroot}%{_prefix} … install` with all 13 dir overrides | macros:981996 |
| `%_smp_mflags` | `-j$(getconf _NPROCESSORS_ONLN)` when >1 CPU | x86_64-linux/macros:3537 |
| `%_package_version` | `30005` — rpm-3.0.5-compatible headers | macros:303 |
| `%__check_files` / `%_unpackaged_files_terminate_build` / `%_missing_doc_files_terminate_build` | `check-files %{buildroot}`; both terminate flags = **1** (strict) | macros:310,316,322 |
| `%_use_internal_dependency_generator` | **1** (internal); external fallbacks `%__find_provides/%__find_requires` = `find-provides/find-requires`; perl helpers `perl.prov/perl.req` | macros:326,334335,346347 |
| `%debug_package` / `%__debug_install_post` | auto `-debug` subpackage template + `find-debuginfo.sh` invocation | macros:112131 |
| `%find_lang` | `find-lang.sh %{buildroot}` | macros:1097 |
| `%requires_eq()`, `%perl_sitearch`, `%perl_archlib` | perl helper macros | macros:10761078 |
| `%ix86` | `i386 i486 i586 i686 athlon` arch alias list | macros:1086 |
| `%debian_patch` | applies `debian/patches` via quilt/00list/glob (SYSGO addition) | common:2136 |
| `%sysgo_modulepatch(cvs-path)` / `%sysgo_install_modulepatch(cvs-path file)` | applies/installs per-module patches from `%{_sysgo_modulepatch_dir}` = `%{_pikeos_prefix}/build/module-patches`, with cpu/proc-specific subdirs | common:7594 |
| `%pikeos_clone_project(demo dst)` / `%_pikeos_init_devel_project` / `%pikeos_prepare_package` / `%pikeos_prepare_demo` / `%pikeos_build_package` / `%pikeos_build_recipe` / `%pikeos_install_demo(dir)` / `%pikeos_bsp_prepare_basic_fusion(board)` / `%pikeos_bsp_prepare_cert_fusion(name)` | PikeOS project build orchestration (projectconfigurator/cloneproject/build-recipe/make wrappers) | common:96144 |
| `%pikeos_psp_src_name()` / `%pikeos_psp_config_name()` | PSP package rename functions | common:7172 |
| `%__sysgo_track_compile_pre/post`, `%_fixowner` hook, `%__sysgo_check_files`, `%__spec_install_post` (override) | compile-time file tracking (BaBS `BABS_TRACK_COMPILE`), post-install checker hook | common:146197 |
### 3.3 Install / transaction / database macros
| Macro | Meaning | Cite |
|---|---|---|
| `%_signature` | `none` (default signing off) | macros:153 |
| `%__gpg_check_password_cmd`, `%__pgp_check_password_cmd`, `%__pgp5_check_password_cmd`, `%__gpg_sign_cmd`, `%__pgp_sign_cmd`, `%__pgp5_sign_cmd` | external signer command templates (verify done internally via beecrypt) | macros:526541 |
| `%_transaction_color` | `3` (Elf32+Elf64 permitted) | macros:582 |
| `%_vsflags_{build,erase,install,query,rebuilddb,up2date,verify}` | all `0` — digest/signature verify flags per mode | macros:626633 |
| `%_query_all_fmt` | `%{name}-%{version}-%{release}` for `rpm -qa` | macros:693 |
| `%_install_langs` | `all` | macros:236 |
| `%_query_selector_match` | `default` (glob-like) | macros:267 |
| `%_dependency_whiteout[_7_0,_7_1,_7_2]` | legacy dependency-loop breakers (`p>q` pairs) | macros:650687 |
| `%_dbapi` / `%_dbapi_rebuild` | `3` / `3` — Berkeley DB backend | macros:516517 |
| `%__dbi_cdb` | `create cdb mpool mp_mmapsize=16Mb mp_size=1Mb` | macros:454 |
| `%__dbi_other` / `%__dbi_rebuild` / `%__dbi_transient` / `%__dbi_perms` | tmpdir+cdb; `nofsync !log !txn !cdb`; +`temporary private`; `perms=0644` | macros:456461 |
| `%__dbi_htconfig` / `%_dbi_htconfig[_current/_rebuild]` | hash-db config composition | macros:465477 |
| `%__dbi_btconfig` / `%_dbi_btconfig[_current/_rebuild]` | btree-db config composition | macros:481493 |
| `%_dbi_tags` | `Packages:Name:Basenames:Group:Requirename:Providename:Conflictname:Triggername:Dirnames:Requireversion:Provideversion:Installtid:Sigmd5:Sha1header:Filemd5s:Depends:Pubkeys` | macros:496 |
| `%_dbi_config_Packages` | `%{_dbi_htconfig} lockdbfd nofsync` | macros:499 |
| `%_dbi_config_Depends` | `%{_dbi_htconfig} temporary private nofsync` | macros:502 |
| `%_dbi_config_{Dirnames,Requireversion,Provideversion,Installtid,Removetid}` | `%{_dbi_btconfig} nofsync` | macros:504508 |
| `%_dbi_config` | `%{_dbi_htconfig} nofsync` (default) | macros:519 |
### 3.4 Target-configuration macros (`config/rpm/`)
**`common`** (product identity, cited §2.1): `%_pikeos_prefix /opt/pikeos-D5.0`, `%vendor SYSGO AG`, `%_pikeos_version D5.0`, `%distribution PikeOS D5.0`, `%packager <support@pikeos.com>`, `%_pikeos_url`, `%_pikeos_rpm_prefix pikeos-`, `%_sysgo_buildenv_dirname lin64`, `%_sysgo_buildenv_prefix /opt/sbe-D3.1`, `%_sysgo_*` aliases of the pikeos values, `%_pikeos_build_id %{_pikeos_version}-%{_pikeos_mod_release}`.
**Per-target files** (`config/rpm/targets/<arch>-linux`, 16 files) define: `%_pikeos_target_cpu`, `%_pikeos_target_proc`, `%_pikeos_target_arch` (=cpu_proc, `+ -diab` on DIAB variants), `%_pikeos_tool_prefix` (arch + `-`), `%_pikeos_target_name` (human label), `%_pikeos_cdk_dir` = `%{_pikeos_prefix}/cdk/<cpu>/<proc>`, `%_pikeos_arch_pool` = `%{_pikeos_prefix}/target/<cpu>/<proc>`, `%_pikeos_target_config` (gcc triplet), optional `%_pikeos_cpu_id`, `%_pikeos_cpu_arch`, `%_pikeos_cpu_endian`, `%_pikeos_has_fpu`, `%_pikeos_fpu_id`, `%_pikeos_cache_size`, `%_pikeos_has_altivec`, `%_pikeos_multilib_gcc`, `%_pikeos_wrdsz` (32/64), `%_pikeos_align` (0x1000).
**Per-host files** (`config/rpm/hosts/*`, 6 files) define: `%_pikeos_host_name`, `%_pikeos_host_arch`, `%_pikeos_rpm_host` (`<name>-` or `%nil` on Linux), `%_pikeos_host_config` (host triplet), `%_pikeos_host_prefix`, `%_pikeos_host_dirname`, `%_pikeos_host_dir` = `%{_pikeos_prefix}/<dirname>`; win32/win64 add `%_pikeos_cygwin_{config,prefix,dirname,dir}`; every host file mirrors all values into `%_sysgo_host_*` aliases.
### 3.5 Platform macros (`lib/rpm/<arch>-linux/macros`)
`x86_64-linux/macros` (66 lines): `%_arch x86_64`, `%_vendor unknown`, `%_os linux`, `%_gnu -gnu`, `%_target_platform %{_target_cpu}-%{_vendor}-%{_target_os}`, `%optflags -O2 -g`, configure tree with `%_sysconfdir /opt/pikeos-D5.0/config`, `%_localstatedir /opt/pikeos-D5.0/rpm/var`, `%_lib lib64`, `%_initrddir`, `%_smp_mflags`, multilib (`%_multilibno 2`, `%_multilibpatt …`), and **build-root policy**: `%__os_install_post` = `brp-compress brp-strip brp-strip-static-archive brp-strip-comment-note`, wired into `%__spec_install_post` (lines 5164). `noarch-linux/macros` is identical except `%_arch noarch`.
### 3.6 Macro load order (the effective stack)
From `rpmrc:355` (`macrofiles:`), confirmed by `--showrc`:
```
1. /opt/pikeos-D5.0/rpm/lib/rpm/macros (master, §3.13.3)
2. /opt/pikeos-D5.0/config/rpm/hosts/lin32 (host — NOTE: compiled-in default is lin32 even on x86_64; see §6)
3. /opt/pikeos-D5.0/config/rpm/targets/%{_target} (target, e.g. x86_64-linux)
4. /opt/pikeos-D5.0/config/rpm/common (product identity + PikeOS build macros)
5. /opt/pikeos-D5.0/rpm/lib/rpm/%{_target}/macros (platform, §3.5)
6. config/rpm/macros.specspo : macros.prelink : macros.solve : macros.up2date : macros (optional, absent)
7. /opt/pikeos-D5.0/config/rpm/%{_target}/macros (optional)
8. ~/.rpmmacros
```
Later definitions win. The compiled-in fallback in `librpm-4.2.so` is `…/macros:…/hosts/lin32:…/targets/%{_target}:…/common:./.rpmmacros:~/.rpmmacros` (note `./.rpmmacros` instead of the platform file — a vendor customization).
### 3.7 Built-in macro functions observed
`%(...)` shell eval, `%[...]`? (not used), `%{?cond:…}`/`%{!?cond:…}` conditionals, `%{-opt:…}` option-argument forms (`%GNUconfigure(MCs:)`), and **`%{u2p:PATH}`** — a vendor-added "unix-to-path" builtin used throughout `___build_pre` (macros:742761) and `common:4169`; verified live: `%{u2p:/opt/foo/bar}``/opt/foo/bar` (identity on Linux; on cygwin/mingw hosts it converts to the host path form). `uos-pkg` must implement `u2p` as a host-dependent path-conversion builtin.
### 3.8 rpmlib feature set (from `--showrc`)
`rpmlib(pikeos-D5.0)` (vendor virtual feature, "PikeOS virtual package"), `VersionedDependencies 3.0.3-1`, `CompressedFileNames 3.0.4-1`, `PayloadIsBzip2 3.0.5-1`, `PayloadFilesHavePrefix 4.0-1`, `ExplicitPackageProvide 4.0-1`, `HeaderLoadSortsTags 4.0.1-1`, `ScriptletInterpreterArgs 4.0.3-1`, `PartialHardlinkSets 4.0.4-1`, `ConcurrentAccess 4.1-1`.
---
## 4. Host/Target Matrix (`config/rpm/`)
### 4.1 Targets — 16 definition files covering 8 architecture families
| File | cpu_proc (arch) | gcc target_config | endian | word | FPU / notes |
|---|---|---|---|---|---|
| `arm_v7hf-linux` | `arm_v7hf` | `arm-unknown-eabihf` | little | 32 | fpu yes, `vfpv3-d16`, cpu_arch `armv7-a` |
| `arm_v8hf-linux` | `arm_v8hf` | `aarch64-unknown-elf` | little | 64 | fpu yes, cpu_arch `armv8-a` |
| `riscv_rv64-linux` | `riscv_rv64` | `riscv64-unknown-elf` | little | 64 | fpu yes, cpu_arch `rv64g` |
| `x86_amd64-linux` | `x86_amd64` | `x86_64-unknown-elf` | little | 64 | fpu yes |
| `x86_i686-linux` | `x86_i686` | `i686-unknown-elf` | little | 32 | fpu yes, cpu_id `i686` |
| `ppc_oea-linux` | `ppc_oea` | `powerpc-unknown-elf` | big | 32 | cpu_id `603`, cache 8, multilib |
| `ppc_e500-linux` | `ppc_e500` | `powerpc-unknown-elfspe` | big | 32 | cpu_id `8540`, cache 32 |
| `ppc_e500mc-linux` | `ppc_e500mc` | `powerpc-unknown-elf` | big | 32 | cpu_id `e500mc`, multilib |
| `ppc_e500mc-4g-linux` | `ppc_e500mc-4g` | `powerpc-unknown-elf` | big | 32 | 4G:4G memory split, multilib |
| `ppc_e500mc-diab-linux` | `ppc_e500mc-diab` | `powerpc-unknown-elf` | big | 32 | DIAB toolchain variant |
| `ppc_e500mc-4g-diab-linux` | `ppc_e500mc-4g-diab` | `powerpc-unknown-elf` | big | 32 | 4G:4G + DIAB |
| `ppc_e5500-linux` | `ppc_e5500` | `powerpc64-unknown-elf` | big | 64 | cpu_id `e5500`, multilib |
| `ppc_e6500-linux` | `ppc_e6500` | `powerpc64-unknown-elf` | big | 64 | cpu_id `e6500`, multilib |
| `mips_isa32be-linux` | `mips_isa32be` | `mipsisa32r2-unkown-elf` (sic) | big | 32 | fpu yes |
| `mips_isa32le-linux` | `mips_isa32le` | `mipsisa32r2el-unkown-elf` (sic) | little | 32 | fpu yes |
| `sparc_v8-linux` | `sparc_v8` | `sparc-unknown-elf` | big | 32 | fpu yes |
All targets: `%_pikeos_align 0x1000`; cdk dir `<prefix>/cdk/<cpu>/<proc>`; arch pool `<prefix>/target/<cpu>/<proc>`; tool prefix `<arch>-`.
**UniversalisOS relevance:** the replica kernel targets `armv7` (→ `arm_v7hf`), `aarch64` (→ `arm_v8hf`), `riscv` (→ `riscv_rv64`) — all present in the matrix, so `uos-pkg` inherits target definitions 1:1.
### 4.2 Hosts — 6 definition files
| File | host_name | arch | host_config (triplet) | rpm_host infix | dirname | extra |
|---|---|---|---|---|---|---|
| `lin32` | linux | i386 | `i686-pc-linux-gnu` | `%nil` (empty) | `lin64` (sic — 32-bit tools run from lin64 tree) | — |
| `lin64` | linux | x86_64 | `x86_64-pc-linux-gnu` | `%nil` | `lin64` | — |
| `cygwin` | cygwin | i386 | `i686-pc-cygwin` | `cygwin-` | `cygwin` | — |
| `cygwin64` | cygwin | x86_64 | `x86_64-pc-cygwin` | `cygwin-` | `cygwin64` | — |
| `win32` | win32 | i386 | `i686-w64-mingw32` | `win32-` | `mingw` | cygwin companion: `i686-pc-cygwin`, dir `cygwin` |
| `win64` | win32 | x86_64 | `x86_64-w64-mingw32` | `win32-` | `mingw64` | cygwin companion: `x86_64-pc-cygwin`, dir `cygwin64` |
Host dir = `%{_pikeos_prefix}/<dirname>`; every value mirrored into `%_sysgo_host_*`.
---
## 5. `uos-pkg` — From-Scratch Reimplementation Design
**Goal:** a clean-room packaging toolchain for the UniversalisOS build environment that is **functionally identical** to the PikeOS RPM 4.2 stack: same CLI surface, same on-disk package format (so existing `.rpm` artifacts install), same macro semantics (so existing `.spec` files and `config/rpm/*` files work unmodified), same rpmdb behavior. Written in C++ (freestanding-friendly core library `libuospkg` + CLI), no GPL/LGPL code reuse — format-level compatibility only (RPM format is documented; cpio/gzip are open formats).
### 5.1 Component map (1:1 to the PikeOS stack)
| PikeOS component | uos-pkg component | Notes |
|---|---|---|
| `rpm` (mode-dispatched CLI) | `uos-pkg` single binary, mode by argv[0] symlink or subcommand | symlinks `uos-pkg-{build,query,install,verify,sign,db}` mirror `rpmb/rpmq/rpmi/rpmk/rpmv/rpmd` |
| `rpmbuild` | `uos-pkg build` (`-bp -bc -bi -bl -ba -bb -bs -t* --rebuild --recompile --target --buildroot --clean --rmsource --rmspec --short-circuit --nodirtokens`) | identical stage semantics |
| `rpm -q/-V/-i/-U/-e/-K/--initdb/--rebuilddb` | `uos-pkg query|verify|install|upgrade|erase|checksig|initdb|rebuilddb` | same flags (§5.3) |
| `rpm2cpio` | `uos-pkg extract` (+ `uos-rpm2cpio` compat wrapper) | gzip+bzip2 payloads |
| `rpmgraph` | `uos-pkg graph` | graphviz digraph output |
| `gendiff` | `uos-pkg gendiff` (or keep the 20-line sh script) | trivial |
| `librpm/librpmbuild/librpmdb` | `libuospkg` (format), `libuosbuild` (spec/build engine), `libuosdb` (database) | C++17, freestanding-capable core |
| Berkeley DB 4.1.24 rpmdb | **uosdb**: append-only log-structured store with the same logical indexes (§5.4) | BDB format is legacy; we keep *logical* parity (same indexes, same query results), not byte parity |
| `lib/rpm/macros` + `rpmrc` + `rpmpopt-4.2` | `share/uos-pkg/macros`, `uosrc`, `uospopt` — byte-identical copies with path prefix retargeted (`/opt/pikeos-D5.0` → `%{uos_prefix}`) | macro engine must parse the original files unmodified as a conformance test |
| `config/rpm/{common,hosts/*,targets/*}` | `config/uos-rpm/{common,hosts/*,targets/*}` — same files, `pikeos`→`uos` token rename | 16 targets + 6 hosts preserved exactly |
| helper scripts (`find-provides`, `brp-*`, `check-files`, `find-lang.sh`, …) | reimplemented as `uos-pkg` builtins (`--internal-find-provides` etc.) with sh wrappers for compat | eliminates perl/sh host deps |
| `host-provides` / `buildenv-provides` machinery | `uos-pkg proxy host` / `uos-pkg proxy buildenv <pkg>` | generates identical spec + builds + installs (§5.6) |
### 5.2 Package file format (byte-level parity target)
Implement the RPM 4.2 container exactly (so PikeOS-built `.rpm` files install under `uos-pkg` and vice versa):
```
+-------------+ lead: 96 bytes, magic 0xEDABEEDB, major 3, minor 0,
| lead | type (0=bin,1=src), archnum, osnum, name[66], sigtype 5
+-------------+ signature header: header structure, magic 0x8EADE801,
| signature | RSA/DSA/SHA1/MD5 entries, 8-byte aligned
+-------------+ header: magic 0x8EADE801, sorted tags, i18n table;
| header | 133 query tags (verified list from --querytags)
+-------------+ payload: cpio (newc, "070701") compressed
| payload | gzip (w9.gzdio, default) or bzip2 (w9.bzdio)
+-------------+
```
- Header store: region + immutable section, tag sorting (`HeaderLoadSortsTags`), compressed filenames as (dirname,basename,dirindex) tuples (`CompressedFileNames`), `./`-prefixed payload paths (`PayloadFilesHavePrefix`).
- Digests: MD5 per file (`Filemd5s`), SHA1 over header (`Sha1header`), MD5 over header+payload (`Sigmd5`). Signatures: DSA/RSA via an internal minimal implementation (BeeCrypt replacement) — verification only is mandatory; signing optional.
- rpmlib dependencies: emit/require the same feature strings as §3.8, **including** `rpmlib(uos-5.0)` as the renamed virtual feature (the original `rpmlib(pikeos-D5.0)` string must also be *accepted* when installing legacy packages — aliasing table in the dependency resolver).
- `rpm2cpio` equivalence: `uos-pkg extract pkg.rpm | cpio -idm` must reproduce the payload; the pure-sh fallback algorithm (`rpm2cpio.sh`: skip 96-byte lead, parse signature/header sizes via `od`, `dd | gunzip`) documents the exact offsets and is the conformance reference.
### 5.3 CLI surface (parity with rpm 4.2)
```
uos-pkg query (-q) [-c -d -l -s --dump --qf FMT -a -f FILE -g GROUP -p PKG --specfile --whatrequires CAP --whatprovides CAP --scripts --provides --requires/-R --obsoletes --conflicts --info --changelog --xml --setperms --setugids]
uos-pkg verify (-V) [--nomd5 --nofiles --nodeps --noscript -a -f -g -p ...]
uos-pkg install (-i) / upgrade (-U) / freshen (-F) / erase (-e)
[--aid --allfiles --allmatches --badreloc --excludepath --force --hash/-h --ignorearch --ignoreos --ignoresize --includedocs --justdb --nodeps --nodigest --noorder --nopre --nopost --nopreun --nopostun --noscripts --notriggers --oldpackage --percent --prefix PATH --relocate OLD=NEW --repackage --replacefiles --replacepkgs --test]
uos-pkg sign (--addsign/--resign -K/--checksig --import --nodigest --nosignature)
uos-pkg db (--initdb --rebuilddb)
uos-pkg build (rpmbuild stage flags, §5.1)
uos-pkg extract | graph | gendiff | proxy | eval (-E) | define (-D) | showrc | querytags | macros=LIST | rcfile=LIST | root=DIR | version
```
All 133 query tags from `--querytags` must be supported by the query formatter (headerSprintf-compatible: `%{TAG}`, `%|TAG?{t}:{f}|` conditionals, `[...]` array iteration, `:shescape`/`:octal`/`:depflags`/`:json`? (4.2 set: `shescape`, `octal`, `hex`, `date`, `depflags`, `perms`, `fflags`, `vflags`) modifiers). The popt alias file `rpmpopt-4.2` (472 lines) is ported to `uospopt` verbatim.
### 5.4 Database (uosdb) — logical parity with the BDB rpmdb
- Location: `%{_dbpath}` = `<prefix>/var/lib/rpm` (same macro).
- Logical schema mirrors `%_dbi_tags` (macros:496): primary `Packages` store + indexes `Name Basenames Group Requirename Providename Conflictname Triggername Dirnames Requireversion Provideversion Installtid Sigmd5 Sha1header Filemd5s Depends Pubkeys`.
- Implementation: single-file log-structured store (`Packages.uosdb`) + per-index sorted-string tables; fcntl exclusive/shared locking replicating `lockdbfd`; `nofsync` default per `%_dbi_config*`; `--rebuilddb` regenerates all indexes from headers (equivalent of `%__dbi_rebuild nofsync !log !txn !cdb`).
- **Import path:** `uos-pkg db --import-bdb <dir>` reads legacy Berkeley DB 4.1.24 files (documented hash/btree formats) to migrate an existing PikeOS rpmdb.
- `ConcurrentAccess` semantics: scriptlets may query the db mid-transaction (in-process snapshot).
### 5.5 Macro engine (the heart of spec compatibility)
A faithful rpm-4.2 macro processor:
1. **Syntax:** `%name`, `%{name}`, `%{name:args}` builtins, `%name(args)` parameterized, `%(...)` shell, `%{?c:t}`/`%{!?c:f}`/`%{?c}` conditionals, `%{-o:…}`/`%{-o*}` option forms, `%%` escape, line continuation `\`, `#` comments, `%define/%global/%undefine` in spec files, BUFSIZ-8192 expansion buffer semantics (macros:778).
2. **Builtins:** at minimum `u2p` (host path conversion — identity on linux hosts, cygwin/mingw conversion on windows hosts; §3.7), `basename`, `dirname`, `suffix`, `expand`, `unexpand`, `verbose`, `nil`, `echo`, `warn`, `error`, `trace`, `dump`, `getenv`, `getconfdir`, `S P F` spec-section refs, plus lua-free 4.2 set.
3. **Load order** exactly as §3.6 with `%{_target}` interpolation in the file list; `--macros=` replaces the list; `-D` defines land in the highest-priority context.
4. **Conformance test:** `uos-pkg eval` on every macro in `config/rpm/*` and `lib/rpm/macros` must produce byte-identical expansions to the original `rpm -E` (differential test harness against the mirrored binaries, which run fine under `LD_LIBRARY_PATH=src/rpm/lib64`).
### 5.6 Build engine (rpmbuild parity)
- Spec parser: preamble tags (`Name Version Release Epoch Summary Group License Copyright Vendor Packager Distribution URL BuildRoot BuildRequires BuildArchitectures AutoReqProv Provides Requires Obsoletes Conflicts SourceN PatchN …`), sections `%description %prep %build %install %check %clean %files %changelog %pre %post %preun %postun %verifyscript %trigger*`, subpackages `%package/-n`, `%files` attributes `%defattr %attr %config %doc %dir %lang %ghost %exclude`.
- Scriptlet execution via `%___build_cmd` template with the SYSGO-overridden `%___build_pre` (PATH/LD_LIBRARY_PATH injection from `common:4069`, including `BABS_BUILDENV_PREFIX` handling) — the replica keeps this logic, retargeted to `uos_` macros.
- Stage pipeline `-bp→-bc→-bi→-bl→-bb/-ba`, `%setup`/`%patch` builtins, build-root policies (`brp-*` equivalents), `check-files` strictness (`%_unpackaged_files_terminate_build 1`), internal dependency generator producing SONAME/interpreter/perl deps identical to `find-provides`/`find-requires` output.
- PikeOS-specific macros from `common` (`%pikeos_build_package` etc.) are provided under `uos_` names (`%uos_build_package`, `%uos_clone_project`, …) with a **compatibility alias table** so legacy specs build unmodified; the alias table is the only place the old product token appears, isolated in `share/uos-pkg/legacy-aliases.macros`.
### 5.7 Proxy-package generation (host/buildenv parity)
`uos-pkg proxy host`:
1. emit `Provides: /bin/sh`, `/usr/bin/env`, interpreters (`bash perl csh` on Linux/BSD; `bash perl` on cygwin) — mirrors `find-host-provides.sh:83100`;
2. scan `/lib /usr/lib` (`/compat/linux` prefix on BSD) for `lib*.so.[0-9]`, `ld-linux*.so.[0-9]`; parse ELF dynamic section: emit SONAME and each `VERDEF` as `libname(VER)`; append `(64bit)` marker for ELF64 — mirrors `check_lib()` lines 4473;
3. render the `host-provides` spec template (Version 0.0, Release 1, noarch, AutoReqProv no, empty %files), build, and install into the uosdb.
`uos-pkg proxy buildenv <name>`: instantiate the `sbe-proxy-##PKGNAME##` template (`buildenv-provides.spec.in`) per build-environment component.
### 5.8 Macro-set mapping (1:1)
Every macro in §3 keeps its name and semantics; only the *values* carrying the product prefix change, via a single retargeting layer:
| PikeOS macro | uos-pkg value | Mechanism |
|---|---|---|
| `%_pikeos_prefix /opt/pikeos-D5.0` | `%_uos_prefix /opt/uos-5.0` (+ legacy alias) | `config/uos-rpm/common` |
| `%_pikeos_rpm_prefix pikeos-` | `%_uos_rpm_prefix uos-` | same |
| `%_pikeos_version D5.0` | `%_uos_version 5.0` | same |
| `%vendor SYSGO AG`, `%packager`, `%_pikeos_url` | UniversalisOS identity | same |
| all `%_pikeos_target_*`, `%_pikeos_host_*` | `%_uos_target_*`, `%_uos_host_*` | renamed copies of the 22 files |
| `%_sysgo_*` aliases | `%_uos_sys_*` (or drop; internal only) | same |
| `%{u2p:…}` | identical builtin | macro engine |
| master `macros` paths `/opt/pikeos-D5.0/rpm/…` | `/opt/uos-5.0/pkg/…` | retargeted copy |
The legacy-alias file maps `%_pikeos_*``%_uos_*` so that unmodified PikeOS specs/config evaluate identically. New UniversalisOS content uses only `uos_` names.
### 5.9 Verification & conformance plan
1. **Differential macro tests:** for each of the 241 macros + all `config/rpm` entries, compare `uos-pkg eval` vs mirrored `rpm -E` output (harness: `LD_LIBRARY_PATH=src/rpm/lib64 src/rpm/bin/rpm --rcfile … --macros … -E`).
2. **Format round-trip:** build a package with mirrored `rpmbuild`, install with `uos-pkg`; build with `uos-pkg build`, install with mirrored `rpm -i` (in a sandbox root) — both directions must succeed; `rpm2cpio` vs `uos-pkg extract` byte-compare payloads.
3. **DB parity:** after identical install sequences, `query -qa --qf` dumps must match; `rpmgraph` vs `uos-pkg graph` digraphs must be isomorphic.
4. **Proxy parity:** `find-host-provides.sh` output vs `uos-pkg proxy host --emit-provides` diffed on the same machine.
5. **Real-world corpus:** the 1906 package names recovered from the mirrored rpmdb `Name` index serve as the naming-conformance corpus; synthetic specs generating each family must produce identical NEVRA strings.
### 5.10 Non-goals / deliberate deviations
- No byte-level Berkeley DB compatibility (logical parity only; import tool provided).
- No PGP2/PGP5 external signers (`%__pgp*_sign_cmd`) — GPG-compatible signing only; verification of legacy signatures still supported.
- No `rpmcache`/up2date universe solver (`%_bh*`, `%_solve_*` macros parsed but inert).
- Internationalization: English-only CLI (the original ships 20+ locale catalogs; messages are out of parity scope).
- The `lin32`-as-default-host quirk in the compiled-in macrofiles list (§3.6) is reproduced for fidelity but documented; `uos-pkg` selects the host file matching the actual host arch unless `--legacy-host-default` is given.
---
## 6. Notable findings / quirks (relevant to the replica)
1. **Compiled-in default host is `lin32`** even though the tools are x86_64 binaries (`rpmrc:355` and the `librpm-4.2.so` embedded string). On a 64-bit host the effective host config comes from `hosts/lin32` unless overridden — `lin32` itself sets `%_pikeos_host_dirname lin64` (sic), so paths still resolve to the 64-bit tree.
2. **`./.rpmmacros`** (cwd-local macro file) appears in the *embedded* macrofiles list but not in the on-disk `rpmrc` — a vendor patch to the library.
3. **`rpmlib(pikeos-D5.0)`** is a custom virtual rpmlib capability injected by the vendor build; packages may `Require:` it. `uos-pkg` must alias it.
4. **`%{u2p:…}`** is a vendor-added macro builtin (not in stock rpm 4.2) for Windows-host path conversion; used in every build scriptlet prelude.
5. The shipped rpmdb is an **empty template** (`Packages` = 0 bytes) but secondary indexes retain ~1906 historical package-name keys — a goldmine for the naming taxonomy (§2.3).
6. zlib inside `librpm` reports **1.1.4** inflate/deflate (2002-era) while linking a 1.2.7 `zlibVersion` symbol — payload compression is plain gzip either way.
7. `mips_isa32*` target files contain the misspelled triplet `mipsisa32r2-unkown-elf` — reproduce verbatim for parity (gcc configure consumes it).
8. Strict-build defaults: unpackaged files **and** missing `%doc` files terminate the build (`macros:316,322`) — harsher than stock rpm 4.2 defaults.
9. `%_fixowner` is deliberately abused as the earliest post-`%setup` hook for compile tracking (`common:184190`) — the replica must preserve hook ordering.
10. The banned two-character product token appears in original comments (e.g. `common:78,92` example CVS paths) and as an infix in ~14 recovered legacy package names (a doc package, an API family, a CFS family, a bus family, and a base family, all of the form `pikeos-<token>…`); the replica's alias table handles these as opaque legacy strings, never generating them.
---
*End of specification. All citations refer to files under `~/portugalfuturista/universalisos/` (`src/rpm/…` for binaries and shipped config, `pikeos-mirror/…` for the config/rpm tree).*