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 spkgbuild, 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 spkgbuild 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/spkgbuild
    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 spkgbuild

    Cada campo del spkgbuild 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 spkgbuild. 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 spkgbuild 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="-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 spkgbuild

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

    $ vim spkgbuild

    El spkgbuild 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 spkgbuild 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
    ==> .checksums 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
    ...
    ==> .pkgfiles 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.