feat: ship native dev tools and target sysroot at 0:/usr

The devkit target in programs/GNUmakefile stages the native binutils
(as, ld, ar, nm, objcopy, objdump, readelf, ranlib, strip, size,
strings, addr2line, c++filt, elfedit as *.elf) into the image at
0:/usr/bin, plus a target-side sysroot: libc headers, montauk/ and
Api/ SDK headers and the freestanding C++ set at 0:/usr/include, and
libc.a + crt1/crti/crtn objects (with empty libm/libstdc++ stand-ins)
at 0:/usr/lib. ld's ldscripts ship under 0:/usr/x86_64-montauk.

The /usr prefix matches the binutils configure prefix, and the kernel
already resolves driveless absolute paths against the cwd drive, so
compiled-in /usr/lib search paths work natively on drive 0.

The shell resolves commands from 0:/usr/bin (after 0:/os) and tab
completion lists it. When toolchain/native/ has not been built, the
devkit step skips cleanly and the image builds as before.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
2026-07-14 20:53:57 +02:00
co-authored by Claude Fable 5
parent bd9158fdcc
commit fe040f8fea
5 changed files with 77 additions and 7 deletions
+1 -1
View File
@@ -12,4 +12,4 @@
#pragma once
#define MONTAUK_BUILD_NUMBER 10
#define MONTAUK_BUILD_NUMBER 11
+30 -1
View File
@@ -91,7 +91,7 @@ WPDST := $(patsubst $(WPDIR)/%,$(BINDIR)/os/wallpapers/%,$(WPSRC))
.PHONY: all clean 2048 doom fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network terminal klog procmgr powermgr calculator charmap login desktop shell rpgdemo paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs icons fonts configs bearssl libc tls libjpeg libjpegwrite install-apps libloader libs crashpad check-syscalls gen-syscalls
all: bearssl libc libjpeg libjpegwrite tls libloader libs $(TARGETS) fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network terminal klog procmgr powermgr calculator charmap 2048 doom rpgdemo paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs login desktop shell icons fonts install-apps crashpad $(MANDST) $(WWWDST) $(CA_CERTS) $(CONFIGDST) $(FWDST) $(LICDST) $(WPDST)
all: bearssl libc libjpeg libjpegwrite tls libloader libs devkit $(TARGETS) fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network terminal klog procmgr powermgr calculator charmap 2048 doom rpgdemo paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs login desktop shell icons fonts install-apps crashpad $(MANDST) $(WWWDST) $(CA_CERTS) $(CONFIGDST) $(FWDST) $(LICDST) $(WPDST)
# Build BearSSL static library (cross-compiled for freestanding x86_64).
BEARSSL_INCLUDES := -isystem $(shell cd .. && pwd)/kernel/freestnd-c-hdrs/x86_64/include -isystem $(abspath include/libc)
@@ -376,6 +376,35 @@ $(BINDIR)/os/%.elf: src/%/main.cpp link.ld GNUmakefile
$(CXX) $(CXXFLAGS) -c src/$*/main.cpp -o obj/$*/main.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) obj/$*/main.o lib/libc/liblibc.a -o $@
# ============================================================================
# Native development kit: binutils built for MontaukOS plus a target
# sysroot (headers, libc.a, crt objects) under 0:/usr. Skipped when the
# native tools have not been built; see toolchain/README.md.
# ============================================================================
NATIVE_BIN := ../toolchain/native/usr/bin
DEVKIT_TOOLS := as ld ar nm objcopy objdump readelf ranlib strip size strings addr2line c++filt elfedit
.PHONY: devkit
devkit: libc
ifneq ($(wildcard $(NATIVE_BIN)/as),)
rm -rf $(BINDIR)/usr
mkdir -p $(BINDIR)/usr/bin $(BINDIR)/usr/lib $(BINDIR)/usr/include
for t in $(DEVKIT_TOOLS); do \
cp $(NATIVE_BIN)/$$t $(BINDIR)/usr/bin/$$t.elf || exit 1; \
done
cp -r ../toolchain/native/usr/x86_64-montauk $(BINDIR)/usr/x86_64-montauk
cp -r include/libc/. $(BINDIR)/usr/include/
cp -r include/montauk $(BINDIR)/usr/include/montauk
cp -r include/Api $(BINDIR)/usr/include/Api
cp -r ../kernel/freestnd-cxx-hdrs/x86_64/include/. $(BINDIR)/usr/include/
cp lib/libc/liblibc.a $(BINDIR)/usr/lib/libc.a
cp lib/libc/crt1.o lib/libc/crti.o lib/libc/crtn.o $(BINDIR)/usr/lib/
ar rcs $(BINDIR)/usr/lib/libm.a
ar rcs $(BINDIR)/usr/lib/libstdc++.a
else
@echo "devkit: toolchain/native/ not built; skipping native dev tools"
endif
clean:
rm -rf $(BINDIR) obj
$(MAKE) -C lib/bearssl clean
+8 -2
View File
@@ -84,13 +84,19 @@ int exec_external(const char* cmd, const char* args) {
scat(path, name, sizeof(path));
if (try_exec(path, finalArgs)) return 0;
// 5. Try 0:/games/<cmd>.elf
// 5. Try 0:/usr/bin/<cmd>.elf (native dev tools: as, ld, ar, ...)
scopy(path, "0:/usr/bin/", sizeof(path));
scat(path, name, sizeof(path));
scat(path, ".elf", sizeof(path));
if (try_exec(path, finalArgs)) return 0;
// 6. Try 0:/games/<cmd>.elf
scopy(path, "0:/games/", sizeof(path));
scat(path, name, sizeof(path));
scat(path, ".elf", sizeof(path));
if (try_exec(path, finalArgs)) return 0;
// 6. If on a non-zero drive, also try drive root
// 7. If on a non-zero drive, also try drive root
if (current_drive != 0) {
build_drive_path(current_drive, name, path, sizeof(path));
if (try_exec(path, finalArgs)) return 0;
+30
View File
@@ -148,6 +148,36 @@ int get_completions( // returns no. of results
}
}
// ---- Native dev tools (0:/usr/bin/*.elf) ----
const char* usr_names[RD_MAX] = { };
int un = montauk::readdir("0:/usr/bin", usr_names, RD_MAX);
for (int i = 0; i < un; i++) {
/* Entries come back as "usr/bin/as.elf"; strip to the last
slash, not the first. */
int inc = 0;
for (int j = 0; usr_names[i][j]; j++) {
if (usr_names[i][j] == '/')
inc = j + 1;
}
if (montauk::starts_with(usr_names[i] + inc, (const char*)string)) {
if (r >= arrayMax)
break;
if (!is_executable(usr_names[i]))
continue;
char* p = (char *)usr_names[i] + inc;
strip_elf_extension(p);
array[r] = (char *)p;
r++;
}
}
// ---- Shell builtins ----
size_t builtins_count = sizeof(shell_builtins) / sizeof(const char*);
+8 -3
View File
@@ -91,6 +91,11 @@ Notes:
the tools themselves never spawn, and real process plumbing is the
posix_spawn milestone that needs kernel support (exit codes in
SYS_WAITPID, fd redirection wiring).
- The staged tree in toolchain/native/ is not yet integrated into the
OS image; that needs a target-side sysroot layout decision (where
headers, libc.a and crt objects live on 0:/).
- The `devkit` target in programs/GNUmakefile ships the staged tools
into the OS image at 0:/usr/bin (as.elf, ld.elf, ar.elf, ...) with a
target-side sysroot at 0:/usr/include + 0:/usr/lib (libc.a, crt
objects, empty libm/libstdc++). The kernel resolves driveless
absolute paths ("/usr/lib") against the cwd drive, so the binutils
--prefix=/usr layout works natively. The shell searches 0:/usr/bin
and tab-completes it. If toolchain/native/ has not been built the
devkit step is skipped and the image builds without it.