Sortix nightly manual
This manual documents Sortix nightly, a development build that has not been officially released. You can instead view this document in the latest official manual.
guide for porting software
port(5) format.Ports are usually named after their primary program or library if relevant. Libraries should always be prefixed with lib. The port should be ideally split if it happens to contain both a major program and a major library.Upstream projects should consider this operating system to be yet another unknown operating system implementing the standard interfaces. Explicit support for this operating system should generally not be upstreamed and should instead be maintained in the patches. This policy is to avoid burdening upstreams with maintaining support that is subject to change. Simply registering the operating system as existing is exempted, but preferably the software should be patched to compile for any unknown operating system that has the needed interfaces.Patches should ideally be of upstreamable quality, although it may not be reasonably practical to make a general solution the upstream could accept. Non-trivial patches should be prefaced with a comment explaining the rationale for the patch.Third party software should be selected into the ports collection with care, ideally because they're widely considered high quality and stable. Low quality software with poor code quality should preferably not be ported, instead a better replacement should be standardized on.The build system is expected to follow the relevant conventions, such as the GNU coding conventions for ./configure and Makefile scripts and the de-facto conventional behavior. Deficiencies are fixed via patches instead of being worked around. Ports with their own custom build system implementation should be improved if they don't implement the interface correctly.Generated files are preferably patched instead of their input files due to the difficulty regenerating them. For instance configure should be patched directly instead of configure.ac and likewise Makefile.in instead of Makefile.am.Ports must not bundle their dependencies as it's problematic to silently have multiple stale versions of the same library. If a port bundles a dependency unless it's installed, then the dependency must be made mandatory.Ports must both compile natively and cross-compile. Ports must assume the best about the host operating system when cross-compiling and unable to test for bugs.It must be possible to reasonably boostrap the latest ports collection from the latest stable release.Test the port works with all the optional dependencies:The ‘!!’ suffix includes the port's optional dependencies as well.Read all the configure and makefile output and look for anything where it looks like a wrong conclusion was made or an optional dependency was not used.Review the size of the binary package and whether it installs any large unnecessary files:Review the .patch, .execpatch and .rmpatch files (if any) and clean them up as needed by updating the port's source code and forcing a rebuild to regenerate the patches.Consider installing a cross-compiler for a second architecture and testing the port works everywhere per cross-development(7).Comments about the port should go in comments at the end of the .port file using shell-style comments. Non-trivial patches and aspects should be documented this way.Finally remove the DEVELOPMENT variable and submit the port for review.The available-ports top-level makefile target can be used to search for ports with newly available versions, while upgrade-ports updates VERSION to the latest available version and switches the port into development mode. The PACKAGES environment variable can be set to a subset of ports to upgrade. The build will fail and report the sha256sum observed upstream and the SHA256SUM variable must be manually updated once it has been verified as as authentic.The old patch will be reapplied and the build will fail if any hunks could not be applied. In that case, the .rej files contains the rejected hunks and the merge conflicts need to be resolved. Delete any .rej and .orig files afterwards and continue the build. The patch files with be regenerated on a successful build as usual.Finally perform the quality assurance and testing of new ports.
example can be built along with the operating system by creating the /src/ports/example/example.port file with the meta information documented in port(5).Start the port by defining how to get the latest stable version of the upstream release:The upstream website usually contains the needed information. Guides such as Beyond Linux from Scratch and the packaging metadata for other systems may contain useful information on how to port and patch the software.UPSTREAM_SITE is the upstream primary download directory without a trailing slash and should download via a secure connection insofar possible.SHA256SUM is the sha256sum(1) of the upstream release, which should be verified with other reputable packaging systems. It can be left as the wrong value, and the download will fail and mention which hash it found instead.BUILD_LIBRARIES is the build time library dependencies (space delimited with a ‘?’ suffix for optional dependencies). It can be left empty until known. The dependencies can likely be found in the documentation, running ‘./configure --help’, or noticing what the software looks for while being built. The above example defines a mandatory build time dependency on libfoo and optional build time dependencies on libbar and libqux. Mandatory dependencies need to be ported first.BUILD_SYSTEM is set here to a standard configure script.LICENSE can be set to the abbreviation of the software's license.DEVELOPMENT is set to true to switch the port into development mode, where the port's working directory has writable files that can be patched during the build. The example.patch, example.execpatch, and example.rmpatch patch files are regenerated when the port builds successfully. If the upstream release works out of the box without any patches, then the port is already completed and the development mode can be skipped. The port's working directory will never be deleted automatically when it is in development mode. The DEVELOPMENT variable must be removed before submitting the finished port.
NAME=example BUILD_LIBRARIES='libfoo libbar? libqux?' VERSION=1.2.3 DISTNAME=$NAME-$VERSION COMPRESSION=tar.gz ARCHIVE=$DISTNAME.$COMPRESSION SHA256SUM=b8d67e37894726413f0d180b2c5a8369b02d4a2961bb50d2a8ab6f553f430976 UPSTREAM_SITE=https://example.com/pub/example UPSTREAM_ARCHIVE=$ARCHIVE BUILD_SYSTEM=configure LICENSE=example DEVELOPMENT=true
development(7):The PACKAGES environment variable builds only the mentioned ports and the ‘!’ suffix includes the port's mandatory dependencies as well. The top level makefile uses a sysroot when building the ports which can be used to determine which dependencies are mandatory. The mandatory ports can be found by starting with an empty list of build libraries and a clean sysroot, and then trying to build the port and adding the dependencies whose absense is causing the build to fail.The higher level tix-port(8) program manages the build by downloading the source code, patching it, building the port, and installing the binary package. The lower level tix-build(8) program will abort with an interactive menu if the port fails to build. See the section below for how to troubleshoot common situations.The binary package repository/$HOST/example.tix.tar.xz is cached when built and the repository/$HOST/example.version file is used to rebuild the binary package when the version changes. The files should be manually removed to force a rebuild when the port has been modified while in the development mode.The port's patch files are regenerated whenever the port builds successfully. It's recommended to add them to a work-in-progress git commit when working to keep track of the progress.
cd /src make clean-sysroot make PACKAGES='example!'
rm -f repository/*/example.tix.tar.xz # delete stale binary package rm -f repository/*/example.version # optional make clean-repository # or: remove all binary packages
make clean-sysroot make PACKAGES='example!!'
du -h repository/*/example.tix.tar.xz tar -t -f repository/*/example.tix.tar.xz
make available-ports # Search for newly available versions of ports make upgrade-ports PACKAGES=example # Update example port make PACKAGES='example!!' # Find the new sha256sum # Verify the new sha256sum is authentic. make PACKAGES='example!!' # Any old patches may fail to apply. find ports/example -name '*.rej' -o -name '*.orig' make PACKAGES='example!!' # Regenerate patches on a successful build. sed -E '/^DEVELOPMENT=true$/d' ports/example/example.port make PACKAGES='example!!' # Final build and testing.
checking host system type... Invalid configuration `x86_64-sortix': system `sortix' not recognized
| -aos* | -aros* | -cloudabi* | -sortix* \
V=1 which can be made permanent using MAKE_VARS=V=1.
// PATCH: Use foo instead because bar doesn't work yet. #ifdef __sortix__ foo(); #else bar(); #endif
#if __has_include(<foo.h>) #include <foo.h> #endif
pkg-config(1) for locating dependencies.The tix-eradicate-libtool-la(1) program can be used to remove any installed .la files in the DESTDIR as a post-install script:
DESTDIR before the binary package is created. An executable example.post-install script can be placed next to the example.port files:The script must fail if any errors occur and protect against being accidentally invoked without the appropriate environment variables being set. E.g.:
#!/bin/sh set -e [ -n "$TIX_INSTALL_DIR" ] mv "$TIX_INSTALL_DIR$PREFIX/share/foo" "$TIX_INSTALL_DIR$PREFIX/share/bar"
- Providing fallback implementations of missing standard library interfaces.
- Replacing buggy implementations of standard library interfaces.
- Sharing common utility functions between projects.
- The replacement implementations tend to be non-portable and one is supposed to modify the source code to rely on private standard library details that may be subject to change.
- Gnulib is highly forked by design and adding support for new operating systems needs to be done upstream and it may take years for the support to reach new downstream releases.
- Gnulib has assumed the worst in the past when cross-compiling, assuming unknown operating systems are buggy, injecting a non-portable replacement that doesn't compile, even when the standard library function is correct and could just have been used.
- Replacing standard library functions can hide bugs that would otherwise have found and fixed.
- Gnulib is not organized into the three categories and it's non-trivial to find out whether any interface has been replaced that shouldn't have been.
- There is no way to satisfy gnulib by correctly implementing the standard library without contributing explicit support upstream for new systems and committing to private implementation details.
PKG_CONFIG environment variable, and if unset, then using the --host option to locate a cross-pkg-config, and finally falling back on invoking pkg-config(1) directly . Dependencies for the build machine should likewise be located using the PKG_CONFIG_FOR_BUILD environment variable.Ports failing to use this search order may fail to cross-compile as they accidentally use dependencies from the build machine when cross-compiling to the host machine. The easiest fix is to use a shell parameter expansion:
pkg-config(1) as above for dependencies as it's a general solution with cross-compilation support, but some ports install their own foo-config program in the PATH. These programs are inherently unable to support cross-compilation, as they provide answers about the build machine, and the host machine's bin directory cannot be executed on the current machine.Ports installing foo-config programs must be patched to not install them. pkg-config(1) configuration files should be installed instead.Ports invoking foo-config programs, even as a fallback, must be patched to unconditionally use pkg-config(1) instead.
DESTDIR environment variable as a secondary temporary prefix during the installation. The makefile may need to be patched to inherit the variable from the environment and to use it during the installation phase. The build will erroneously attempt to install onto the root directory of the build machine if the environment variable isn't respected.
portability(7) lists common differences in the standard library. port(5) documents the advanced features useful for certain situations. Ports may fail at runtime instead of during compilation. Resolving these issues can require troubleshooting, debugging, research, and seeking help from the operating system developers and the upstream. Missing operating system functionality may need to be implemented.