feat(compiler): resolve the install root from the binary's location
The engine runtime and the bundled ludic.* packages belong to the toolchain,
not to the project, so the compiler has to know where the toolchain lives. It
derived that from the directory the binary sits in, which is `bin` — so an
in-repo build only found runtime/native/cocoa.ll when the caller set
LUDIC_HOME=., and an installed compiler had no way to find it at all.
ludic_home() derives it properly instead: $LUDIC_HOME when set, else the
binary's directory with a trailing `bin/` stripped, else a $PATH scan for
argv[0] (an install is invoked by bare name, which carries no directory). Both
layouts that exist then have the same shape — ~/.ludic/{bin,runtime,packages}
and a repo checkout — so the same rule serves both and LUDIC_HOME becomes an
override rather than a requirement.
`import "ludic.core/…"` also falls back to $LUDIC_HOME/packages, after the
project's own ludic_modules/, so a project that has not fetched its own copy
gets the packages that shipped with the toolchain instead of a symlink farm.
The `ludic` multi-call name is dropped from the compiler: that name now belongs
to the CLI, and --run is the flag it drives.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
7e07573026
commit
005cc39394
4 changed files with 20115 additions and 19835 deletions
|
|
@ -8,11 +8,12 @@
|
|||
# ludicc app.ludic -o bin/app # native binary (windowed if a game)
|
||||
# ludicc app.ludic -o bin/app --headless # force headless
|
||||
# ludicc app.ludic --emit-llvm -o app.ll # stop at the IR
|
||||
# ludic app.ludic # compile to a temp binary and run it
|
||||
# ludicc app.ludic --run # compile to a temp binary and run it
|
||||
#
|
||||
# The multi-call twist: when argv[0] is "ludic" it defaults to compile-and-run.
|
||||
# With no -o and no run, IR still goes to stdout — the contract `x reseed` and
|
||||
# `x bootstrap` rely on, so the bootstrap is untouched.
|
||||
# This is the compiler, not the command line a user of the language meets: that
|
||||
# is `ludic` (tools/ludic-cli), which drives this. With no -o and no --run, IR
|
||||
# still goes to stdout — the contract `ludic dev reseed` and `ludic dev
|
||||
# bootstrap` rely on, so the bootstrap is untouched.
|
||||
|
||||
# basename: the part of a path after the last '/'.
|
||||
function base_name(path: pointer) -> pointer {
|
||||
|
|
@ -59,11 +60,10 @@ function chomp(s: pointer) -> pointer {
|
|||
}
|
||||
|
||||
# print "ludic <version>" and exit. The version is read at runtime from the
|
||||
# VERSION file next to LUDIC_HOME (the single source of truth a release bumps),
|
||||
# VERSION file at the install root (the single source of truth a release bumps),
|
||||
# so a version change never requires reseeding the compiler.
|
||||
function show_version() -> void {
|
||||
let home = ensure_slash(getenv_or("LUDIC_HOME", dir_of(arg(0))))
|
||||
let v = read_file(join_path(home, "VERSION"))
|
||||
let v = read_file(join_path(ludic_home(), "VERSION"))
|
||||
if (v == null) { print("ludic (version unknown)") }
|
||||
else { print(`ludic {chomp(v)}`) }
|
||||
exit(0)
|
||||
|
|
@ -79,9 +79,6 @@ entry {
|
|||
var run = false # compile then execute the result
|
||||
g_coverage = false # --coverage: instrument each statement with a per-line hit counter
|
||||
|
||||
# multi-call: invoked as `ludic` -> run mode by default
|
||||
if (base_name(arg(0)) == "ludic") { run = true }
|
||||
|
||||
var ai = 1
|
||||
while ai < arg_count() {
|
||||
let a = arg(ai)
|
||||
|
|
@ -127,7 +124,7 @@ entry {
|
|||
|
||||
# a game gets a window by default; a plain program stays headless. An explicit
|
||||
# flag always wins. The stdout-IR path (no target) also stays headless, which
|
||||
# is what `x reseed` compiles the compiler itself with.
|
||||
# is what `ludic dev reseed` compiles the compiler itself with.
|
||||
let has_target = run or (out != null)
|
||||
if want == 1 { g_windowed = true }
|
||||
else if want == 2 { g_windowed = false }
|
||||
|
|
@ -153,7 +150,7 @@ entry {
|
|||
if not ir_flush(ll) { die("ludicc: cannot write IR\n") }
|
||||
|
||||
let cc = getenv_or("LUDIC_CC", "clang")
|
||||
let home = ensure_slash(getenv_or("LUDIC_HOME", dir_of(arg(0))))
|
||||
let home = ludic_home()
|
||||
|
||||
# clang twice: assemble the IR, then link. A windowed build adds the macOS
|
||||
# platform layer and the Cocoa framework.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue