Port definition (port.def.sh) specification¶
This document serves as a formal representation of the Ports API 1 interface.
The port.def.sh file is a declarative manifest and build script used by the
Phoenix-RTOS port management tooling. It defines how a third-party application
should be fetched, configured, built, and integrated into the Phoenix-RTOS.
This format is designed to be sourced directly by Bash scripts invoked internally by the build system during port discovery and dependency resolution.
The port.def.sh file contains two parts: a static section that supplies the
build system with essential metadata about the port, and an executable section
that implements the functions responsible for preparing, patching, building, and
installing the port.
Static section¶
All static fields must be defined, unless stated otherwise.
Identification¶
ports_apiVersion of the port manager API this script supports.
Currently supported API versions:
1.nameCase-sensitive unique identifier for the port, usually a package name (e.g.
busybox).versionVersion of the port, usually derived from the upstream version.
Must follow Python Version specifiers scheme.
desc(optional)A short, human-readable description of the ported package.
Source acquisition & verification¶
A port definition can either pull the source from an archive file or from a Git repository (options are mutually exclusive):
If pulling from an archive file, it must supply:
sourceBase URL where the source is hosted.
archive_filenameThe name of the downloaded file.
If pulling from a Git repository, it must supply:
git_sourceURL of Git repository from which to pull the source.
git_revGit revision to pull.
Currently, only a single archive file/repository to pull can be defined per port definition.
The rest of the fields are common to both cases:
src_pathPath to a source tree in the archive/repository, relative to archive/repository root. For example, when extraction of
./somepkg-1.27.tar.gzcreates a directory./somepkg-1.27-srcthat contains the source ofsomepkg, thensrc_path="somepkg-1.27-src".sha256An expected SHA256 checksum of the downloaded archive, obtained through
sha256sum | cut -d' ' -f1
or of the cloned repository, obtained through
git archive --format=tar HEAD | sha256sum | cut -d' ' -f1
sizeSize (in bytes) of the downloaded archive or the git repository excluding
.git.
Licensing¶
licenseThe SPDX identifier for the software license (e.g.,
GPL-2.0-only).license_filePath to the license file within the source tree.
Requirements¶
supportsDefines OS compatibility requirements (e.g.,
phoenix>=3.3defines compatibility with Phoenix-RTOS release 3.3 and higher).dependsDefines mandatory dependencies on other ports (e.g.
openssl>=1.1.1, enforces that OpenSSL >=1.1.1 will be installed prior to the port).optionalLike
depends, but will build the dependency only if it is explicitly enabled in the ports.yaml configuration file.conflictsExpresses conflicts with other ports that provide the same functionality (e.g. OpenSSL 3.0 can conflict with OpenSSL 1.1.1, but both are commonly used today).
Variant flags¶
A similar behaviour to FreeBSD
flavors and
Gentoo’s USE flags can be achieved
using iuse coupled with helpers like b_use().
iuseList of flags exported by the port. For example,
iuse="longtest safe"declares that a given port supports two flags,longtestandsafe, that alter the build process.
Executable section¶
Aside from static section, the port.def.sh must supply the implementation
of functions necessary for the actual port installation.
After sourcing the static section, the build system executes the following functions sequentially:
- p_common() (optional)¶
Initial phase - should be used, e.g. for exporting common variables/functions to be used across the remaining functions.
- p_prepare()¶
Port preparation phase - place for patching, initializing the port build (autoconf, CMake, bootstrap, etc.).
- p_build()¶
Port building and installation phase invoked after
p_prepare(). Anymake,b_install()commands must go here.
- p_build_test() (optional)¶
Port tests building phase, invoked after
p_build()when the port is built with tests enabled. Anymake,b_install()commands for building port tests must go here.
Provided environment in the executable section¶
The build system provides the following environment for the use in the executable section implementation.
Variables¶
STRIPTarget-specific binary stripper
CROSSThe cross-compiler prefix (e.g.,
arm-phoenix-).PREFIX_PORTThe directory containing the
port.def.shfile.PREFIX_PORT_WORKDIRAbsolute path (based on declared
src_path) to the directory where port source tree is extracted.PREFIX_PORT_INSTALLPoints to the target installation directory (potentially different for various ports, depending on whether they conflict with each other). Can be an arbitrary path.
PREFIX_HPoints to the target include directory where the headers should be installed.
PREFIX_APoints to the target library directory where the libraries should be installed.
PREFIX_FSThe root of the Phoenix-RTOS
rootfspartition.PREFIX_PROGThe destination directory for built binaries.
PREFIX_STRIPPEDThe destination directory for stripped built binaries.
PREFIX_PROG_TO_INSTALLVariable equal to either
PREFIX_PROGorPREFIX_PROG_STRIPPED, depending on whether to install stripped binaries. Usually used as an argument tob_install().
Helper functions¶
- b_port_apply_patches(srcdir[, patch_subdir])¶
Applies patches to the source tree located in
srcdir. This function is non-recursive; if patches are organized into subdirectories, call this function multiple times with the appropriatepatch_subdir.Looks for files ending in
*.patchwithin${PREFIX_PORT}/patches/${patch_subdir}.To prevent double-patching, the function creates a marker file for every successfully applied patch.
- Parameters:
srcdir – The absolute path to the extracted source code (usually
$PREFIX_PORT_WORKDIR).patch_subdir – (Optional) A subdirectory within the port’s
patches/folder. Defaults to.(the root of the patches folder).
Example:
p_prepare() { # Apply patches from the root ./patches directory b_port_apply_patches "${PREFIX_PORT_WORKDIR}" # Apply architecture-specific patches from ./patches/arm b_port_apply_patches "${PREFIX_PORT_WORKDIR}" "arm" }
- b_dependency_dir(dep_name)¶
Returns the installation directory of a required dependency named
dep_name.If the dependency is not installed, the function aborts the installation process.
- Parameters:
dep_name – The name of the optional dependency to query (e.g.
openssl).
- b_optional_dir(dep_name)¶
Returns the installation directory of an optional dependency named
dep_name.If the optional dependency is not installed, the function returns an empty string.
- Parameters:
dep_name – The name of the optional dependency to query (e.g.
openssl).
The installation directory returned by b_dependency_dir() and
b_optional_dir() serves as the root for lib and include directories
containing the dependency’s libraries and headers.
- b_use(flag_name)¶
Returns 0 (success) if the specified flag is enabled, and a non-zero value otherwise.
This is typically used in conditional logic within port functions to check if optional features or configurations have been toggled on by the user or the system.
- Parameters:
flag_name – The name of the flag to check.
Example:
local conf_args=() if b_use "x11"; then conf_args+=("--with-x") fi
- b_use_ensure(flag_name, reason)¶
Ensures that a specific flag is enabled. If the flag is not enabled, the function terminates the build process with an error message indicating the required flag and the reason it is needed.
- Parameters:
flag_name – The name of the flag to verify.
reason – A descriptive string explaining why this flag is mandatory for the current operation.
- b_install(*filelist, dstdir)¶
Installs one or more files into the target filesystem directory. The destination path is relative to the package root (
${PREFIX_FS}/root/).The function creates the destination directory if it does not exist and verifies that each source file is present before attempting installation. Files are installed with executable permissions (
755).- Parameters:
*filelist – One or more absolute paths to the source files to be installed.
dstdir – The destination directory path (relative to the target root) where the files should be placed.
Example:
# Install lua, luac to /usr/bin b_install "${PREFIX_PROG_TO_INSTALL}/lua" /usr/bin # Install multiple lua tests to /usr/share/lua/tests b_install "${lua_test_dir}"/*.lua /usr/share/lua/tests
- b_install_host(*filelist)¶
Installs one or more executable files into the host-specific build directory (e.g.
${PREFIX_BUILD}/host-prog/). This is typically used for build-time tools (like code generators or custom compilers) that need to be executed on the host system during the cross-compilation process.The function ensures the destination directory exists and verifies the existence of each source file before installation.
- Parameters:
*filelist – A list of absolute or relative paths to the files intended for installation.
Example port definition¶
Below is an example port of openvpn that applies patches using
b_port_apply_patches(), invokes ./configure, builds the port using
make and installs the openvpn binary to /sbin.
#!/usr/bin/env bash
#shellcheck disable=2034
{
ports_api=1
name="openvpn"
version="2.4.7"
desc="Secure IP/Ethernet tunnel daemon"
source="https://swupdate.openvpn.org/community/releases/"
archive_filename="${name}-${version}.tar.gz"
src_path="${name}-${version}/"
size="1457784"
sha256="73dce542ed3d6f0553674f49025dfbdff18348eb8a25e6215135d686b165423c"
license="GPL-2.0-only"
license_file="COPYING"
conflicts=""
depends="openssl>=1.1.1a lzo>=2.10"
optional=""
supports="phoenix>=3.3"
}
p_prepare() {
b_port_apply_patches "${PREFIX_PORT_WORKDIR}"
if [ ! -f "$PREFIX_PORT_WORKDIR/config.h" ]; then
OPENVPN_CFLAGS="-std=gnu99 -I${PREFIX_H}"
(cd "$PREFIX_PORT_WORKDIR" && autoreconf -i -v -f)
(cd "$PREFIX_PORT_WORKDIR" && \
"./configure" CFLAGS="$CFLAGS $OPENVPN_CFLAGS" LDFLAGS="$LDFLAGS" \
--host="${HOST}" --sbindir="$PREFIX_PROG")
fi
}
p_build() {
make -C "$PREFIX_PORT_WORKDIR"
make -C "$PREFIX_PORT_WORKDIR" install-exec
$STRIP -o "$PREFIX_PROG_STRIPPED/openvpn" "$PREFIX_PROG/openvpn"
b_install "$PREFIX_PROG_TO_INSTALL/openvpn" /sbin/
}