Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ lib/*
examples/*
inst
.DS_Store
*.hash
156 changes: 88 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,73 +1,93 @@
# kos-ports: KallistiOS Package Manager

## Introduction
**kos-ports** is a package manager and repository of various useful libraries that
have been ported to the Dreamcast operating system
[KallistiOS](https://github.com/KallistiOS/KallistiOS). These libraries include
common audiovisual formats (jpg, png, mp3, ogg, mpeg), compression formats (libbz2,
zlib), scripting languages (Lua, Tcl, MicroPython), gaming APIs (OpenGL, OpenAL,
SDL), and more. Each port is meant to be as self-contained as possible and should
build on the current version of KallistiOS. Dependency libraries will be fetched and
built automatically, if necessary.

**kos-ports** is a package manager and repository of libraries ported to the Dreamcast operating system [KallistiOS](https://github.com/KallistiOS/KallistiOS). It includes libraries for audio, video, compression, scripting, and game development. Each port is self-contained and builds against the current KallistiOS version. Dependencies are automatically fetched and built as needed.

## Prerequisites
### KallistiOS
Users must have a [KallistiOS](https://github.com/KallistiOS/KallistiOS) environment
set up already. This means you must have an SH4 toolchain built and have already
compiled KallistiOS itself. Before attempting to build a port, make sure you have
sourced your KallistiOS `environ.sh` file in your current terminal.

### Environment
1. `curl` or `wget` are required to download packages. `curl` is used by default,
but `wget` may be set as an alternative in `config.mk`.
2. GNU make and Bash. Other make tools and shells have not been tested and
may not work properly.
3. Git and CMake may be required for some packages in the collection.
4. Python is required to validate packages. If you don't have Python and wish to
skip validation, you can set this in `config.mk`.

### Building a port
kos-ports was modelled after the FreeBSD ports collection, so some users may
be familiar with the usage.

To build a port, simply enter its directory and type `make install clean`.

The package management scripts should fetch, unpack, patch, and build the package
as well as any dependencies, then clean up files after itself. Once built, the
package's headers will be available in `kos-ports/include` and the built library
in `kos-ports/lib`. These paths are automatically included in your build flags if
you are using the KOS Makefile system.

## Using the ports tree
There are a few available `make` targets that can be used in each port directory:

- **install**: Perform all steps to download, patch, build, and install the port in
question.
- **clean**: Clean up any dist files and intermediate build results.
- **uninstall**: Uninstall the port. This does not make sure dependencies are still
fulfilled, so keep that in mind!
- **portinfo**: Print to the terminal a description and various metadata about the
port in question.

### Managing all ports
The following helper scripts are provided in the `utils` directory to perform
the above operations on **all** ports in the tree:
- `build-all.sh` will **install** all ports.
- `uninstall-all.sh` will **uninstall** all ports.
- `clean-all.sh` will **clean** all ports.

#### Lesser used targets (mainly for internal use):
- **version-check**: Check the version of the port that is currently installed.
- **depends-check**: Check if all dependencies of the port are installed.
- **abi-check**: Check if the current KOS floating-point ABI is compatible.
- **fetch**: Download dist files from upstream.
- **validate-dist**: Check downloaded distfiles for validity, if enabled.
- **unpack**: Unpack any fetched packages for the port.
- **build-stamp**: Build the port, but do not install it.
- **clean-dist**: Clean up any dist files. Does not clean build files.
- **clean-build**: Cleans up build files, leaving dist files in place.

## Porting a new library
Porting a new library is meant to be a relatively simple task. Take a look at
an existing port, such as `libpng`, to get an idea how the package manager works.
If you need assistance, feel free to reach out using the usual support channels.

### KallistiOS Setup

- You must have a working [KallistiOS](https://github.com/KallistiOS/KallistiOS) environment and SH4 toolchain.
- Build KallistiOS and source its `environ.sh` in your terminal **before** using kos-ports:
```sh
source /opt/toolchains/dc/kos/environ.sh
```

### Required Tools

- `curl` (default) or `wget` for downloads (set in `config.mk`)
- GNU make and Bash (other shells/make tools are not supported)
- `git` and `cmake` (required for some ports)
- Python (for validating downloads; can be disabled in `config.mk`)

## Building and Installing Ports

To build and install a single port:
```sh
cd <portname>
make install clean
```
- This will fetch, unpack, patch, build, and install the port and its dependencies.
- Headers are installed to `kos-ports/include/`
- Libraries are installed to `kos-ports/lib/`
- If you use the KOS Makefile system, these paths are automatically included.

### Common Make Targets (per-port)

- `make install` – Build and install the port (and dependencies)
- `make update` – Update the port if a new version is available (for git-based ports)
- `make clean` – Remove build and dist files for the port
- `make uninstall` – Remove the port (does not check dependencies)
- `make portinfo` – Show port description and metadata

### Managing All Ports

Scripts in the `utils/` directory let you operate on all ports at once:
- `utils/build-all.sh` – Install all ports
- `utils/uninstall-all.sh` – Uninstall all ports
- `utils/clean-all.sh` – Clean all ports
- `utils/update-all.sh` – Update all installed ports

### Advanced/Developer Targets

- `make show-deps` – Show all dependencies and their status
- `make depends-check` – Check if all dependencies are installed
- `make abi-check` – Check KOS floating-point ABI compatibility
- `make fetch` – Download dist files from upstream
- `make validate-dist` – Validate downloaded distfiles (if enabled)
- `make unpack` – Unpack fetched packages
- `make build-stamp` – Build the port, but do not install
- `make clean-dist` – Remove only dist files
- `make clean-build` – Remove only build files

## Directory Structure

- `include/` – Installed headers
- `lib/` – Installed libraries
- `examples/` – Example code (if provided by the port)
- `dist/` – Downloaded source files and git checkouts (temporary)
- `build/` – Build directory (temporary)
- `inst/` – Temporary install directory for each port

## Porting a New Library

Porting a new library is straightforward:
1. Copy an existing port (e.g., `libpng`) as a template.
2. Fill in the Makefile metadata and download instructions.
3. **Follow the standard Makefile patterns**:
- Use `INSTALLED_HDRS` for header files.
- Avoid using both `NOCOPY_TARGET` and a custom `PREINSTALL` for installation.
- Let the build system handle installation unless absolutely necessary.
4. Test with `make install clean` and ensure headers/libraries are installed correctly.
5. If you need help, reach out via the usual support channels.

## Troubleshooting

- **"No rule to make target 'store-hash'"**: Ensure your port's Makefile follows the standard patterns and you are using the latest scripts.
- **Build errors**: Make sure you have sourced `environ.sh` and have all prerequisites installed.
- **Dependency issues**: Run `make show-deps` to check for missing dependencies.

---

For more details, see the comments in each script and Makefile, or contact the maintainers.
10 changes: 1 addition & 9 deletions raylib4dc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ LICENSE = zlib License - http://opensource.org/licenses/Zlib
SHORT_DESC = raylib is a simple and easy-to-use library to enjoy videogames programming.

DEPENDENCIES = libGL
NOCOPY_TARGET = 1

# What files we need to download, and where from.
GIT_REPOSITORY = https://github.com/raylib4Consoles/raylib
Expand All @@ -17,15 +16,8 @@ TARGET = libraylib.a
HDRS = raylib.h raymath.h rlgl.h
HDR_INSTDIR = raylib
DISTFILE_DIR = ${PORTNAME}-${PORTVERSION}/src
INSTALLED_HDRS = ${HDRS}

KOS_MAKEFILE = Makefile

PREINSTALL = raylib_preinstall

include ${KOS_PORTS}/scripts/kos-ports.mk
raylib_preinstall:
@mkdir -p inst/lib inst/include
@cp build/${DISTFILE_DIR}/${TARGET} inst/lib
@for hdr in ${HDRS}; do \
cp build/${DISTFILE_DIR}/$$hdr inst/include; \
done
31 changes: 30 additions & 1 deletion scripts/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,19 @@ else
endif
touch build-stamp

install: setup-check version-check abi-check depends-check force-install
install: setup-check abi-check depends-check
@if [ -f "${KOS_PORTS}/lib/.kos-ports/${PORTNAME}" ] ; then \
installed_version=`cat "${KOS_PORTS}/lib/.kos-ports/${PORTNAME}"` ; \
if [ "$$installed_version" = "${PORTVERSION}" ] ; then \
if [ -f "${KOS_PORTS}/lib/.kos-ports/${PORTNAME}.hash" ] ; then \
echo "${PORTNAME} version ${PORTVERSION} is already installed." ; \
echo "To force reinstall, run: make uninstall && make install" ; \
echo "To check for updates, run: make update" ; \
exit 0 ; \
fi ; \
fi ; \
fi ; \
$(MAKE) force-install store-hash

force-install: build-stamp $(PREINSTALL)
@if [ ! -d "inst" ] ; then \
Expand Down Expand Up @@ -102,3 +114,20 @@ force-install: build-stamp $(PREINSTALL)

@echo "Marking ${PORTNAME} ${PORTVERSION} as installed."
@echo "${PORTVERSION}" > "${KOS_PORTS}/lib/.kos-ports/${PORTNAME}"

# Store git hash after successful build
store-hash:
@if [ -n "${GIT_REPOSITORY}" ] ; then \
branch="${GIT_BRANCH}" ; \
if [ -z "$$branch" ] ; then \
branch="HEAD" ; \
fi ; \
current_hash=`git ls-remote ${GIT_REPOSITORY} $$branch | cut -f1` ; \
if [ -n "$$current_hash" ] ; then \
mkdir -p ${KOS_PORTS}/lib/.kos-ports ; \
echo "$$current_hash" > ${KOS_PORTS}/lib/.kos-ports/${PORTNAME}.hash ; \
echo "Stored git hash: $$current_hash" ; \
else \
echo "Warning: Could not retrieve git hash for ${GIT_REPOSITORY} $$branch" ; \
fi ; \
fi
91 changes: 79 additions & 12 deletions scripts/version.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,88 @@
# Copyright (C) 2015 Lawrence Sebald
#

version-check:
# Update target that handles both git and version-based ports
update:
@if [ -f ${KOS_PORTS}/lib/.kos-ports/${PORTNAME} ] ; then \
a=`cat ${KOS_PORTS}/lib/.kos-ports/${PORTNAME}` ; \
${KOS_PORTS}/scripts/vercmp.sh $$a ${PORTVERSION} ; \
res=$$? ; \
if [ "$$res" -eq "0" ] ; then \
echo "${PORTNAME} is already installed and is latest version. Exiting." ; \
exit 1 ; \
elif [ "$$res" -eq "1" ] ; then \
echo "${PORTNAME} is already installed and is newer than latest version!" ; \
echo "Ports collection out of sync. Please update! Exiting." ; \
exit 255 ; \
if [ -n "${GIT_REPOSITORY}" ] ; then \
if [ -f "${KOS_PORTS}/lib/.kos-ports/${PORTNAME}.hash" ] ; then \
last_hash=`cat ${KOS_PORTS}/lib/.kos-ports/${PORTNAME}.hash` ; \
echo "Last stored hash: $$last_hash" ; \
branch="${GIT_BRANCH}" ; \
if [ -z "$$branch" ] ; then \
branch="HEAD" ; \
fi ; \
current_hash=`git ls-remote ${GIT_REPOSITORY} $$branch | cut -f1` ; \
if [ -z "$$current_hash" ] ; then \
echo "Error: Could not retrieve git hash for ${GIT_REPOSITORY} $$branch" ; \
echo "Please check your network connection and repository URL." ; \
exit 1 ; \
fi ; \
echo "Current repository hash: $$current_hash" ; \
if [ "$$last_hash" = "$$current_hash" ] ; then \
echo "${PORTNAME} is up to date with git repository. No changes detected." ; \
exit 0 ; \
else \
echo "${PORTNAME} has new changes in repository. Rebuilding..." ; \
cd ${KOS_PORTS} && $(MAKE) -C ${PORTNAME} clean install ; \
fi ; \
else \
echo "${PORTNAME} is installed but no git hash is stored yet." ; \
echo "Performing clean reinstall to ensure latest state..." ; \
cd ${KOS_PORTS} && $(MAKE) -C ${PORTNAME} uninstall clean install ; \
fi ; \
else \
echo "${PORTNAME} $$a installed. Update to ${PORTVERSION}." ; \
installed_version=`cat ${KOS_PORTS}/lib/.kos-ports/${PORTNAME}` ; \
${KOS_PORTS}/scripts/vercmp.sh $$installed_version ${PORTVERSION} ; \
res=$$? ; \
if [ "$$res" -eq "0" ] ; then \
echo "${PORTNAME} version $$installed_version is up to date." ; \
exit 0 ; \
elif [ "$$res" -eq "1" ] ; then \
echo "${PORTNAME} version $$installed_version is newer than ports version ${PORTVERSION}!" ; \
echo "Ports collection might be out of sync. Please check for updates." ; \
exit 1 ; \
else \
echo "${PORTNAME} version $$installed_version is installed, but version ${PORTVERSION} is available." ; \
echo "Performing clean reinstall to update..." ; \
cd ${KOS_PORTS} && $(MAKE) -C ${PORTNAME} uninstall clean install ; \
fi ; \
fi ; \
else \
echo "${PORTNAME} is not currently installed." ; \
echo "Nothing to update. To install this port, run: make clean install" ; \
exit 1 ; \
fi

# Show dependencies for this port
show-deps:
@if [ -n "${DEPENDENCIES}" ] ; then \
echo "Dependencies for ${PORTNAME}:" ; \
for _dep in ${DEPENDENCIES}; do \
if [ -f "${KOS_PORTS}/lib/.kos-ports/$$_dep" ] ; then \
printf " ✓ %s (installed)\n" "$$_dep" ; \
else \
printf " ✗ %s (not installed)\n" "$$_dep" ; \
fi ; \
if [ -f "${KOS_PORTS}/$$_dep/Makefile" ] ; then \
cd "${KOS_PORTS}/$$_dep" && \
subdeps=`${MAKE} print-deps 2>/dev/null` ; \
if [ -n "$$subdeps" ] ; then \
echo " Sub-dependencies:" ; \
for _subdep in $$subdeps; do \
if [ -f "${KOS_PORTS}/lib/.kos-ports/$$_subdep" ] ; then \
printf " ✓ %s (installed)\n" "$$_subdep" ; \
else \
printf " ✗ %s (not installed)\n" "$$_subdep" ; \
fi ; \
done ; \
fi ; \
fi ; \
done ; \
else \
echo "${PORTNAME} has no dependencies beyond the base system." ; \
fi

# Helper target to print dependencies
print-deps:
@echo "${DEPENDENCIES}"
21 changes: 7 additions & 14 deletions utils/build-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,14 @@ error_count=0
for _dir in ${KOS_PORTS}/* ; do
if [ -d "${_dir}" ] ; then
if [ -f "${_dir}/Makefile" ] ; then
echo "Checking if ${_dir} is installed and up-to-date..."
${KOS_MAKE} -C "${_dir}" version-check > /dev/null 2>&1
portname=$(basename "${_dir}")
echo "Building ${_dir}..."
${KOS_MAKE} -C "${_dir}" clean install
rv=$?
if [ "$rv" -eq 0 ] ; then
echo "Building ${_dir}..."
${KOS_MAKE} -C "${_dir}" install clean
rv=$?
echo $rv
if [ "$rv" -ne 0 ] ; then
echo "Error building ${_dir}."
errors="${errors}${_dir}: Build failed with return code ${rv}\n"
error_count=$((error_count + 1))
fi
else
echo "${_dir} is already installed and up-to-date. Skipping."
if [ "$rv" -ne 0 ] ; then
echo "Error building ${_dir}."
errors="${errors}${_dir}: Build failed with return code ${rv}\n"
error_count=$((error_count + 1))
fi
fi
fi
Expand Down
Loading