Luna/ports
apio 8748364b7e
All checks were successful
continuous-integration/drone/push Build is passing
ports: Add a binutils port =D
I can't believe the fact that there is a working gas and ld on Luna. At least, for a hello world program anyway :)

objdump seems to have some problems with stack size in some cases, but apart from that, no crashes.

And that can easily be solved with either more stack preallocation or stack resizing in the kernel on page faults.
2023-08-08 16:00:31 +02:00
..
bc ports+tools: Add bc port 2023-07-24 19:14:22 +02:00
binutils ports: Add a binutils port =D 2023-08-08 16:00:31 +02:00
minitar ports: Add some defaults for CMake projects as well 2023-07-24 18:50:51 +02:00
nasm ports: Basic ports system + nasm port 2023-07-24 17:07:49 +02:00
README.md ports: Add a binutils port =D 2023-08-08 16:00:31 +02:00

Ports

As Luna is a Unix-like system, most third-party programs that are designed for/are compatible with Unix systems should run fine on it.

Obviously, since Luna's kernel and standard library are very much a work-in-progress, it is not a fully-featured POSIX implementation and some features/functions that programs require may be missing.

Despite that, some third party programs can already run on Luna unmodified/with minimal patches. This folder is a collection of build scripts and patches for such programs.

List of ported programs

Try to keep this list in alphabetical order.

Name Version Description URL
bc 6.6.0 An implementation of the POSIX bc calculator https://github.com/gavinhoward/bc
binutils 2.39 The GNU suite of binary utilities https://www.gnu.org/software/binutils
minitar 1.7.5 Tiny and easy-to-use C library to read/write tar archives https://git.cloudapio.eu/apio/minitar
nasm 2.16.01 An assembler for the x86 CPU architecture https://nasm.us

Installing ports

Luna's ports system uses binary packages, so that a compiled port can be installed either from the host system, or directly inside Luna (in the future, as right now the root file system is read-only and there's no way to obtain the package file).

The format of these binary packages is a simple compressed tar archive with all the files to install into the system root.

Thus, there are separate scripts for making the packages and for installing them.

tools/make-package.sh <PORT_NAME> will compile and create a package in ports/out/<PORT_NAME>-<PORT_VERSION>.tar.gz.

tools/install-package.sh <PORT_NAME> will optionally create a package if one doesn't exist for the current version of that port, optionally remove an old version, and then install the port into the system root.

Removing ports

tools/uninstall-package.sh <PORT_NAME> will remove all files associated with a port from the system root.

Creating a new port

Interested in porting a new program to Luna?

Create a new subdirectory inside this one (the ports directory) named after the package, then add a PACKAGE file.

The PACKAGE file

This file has essential metadata about the port, plus build instructions. It is a normal shell script, that sets the required variables and functions for the port.

Basic metadata

The name variable should be set to the name of the ported program.

The version variable should be set to the currently ported version of the program.

Example:

name="example"
version="1.0.0"

Download options

There are two supported ways to download a port's source code, which must be determined by the format variable:

  • Tarballs (format=tar)

    The url variable should be set to the URL of the source code. If applicable, it is advised to use the version variable from before, to avoid changing the URL when updating the package.

    The output variable should be set to the name of the downloaded file (usually just the base name of the URL). It is also advised to use the version variable.

    The sha256sum variable should be set to the SHA256 checksum of the tarball for that version (if upstream provides checksums, use those, else download the tarball yourself and calculate the checksum). This one will have to be changed every time the port is updated to a new version.

    Example:

    format=tar
    url="https://example.org/downloads/$version/example-$version.tar.xz"
    output="example-$version.tar.xz"
    sha256sum="df33788c71255b8ce2d845e9d32d166676e2c476d685883210736f1085d5a7c1"
    
  • Git repositories (format=git)

    The url variable should be set to the URL of the repository.

    Optional (but recommended): If the upstream project has tags for every release, you can set the tag variable to the tag name for that release. This will checkout the code for that specific release.

    Example:

    format=git
    url="https://git.example.org/example/example.git"
    tag="1.0.0"
    

