Skip to content
Haiku OSHow-To Published Updated 5 min readViews unavailable

How to Set Up a Haiku Development Environment and Build From Source

Prepare a native Haiku toolchain, compile and inspect a minimal Kit application, then build a reproducible x86_64 system image safely.

Haiku is both a development target and a practical native development host. Small applications can be compiled directly against the Kit APIs, while rebuilding the operating system adds a separate source tree, Haiku’s custom Jam, cross-tools, package downloads, and boot-image testing. Keep those two workflows distinct so a first GUI program does not inherit the complexity of a complete OS build.

Establish a clean native baseline

Update the installed Haiku release through its normal package workflow and save the architecture and revision before debugging a compiler problem:

uname -a
getarch
pkgman search -a -i -D

The development headers are provided by haiku_devel. Search before installing so the repository can resolve the package appropriate to the running architecture:

pkgman search -a haiku_devel
pkgman install haiku_devel

Check the actual tools rather than assuming package success proves the environment:

which c++ rc xres make
c++ --version

Do not copy headers or libraries manually into /boot/system. Packagefs owns packaged system content; unmanaged additions belong in the documented non-packaged hierarchy. Keep projects under a user-owned directory and put generated objects in a separate build directory.

Compile a minimal Kit application

Create hello.cpp:

#include <Application.h>
#include <Rect.h>
#include <Window.h>

int
main()
{
    BApplication app("application/x-vnd.example-HelloHaiku");
    BWindow* window = new BWindow(BRect(100, 100, 460, 280),
        "Hello Haiku", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE);
    window->Show();
    app.Run();
    return 0;
}

The application signature should follow Haiku’s reverse-domain MIME-style convention and be unique. BApplication connects the process to the application services and runs its message loop. BWindow is another BLooper; Show() starts its window thread. The B_QUIT_ON_WINDOW_CLOSE flag makes this one-window example terminate when the window closes.

Compile with warnings enabled and link the main Kit library:

mkdir -p build
c++ -Wall -Wextra -std=c++17 hello.cpp -o build/HelloHaiku -lbe

libbe contains the core Application, Interface, Storage, and related Kit APIs. Extra functionality may require additional libraries, but adding libraries speculatively can conceal undeclared dependencies. Read the relevant Haiku Book class/group documentation and link only what the program uses.

Test more than process startup

Run the exact binary just produced:

./build/HelloHaiku

Verify the window appears in Deskbar, activates, moves between workspaces, and exits without leaving a team behind. Launch it from both Terminal and Tracker. Check linkage and attributes with the tools available on the installed release, and retain compiler output:

listattr -l build/HelloHaiku

For a real application, add tests for message handling, failed file operations, locale, keyboard navigation, different font sizes, and clean shutdown. A window opening once does not prove ownership, locking, or error paths are correct. Use Debugger and system logs for crashes rather than repeatedly changing compiler flags.

Resources such as vector icons and version metadata can be compiled from an .rdef with rc and attached with xres. Treat that as a separate, reviewable build step and inspect the final executable with listres. Do not describe all application metadata as BFS attributes: executable resources and file attributes are different mechanisms even though Haiku tools can expose both in an integrated desktop.

Choose an appropriate project build system

A one-file experiment can use a direct compiler command. As the project grows, adopt a reproducible Make, CMake, Meson, or Jam setup supported by its dependencies. Commit source, resource definitions, and build rules—not generated binaries or machine-specific paths.

Build from a clean directory before release. Record compiler architecture, dependency packages, exact command, and warnings. Test on every architecture you claim; an x86_64 binary does not establish x86 hybrid/GCC2 compatibility. Package distributable software through HaikuPorts rather than installing arbitrary output into package-managed directories.

Prepare separately to build Haiku itself

Building the operating system is not required for application development. When it is the goal, read the current prerequisite page for the host and target. On Haiku, the official page currently lists these additional requirements for the basic build:

pkgman install cmd:python3 cmd:xorriso devel:libzstd

Haiku uses its own Jam fork; a similarly named generic Jam is not interchangeable. Follow the prerequisite guide to build Jam from the official buildtools repository and ensure that version is first on PATH.

Clone the two official repositories as siblings and record their revisions:

git clone https://review.haiku-os.org/buildtools
git clone https://review.haiku-os.org/haiku
git -C buildtools rev-parse HEAD
git -C haiku rev-parse HEAD

The Gerrit endpoints are Git remotes, so a browser-style HTTP request may show 404 while git clone and git ls-remote are valid. Use the official source guide rather than replacing them because of that web response.

Configure an out-of-tree x86_64 system build

On an x86_64 Haiku host, the official prerequisites note that cross-tools are still needed because the complete build includes objects the default compiler alone cannot produce. From the Haiku checkout:

cd haiku
mkdir generated.x86_64
cd generated.x86_64
../configure --cross-tools-source ../../buildtools --build-cross-tools x86_64
jam -q -j2 @nightly-anyboot

Adjust -j to available memory and CPUs. -q stops at the first failure. Preserve configure and Jam logs; diagnose the first error instead of deleting the generated directory immediately. Never run Jam with sudo: it creates root-owned build state and makes a mistaken raw-device target far more dangerous.

The output is useful only after artifact validation. Compute its checksum, attach it to a disposable VM, boot the image, verify its revision and packages, and exercise the subsystem you changed. Keep firmware mode, VM devices, source hashes, configure command, Jam target, and test results together.

Maintain two reproducible loops

For an application, the loop is edit, warning-clean compile, targeted test, clean build, package, and test installation/removal. For Haiku itself, it is matching official sources, documented prerequisites, out-of-tree configure, named Jam target, bootable image, and VM or hardware verification.

Do not use a successful OS build as proof that an application follows API or packaging policy, and do not use one working native application as proof that the cross-toolchain can build an image. Separating the loops makes failures smaller, reports reproducible, and destructive image testing easier to contain.

Related:

Sources:

Comments