root@starkos:~$ portcreate

Crear puertos

Cómo funciona el sistema de puertos de starkOS y cómo crear uno propio con portcreate, desde la plantilla inicial hasta el paquete instalable.

Un puerto es la receta o conjunto de instrucciones que describe cómo construir un programa desde su código fuente: de dónde se descarga, qué dependencias necesita y qué comandos hay que ejecutar para compilarlo e instalarlo. En starkOS un puerto es, en la práctica, un directorio con una plantilla sbuild, que es lo mínimo que requiere starkpm para poder construir un paquete. En algunos puertos podremos encontrar adicionalmente parches, ficheros de configuración o hooks pre/post install o pre/post remove que requieren ejecutarse durante el proceso de instalación o elminación del puerto en el sistema.

Es fácil confundir ambos términos porque uno se convierte en el otro, pero cumplen funciones distintas:

En resumen: construyes un puerto para obtener un paquete instalable en el sistema, con el comando portsync sincronizas puertos (recetas), no paquetes; cada máquina compila su propios paquetes a partir de puertos.

  1. 01

    Requisitos y repositorio local

    Necesitas fakeroot para poder construir puertos sin usar root directamente. Instálalo con starkpm si no lo tienes:

    # portsync
    # stark install fakeroot

    Se recomienda mantener los puertos propios en un repositorio local, dentro de tu directorio personal:

    $ mkdir $HOME/local
  2. 02

    Crear la plantilla con portcreate

    Como ejemplo se usará dfc, una herramienta de línea de comandos que muestra el uso del espacio de almacenamiento con gráficos y colores. Usa portcreate <puerto> para generar la plantilla inicial y entra en su directorio:

    $ portcreate 
    Usage: portcreate [-b builder] 
    
    Create a port template directory with sbuild file.
    
    Options:
      -b   Specify build system (default: autotools)
                    Available: autotools, meson, cmake, go, python
      -h            Show this help message
    
    Examples:
      portcreate myport              # Creates autotools template
      portcreate -b meson myport     # Creates meson template
      portcreate -b cmake myport     # Creates cmake template
      portcreate -b go myport        # Creates go template
      portcreate -b python myport    # Creates python template

    La plantilla generada tiene este aspecto:

    $ portcreate myport
    	    Template port created for 'myport' using 'autotools' build system.
    	    
    $ cat myport/sbuild
    description="" maintainer="starkOS Team, starkos at disroot dot org" homepage="" name=myport version= release=1 noextract="" backup="" source="" build() { cd $name-$version ./configure --prefix=/usr make make DESTDIR="$PKG" install }
  3. 03

    Formato de sbuild

    Cada campo del sbuild tiene un propósito concreto:

    Campo Obligatorio Descripción
    descriptionBreve descripción del puerto
    maintainerMantenedor del puerto
    homepageSitio web del proyecto
    dependsNoDependencias, en un fichero a parte en el directorio del puerto
    nameNombre del puerto, igual al del directorio
    versionVersión del programa
    releaseRevisión del puerto para una misma versión
    sourcedirección remota del código fuente
    noextractNoFuentes que no deben descomprimirse
    backupNoFicheros a respetar en una actualización
    nostripNoFicheros a excluir del strip
    build()Función con los comandos de compilación

    Dentro de build(), $PKG es el directorio de instalación simulada y $SRC el directorio donde quedan las fuentes ya extraídas.

    El nombre del puerto debe ir en minúsculas y no puede contener espacios; si el proyecto original usa mayúsculas, corrígelo con sed al escribir el sbuild. Si la fuente usa versionado por fecha, no se podrán escribir guiones (-), sustitúyelos por guiones bajos (_) o puntos (.) si es realmente necesario.

  4. 04

    Esquemas recomendados para cada constructor

    Las opciones globales se definen en /etc/starkpm.conf; para un puerto concreto se sobrescriben en su propio sbuild con options="". Antepón ! para desactivar una opción, por ejemplo options="!strip !emptydirs".

    make
    
    ./configure \
        	--prefix=/usr \
        	--disable-option \
        	--enable-option
    make
    make DESTDIR="$PKG" install
    
    autoconf / automake
    
    autoreconf -fi
    ./configure \
        	--prefix=/usr \
        	--disable-option \
        	--enable-option
    make
    make DESTDIR="$PKG" install
    
    meson
    

    The distribution provides a starkos-meson wrapper script which sets some common options.

    starkos-meson $name-$version build \ -Doption=false \ -Doption2=true meson compile -C build DESTDIR="$PKG" meson install --no-rebuild -C build
    cmake
    
    cmake -S $name-$version -B build \
    	-DCMAKE_INSTALL_PREFIX=/usr \
    	-DCMAKE_INSTALL_LIBDIR=lib \
    	-DCMAKE_INSTALL_LIBEXECDIR=lib \
    	-DCMAKE_BUILD_TYPE=Release \
    	-DCMAKE_C_FLAGS_RELEASE="$CFLAGS" \
    	-DCMAKE_CXX_FLAGS_RELEASE="$CXXFLAGS" \
    	-DOPTION=ON/OFF \
    	-Wno-dev
    cmake --build build
    DESTDIR="$PKG" cmake --install build
    
    go
    
    cd $name-$version
    
    	export CGO_LDFLAGS="${LDFLAGS}"
    	export CGO_CFLAGS="${CFLAGS}"
    	export CGO_CPPFLAGS="${CPPFLAGS}"
    	export CGO_CXXFLAGS="${CXXFLAGS}"
    	export GOFLAGS="$GOFLAGS -buildmode=pie -trimpath -mod=readonly \
    			-modcacherw -ldflags=-linkmode=external"
    	export GOPATH="$SRC"/go
    	export PATH="$PATH":"$GOPATH"/bin
    
    go build -o bin/$name *.go
    
    python
    
    python3 setup.py build
    python3 setup.py install --prefix=/usr --root="$PKG"
    
    
    pip (python) 
    
    pip3 install --isolate --root="$PKG"
    
    
    build (python)
    
    python3 -m build --wheel --skip-dependency-check --no-isolation
    python3 -m installer --destdir="$PKG"
    
    gpep517 (python)
    
    gpep517 build-wheel --wheel-dir .dist --output-fd 3 3>&1 >&2
    python3 -m installer -d "$PKG"  .dist/*.whl
    
  5. 05

    Editar el sbuild

    Con el formato claro, ya se puede rellenar la plantilla con los datos reales de curl:

    $ vim sbuild

    El sbuild completo de dfc quedaría así:

    description="Utility and a library used for transferring files"
    homepage="https://curl.se"
    maintainer="starkOS Team, starkos at disroot dot org"
    
    name=curl
    version=8.21.0
    release=1
    source="https://curl.haxx.se/download/$name-$version.tar.xz"
    
    build() {
    	cd $name-$version
    
    	autoreconf
    	./configure \
    		--prefix=/usr \
    		--disable-static \
    		--disable-ldap \
    		--disable-ldaps \
    		--enable-ipv6 \
    		--enable-threaded-resolver \
    		--with-ca-bundle=/etc/ssl/cert.pem \
    		--with-ca-path=/etc/ssl/certs \
    		--with-nghttp2 \
    		--with-openssl \
    		--without-brotli \
    		--without-libidn2 \
    		--without-libpsl \
    		--without-librtmp \
    		--without-zstd 
    	make
    	make DESTDIR="$PKG" install
    }
    

    Se recomienda guardar las fuente siguiendo "$name-$version.*". Si la fuente necesita guardarse con otro nombre, usa <nombre-nuevo>::<url> en source="", por ejemplo "$name-$version.tar.gz::https://proyecto/archivo/v${version}.tar.gz".

  6. 06

    Construir el paquete

    Con el sbuild terminado, ejecuta portbuild dentro del directorio del puerto para descargar la fuente y compilarla. Para un puerto nuevo, hazlo primero con fakeroot; si algo está mal configurado, no afectará a tu sistema.

    $ fakeroot portbuild
    ==> Building: curl-8.21.0-1
    ==> Fetching: https://curl.haxx.se/download/curl-8.21.0.tar.xz
    ==> .csums updated
    ==> Unpacking: /mnt/starkos/var/cache/starkpm/sources/curl-8.21.0.tar.xz
    
    ==> Build start: curl-8.21.0-1
    + build
    + cd curl-8.21.0
    + autoreconf
    ...
    ==> .files updated
    ==> Packaging success: curl-8.21.0-1.spkg.tar.xz (1.3M)
    	    
  7. 07

    Instalar el paquete

    Una vez construido, puedes instalarlo directamente con portbuild:

    # portbuild -i

Para dependencias, sincronización de repositorios y actualización del sistema una vez instalado el paquete, consulta la guía de instalación.