Skip to content

Instantly share code, notes, and snippets.

@5HT
Created September 8, 2026 17:40
Show Gist options
  • Select an option

  • Save 5HT/17759f2983a92df4eaf8656e3770e7de to your computer and use it in GitHub Desktop.

Select an option

Save 5HT/17759f2983a92df4eaf8656e3770e7de to your computer and use it in GitHub Desktop.
BTRON on NetBSD/FreeBSD/OpenBSD
# BTRON POSIX Port – Minimal Changes for NetBSD / OpenBSD / FreeBSD
**Repository:** https://github.com/bitedits/btron
**Target command:** `make run-posix`
**Analysis date:** 2026-09-08
## Goal
Make the POSIX-hosted desktop (`btron-posix`) build and run successfully out of the box on:
- NetBSD
- OpenBSD
- FreeBSD
with a plain:
```sh
$ make run-posix
```
## Root Cause
The Host OS / SDL2 detection block at the top of `Makefile` is broken:
```makefile
else ifeq ($(UNAME_S), Linux)
...
else ifneq (,) # ← always true!
# hard-coded MinGW paths + -lgdi32 -lwinpthread
...
else
SDL_LIBS := -lSDL2 -lz -lgdi32 -lpthread # still contains -lgdi32
endif
```
On FreeBSD / NetBSD / OpenBSD (`uname -s` returns those names) the broken `else ifneq (,)` always matches. The build therefore receives Windows-only flags (`-lgdi32`, MinGW include/lib paths) and linking fails immediately.
No other source-level Linuxisms block the POSIX target. The C code is already reasonably portable (`#ifdef __APPLE__` / `#ifdef _WIN32`, standard POSIX + SDL2 + zlib + math).
## Minimal Makefile Changes Required
### 1. Fix the OS detection block (the only hard blocker)
Replace the current `ifeq ($(UNAME_S), Darwin) … else ifeq Linux … else ifneq (,) …` chain with a version that treats the three BSDs (and generic Unix) like Linux:
```makefile
# Host OS / SDL2 detection
UNAME_S := $(shell uname -s)
EXEEXT :=
ifneq (,$(findstring MINGW,$(UNAME_S)))
EXEEXT := .exe
endif
ifeq ($(UNAME_S), Darwin)
SDL_CFLAGS := $(shell sdl2-config --cflags 2>/dev/null || echo "-I/usr/local/include/SDL2")
SDL_LIBS := $(shell sdl2-config --libs 2>/dev/null || echo "-lSDL2") \
-lz -lpthread -framework ApplicationServices -framework Cocoa
QEMU_DISPLAY := -display cocoa,show-cursor=on,zoom-to-fit=on
KERNEL_DISPLAY := $(QEMU_DISPLAY)
else ifneq (,$(filter $(UNAME_S),Linux FreeBSD NetBSD OpenBSD DragonFly))
# Linux + the three BSDs (and DragonFly) share the same portable path
SDL_CFLAGS := $(shell sdl2-config --cflags 2>/dev/null || \
pkg-config --cflags sdl2 2>/dev/null || \
echo "-I/usr/local/include/SDL2 -I/usr/include/SDL2")
SDL_LIBS := $(shell sdl2-config --libs 2>/dev/null || \
pkg-config --libs sdl2 2>/dev/null || \
echo "-lSDL2") \
-lz -lm -lpthread
QEMU_DISPLAY := -display default,show-cursor=on
KERNEL_DISPLAY := -display default
else ifneq (,$(findstring MINGW,$(UNAME_S)))
SDL_CFLAGS := $(shell sdl2-config --cflags 2>/dev/null || echo "-IC:/msys64/mingw64/include/SDL2 -Dmain=SDL_main")
SDL_LIBS := $(shell sdl2-config --libs 2>/dev/null || echo "-LC:/msys64/mingw64/lib -lmingw32 -mwindows -lSDL2main -lSDL2") -lz -lgdi32 -lwinpthread
QEMU_DISPLAY := -display default,show-cursor=on
KERNEL_DISPLAY := -display default
else
# generic Unix fallback (no -lgdi32)
SDL_CFLAGS := $(shell sdl2-config --cflags 2>/dev/null || \
pkg-config --cflags sdl2 2>/dev/null || \
echo "-I/usr/local/include/SDL2 -I/usr/include/SDL2")
SDL_LIBS := $(shell sdl2-config --libs 2>/dev/null || \
pkg-config --libs sdl2 2>/dev/null || \
echo "-lSDL2") -lz -lm -lpthread
QEMU_DISPLAY := -display default,show-cursor=on
KERNEL_DISPLAY := -display default
endif
```
After this change, `make posix` / `make run-posix` will compile and link on all three BSDs (provided SDL2 is present).
### 2. Soften the `tad_bin` dependency (strongly recommended for “out of the box”)
```makefile
posix: $(POSIX_TARGET)
@ln -sf $(POSIX_TARGET) $(DEFAULT_TARGET)
@echo "=========================================================="
@echo " B-System POSIX Kernel & Desktop successfully built!"
@echo " Startup File: $(POSIX_STARTUP)"
@echo " Run './btron' or 'make run-posix' to start."
@echo "=========================================================="
@if command -v elixir >/dev/null 2>&1; then $(MAKE) tad_bin; else \
echo "Note: elixir not found — tad_bin documents skipped (desktop still runs)."; fi
run-posix: $(POSIX_TARGET)
./$(POSIX_TARGET)
```
(or make `tad_bin` a separate optional target).
The desktop boots without the TAD documents; only the in-app browser is affected. Elixir is **not** in base NetBSD / OpenBSD / FreeBSD, so this is needed for a true zero-extra-tool experience.
### 3. No C source changes required
- `core_posix.c`, `dp_sdl.c`, `main.c`, etc. already use only portable POSIX + SDL2 constructs.
- Headers (`<sys/utsname.h>`, `<pthread.h>`, `<termios.h>`, `<zlib.h>`, `<math.h>`) exist on all three systems.
- The only Darwin-specific code is properly guarded by `#ifdef __APPLE__`.
## Runtime Prerequisites (not Makefile changes)
On a stock system you still need SDL2 development packages:
| OS | Package command (SDL2 + headers) |
|----------|-------------------------------------------|
| FreeBSD | `pkg install sdl2` |
| NetBSD | `pkgin install SDL2` (or pkgsrc) |
| OpenBSD | `pkg_add sdl2` |
- zlib and libm are part of the base system.
- A C99 compiler (clang or gcc) is part of the base system on all three.
## Summary – Absolute Minimum Patch
1. **Fix the broken `else ifneq (,)` / `-lgdi32` detection** – group FreeBSD / NetBSD / OpenBSD with Linux.
2. **(Optional but recommended)** Make `tad_bin` non-fatal when `elixir` is missing.
With only change #1, `make run-posix` will succeed on all three BSDs once SDL2 is installed. No other modifications to the POSIX port are needed.
---
*Generated from analysis of https://github.com/bitedits/btron*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment