Blame etc/README.md

fe49bc
> N.B. If you're interested in building Midipix using this script, please join
fe49bc
the project's IRC channel #midipix on Libera and ask for the address of the
fe49bc
internal repositories required in order to build Midipix.
fe49bc
fe49bc
> N.B. Due to the present state of the (largely) automated package upstream
fe49bc
updates integration script and, despite frequent contributions, lack of
fe49bc
human resources, it bears mentioning that the 3rd party packages built
fe49bc
and distributed by this script are often not up to date with their resp.
fe49bc
upstream and *may* hence be **insecure**. It is advised that this be taken
fe49bc
into account when deploying and using Midipix distributions.
fe49bc
fe49bc
[//]: # "{{{ Table of contents"
fe49bc
# Table of Contents
fe49bc
fe49bc
1. [What is Midipix, and how is it different?](#1-what-is-midipix-and-how-is-it-different)  
fe49bc
2. [Building and deployment](#2-building-and-deployment)  
fe49bc
	2.1. [Building, installing, and using a Midipix distribution](#21-building-installing-and-using-a-midipix-distribution)  
fe49bc
		2.1.1. [Build-time dependencies](#211-build-time-dependencies)  
fe49bc
			2.1.1.1. [Alpine-specific notate bene](#2111-alpine-specific-notate-bene)  
fe49bc
	2.2. [Deployment](#22-deployment)  
fe49bc
	2.3. [System requirements](#23-system-requirements)  
fe49bc
	2.4. [Troubleshooting](#24-troubleshooting)  
fe49bc
3. [Common concepts and tasks / FAQ](#3-common-concepts-and-tasks-faq)  
fe49bc
	3.1. [Common tasks](#31-common-tasks)  
fe49bc
	3.2. [Adding a package](#32-adding-a-package)  
fe49bc
	3.3. [Addressing build failure](#33-addressing-build-failure)  
fe49bc
	3.4. [Package archive files and Git repositories](#34-package-archive-files-and-git-repositories)  
fe49bc
	3.5. [Patches and ``vars`` files](#35-patches-and-vars-files)  
fe49bc
4. [Reference](#4-reference)  
fe49bc
	4.1. [Build steps](#41-build-steps)  
fe49bc
	4.2. [Build variables](#42-build-variables)  
fe49bc
	4.3. [File installation DSL](#43-file-installation-dsl)  
fe49bc
	4.4. [Package variables](#44-package-variables)  
fe49bc
		4.4.1. [Package variable types](#441-package-variable-types)  
fe49bc
		4.4.2. [Package variables](#442-package-variables)  
fe49bc
	4.5. [Fault-tolerant & highly optimised 3D laser show-equipped usage screen](#45-fault-tolerant--highly-optimised-3d-laser-show-equipped-usage-screen)  
fe49bc
	4.6. [``pkgtool.sh``](#46-pkgtoolsh)  
fe49bc
	4.7. [Bourne shell coding rules](#47-bourne-shell-coding-rules)  
fe49bc
5. [References](#5-references)  
fe49bc
fe49bc
[//]: "}}}"
fe49bc
fe49bc
[//]: # "{{{ 1. What is Midipix, and how is it different?"
fe49bc
## 1. What is Midipix, and how is it different?
fe49bc
fe49bc
midipix is a development environment that lets you create programs
fe49bc
for Windows using the standard C and POSIX APIs. No compromises made,
fe49bc
no shortcuts taken.  
fe49bc
  
fe49bc
If you are interested in cross-platform programming that reclaims
fe49bc
the notion of write once, compile everywhere; if you believe that the
fe49bc
'standard' in the C Standard Library should not be a null signifier;
fe49bc
and if you like cooking your code without #ifdef hell and low-level
fe49bc
minutiae, then this page is for you.  
fe49bc
  
fe49bc
midipix makes cross-platform programming better, simpler and faster,
fe49bc
specifically by bringing a modern, conforming C Runtime Library to the
fe49bc
Windows platform. While the idea itself is not new, the approach taken
fe49bc
in midipix to code portability is radically different from that found
fe49bc
in other projects.  
fe49bc
  
fe49bc
*(reproduced from [[2](https://midipix.org/#sec-midipix)])*
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: "}}}"
fe49bc
fe49bc
[//]: # "{{{ 2. Building and deployment"
fe49bc
## 2. Building and deployment
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 2.1. Building, installing, and using a Midipix distribution"
fe49bc
### 2.1. Building, installing and using a Midipix distribution
fe49bc
fe49bc
A Midipix distribution consists of the following:
fe49bc
fe49bc
* the native Midipix toolchain, consisting of perk, gcc, its dependencies,
fe49bc
  and binutils,
fe49bc
* musl, a lightweight, fast, simple, and free libc[[1](https://www.musl-libc.org/faq.html)] used by Midipix,
fe49bc
* the Midipix runtime components that bridge the gap between the libc and the
fe49bc
  executive subsystems of all Windows NT-derived Windows OS starting with and
fe49bc
  including Windows XP, and
fe49bc
* a steadily increasing number of 3rd party open source packages, as expected in
fe49bc
  any modern POSIX-compliant \*nix environment, including GNU coreutils, shells,
fe49bc
  libraries such as ncurses, libressl, as well as Perl and Python.
fe49bc
fe49bc
Install the build-time dependencies listed in section [2.1.1](#211-build-time-dependencies),
fe49bc
clone this repository (e.g. ``git clone https://dev.midipix.org/build/midipix_build``)
fe49bc
and run the following command line:
fe49bc
fe49bc
```shell
fe49bc
./build.sh -a nt64 -b release -D zipdist -P -v
fe49bc
```
fe49bc
fe49bc
By default, the build will take place within ``${HOME}/midipix/nt64/release``
fe49bc
and package archive files and/or Git repositores will be downloaded into
fe49bc
``${HOME}/midipix/dlcache``. Consult sections [4.2](#42-build-variables) and
fe49bc
[4.4](#44-package-variables) for the list of available build/package variables
fe49bc
and how to override them.  
fe49bc
Parallelisation is enabled by the above command line for both packages that can
fe49bc
be built independently of each other and ``make(1)`` via ``-j``, limited to the
fe49bc
amount of logical processors on the build host divided by two (2).
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 2.1.1. Build-time dependencies"
fe49bc
### 2.1.1. Build-time dependencies
fe49bc
fe49bc
* **Alpine Linux**:
fe49bc
  binutils bison bzip2 cmake coreutils curl findutils g++ gawk gcc git grep gzip libc-dev linux-headers lzip m4 make musl-dev net-tools patch perl perl-xml-parser procps sed tar util-linux util-linux-dev wget xz zip
fe49bc
* **Arch Linux**:
fe49bc
  binutils bison bzip2 cmake coreutils curl findutils gawk gcc git grep gzip lzip m4 make net-tools patch perl perl-xml-parser procps-ng sed tar util-linux util-linux-libs wget xz zip
fe49bc
* **Debian/-derived Linux**:
fe49bc
  binutils bison bzip2 cmake coreutils curl findutils g++ gawk gcc git grep gzip hostname libc6-dev libxml-parser-perl lzip m4 make patch perl procps sed tar util-linux uuid-dev wget xz-utils zip
fe49bc
* **Gentoo Linux**:
fe49bc
  binutils bison bzip2 cmake coreutils curl findutils gawk =gcc-7.5.0-r1 dev-vcs/git grep gzip lzip m4 make patch perl dev-perl/XML-Parser procps sed tar util-linux libuuid wget xz-utils zip
fe49bc
* **OpenSUSE Linux**:
fe49bc
  binutils bison bzip2 cmake coreutils curl findutils gawk gcc gcc-c++ git grep gzip hostname linux-glibc-devel lzip m4 make patch perl perl-XML-Parser procps sed tar util-linux libuuid1 wget xz zip
fe49bc
  
fe49bc
#### The distro matrix:
fe49bc
fe49bc
|  Alpine Linux:  |    Arch Linux:     |   Debian/-derived Linux:   |    Gentoo Linux:    |  OpenSUSE Linux:  |
fe49bc
| --------------- | ------------------ | -------------------------- | ------------------- | ----------------- |
fe49bc
| binutils        | binutils           | binutils                   | binutils            | binutils          |
fe49bc
| bison           | bison              | bison                      | bison               | bison             |
fe49bc
| bzip2           | bzip2              | bzip2                      | bzip2               | bzip2             |
fe49bc
| cmake           | cmake              | cmake                      | cmake               | cmake             |
fe49bc
| coreutils       | coreutils          | coreutils                  | coreutils           | coreutils         |
fe49bc
| curl            | curl               | curl                       | curl                | curl              |
fe49bc
| findutils       | findutils          | findutils                  | findutils           | findutils         |
fe49bc
| g++             | -                  | g++                        | -                   | gcc-c++           |
fe49bc
| gawk            | gawk               | gawk                       | gawk                | gawk              |
fe49bc
| gcc             | gcc                | gcc                        | =gcc-7.5.0-r1       | gcc               |
fe49bc
| git             | git                | git                        | dev-vcs/git         | git               |
fe49bc
| grep            | grep               | grep                       | grep                | grep              |
fe49bc
| gzip            | gzip               | gzip                       | gzip                | gzip              |
fe49bc
| -               | -                  | hostname                   | -                   | hostname          |
fe49bc
| libc-dev        | -                  | libc6-dev                  | -                   | linux-glibc-devel |
fe49bc
| linux-headers   | -                  | -                          | -                   | -                 |
fe49bc
| lzip            | lzip               | lzip                       | lzip                | lzip              |
fe49bc
| m4              | m4                 | m4                         | m4                  | m4                |
fe49bc
| make            | make               | make                       | make                | make              |
fe49bc
| musl-dev        | -                  | -                          | -                   | -                 |
fe49bc
| net-tools       | net-tools          | -                          | -                   | -                 |
fe49bc
| patch           | patch              | patch                      | patch               | patch             |
fe49bc
| perl            | perl               | perl                       | perl                | perl              |
fe49bc
| perl-xml-parser | perl-xml-parser    | libxml-parser-perl         | dev-perl/XML-Parser | perl-XML-Parser   |
fe49bc
| procps          | procps-ng          | procps                     | procps              | procps            |
fe49bc
| sed             | sed                | sed                        | sed                 | sed               |
fe49bc
| tar             | tar                | tar                        | tar                 | tar               |
fe49bc
| util-linux      | util-linux         | util-linux                 | util-linux          | util-linux        |
fe49bc
| util-linux-dev  | util-linux-libs    | uuid-dev                   | libuuid             | libuuid1          |
fe49bc
| -               | vi                 | -                          | -                   | -                 |
fe49bc
| wget            | wget               | wget                       | wget                | wget              |
fe49bc
| xz              | xz                 | xz-utils                   | xz-utils            | xz                |
fe49bc
| zip             | zip                | zip                        | zip                 | zip               |
fe49bc
fe49bc
> N.B. Busybox is not supported. Awk implementations other than GNU Awk are not supported.  
fe49bc
  
fe49bc
> N.B. clang is not supported.  
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 2.1.1.1. Alpine-specific notate bene"
fe49bc
#### 2.1.1.1. Alpine-specific notate bene
fe49bc
fe49bc
Some packages (*coreutils*, *grep*, and *tar*, among others) override Alpine's
fe49bc
BusyBox utilities of the same name, as the latter are either non-conformant or
fe49bc
defective.
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 2.2. Deployment"
fe49bc
### 2.2. Deployment
fe49bc
fe49bc
On successful completion of the build, a ZIP archive containing the Midipix
fe49bc
distribution will be created inside ``${PREFIX}`` (see section [4.2](#42-build-variables).)
fe49bc
Create a directory on the target machine and extract the contents of the distribution
fe49bc
ZIP archive into it, run ``bash.bat``, and then ``/install.sh`` inside the resulting
fe49bc
self-contained Midipix installation shell window.  
fe49bc
  
fe49bc
Make sure to consult the notate bene below:  
fe49bc
  
fe49bc
> N.B. The pathname of the target directory containing ``bash.bat`` and all other
fe49bc
distribution files must not contain whitespaces.  
fe49bc
  
fe49bc
> N.B. The Midipix installer defaults to ``/dev/fs/c/midipix (C:\midipix)``. If left
fe49bc
unchanged, the distribution ZIP archive must not be extracted into a directory of the
fe49bc
same pathname.  
fe49bc
  
fe49bc
> N.B. The user installing and using Midipix must have been delegated the ``SeCreateSymbolicLinkPrivilege``
fe49bc
("Create symbolic links") privilege[[3](https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment)] and additionally be a non-administrator account
fe49bc
owing to the UAC-related filtering policy of tokens introduced by Windows Vista[[4](https://docs.microsoft.com/en-us/previous-versions/dotnet/articles/bb530410%28v%3dmsdn%2e10%29)].  
fe49bc
  
fe49bc
> N.B. On Windows 10 and 11, Windows Defender as well as SmartScreen must be disabled.
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 2.3. System requirements"
fe49bc
### 2.3. System requirements
fe49bc
fe49bc
The following build-time system requirements are assessed on build hosts
fe49bc
equipped with the following hardware at minimum:
fe49bc
fe49bc
* Intel(R) Xeon(R) CPU W3520 @ 2.67GHz (8 cores)
fe49bc
* 7200 RPM SATA 3.1 HDD
fe49bc
* 6 GB RAM
fe49bc
fe49bc
| Target architecture | Build kind | Distribution kinds selected | Average build time | Disk space required | Peak RAM usage |
fe49bc
| ------------------- | ---------- | --------------------------- | ------------------ | ------------------- | -------------- |
fe49bc
| nt64                | debug      | (none)                      | 2 hours            | 57.62 GB            | 3.55 GB        |
fe49bc
| nt64                | release    | (none)                      | 1 hours 45 minutes | 36.51 GB            | 3.21 GB        |
fe49bc
fe49bc
Package archive files and/or Git repositories additionally consume at least
fe49bc
1.82 GB.
fe49bc
fe49bc
*(last update: Thu, 05 Mar 2020 09:25:41 +0000)*
fe49bc
fe49bc
These are the Midipix distribution disk space system requirements:
fe49bc
fe49bc
| Target architecture | Build kind | Distribution | Installation directory | Archive file |
fe49bc
| ------------------- | ---------- | ------------ | ---------------------- | ------------ |
fe49bc
| nt64                | debug      | 7.3 GB       |  2.3 GB                | 2.1 GB       |
fe49bc
| nt64                | release    | 3.2 GB       |  913 MB                | 830 MB       |
fe49bc
fe49bc
The installation directory and archive file may be safely deleted post-installation.
fe49bc
fe49bc
*(last update: Thu, 07 Jan 2021 18:20:06 +0000)*
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 2.4. Troubleshooting"
fe49bc
### 2.4. Troubleshooting
fe49bc
fe49bc
Midipix presently provides, inter alia, strace-like functionality via
fe49bc
ntctty's logging capabilities. This is available both through the regular
fe49bc
``strace(1)`` command as distributed, which however **must** be provided
fe49bc
with an absolute pathname without consideration for ``${PATH}``, as well
fe49bc
as directly via ``ntctty.exe`` for a session by running ``ntctty.exe``
fe49bc
with the ``--log-level 7`` option, e.g.:
fe49bc
fe49bc
```shell
fe49bc
$ #strace ls -la /        # (incorrect, relative pathname)
fe49bc
$ strace /bin/ls -la /    # (correct, absolute pathname)
fe49bc
$ ntctty.exe --log-level 7 -e /bin/ls -la /
fe49bc
$ ntctty.exe --log-level=7 -e /bin/ls -la /
fe49bc
$ ntctty.exe --log-level 7 -e /bin/sh -c "ls -la /"
fe49bc
$ ntctty.exe --log-level=7 -e /bin/sh -c "ls -la /"
fe49bc
```
fe49bc
fe49bc
By default, ``ntctty.exe`` log files are written into the /var/log/ntctty
fe49bc
directory; this may be adjusted with the ``--log-dir`` and/or
fe49bc
``--log-file`` options. ``strace(1)`` logs to stderr by default.
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
fe49bc
[//]: # "{{{ 3. Common concepts and tasks"
fe49bc
## 3. Common concepts and tasks
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 3.1. Common tasks"
fe49bc
### 3.1. Common tasks
fe49bc
fe49bc
Rebuild set of packages in isolation:
fe49bc
```shell
fe49bc
./build.sh [ ... ] -r mc,zsh
fe49bc
```
fe49bc
  
fe49bc
Restart the ``@install`` (shorthand alias) step, with implicit ``finish``, of the
fe49bc
``mc`` and ``zsh`` packages.
fe49bc
```shell
fe49bc
./build.sh [ ... ] -r mc,zsh:@install
fe49bc
```
fe49bc
  
fe49bc
Rebuild set of packages along w/ their dependencies, if any, as needed, or forcibly,
fe49bc
respectively:
fe49bc
```shell
fe49bc
./build.sh [ ... ] -r \*mc,zsh
fe49bc
./build.sh [ ... ] -r \*\*mc,zsh
fe49bc
```
fe49bc
  
fe49bc
Forcibly rebuild all reverse dependencies of a set of packages:
fe49bc
```shell
fe49bc
./build.sh [ ... ] -r \*\*\*glib,libflac
fe49bc
```
fe49bc
  
fe49bc
Restart the ``@configure``, ``@build``, and ``@install`` (shorthand alias) steps of the
fe49bc
``coreutils`` package:
fe49bc
```shell
fe49bc
./build.sh -r coreutils:@configure,@build,@install
fe49bc
```
fe49bc
  
fe49bc
Rebuild entire build groups including or excluding group dependencies, respectively:
fe49bc
```shell
fe49bc
./build.sh [ ... ] -r ALL native_runtime
fe49bc
./build.sh [ ... ] -r ALL =native_runtime
fe49bc
```
fe49bc
  
fe49bc
Forcibly (re)download all archive files and/or Git repositories associated with all packages:
fe49bc
```shell
eb7c32
./build.sh [ ... ] -r ALL:@fetch,finish
fe49bc
```
eb7c32
> N.B. the "finish" (pseudo-)build step must be included here and in similar use cases so that all
eb7c32
affected packages are marked as having finished building in order to correctly satisfy package-package
eb7c32
dependencies.
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 3.2. Adding a package"
fe49bc
## 3.2. Adding a package
fe49bc
fe49bc
Packages are grouped into *build groups* according to sets of common package
fe49bc
variable defaults, such as ``${PKG_CFLAGS_CONFIGURE}, ${PKG_LDFLAGS_CONFIGURE}``
fe49bc
and ``${PKG_CONFIGURE_ARGS}``, and semantic interrelatedness, such as the
fe49bc
``native_runtime`` build group comprising the Midipix runtime components.
fe49bc
Packages may belong to more than one build group such as when subsumed by a shorthand
fe49bc
build group e.g. the ``dev_packages`` build group, as long as the default set of build
fe49bc
groups or as overriden on the command line does not entail group membership conflicts.  
fe49bc
  
fe49bc
Build groups files beneath ``groups.d/`` named ``[0-9][0-9][0-9].<group name>.group``
931865
contain package variable defaults, optionally the alphabetically sorted list of contained
931865
packages, if any, in ``<upper case group name>_PACKAGES``, and their package variables
fe49bc
sorted alphabetically with the exception of ``${PKG_DEPENDS}`` (if present,)
fe49bc
``${PKG_SHA256SUM}``, ``${PKG_URL}``, and ``${PKG_VERSION}``, and/or ``${PKG_URLS_GIT}``,
cf8543
which are specified in this order. Build group files require the following epilogue, the
cf8543
parameters enclosed in square brackets being optional:
931865
931865
```shell
cf8543
ex_pkg_register_group "<group name>" "${RTL_FILEOP_SOURCE_FNAME}" [["owner|copy"] ["auto|noauto"]];
931865
931865
# vim:filetype=sh textwidth=0
931865
```
931865
cf8543
If ``copy`` is specified, the build group will copy all of its packages from their respective
cf8543
build groups without taking ownership thereof, if ``owner`` is specified, the default, the build
cf8543
group owns all of its packages. If ``noauto`` is specified, the build group will not be added to
cf8543
the list of build groups to build by default, if ``auto`` is specified, the build group will be
cf8543
added to the list of build groups to build by default.  
8b075b
  
8b075b
If a build group that specifies ``copy`` should copy all of its build group variables from another
8b075b
build group, use the following code:
8b075b
8b075b
```shell
8b075b
ex_pkg_copy_group_vars "<source group name>" "<destination group name>";
8b075b
```
8b075b
cf8543
Additionally, single package files may be added beneath ``groups.d/[0-9][0-9][0-9].<group name>.d/``,
cf8543
named ``<package name>.package`` containing the package's variables, with the following epilogue,
cf8543
the parameters enclosed in square brackets being optional:
931865
931865
```shell
cf8543
ex_pkg_register "<package_name>" "${RTL_FILEOP_SOURCE_FNAME}" ["<group name>"];
931865
931865
# vim:filetype=sh textwidth=0
931865
```
cf8543
931865
1. Pick a build group according to the criteria mentioned and specifiy the set of package
931865
variables required (see above and section [4.4](#44-package-variables)) in either the
931865
corresponding group file or a single package file; in the former case, do also add the
931865
package to the build group's list of contained packages.
931865
  
931865
2. Consult section [3.5](#35-patches-and-vars-files) if the package to be added
fe49bc
requires patches or additional code amending or replacing package build steps
fe49bc
or the entire package build. Consult section [4.1](#41-build-steps) for a list
fe49bc
of package build steps and how they are overriden.
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 3.3. Addressing build failure"
fe49bc
## 3.3. Addressing build failure
fe49bc
fe49bc
During package build, standard error and output are redirected into a log file beneath
fe49bc
``${BUILD_WORKDIR}`` named ``${PKG_NAME}_stderrout.log``, following a package variable
fe49bc
dump. If ``-V build`` was specified, package logs will additionally be printed to standard
fe49bc
output. If ``-V xtrace`` was specified, ``xtrace`` will be set during package builds for
fe49bc
rudimentary debugging purposes. Additionally, packages using GNU autotools will, if
fe49bc
package configuration failed or appears relevant, log the configuration process in detail
fe49bc
in, most usually, ``${PKG_BUILD_DIR}/config.log``.  
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 3.4. Package archive files and Git repositories"
fe49bc
### 3.4. Package archive files and Git repositories
fe49bc
fe49bc
Packages may have either or both of a SHA-256 message digest checked and to be extracted tarball
fe49bc
(set in ``${PKG_URL}``, ``${PKG_FNAME}``, and ``${PKG_SHA256SUM}``) and/or Git repository or set
fe49bc
thereof (set in ``${PKG_URLS_GIT}``.) Complementing these, an implicitly inferred or, in the
fe49bc
presence of both, explicit primary source directory is specified for each package in ``${PKG_SUBDIR}``.
fe49bc
Furthermore, these may be subject to download caching and/or setting up as well as maintaining
fe49bc
mirrors, including automatic cleanup as well as deduplication in both cases.  
fe49bc
  
fe49bc
A list of pertinent package variables and their formats follows:  
fe49bc
fe49bc
| Name           | Format                                          |
fe49bc
| -------------- | ----------------------------------------------- |
fe49bc
| PKG_FNAME      | ``<single file name>``                          |
fe49bc
| PKG_SHA256SUM  | ``<SHA-256 message digest>``                    |
fe49bc
| PKG_SUBDIR     | ``<relative or single directory name>``         |
fe49bc
| PKG_URL        | ``scheme:[//authority]path[?query][#fragment]`` |
fe49bc
| PKG_URLS_GIT   | ``[subdir=]URL[@branch]``                       |
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 3.5. Patches and ``vars`` files"
fe49bc
## 3.5. Patches and ``vars`` files
fe49bc
fe49bc
Package patches are applied prior and/or subsequent to (GNU autotools or similar) package
fe49bc
configuration during the ``configure_patch_pre`` and/or ``configure_patch`` build steps,
fe49bc
respectively (see section [4.1](#41-build-steps).) Patch files are searched for beneath
fe49bc
``patches/`` with the following globs and in-order:
fe49bc
* ``${PKG_NAME}-${PKG_VERSION}_pre.local.patch``
fe49bc
  or ``${PKG_NAME}_pre.local.patch`` (for packages lacking ``${PKG_VERSION}``)
fe49bc
* ``${PKG_NAME}-${PKG_VERSION}_pre.local@${BUILD_HNAME}.patch``
fe49bc
  or ``${PKG_NAME}_pre.local@${BUILD_HNAME}.patch`` (for packages lacking ``${PKG_VERSION}``)
fe49bc
* ``${PKG_NAME}/*.patch``
fe49bc
* ``${PKG_NAME}-${PKG_VERSION}.local.patch``
fe49bc
  or ``${PKG_NAME}.local.patch`` (for packages lacking ``${PKG_VERSION}``)
fe49bc
* ``${PKG_NAME}-${PKG_VERSION}.local@${BUILD_HNAME}.patch``
fe49bc
  or ``${PKG_NAME}.local@${BUILD_HNAME}.patch`` (for packages lacking ``${PKG_VERSION}``)
fe49bc
* ``${PKG_PATCHES_EXTRA}`` (if set)
fe49bc
  
fe49bc
If the default set of package build steps does not suffice, such as if additional commands
fe49bc
must be executed after package configuration or prior to building, or if an entire or all
fe49bc
build step must be replaced, overrides may be specified in the form of functions in the
fe49bc
package's ``vars/${PKG_NAME}.vars`` as well as ``vars.<group name>/${PKG_NAME}.vars``
fe49bc
``vars`` file(s). Consult section [4.1](#41-build-steps) for a list of package build steps
fe49bc
and how they are overriden.
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
fe49bc
[//]: # "{{{ 4. Reference"
fe49bc
## 4. Reference
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 4.1. Build steps"
fe49bc
## 4.1. Build steps
fe49bc
fe49bc
Package builds are divided up into consecutively executed build steps until
fe49bc
completion or aborted on failure unless relaxed mode is enabled by passing
fe49bc
``-R``.  
fe49bc
  
fe49bc
Each build step corresponds to a function in the corresponding ``subr/pkg_*.subr``
fe49bc
script and may be overriden entirely by a function named ``pkg_<package name>_<build step>()``
fe49bc
or composed in terms of prior and/or subsequent execution by a function named
fe49bc
``pkg_<package name>_<build step>_pre()`` and/or ``pkg_<package name>_<build step>_post()``,
fe49bc
respectively, in the package's ``vars`` file. If a function named ``pkg_<package name>_all()``
fe49bc
exists, it will override all build steps.  
fe49bc
  
fe49bc
Build step functions receive the following arguments in the order specified:
fe49bc
  
fe49bc
| Name          | Description                                              |
fe49bc
| ------------- | -------------------------------------------------------- |
fe49bc
| \_group\_name | Package name                                             |
fe49bc
| \_pkg\_name   | Group name                                               |
fe49bc
| \_restart\_at | Optional list of build steps to restart package build at |
fe49bc
  
fe49bc
Build step status is tracked on a per-package basis by state files beneath
fe49bc
``${BUILD_WORKDIR}`` following the format ``.<package name>.<build step>``;
fe49bc
package build completion corresponds to the pseudo-build step ``finish``.
fe49bc
fe49bc
| Name                | Description                                                                                                                                                                                                                                              |
fe49bc
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
fe49bc
| fetch_clean         | Delete and create ``${PKG_SUBDIR}``                                                                                                                                                                                                                      |
fe49bc
| fetch_download      | Download package archive & verify w/ SHA-256 message digest and/or clone Git repository/ies                                                                                                                                                              |
fe49bc
| fetch_extract       | Extract package archive, if any                                                                                                                                                                                                                          |
fe49bc
| configure_clean     | Delete and create ``${PKG_BUILD_DIR}``                                                                                                                                                                                                                   |
fe49bc
| configure_patch_pre | Apply ``chainport`` patches and/or patches beneath ``patches/`` prior to (GNU autotools or similar) configuration                                                                                                                                        |
fe49bc
| configure_autotools | Bootstrap (GNU autools or similar) environment, and install ``config.sub`` and ``config.cache``                                                                                                                                                          |
fe49bc
| configure_patch     | Apply patches beneath ``patches/`` and/or set in ``${PKG_PATCHES_EXTRA}`` after (GNU autotools or similar) configuration                                                                                                                                 |
fe49bc
| configure           | Perform package (GNU autools or similar or CMake) configuration w/ configuration-time set of environment variables                                                                                                                                       |
fe49bc
| build_clean         | Clean ``${PKG_BUILD_DIR}`` w/ ``make clean`` invocation                                                                                                                                                                                                  |
fe49bc
| build               | Call ``make(1)`` w/ build-time set of make variables                                                                                                                                                                                                     |
fe49bc
| install_clean       | Delete and create ``${PKG_DESTDIR}``                                                                                                                                                                                                                     |
fe49bc
| install_subdirs     | Create default directory hierarchy in ``${PKG_DESTDIR}``, optionally amended w/ ``${PKG_INSTALL_FILES_DESTDIR_EXTRA}``                                                                                                                                   |
fe49bc
| install_make        | Call ``make(1)`` w/ ``${PKG_INSTALL_TARGET}`` (defaults to ``install``) and installation-time set of make variables                                                                                                                                      |
fe49bc
| install_files       | Install ``${PKG_INSTALL_FILES}`` and/or ``${PKG_INSTALL_FILES_V2}``, fix directory and file mode bits within ``${PKG_DESTDIR}`` and optionally ``${PKG_DESTDIR_HOST}``, ``pkgconf(1)`` package files, and/or stripped binaries within ``${PKG_DESTDIR}`` |
fe49bc
|                     | Purge libtool ``.la`` files and install shared objects within ``${PKG_DESTDIR}`` w/ ``perk`` and corresponding symbolic links                                                                                                                            |
fe49bc
| install             | Install into ``${PKG_PREFIX}``, and optionally ``${PKG_DESTDIR_HOST}`` into ``${PREFIX}``, under mutex, and add package to ``${PREFIX}/pkglist.${PKG_BUILD_TYPE}`` (unless inhibited)                                                                    |
fe49bc
| install_rpm         | Build package RPM w/ auto-generated specifiation file based on ``etc/package.spec`` beneath ``${PREFIX_RPM}``                                                                                                                                            |
fe49bc
| clean               | Clean ``${PKG_BUILD_DIR}`` and/or ``${PKG_DESTDIR}`` and/or ``${PKG_DESTDIR_HOST}`` and/or ``${PKG_BASE_DIR}/${PKG_SUBDIR}`` as per ``-C build,dest,src``, resp., if any                                                                                 |
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 4.2. Build variables"
fe49bc
## 4.2. Build variables
fe49bc
fe49bc
The following variables are primarily defined in ``vars.env.d/*.env`` and may be
fe49bc
overriden on a per-build basis on the command-line, the environment, and/or
fe49bc
``${HOME}/midipix_build.vars``, ``${HOME}/.midipix_build.vars``, and/or
fe49bc
``../midipix_build.vars``, e.g.:
fe49bc
fe49bc
```shell
fe49bc
./build.sh -a nt64 -b release -D minipix,zipdist -P -v PREFIX_ROOT="${HOME}/midipix_tmp"
fe49bc
env ARCH=nt64 BUILD_KIND=release PREFIX_ROOT="${HOME}/midipix_tmp" ./build.sh -D minipix,zipdist -P -v
fe49bc
```
fe49bc
fe49bc
| Variable name    | Default value                        | Description                                                                   |
fe49bc
| ---------------- | ------------------------------------ | ----------------------------------------------------------------------------- |
fe49bc
| ARCH             | nt64                                 | Target 32-bit (nt32) or 64-bit (nt64) architecture                            |
fe49bc
| BUILD_DLCACHEDIR | ${PREFIX_ROOT}/dlcache               | Absolute pathname to package downloads cache root directory                   |
fe49bc
| BUILD_HNAME      | $(hostname)                          | Build system hostname                                                         |
fe49bc
| BUILD_KIND       | debug                                | Build w/ debugging (debug) or release compiler flags                          |
308fa7
| PREFIX_LOCAL     | ${PREFIX}/localcross                 | Absolute pathname to local cross-toolchain root directory                     |
fe49bc
| BUILD_WORKDIR    | ${PREFIX}/tmp                        | Absolute pathname to temporary package build root directory                   |
fe49bc
| PREFIX           | ${PREFIX_ROOT}/${ARCH}/${BUILD_KIND} | Absolute pathname to architecture- & build type-specific build root directory |
fe49bc
| PREFIX_CROSS     | ${PREFIX}/${DEFAULT_TARGET}          | Absolute pathname to toolchain root directory                                 |
fe49bc
| PREFIX_MINGW32   | ${PREFIX}/x86_64-w64-mingw32         | Absolute pathname to MinGW toolchain root directory                           |
fe49bc
| PREFIX_MINIPIX   | ${PREFIX}/minipix                    | Absolute pathname to minipix distribution root directory                      |
fe49bc
| PREFIX_NATIVE    | ${PREFIX}/native                     | Absolute pathname to cross-compiled packages root directory                   |
fe49bc
| PREFIX_ROOT      | ${HOME}/midipix                      | Absolute pathname to top-level directory                                      |
fe49bc
| PREFIX_RPM       | ${PREFIX}/rpm                        | Absolute pathname to package RPM archive root directory                       |
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 4.3. File installation DSL"
fe49bc
## 4.3. File installation DSL
fe49bc
fe49bc
File and directory installation, comprising e.g. copying, moving, creating
fe49bc
symbolic links, setting owner and/or permission metadata, are expressed in
fe49bc
a descriptive domain-specific language and integrated with package building
fe49bc
via the package variable ``${PKG_INSTALL_FILES_V2}``, applying during
fe49bc
``install_files`` after the ``install_make`` build step, and ``${PKG_INSTALL_FILES_DESTDIR}``
fe49bc
and ``${PKG_INSTALL_FILES_DESTDIR_EXTRA}`` during ``install_subdirs``. The
fe49bc
``${PKG_INSTALL_FILES_V2}`` must adhere to the following syntax specified in EBNF:  
fe49bc
fe49bc
```
fe49bc
(*
fe49bc
SH_GLOB_PATTERN      = any valid portable shell pattern (see sh(1)); superset of PATHNAME
fe49bc
SH_SUBSTRING_PATTERN = any valid portable substring processing shell pattern (see sh(1));
fe49bc
                       superset of PATHNAME
fe49bc
PARAMETER            = any valid portable shell variable name except that [0-9] may occur
fe49bc
                       the beginning
fe49bc
PATHNAME             = any valid filename, directory name, relative or absolute pathname
fe49bc
                       excluding the characters NUL and NL
fe49bc
 *)
fe49bc
fe49bc
spec                 = { op_flag, } op_unary, "=", op_spec, "\n", { spec } ;
fe49bc
                     | { op_flag, } op_binary, op_spec, "=" op_spec, "\n", { spec } ;
fe49bc
                     | "#" COMMENT ;
fe49bc
op_unary             = "-" | "/" | "t" ;
fe49bc
op_binary            = ":" | "!" | "@" | "+" | "g" | "m" | "o" | "T" ;
fe49bc
op_flag              = "?" ;
fe49bc
op_spec              = pattern_spec | PATHNAME | expr_spec | op_spec ;
fe49bc
fe49bc
pattern_spec         = "%<", SH_GLOB_PATTERN, ">" ;
fe49bc
fe49bc
expr_spec            = "%[", expr, { sexpr_spec }, "%]" ;
fe49bc
expr                 = [ "@" ], "0" .. "9" | "DNAME" | "FNAME" | "ITEM" | PARAMETER ;
fe49bc
fe49bc
sexpr_spec           = sexpr_op_unary, SH_SUBSTRING_PATTERN, { sexpr } ;
fe49bc
sexpr_op_unary       = "##" | "#" | "%%" | "%" ;
fe49bc
```
fe49bc
  
fe49bc
Single ``"="`` characters in ``spec``, the ``"%<"`` and ``"%["`` character
fe49bc
sequences in ``pattern_spec`` and ``expr_spec``, resp., and the ``sexpr_op_unary``
fe49bc
as well as ``sexpr_op_binary`` characters or character sequences may be
fe49bc
escaped with a single backslash (``"\"``.) ``SH_SUBSTRING_PATTERN`` differs
fe49bc
from ``SH_GLOB_PATTERN`` solely in that any of ``sexpr_op_unary`` and
fe49bc
``sexpr_op_binary`` occuring at the beginning of or in the former must
fe49bc
be escaped with a single backslash (``"\"``,) e.g. ``"#\#pattern"`` and
fe49bc
``"%\%pattern"``, etc. and ``"#pat\%ern"`` and ``%patt\#ern", etc., resp.  
fe49bc
  
fe49bc
Named parameters (``PARAMETER``) are supplied via the ``-p name=value``
fe49bc
argument to ``rtl_install()``, whereas numbered parameters are for
fe49bc
internal usage only; the ``"DNAME"``, ``"FNAME"``, and ``"ITEM"`` parameters
fe49bc
lazily evaluate to the directory name, file (aka base) name, and full
fe49bc
pathname of the current item being processed relative to a specification
fe49bc
with a pattern in it.
fe49bc
  
fe49bc
The following parameters are defined by default during ``install_files``:
fe49bc
fe49bc
| Name           | Value                                  |
fe49bc
| -------------  | -------------------------------------- |
fe49bc
| _builddir      | ${PKG_BUILD_DIR}                       |
fe49bc
| _destdir       | ${PKG_BASE_DIR}/${PKG_DESTDIR}         |
fe49bc
| _destdir_host  | ${PKG_BASE_DIR}/${PKG_DESTDIR_HOST}    |
fe49bc
| _files         | ${MIDIPIX_BUILD_PWD}/files/${PKG_NAME} |
fe49bc
| _name          | ${PKG_NAME}                            |
fe49bc
| _prefix        | ${PKG_PREFIX}                          |
fe49bc
| _prefix_host   | ${PREFIX}                              |
fe49bc
| _prefix_native | ${PREFIX_NATIVE}                       |
fe49bc
| _subdir        | ${PKG_BASE_DIR}/${PKG_SUBDIR}          |
fe49bc
| _target        | ${PKG_TARGET}                          |
fe49bc
| _version       | ${PKG_VERSION:-}                       |
fe49bc
| _workdir       | ${BUILD_WORKDIR}                       |
fe49bc
  
fe49bc
The following operation flags are defined:
fe49bc
fe49bc
| Flag      | Description              |
fe49bc
| --------- | ------------------------ |
fe49bc
| ``?``     | Continue on soft failure |
fe49bc
  
fe49bc
The following operations are defined:
fe49bc
fe49bc
| Operation      | Arity  | Description                                                      |
fe49bc
| -------------- | ------ | ---------------------------------------------------------------- |
fe49bc
| ``-``          | Unary  | Remove directories and/or files                                  |
fe49bc
| ``/``          | Unary  | Create directories or trees thereof                              |
fe49bc
| ``t``          | Unary  | touch(1) files and/or directories                                |
fe49bc
| ``:``          | Binary | Copy directories and/or files                                    |
fe49bc
| ``!``          | Binary | Move/rename directories and/or files                             |
fe49bc
| ``@``          | Binary | Create/update symbolic links                                     |
fe49bc
| ``+``          | Binary | Copy directories and/or files if newer and follow symbolic links |
fe49bc
| ``g``          | Binary | Set group owner of files and/or directories                      |
fe49bc
| ``m``          | Binary | Set mode bits of files and/or directories                        |
fe49bc
| ``o``          | Binary | Set user and/or group owner of files and/or directories          |
fe49bc
| ``T``          | Binary | touch(1) files and/or directories with timestamp                 |
fe49bc
  
fe49bc
The following expression modifiers are defined:
fe49bc
fe49bc
| Modifier       | Description                               |
fe49bc
| -------------- | ----------------------------------------- |
fe49bc
| ``@``          | Recursively reevaluate after substituting |
fe49bc
  
fe49bc
The following subexpression operators are defined:
fe49bc
fe49bc
| Operation      | Arity  | Description                                                      |
fe49bc
| -------------- | ------ | ---------------------------------------------------------------- |
fe49bc
| ``##``         | Unary  | Remove largest prefix from left-hand side                        |
fe49bc
| ``#``          | Unary  | Remove prefix from left-hand side                                |
fe49bc
| ``%%``         | Unary  | Remove largest postfix from right-hand side                      |
fe49bc
| ``%``          | Unary  | Remove postfix from right-hand side                              |
fe49bc
  
fe49bc
```shell
fe49bc
#
fe49bc
# Examples:
fe49bc
# 
fe49bc
fe49bc
#
fe49bc
# Create directory %[_minipix]/bin and copy all files
fe49bc
# in %[_minipix_dist]/bin/ to %[_minipix]/bin/ with
fe49bc
# identical file names.
fe49bc
/=%[_minipix]/bin
fe49bc
?%[_minipix_dist]/bin/%<*>=%[_minipix]/bin/%[FNAME]
fe49bc
fe49bc
#
fe49bc
# Rename all files in share/info/ matching *.info to
fe49bc
# their filenames with the `.info' postfix removed and
fe49bc
# `-2.64.info' appended and all files in share/man/man1/
fe49bc
# matching *.1 with the `.1' postfix removed and -2.64.1
fe49bc
# appended.
fe49bc
!share/info/%<*.info>=share/info/%[FNAME%.info]-2.64.info
fe49bc
!share/man/man1/%<*.1>=share/man/man1/%[FNAME%.1]-2.64.1
fe49bc
fe49bc
#
fe49bc
# Create/update symbolic links named include/ffi.h and
fe49bc
# include/ffitarget.h with ../lib/libffi-3.2.1/include/ffi.h
fe49bc
# and ../lib/libffi-3.2.1/include/ffitarget.h as targets, resp.
fe49bc
@../lib/libffi-3.2.1/include/ffi.h=include/ffi.h
fe49bc
@../lib/libffi-3.2.1/include/ffitarget.h=include/ffitarget.h
fe49bc
fe49bc
#
fe49bc
# Manual invocation:
fe49bc
PKG_INSTALL_FILES_V2="
fe49bc
        [ ... ]
fe49bc
";
fe49bc
rtl_install                                                     \
fe49bc
                -p "_builddir=${PKG_BASE_DIR}/${PKG_BUILD_DIR}" \
fe49bc
                -p "_minipix=${PREFIX_MINIPIX##*/}"             \
fe49bc
                -p "_minipix_dist=${PREFIX}/minipix_dist"       \
fe49bc
                -p "_native=${PREFIX_NATIVE##*/}"               \
fe49bc
                -p "_subdir=${PKG_BASE_DIR}/${PKG_SUBDIR}"      \
fe49bc
                -p "_target=${PKG_TARGET}"                      \
fe49bc
                -n -- "${PREFIX}"                               \
fe49bc
                "${PKG_INSTALL_FILES_V2}"; then
fe49bc
        return 1;
fe49bc
fi;
fe49bc
fe49bc
#
fe49bc
# Usage screen:
fe49bc
usage: rtl_install [-i] [-I ifs] [-n] [-p name=val] [-v] prefix spec_list
fe49bc
       -i...........: continue on soft errors
fe49bc
       -I ifs.......: process spec_list with ifs instead of NL
fe49bc
       -n...........: perform dry run
fe49bc
       -p name=val..: set named parameter
fe49bc
       -v...........: increase verbosity
fe49bc
       prefix.......: pathname prefix
fe49bc
       spec_list....: ifs-separated list of specs
fe49bc
```
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 4.4. Package variables"
fe49bc
### 4.4. Package variables
fe49bc
fe49bc
The following variables are package-specific and receive their value from either
fe49bc
top-level defaults defined in ``vars.env.d/*.env``, build group-specific defaults from the
fe49bc
build group the package pertains to and defined in its corresponding file beneath
931865
``groups.d/`` or ``groups.d/[0-9][0-9][0-9].<group name>.d/``, or package-specific overrides
931865
defined either in the latter and/or in its corresponding file beneath ``vars/``, with one of
931865
the following prefixes:
fe49bc
fe49bc
| Variable name prefix                              |
fe49bc
| ------------------------------------------------- |
fe49bc
| DEFAULT                                           |
fe49bc
| DEFAULT_``${BUILD_TYPE}``                         |
fe49bc
| DEFAULT_``${GROUP_NAME}``                         |
fe49bc
| ``${GROUP_NAME}``                                 |
fe49bc
| [PKG_``${RELATED_PACKAGE(S)}``]                   |
fe49bc
| [PKG_``${RELATED_PACKAGE(S)}``_``${BUILD_KIND}``] |
fe49bc
| PKG_``${NAME}``                                   |
fe49bc
| PKG_``${NAME}``_``${BUILD_KIND}``                 |
fe49bc
fe49bc
Additionally, overrides may be specified on a per-build basis on the command-
fe49bc
line, with each variable prefixed w/ ``PKG_``, e.g.:
fe49bc
``./build.sh [ ... ] PKG_ZSH_CC="/usr/bin/clang"``.  
fe49bc
  
fe49bc
The minimum set of package variables that must be provided is ``SHA256SUM, URL,
fe49bc
VERSION`` and/or ``URLS_GIT``, respectively.
fe49bc
fe49bc
[//]: # "{{{ 4.4.1 Package variable types"
fe49bc
## 4.4.1 Package variable types
fe49bc
fe49bc
| Type definition               | Description                                                                                                                                  |
fe49bc
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
fe49bc
| DirName(Abs)			| Absolute pathname to directory                                                                                                               |
fe49bc
| DirName(Rel)			| Relative pathname to director                                                                                                                |
fe49bc
| DirName(Unit)			| Single non-{absolute,relative} directory nam                                                                                                 |
fe49bc
| DirName			| Absolute or relative pathname to director                                                                                                    |
fe49bc
| CmdName			| Absolute or relative pathname to comman                                                                                                      |
fe49bc
| FileName(Abs)			| Absolute pathname to file                                                                                                                    |
fe49bc
| FileName(Rel)			| Relative pathname to file                                                                                                                    |
fe49bc
| FileName(Unit)		| Single non-{absolute,relative} file name                                                                                                     |
fe49bc
| FileName			| Absolute or relative pathname to file                                                                                                        |
fe49bc
| Flag(<type>,<default>)	| Boolean flag of type <type>, e.g. Flag(Boolean) (``true``, ``false``,) Flag(UInt) (0, 1,) Flag(ExitStatus) (>=1, 0) with default or ``auto`` |
fe49bc
| FlagLine			| String of {SP,VT}-separated flags, arguments, options, etc. pp. to a command                                                                 |
fe49bc
| List(<sep>[,<sep\|type>..])	| \<sep\>-separated list, optionally recursively and/or sub-typing, e.g.: ``List(:,=,String)`` and ``"name=value:name2=value"``                |
fe49bc
| PkgName			| Single name of package                                                                                                                       |
fe49bc
| PkgRelation			| Single, possibly parametrised, package-package relation; see section [3.5](#35-package-package-and-packagegroup-group-relationships)         |
fe49bc
| PkgVersion			| Single version of package                                                                                                                    |
fe49bc
| Set(<type>)			| Set of alternatives of <type>, e.g. one of ``cross``, ``host``, ``native``                                                                   |
fe49bc
| String			| Semantically generic string                                                                                                                  |
fe49bc
| URL				| URL in standard format; see section [3.4](#34-package-archive-files-and-git-repositories)                                                    |
fe49bc
| URL(Git)			| Git URL in the format ``[subdir=]URL[@branch]``; see section [3.4](#34-package-archive-files-and-git-repositories)                           |
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 4.4.2 Package variables"
fe49bc
## 4.4.2 Package variables
fe49bc
fe49bc
| Package variable name        | Type             | Description                                                                                                                                |
fe49bc
| ---------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
fe49bc
| AR                           | CmdName          | Toolchain library archive editor ``ar(1)``                                                                                                 |
fe49bc
| AUTOCONF_CONFIG_GUESS        | String           | Either of ``copy`` (copy ``config.guess`` from ``etc/config.guess``) or ``keep``; defaults to ``copy``                                     |
fe49bc
| BASE_DIR                     | DirName(Abs)     | Package build root directory beneath ``${BUILD_WORKDIR}``                                                                                  |
fe49bc
| BUILD_DIR                    | DirName(Unit)    | Package build directory beneath ``${PKG_BASE_DIR}``                                                                                        |
a88b49
| BUILD_STEPS_DISABLE          | List( )          | Build steps to disable during package build                                                                                                |
fe49bc
| BUILD_TYPE                   | Set(String)      | ``cross``: Cross-compiled toolchain, ``host``: host, ``native``: cross-compiled package                                                    |
fe49bc
| CC                           | FileName         | Toolchain C compiler ``cc(1)``                                                                                                             |
fe49bc
| CCLD                         | FileName         | Toolchain C compiler-qua-linker ``cc(1)``                                                                                                  |
fe49bc
| CFLAGS_BUILD_EXTRA           | FlagLine         | Additional C compiler flags during package ``make(1)`` build                                                                               |
fe49bc
| CFLAGS_BUILD                 | FlagLine         | C compiler flags during package ``make(1)``  build                                                                                         |
fe49bc
| CFLAGS_CONFIGURE_EXTRA       | FlagLine         | Additional C compiler flags during package (GNU autotools in implementation and/or interface) configuration                                |
fe49bc
| CFLAGS_CONFIGURE             | FlagLine         | C compiler flags during package (GNU autotools in implementation and/or interface) configuration                                           |
fe49bc
| CMAKE_ARGS_EXTRA             | FlagLine         | Additional arguments to ``cmake(1)``                                                                                                       |
fe49bc
| CMAKE_ARGS                   | FlagLine         | Arguments to ``cmake(1)``                                                                                                                  |
fe49bc
| CMAKE                        | CmdName          | ``cmake(1)`` executable                                                                                                                    |
fe49bc
| CMAKE_LISTFILE               | FileName         | ``cmake(1)`` listfile                                                                                                                      |
fe49bc
| CONFIG_CACHE_EXTRA           | List(\n)         | Additional GNU autotools configuration cache variables                                                                                     |
fe49bc
| CONFIG_CACHE                 | List(\n)         | GNU autotools configuration cache variables                                                                                                |
fe49bc
| CONFIG_CACHE_LOCAL           | List(\n)         | Additional GNU autotools configuration cache variables                                                                                     |
fe49bc
| CONFIGURE_ARGS               | FlagLine         | Arguments to package (GNU autotools in implementation and/or interface) configuration script                                               |
fe49bc
| CONFIGURE_ARGS_EXTRA         | FlagLine         | Additional arguments to package (GNU autotools in implementation and/or interface) configuration script                                    |
fe49bc
| CONFIGURE_ARGS_LIST          | List(:)          | Arguments to package (GNU autotools in implementation and/or interface) configuration script                                               |
fe49bc
| CONFIGURE_ARGS_EXTRA_LIST    | List(:)          | Additional arguments to package (GNU autotools in implementation and/or interface) configuration script                                    |
fe49bc
| CONFIGURE                    | CmdName          | Package's (GNU autotools in implementation and/or interface) configuration script                                                          |
fe49bc
| CONFIGURE_TYPE               | String           | Either of ``autotools`` (GNU autotools or similar) or ``sofort`` or ``cmake`` (CMake)                                                      |
fe49bc
| CPPFLAGS_CONFIGURE_EXTRA     | FlagLine         | Additional C preprocessor flags during package (GNU autotools in implementation and/or interface) configuration                            |
fe49bc
| CXX                          | CmdName          | Toolchain C++ compiler ``c++(1)``                                                                                                          |
fe49bc
| CXXFLAGS_CONFIGURE_EXTRA     | FlagLine         | Additional C++ compiler flags during package (GNU autotools in implementation and/or interface) configuration                              |
fe49bc
| CXXFLAGS_CONFIGURE           | FlagLine         | C++ compiler flags during package (GNU autotools in implementation and/or interface) configuration                                         |
fe49bc
| DEPENDS                      | List( )          | Mandatory package-package dependencies                                                                                                     |
fe49bc
| DESTDIR                      | DirName(Unit)    | Package installation destination directory beneath ``${PKG_BASE_DIR}``                                                                     |
fe49bc
| DESTDIR_HOST                 | DirName(Unit)    | Optional host package installation destination directory beneath ``${PKG_BASE_DIR}``                                                       |
fe49bc
| DISABLED                     | Flag(UInt,0)     | Disable package                                                                                                                            |
fe49bc
| ENV_VARS_EXTRA               | List(:,=)        | Name-value pairs of environment variables to set during package build                                                                      |
fe49bc
| FNAME                        | FileName(Unit)   | Filename of package archive file                                                                                                           |
fe49bc
| FORCE_AUTORECONF             | Flag(UInt,0)     | Forcibly run ``autoreconf -fiv`` prior to package (GNU autotools in implementation and/or interface) configuration                         |
fe49bc
| GITROOT                      | URL              | midipix packages Git URL prefix                                                                                                            |
fe49bc
| INHERIT_FROM                 | String           | Inherit variables from named package                                                                                                       |
fe49bc
| INSTALL_FILES_DESTDIR_EXTRA  | List( )          | Additional files to initialise the package installation destination directory beneath ``${PKG_BASE_DIR}`` with                             |
fe49bc
| INSTALL_FILES_DESTDIR        | List( )          | Files to initialise the package installation destination directory beneath ``${PKG_BASE_DIR}`` with                                        |
fe49bc
| INSTALL_FILES                | List( )          | Files to manually install into the package installation destination directory beneath ``${PKG_BASE_DIR}``                                  |
fe49bc
| INSTALL_FILES_V2             | List( )          | Files to manually install into the package installation destination directory beneath ``${PKG_BASE_DIR}``                                  |
fe49bc
| INSTALL_TARGET_EXTRA         | String           | Additional name of package build ``make(1)`` installation target                                                                           |
fe49bc
| INSTALL_TARGET               | String           | Name of package build ``make(1)`` installation target                                                                                      |
fe49bc
| IN_TREE                      | Flag(UInt,auto)  | Build package in-tree within ``${PKG_SUBDIR}``                                                                                             |
fe49bc
| LDFLAGS_BUILD_EXTRA          | FlagLine         | Additional linker flags during package ``make(1)``  build                                                                                  |
fe49bc
| LDFLAGS_CONFIGURE_EXTRA      | FlagLine         | Additional linker flags during package (GNU autotools in implementation and/or interface) configuration                                    |
fe49bc
| LDFLAGS_CONFIGURE            | FlagLine         | Linker flags during package (GNU autotools in implementation and/or interface) configuration                                               |
fe49bc
| LIBTOOL                      | CmdName          | ``libtool(1)`` implementation (defaults to ``slibtool``)                                                                                   |
fe49bc
| MAKE                         | CmdLine          | Command line of ``make(1)``                                                                                                                |
fe49bc
| MAKEFLAGS_BUILD              | FlagLine         | ``make(1)`` flags during package ``make(1)``  build; subject to field splitting w/ ``:``                                                   |
fe49bc
| MAKEFLAGS_BUILD_EXTRA        | FlagLine         | Additional ``make(1)`` flags during package ``make(1)``  build; subject to field splitting w/ ``:``                                        |
fe49bc
| MAKEFLAGS_BUILD_LIST         | List(:)          | ``make(1)`` flags during package ``make(1)``  build; subject to field splitting w/ ``:``                                                   |
fe49bc
| MAKEFLAGS_BUILD_EXTRA_LIST   | List(:)          | Additional ``make(1)`` flags during package ``make(1)``  build; subject to field splitting w/ ``:``                                        |
fe49bc
| MAKEFLAGS_INSTALL            | FlagLine         | ``make(1)`` flags during package ``make(1)``  installation; subject to field splitting w/ ``:``                                            |
fe49bc
| MAKEFLAGS_INSTALL_EXTRA      | FlagLine         | ``make(1)`` flags during package ``make(1)``  installation; subject to field splitting w/ ``:``                                            |
fe49bc
| MAKEFLAGS_INSTALL_LIST       | List(:)          | ``make(1)`` flags during package ``make(1)``  installation; subject to field splitting w/ ``:``                                            |
fe49bc
| MAKEFLAGS_INSTALL_EXTRA_LIST | List(:)          | ``make(1)`` flags during package ``make(1)``  installation; subject to field splitting w/ ``:``                                            |
fe49bc
| MAKEFLAGS_LOADAVG            | FlagLine         | ``make(1)`` load average limit (e.g. -l load) flag                                                                                         |
fe49bc
| MAKEFLAGS_PARALLELISE        | FlagLine         | ``make(1)`` parallelisation (e.g. -j jobs) flag                                                                                            |
fe49bc
| MAKEFLAGS_VERBOSITY          | String           | Variable-value pair to pass to ``make(1)`` in order to force echo-back of command lines prior to execution                                 |
fe49bc
| MAKE_INSTALL_VNAME           | String           | Variable name of ``make(1)`` installation destination directory variable during package ``make(1)``  installation                          |
fe49bc
| MAKE_SUBDIRS                 | List( )          | ``make(1)`` subdirectories to exclusively build                                                                                            |
fe49bc
| MIRRORS_GIT                  | List( )          | Package Git repository mirror base URLs to attempt cloning from; cf. ``pkgtool.sh -m <dname>``                                             |
fe49bc
| MIRRORS                      | List( )          | Package archive mirror base URLs to attempt downloading from; cf. ``pkgtool.sh -m <dname>``                                                |
fe49bc
| NO_CLEAN_BASE_DIR            | Flag(UInt,0)     | Inhibit cleaning of package build root directory beneath ``${BUILD_WORKDIR}``                                                              |
fe49bc
| NO_CLEAN                     | Flag(UInt,0)     | Inhibit cleaning of package build directory beneath ``${PKG_BASE_DIR}`` pre-finish                                                         |
fe49bc
| NO_LOG_VARS                  | Flag(UInt,0)     | Inhibit logging of build & package variables pre-package build                                                                             |
cb4e88
| NO_PURGE_LA_FILES            | Flag(UInt,0)     | Inhibit purging of .la files                                                                                                               |
fe49bc
| PATCHES_EXTRA                | List( )          | Additional patches to apply                                                                                                                |
fe49bc
| PKG_CONFIG                   | CmdName          | ``pkg-config(1)`` implementation                                                                                                           |
fe49bc
| PKG_CONFIG_LIBDIR            | DirName          | ``pkg-config(1)`` search directory                                                                                                         |
fe49bc
| PKGLIST_DISABLE              | Flag(UInt,0)     | Inhibit inclusion into ``${PREFIX}/pkglist.${PKG_BUILD_TYPE}``                                                                             |
fe49bc
| PREFIX                       | DirName(Abs)     | Top-level installation directory and package search path                                                                                   |
fe49bc
| PYTHON                       | CmdName          | Python >=3.x interpreter                                                                                                                   |
fe49bc
| RANLIB                       | CmdName          | Toolchain library archive index generator ``ranlib(1)``                                                                                    |
fe49bc
| RELATES                      | Set(PkgRelation) | Package-package relationships                                                                                                              |
fe49bc
| RPM_DISABLE                  | Flag(UInt,0)     | Inhibit creation of RPM archive                                                                                                            |
fe49bc
| SHA256SUM                    | String           | SHA-256 message digest of package archive                                                                                                  |
fe49bc
| SOFORT_NATIVE_CC             | FileName         | ``sofort`` variable during ``native`` build: Toolchain C compiler ``cc(1)``                                                                |
fe49bc
| SOFORT_NATIVE_CFLAGS_EXTRA   | FlagLine         | ``sofort`` variable during ``native`` build: Additional C compiler flags during package (GNU autotools or similar) configuration           |
fe49bc
| SOFORT_NATIVE_CFLAGS         | FlagLine         | ``sofort`` variable during ``native`` build: C compiler flags during package (GNU autotools or similar) configuration                      |
fe49bc
| SOFORT_NATIVE_CXXFLAGS_EXTRA | FlagLine         | ``sofort`` variable during ``native`` build: Additional list of C++ compiler flags during package (GNU autotools or similar) configuration |
fe49bc
| SOFORT_NATIVE_CXXFLAGS       | FlagLine         | ``sofort`` variable during ``native`` build: List of C++ compiler flags during package (GNU autotools or similar) configuration            |
fe49bc
| SOFORT_NATIVE_CXX            | FlagLine         | ``sofort`` variable during ``native`` build: Command- or pathname of toolchain C++ compiler ``c++(1)``                                     |
fe49bc
| SOFORT_NATIVE_LDFLAGS_EXTRA  | FlagLine         | ``sofort`` variable during ``native`` build: Additional linker flags during package (GNU autotools or similar) configuration               |
fe49bc
| SOFORT_NATIVE_LDFLAGS        | FlagLine         | ``sofort`` variable during ``native`` build: Linker flags during package (GNU autotools or similar) configuration                          |
fe49bc
| SOFORT_NATIVE_LD             | FileName         | ``sofort`` variable during ``native`` build: Command- or pathname of toolchain C compiler ``cc(1)``                                        |
fe49bc
| SUBDIR                       | DirName(Rel)     | Extracted archive or git-{clone,pull}(1)'d directory                                                                                       |
fe49bc
| TARGET                       | String           | Dash-separated {build,host,target} triplet                                                                                                 |
fe49bc
| URL                          | List( ,URL)      | URL to package archives w/ optional alternatives; see section [3.4](#34-package-archive-files-and-git-repositories)                        |
fe49bc
| URLS_GIT                     | List( ,URL(Git)) | Package Git URL(s) (format: ``[subdir=]URL[@branch]``, see section [3.4](#34-package-archive-files-and-git-repositories))                  |
fe49bc
| VARS_FILE                    | FileName         | Optional package variables file (defaults to ``vars/${PKG_NAME}.vars``)                                                                    |
fe49bc
| VERSION                      | PkgVersion       | Package version                                                                                                                            |
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 4.5. Fault-tolerant & highly optimised 3D laser show-equipped usage screen"
fe49bc
## 4.5. Fault-tolerant & highly optimised 3D laser show-equipped usage screen
fe49bc
fe49bc
```
fe49bc
usage: ./build.sh [-a nt32|nt64]  [-b debug|release]    [-C dir[,..]]  [-D kind[,..]]
fe49bc
                  [-F ipv4|ipv6|offline]    [-h|--help] [-p jobs|-P]    [-r ALL|LAST]
fe49bc
                  [-r [*[*[*]]]name[,..][:ALL|LAST|[^|<|<=|>|>=]step,..]]        [-R]
fe49bc
                  [-v] [-V [+]tag|pat[,..]]
fe49bc
fe49bc
                  [--as-needed] [--debug-minipix]  [--reset-state] [--roar]
cc579e
                  [--theme theme]
cc579e
                  [[=]<group[,..][ ..]>|<variable name>=<variable override>[ ..]]
fe49bc
fe49bc
        -a nt32|nt64        Selects 32-bit or 64-bit architecture; defaults to nt64.
fe49bc
        -b debug|release    Selects debug or release build kind; defaults to debug.
fe49bc
        -C dir[,..]         Clean build directory (build,) ${PREFIX} before processing build
fe49bc
                            scripts (prefix,) source directory (src,) and/or destination
fe49bc
                            directory (dest) after successful package builds.
fe49bc
        -D kind[,..]        Produce minimal midipix distribution directory (minipix,) RPM
fe49bc
                            binary packages (rpm,) and/or deployable distribution ZIP
fe49bc
                            archive (zipdist.) zipdist implies minipix.
fe49bc
        -F ipv4|ipv6|offline
fe49bc
                            Force IPv4 (ipv4) or IPv6 (ipv6) when downloading package
fe49bc
                            archives and/or Git repositories or don't download either at all
fe49bc
                            (offline.)
fe49bc
        -h|--help           Show short/full help screen, respectively.
fe49bc
        -p jobs|-P          Enables parallelisation at group-level, whenever applicable.
fe49bc
                            The maximum count of jobs defaults to the number of logical
fe49bc
                            processors on the host system divided by two (2.)
fe49bc
fe49bc
                            If -R is not specified and at least one (1) package fails to
fe49bc
                            build, all remaining package builds will be forcibly aborted.
fe49bc
fe49bc
        -r ALL|LAST         Restart all packages or the last failed package and resume
fe49bc
                            build, resp.
fe49bc
        -r [*[*[*]]]name[,..][:ALL|LAST|[^|<|<=|>|>=]step,..]
fe49bc
                            Restart the specified comma-separated package(s) w/ inhibition
fe49bc
                            of package build step state resetting completely (`ALL',) starting
fe49bc
                            at the resp. last successfully executed build steps (`LAST',) or the
fe49bc
                            specified comma-separated list of build steps, optionally subject
fe49bc
                            concerning package name(s) and/or build step(s) to the below modifiers:
fe49bc
fe49bc
                            Prepend name w/ `*' to automatically include dependencies, `**'
fe49bc
                            to forcibly rebuild all dependencies, and `***' to forcibly
fe49bc
                            rebuild all packages that depend on the specified package(s).
fe49bc
fe49bc
                            Prepend step w/ `^' to filter build steps with, `<' or `<='
fe49bc
                            to constrain build steps to below or below or equal with, resp.,
fe49bc
                            `>' or `>=' to constrain build steps to above or above or equal
fe49bc
                            with, resp.
fe49bc
fe49bc
                            Currently defined build steps are:
fe49bc
                            fetch_clean, fetch_download, fetch_extract, configure_clean,
fe49bc
                            configure_patch_pre, configure_autotools, configure_patch,
fe49bc
                            configure, build_clean, build, install_clean, install_subdirs,
cc579e
                            install_make, install_files, install, install_rpm,
cc579e
                            and clean.
fe49bc
fe49bc
                            Additionally, the following virtual steps are provided:
fe49bc
                            @fetch, @configure, @build, @install, @clean, and finish.
fe49bc
fe49bc
        -R                  Ignore build failures, skip printing package logs, and continue
fe49bc
                            building (relaxed mode.)
fe49bc
fe49bc
        -v                  Increase logging verbosity.
fe49bc
        -V [+]tag|pat[,..]  Enable logging for messages with tag or pattern matching tags of:
fe49bc
                            + (prefix)..: initialise tags with normal verbosity (implies normal) (see etc/build.theme,)
fe49bc
                            all.........: log everything (see etc/build.theme,)
fe49bc
                            clear|none..: log nothing,
fe49bc
                            normal......: log at normal verbosity (see etc/build.theme,)
fe49bc
                            verbose.....: log at increased verbosity (implies normal) (see etc/build.theme) (-v,)
fe49bc
fe49bc
                            build.......: log package build logs,
fe49bc
                            fileops.....: log RTL file operations,
fe49bc
                            install.....: log RTL installation DSL operations,
fe49bc
                            zipdist.....: log deployable distribution ZIP archive operations,
fe49bc
                            xtrace......: set xtrace during package builds,
fe49bc
fe49bc
                            fatal.......: fatal, unrecoverable errors,
fe49bc
                            info........: informational messages,
fe49bc
                            verbose.....: verbose informational messages,
fe49bc
                            warning.....: warning messages possibly relating to imminent fatal, unrecoverable errors,
fe49bc
fe49bc
                            build_*.....: general build messages (viz.: begin, finish, finish_time, vars,)
fe49bc
                            group_*.....: build group messages (viz.: begin, finish,)
fe49bc
                            pkg_*.......: package build messages (viz.: begin, finish, msg, skip, step, strip.)
fe49bc
fe49bc
        --as-needed         Don't build unless the midipix_build repository has received
fe49bc
                            new commits.
fe49bc
        --debug-minipix     Don't strip(1) minipix binaries to facilitate debugging minipix.
fe49bc
        --reset-state       Reset package build step state on exit.
fe49bc
        --theme theme       Set theme.
fe49bc
cc579e
        <group>[,..][ ..]   One of: dev_packages, dist, host_deps, host_deps_rpm,
cc579e
                            host_toolchain, host_tools, minipix, native_packages,
cc579e
                            native_runtime, native_toolchain, native_tools.
fe49bc
fe49bc
                            Prepend w/ `=' to inhibit group-group dependency expansion.
fe49bc
fe49bc
        <variable name>=<variable override>[ ..]
fe49bc
                            Override build or package variable.
fe49bc
```
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 4.6. ``pkgtool.sh``"
fe49bc
## 4.6. ``pkgtool.sh``
fe49bc
fe49bc
```
fe49bc
usage: ./pkgtool.sh [-a nt32|nt64] [-b debug|release] [-e|-f|-i|-m <dname> -M <dname>|-p|-r|-R|-t]
fe49bc
                    [--theme theme] [-v]
fe49bc
                    [<variable name>=<variable override>[ ..]] name[,name..]
fe49bc
fe49bc
        -a nt32|nt64      Selects 32-bit or 64-bit architecture; defaults to nt64.
fe49bc
        -b debug|release  Selects debug or release build kind; defaults to debug.
fe49bc
        -e                Edit package group file of single named package with ${EDITOR}.
fe49bc
        -f                List files installed by single package.
fe49bc
        -i                List package variables and dependencies of named package(s).
fe49bc
        -m <dname>        Setup package archives mirror in <dname> and/or
fe49bc
        -M <dname>        Setup Git repositories mirror in <dname>
fe49bc
                          Specify "" or '' as <dname> to default to the defaults in
fe49bc
                          ${HOME}/pkgtool.vars, if present.
fe49bc
        -p <log_fname>    Profile last build.
fe49bc
        -r                List reverse dependencies of single named package.
fe49bc
        -R                List recursive reverse dependencies of single named package.
fe49bc
        -t                Produce tarball of package build root directory and build log
fe49bc
                          file for the purpose of distribution given build failure.
fe49bc
        -v                Increase verbosity.
fe49bc
fe49bc
        <variable name>=<variable override>[ ..]
fe49bc
                          Override build or package variable.
fe49bc
```
fe49bc
  
fe49bc
> N.B. When using ``pkgtool.sh`` on a build w/ build variables (see section [4.2](#42-build-variables))
fe49bc
overriden on the command line or via the environment, ensure that they are included in the
fe49bc
``pkgtool.sh`` command line, preceding the package name, or exported, respectively.  
fe49bc
  
fe49bc
> N.B. ``pkgtool.sh`` will source the ``${HOME}/pkgtool.vars`` file, if present, on startup where the
fe49bc
following option arguments may be set: ``-a nt32|nt64`` by setting ``ARCH=...``, ``-b debug|release``
fe49bc
by setting ``BUILD_KIND=...``, ``-m <dname>`` by setting ``ARG_MIRROR_DNAME=...``, and ``-M <dname>``
fe49bc
by setting ``ARG_MIRROR_DNAME_GIT=...``.  
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
[//]: # "{{{ 4.7. Bourne shell coding rules"
fe49bc
## 4.7. Bourne shell coding rules
fe49bc
4e929d
> N.B. Input sanitisation is mandatory whenever input may form part of a parameter name, most usually
4e929d
when indexing with input as a key into a (pseudo-)hash, e.g. PKG_ZSH_<...input...>; failing to do so
4e929d
may introduce security vulnerabilities (e.g.: $(arbitrary_command) and ${arbitrary_variable} facilitating
4e929d
code execution and information disclosure, resp.)  
4e929d
Do not use this code and these coding rules if this is not possible or impractical.
4e929d
4e929d
*(reproduced from [[shrtl](https://github.com/lalbornoz/shrtl/blob/master/README.md)])*
4e929d
fe49bc
If no rationale is specified for any specific point, the rationale is avoidance of undefined behaviour
fe49bc
and/or implicit behaviour contingent on often subtle special cases, both of which are prone to cause
fe49bc
hard to debug or even diagnose bugs.
fe49bc
fe49bc
### Shell options
fe49bc
fe49bc
1)  The `noglob` option is set at all times *except* for when globbing is required, e.g.:
fe49bc
    `set +o noglob; files=*; set -o noglob`
fe49bc
2)  The `nounset` option is set at all times; if a parameter is to be expanded that may be
fe49bc
    unset, use the `${parameter:-word}` expansion format.
fe49bc
3)  The `errexit` option is unset at all times *except* for top-level subshell code that does
fe49bc
    *not* engage in conditional evaluation, e.g. `([...] set -o errexit; [...]) &` due to its
fe49bc
    implicit unsetting when a/any function is subject to conditional evaluation, e.g.: `[...]
fe49bc
    set -o errexit; [...] if some_function; then [ ... ] fi`
fe49bc
fe49bc
### Quoting and brace-enclosing
fe49bc
fe49bc
4)  Quoting with single quotes or double quotes is mandatory at all times *except* for when field 
fe49bc
    splitting subsequent to parameter expansion, etc. is required, e.g.: `params="a b c";
fe49bc
    param="single parameter"; fn ${params} "${param}"`
fe49bc
5)  Enclosing parameter names in braces is mandatory at all times, e.g.: `${parameter_name123}`
fe49bc
fe49bc
### Checking parameter status
fe49bc
fe49bc
6)  Checking for whether a parameter is set/non-empty or unset/empty is expressed with the following
fe49bc
    the idiom: `[ "${parameter:+1}" = 1 ]` and `[ "${parameter:+1}" != 1 ]` 
fe49bc
  
fe49bc
    This is necessary to avoid the potentially costly expansion of a parameter's value when only its
fe49bc
    status of being set/non-empty or unset/empty is of concern, particularly when this is done repeatedly.
fe49bc
fe49bc
### Functions
fe49bc
fe49bc
7)  Functions must explicitly return either `0` or `1` at all times *except* for when specific
fe49bc
    return exit statuses are specified according to the function's interface contract.
fe49bc
8)  Function names must have namespace prefixes followed by a `p` in the topmost namespace prefix
fe49bc
    field in private functions, e.g.: `rtlp_log_do_something() { [...] }`
fe49bc
9)  The non-POSIX but extremely widely available `local` command must be used at at all times
fe49bc
    in functions on all function-local variables.  
fe49bc
  
fe49bc
    This is necessary in order to avoid polluting the (global) parameter namespace.
fe49bc
10) Function-local variables must be lower case and prefixed with a `_`, a prefix comprised of the
fe49bc
    initial letters of each word in the function's name plus, in private functions, the `p` topmost
fe49bc
    namespace prefix field postfix, and a `_`, where words are separated by `_` characters, e.g.:
fe49bc
    `rtlp_log_do_something() { local _rplds_parameter=""; [...] }` and `ex_something() {
fe49bc
    local _es_parameter=""; [ ...] }` 
fe49bc
  
fe49bc
    This is necessary in order to prevent implicit conflicts between two or more functions that share
fe49bc
    a call path and would otherwise use the same variables names, such as `function1() { local
fe49bc
    list="${1}"; function2 "${list}"; }; function2() { local list="${2}"; }`, particularly when those
fe49bc
    functions acess and/or mutate each other's variables. Additionally, local variables are thus marked
fe49bc
    with a `_` prefix and by being lower case.
fe49bc
fe49bc
### `eval` rules
fe49bc
fe49bc
11) The following special characters must be escaped with a backslash at all times in `eval`
fe49bc
    expressions: `<newline>`, `"`, `'`, `[`, `\`, `]`, `<backtick>`, `$`
fe49bc
12) If parameter expansion is to be evaluated with respect to a parameter reference, the following idiom
fe49bc
    must be used at all times: `eval [...]\${${rparameter[...]}}`
fe49bc
13) If quoting with single quotes or double quotes is required - see 4) - or brace-enclosing - see 5) -
fe49bc
    and with respect to 11), viz. the single quotes or double quotes have been escaped with a backslash,
fe49bc
    something must be evaluated as a single field, then that field must be doubly quoted with single or
fe49bc
    double quotes, where the second set of quotes must not be escaped with a backslash, e.g.: `
fe49bc
    rparameter=parameter; eval ${rparameter}="\"a b c\""`. 
fe49bc
    This is very rarely required.
fe49bc
fe49bc
### Passing arguments
fe49bc
fe49bc
14) The `fork/exec/write`-`read` pattern where a parameter is set to the result of a command
fe49bc
    substitution expression which is executed in a subshell process, e.g.: `parameter="$(function)"`
fe49bc
    is prohibited at all times *except* when an actual external command is invoked, e.g. `sort(1)`
fe49bc
    or `sed(1)`.  
fe49bc
  
fe49bc
    This is necessary due to the very significant cost of the mentioned pattern, particularly concerning
fe49bc
    primitive e.g. list or string processing functions with high contention.
fe49bc
15) If a function is to return, produce, evaluate to, etc. an arbitrary value apart from the exit status,
fe49bc
    it shall do so by receiving references to the target variables in the callers' scope from the caller
fe49bc
    prefixed with a single `$` character, e.g. `function \$parameter` and `function() {
fe49bc
    local _fn_rparameter="${1#\$}"; [..]; }` which are then set with `eval` expressions: `
fe49bc
    function() { local _fn_rparameter="${1#\$}"; [...]; eval ${_fn_rparameter}=\'a b c\'; };` Refer to
fe49bc
    11)-13) for the rules concerning `eval`.  
fe49bc
fe49bc
    This is necessary due to 14) as well as the absence of any other calling convention other than using
fe49bc
    implicit global variables, e.g.: `function1() { VARIABLE=; function2; }; function2() { VARIABLE=1;
fe49bc
    }`
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
fe49bc
[//]: # "{{{ 5. References"
fe49bc
## 5. References
fe49bc
fe49bc
* ``Sun, 25 Apr 2016 09:04:08 +0000 [1]``musl FAQ  
fe49bc
* ``Wed, 04 Mar 2020 13:36:19 +0000 [2]``midipix - what is midipix, and how is it different?  
fe49bc
* ``Wed, 29 Apr 2020 23:33:34 +0100 [3]``User Rights Assignment (Windows 10) - Windows security | Microsoft Docs  
fe49bc
* ``Wed, 29 Apr 2020 23:33:50 +0100 [4]``Windows Vista Application Development Requirements for User Account Control Compatibility | Microsoft Docs  
fe49bc
  
fe49bc
[Back to top](#table-of-contents)
fe49bc
fe49bc
[//]: # "}}}"
fe49bc
  
fe49bc
[modeline]: # ( vim: set tw=0: )