Build instructions

Finally, the actual instructions for building a port. There are three (optionally four) steps to building a port:

Patching

This step is optional, if the port builds and runs perfectly without any patches. To apply patches, define a function named do_patch and write all logic required in there:

do_patch()
{
    set -e
    touch $srcdir/systems/luna.c
    patch -ui $portdir/example.patch -p 1 -d $srcdir
}

To refer to the directory containing the PACKAGE file, use the portdir variable. To refer to the directory containing the program's source code, use the srcdir variable. These are provided automatically.

Configuring

Many programs require a configure file or similar to be run before the actual build. For this, you can use the do_configure function.

do_configure()
{
    set -e
    $srcdir/configure --host=$LUNA_ARCH-luna --prefix=/usr --without-foo --without-bar --disable-advanced-features
}

The first two flags --host=$LUNA_ARCH-luna --prefix=/usr are required if using a standard configure script, to indicate that we're cross-compiling (compiling the program for another system).

Alternatively, you can simply set use_default_configure=true without a do_configure function, which will simply run the configure script with these two flags, if you don't need anything else. If using CMake and not needing any extra parameters, setting use_cmake_configure=true will have the same effect.

This function is required (unless setting use_default_configure or use_cmake_configure to true), if you don't need it you can simply make it an empty function.

Building

This step is self-explanatory, and is done using the do_build function.

do_build()
{
    set -e
    make BE_OPTIMIZED=1 -j$MAKEJOBS
}

As always, you can refer to the source directory with srcdir.

If you're using make, you can use the variable MAKEJOBS to run the build process in parallel.

Alternatively, if you're invoking make without any specific parameters, you can set default_build_make=true and skip the do_build function. This is the equivalent of doing make -j$MAKEJOBS. Alternatively, if using CMake, you can set default_build_cmake=true to do the same thing.

In any other case, the do_build function is required.

Installing

This will not install the built program into the system root, but rather into a temporary directory which is then used to generate the package tarball. You can refer to this directory using the installdir variable.

The DESTDIR variable, which is honored by many build systems, is set automatically.

This step is done using the do_install function.

do_install()
{
    set -e
    $LUNA_ARCH-luna-strip bin/example
    mkdir -p $installdir/usr/bin/
    cp bin/example $installdir/usr/bin/
}

If you're invoking make install without any specific parameters, you can set default_install_make=true and skip the do_install function. If the project uses CMake and you don't need to pass any extra parameters, you can set default_install_cmake=true.

In any other case, the do_install function is required.

Example PACKAGE files

minitar

# Basic information
name="minitar"
version="1.7.5"

# Download options
format="git"
url="https://git.cloudapio.eu/apio/minitar.git"
tag="$version"

# Build instructions
use_cmake_configure=true

do_build()
{
    # Also build the examples
    cmake --build . --target examples
}

do_install()
{
    cmake --install . --prefix /usr
    mkdir -p $installdir/usr/bin/
    cp examples/pack examples/untar examples/list $installdir/usr/bin/
}

This port is downloaded using git and built using cmake. Since we're building some extra components, do_build and do_install cannot be set to the default.

nasm

# Basic information
name="nasm"
version="2.16.01"

# Download options
format="tar"
url="https://www.nasm.us/pub/nasm/releasebuilds/$version/nasm-$version.tar.gz"
output="nasm-$version.tar.gz"
sha256sum="d833bf0f5716e89dbcd345b7f545f25fe348c6e2ef16dbc293e1027bcd22d881"

# Build instructions
use_default_configure=true
default_build_make=true
default_install_make=true

do_patch()
{
    mkdir -p $srcdir/asm/include
}

Since this port uses GNU autotools (configure and make), much less manual work is required. In fact, all the required steps are set to the default! A bit of patching is required, however.