Build official language runtimes and databases from source as position independent executables, from typed Pkl recipes.

Build runtimes and databases from source as PIE, from Pkl recipes master

pie resolves an official release, installs its build dependencies, fetches and verifies the source, builds it, proves the result is a position independent executable, and packages it — driven by a typed Pkl recipe per project. Ten recipes: node, python, bun, php, erlang, postgres, mariadb, redis, mongodb, dragonfly. Four version resolvers (nodejs index, directory autoindex, GitHub releases or tags, php.net) validate the requested version against the project's own release index before anything is downloaded, so a typo fails in seconds rather than an hour into a compile. PIE is applied per project, because what else each build links matters — "cc -shared -pie" is a hard error, so a project that also produces shared objects cannot simply carry -pie in LDFLAGS: LDFLAGS node, redis, bun (executables only) LINKFORSHARED cpython (LDFLAGS is reused for stdlib .so files) EXTRA_LDFLAGS_PROGRAM php LDFLAGS_EX postgres CMAKE_EXE_LINKER_FLAGS mariadb, dragonfly LINKFLAGS mongodb For CPython and PHP the configured value is read back out of the generated Makefile and appended to, never replaced: overwriting LINKFORSHARED would silently cost the interpreter its -export-dynamic and break C extensions. Verification parses ELF directly rather than shelling out to readelf, and requires ELF DYN *and* DT_FLAGS_1=PIE *and* PT_INTERP — a shared library is also ET_DYN, so type alone would wrongly pass one. Artifacts are then unpacked to a fresh prefix and smoke tested there, which is what actually proves they are relocatable rather than pinned to the build path. The CPython recipe additionally builds every third-party library from source as a static -fPIC archive and sets MODULE_BUILDTYPE=static, so the interpreter needs nothing but glibc; the recipe's dynamic_allowlist enforces that rather than assuming it. Recipes are Pkl and the generated YAML is gitignored. The schema catches a misspelled resolver, a source URL that ignores the resolved version, or an artifact name missing the architecture at load time. 51 tests, no network required: the ELF parser runs against synthetic ELF64 images (real PIE, shared library, fixed-address executable, DYN without the PIE bit), version selection is tested through pure functions, and every recipe is linted for unknown template variables and missing verification. None of the recipes has been built end to end yet; bun (exact-pinned LLVM) and mongodb (hours, heavy disk) are the likely first failures in CI.


Author Tsiry Sandratraina Date Commit 907aac0c