diff --git a/Build.tar b/Build.tar deleted file mode 100644 index c23a5b0..0000000 Binary files a/Build.tar and /dev/null differ diff --git a/Build.zip b/Build.zip deleted file mode 100644 index d1c319a..0000000 Binary files a/Build.zip and /dev/null differ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..47d1d55 --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +PYTHON := python3 +ARCH_FLAG := $(if $(ARCH),--arch $(ARCH),) +MODE_FLAG := $(if $(DEV),--dev,--release) + +.PHONY: build build-mini build-test build-mini-test clean + +build: + $(PYTHON) build.py build $(ARCH_FLAG) $(MODE_FLAG) + +build-mini: + $(PYTHON) build.py build-mini $(ARCH_FLAG) $(MODE_FLAG) + +build-test: + $(PYTHON) build.py build-test $(ARCH_FLAG) $(MODE_FLAG) + +build-mini-test: + $(PYTHON) build.py build-mini-test $(ARCH_FLAG) $(MODE_FLAG) + +clean: + $(PYTHON) build.py clean diff --git a/README.md b/README.md index c3f64bc..c96f442 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,12 @@ HyperionOS is a modular, hybrid kernel operating system written entirely in Lua. --- +## Building + +See `building.md`. + +--- + ## Features - Functionality is split into kernel modules (`.kmod`) diff --git a/Src/Hyperion-bash/bin/bash b/Src/Hyperion-bash/bin/bash deleted file mode 100644 index 26eee21..0000000 --- a/Src/Hyperion-bash/bin/bash +++ /dev/null @@ -1,295 +0,0 @@ ---:Minify:-- -syscall.open("/dev/tty/TTY1","r") --stdin (Device 0) -syscall.open("/dev/tty/TTY1","w") --stdout (Device 1) -syscall.open("/dev/null","w") --stderr (device 2) - -local success, errorMsg = xpcall(function() - - - -local fs = require("sys.fs") - -syscall.devctl(1,"clear") -syscall.devctl(1,"sfgc",1) -syscall.devctl(1,"spos",1,1) -print("HyperionOS Bash Shell") - -local userhost = (syscall.getUsername() or "Unknown").."@"..(syscall.getHostname() or "Unknown") -local commandHistory = {} -local terminate = false -syscall.setEnviron("SHELL","rtbash") -syscall.setEnviron("PATH","/bin/") -syscall.chdir("/") -local oldWD = "" - -for i = 1, 16 do - syscall.devctl(1,"sbgc",i) - printInline(" "); -end -print("\n") - -syscall.sigcatch(function(sig) - if sig == 1 then - terminate = true - end -end) - -local builtinCmds = {} - -builtinCmds.cd = function(path) - local cwd = syscall.getcwd() - local dirIn = (path or "") - if dirIn == "-" then - if oldWD == "" then - print("bash-cd: No previous working directory set.") - else - print(oldWD) - syscall.chdir(oldWD) - oldWD = cwd - end - return - end - local dirInMod = dirIn - if dirIn:sub(1, 1) ~= "/" then dirInMod = cwd .. "/" .. dirIn end - local parts = {} - for part in dirInMod:gmatch("[^/]+") do - if part == ".." then - if #parts > 0 then table.remove(parts) end - elseif part ~= "." and part ~= "" then - table.insert(parts, part) - end - end - local normDir = "/" .. table.concat(parts, "/") - if normDir:sub(#normDir, #normDir) ~= "/" then normDir = normDir .. "/" end - - if not fs.isDir(normDir) then - print("bash-cd: "..dirIn..": No such directory.") - return - end - oldWD = cwd - syscall.chdir(normDir) -end - - -local function getUserInput() - syscall.devctl(1,"sfgc",3) - printInline(userhost) - syscall.devctl(1,"sfgc",1) - printInline(":") - syscall.devctl(1,"sfgc",10) - printInline(syscall.getcwd()) - syscall.devctl(1,"sfgc",1) - printInline("$ ") - local curOffsetStr = syscall.devctl(1, "gpos") - local curOffsetX = tonumber(curOffsetStr:sub(1, curOffsetStr:find(";")-1)) - local curOffsetY = tonumber(curOffsetStr:sub(curOffsetStr:find(";")+1)) - - local input = "" - local blinkState = false - local cursorPos = 1 - local history = 0 - - while true do - local key=syscall.read(0) - if key then - if key == "\19" then --TODO: REPLACE WITH LEFT ARROW - if cursorPos > 1 then - cursorPos = cursorPos - 1 - end - elseif key == "\20" then --TODO: REPLACE WITH RIGHT ARROW - if cursorPos <= #input then - cursorPos = cursorPos + 1 - end - elseif key == "\17" then --TODO: REPLACE WITH UP ARROW - if history < #commandHistory then - syscall.devctl(1,"spos",curOffsetX,curOffsetY) - printInline((" "):rep(#input + 1)) - history = history + 1 - input = commandHistory[#commandHistory - history + 1] - cursorPos = #input + 1 - end - elseif key == "\18" then --TODO: REPLACE WITH DOWN ARROW - if history > 1 then - syscall.devctl(1,"spos",curOffsetX,curOffsetY) - printInline((" "):rep(#input + 1)) - history = history - 1 - input = commandHistory[#commandHistory - history + 1] - cursorPos = #input + 1 - elseif history == 1 then - syscall.devctl(1,"spos",curOffsetX,curOffsetY) - printInline((" "):rep(#input + 1)) - history = 0 - input = "" - cursorPos = 1 - end - elseif key == "\b" then - if cursorPos > 1 then - syscall.devctl(1,"spos",curOffsetX,curOffsetY) - printInline((" "):rep(#input + 1)) - input = string.sub(input, 1, cursorPos-2)..string.sub(input, cursorPos) - cursorPos = cursorPos - 1 - end - elseif key == "\n" then - syscall.devctl(1,"spos",curOffsetX,curOffsetY) - print(input.." ") - return input - else - input = string.sub(input, 1, cursorPos-1)..key..string.sub(input, cursorPos) - cursorPos = cursorPos + 1 - end - local screenSizeStr = syscall.devctl(1, "size") - local sizeX = tonumber(screenSizeStr:sub(1, screenSizeStr:find(";")-1)) - local sizeY = tonumber(screenSizeStr:sub(screenSizeStr:find(";")+1)) - local totalChars = sizeX * sizeY - local eocCharNum = ((curOffsetY - 1) * sizeX) + curOffsetX + #input - if eocCharNum >= totalChars then - syscall.devctl(1,"spos",sizeX,sizeY) - printInline(" ") - curOffsetY = curOffsetY - 1 - end - end - syscall.devctl(1,"spos",curOffsetX,curOffsetY) - printInline(string.sub(input, 1, cursorPos-1)) - if blinkState then - syscall.devctl(1,"sfgc",16) - syscall.devctl(1,"sbgc",1) - end - if cursorPos > #input then - printInline(" ") - else - printInline(string.sub(input, cursorPos, cursorPos)) - end - syscall.devctl(1,"sfgc",1) - syscall.devctl(1,"sbgc",16) - printInline(string.sub(input, cursorPos+1)) - if cursorPos <= #input then - printInline(" ") - end - local curBlink = ((math.floor(syscall.getUptime() / 500) % 2) == 0) - if curBlink ~= blinkState then - blinkState = curBlink - end - end -end - -local function runCommand(command) - do - local func = load("return " .. command, "@equation", "t", {}) - if func then - local success, result = pcall(func) - if success and type(result) == "number" then - print(result) - return - end - end - end - - terminate = false - local args = string.split(command, " ") - if builtinCmds[args[1]] then - local success, msg = pcall(builtinCmds[args[1]], table.unpack(args, 2)) - if not success then - local errSL = string.sub(msg, string.find(msg, "]") + 2) - syscall.devctl(1,"sfgc",2) - printInline(args[1]..": Program runtime error on line ") - print(string.sub(errSL, 1, string.find(errSL, ":") - 1)) - syscall.devctl(1,"sfgc",1) - print(string.sub(errSL, string.find(errSL, ":") + 1)) - end - return - end - - local cmdPath = "" - if string.find(args[1], "/") then - if fs.exists(args[1]) then - cmdPath = args[1] - end - else - local paths = string.split(syscall.getEnviron("PATH"), ":") - for _, path in pairs(paths) do - if fs.exists(path..args[1]) then - cmdPath = path..args[1] - break - end - end - end - - if cmdPath == "" then - print(args[1]..": Command not found") - return - end - - local progName = string.sub(cmdPath, #cmdPath - string.find(string.reverse(cmdPath), "/") + 2) - - local text = fs.readAllText(cmdPath) - local program, err = load(text, progName) - if not program then - local errSL = string.sub(err, string.find(err, ":") + 1) - syscall.devctl(1,"sfgc",2) - printInline(progName..": Program load error on line ") - print(string.sub(errSL, 1, string.find(errSL, ":") - 1)) - syscall.devctl(1,"sfgc",1) - print(string.sub(errSL, string.find(errSL, ":") + 1)) - return - end - - local proc = syscall.spawn(function(...) - syscall.open("/dev/tty/TTY1","r") - syscall.open("/dev/tty/TTY1","w") - syscall.open("/dev/null","w") - local success, msg = pcall(program, ...) - if not success then - local errSL = string.sub(msg, string.find(msg, ":") + 1) - syscall.devctl(1,"sfgc",2) - printInline(progName..": Program runtime error on line ") - print(string.sub(errSL, 1, string.find(errSL, ":") - 1)) - syscall.devctl(1,"sfgc",1) - print(string.sub(errSL, string.find(errSL, ":") + 1)) - end - end, progName, nil, {table.unpack(args, 2)}) - - while true do - local exited, code = syscall.collect(proc) - if exited then - if code then - print("\nTask exited with code:\n"..tostring(code)) - end - return - end - if terminate then - local success, err = syscall.kill(proc) - if success then - syscall.devctl(1,"sbgc",16) - syscall.devctl(1,"sfgc",2) - print("\nProgram Terminated.") - syscall.devctl(1,"sfgc",1) - end - terminate = false - break - end - sleep(0.05) - end -end - -while true do - local command = getUserInput() - if command ~= "" then - if command ~= commandHistory[#commandHistory] then - table.insert(commandHistory, command) - end - runCommand(command) - end -end - - ---ERROR HANDLING -end, debug.traceback) - -if not success then - syscall.log("Error running shell: "..errorMsg, "ERROR") - syscall.devctl(1,"sfgc",2) - syscall.devctl(1,"sbgc",16) - print() - print("Error running shell: ") - print(errorMsg) -end \ No newline at end of file diff --git a/Src/Hyperion-bash/bin/bashex b/Src/Hyperion-bash/bin/bashex deleted file mode 100644 index 54be23d..0000000 --- a/Src/Hyperion-bash/bin/bashex +++ /dev/null @@ -1,94 +0,0 @@ ---:Minify:-- -syscall.open("/dev/tty/TTY1","r") -syscall.open("/dev/tty/TTY1","w") -syscall.open("/dev/null","r") -syscall.devctl(1,"clear") -syscall.devctl(1,"sfgc",1) -syscall.devctl(1,"spos",1,1) -print("HyperionOS Bash Shell") -local str="" -local stopInput=false -local proc=0 -local fs=require("sys.fs") -local timeout=false -syscall.setEnviron("SHELL","simpleshell") -printInline("> ") -syscall.sigcatch(function(sig) - if sig==1 then - syscall.kill(proc) - print("Terminated") - printInline("> ") - stopInput=false - end -end) - -while true do - if not stopInput then - local input=syscall.read(0) - if input then - if input=="\b" then - if #str>0 then - str=str:sub(1,#str-1) - printInline("\b") - end - elseif input=="\n" then - print("") - stopInput=true - if str == "" then - printInline("> ") - stopInput=false - else - local path=nil - local split=string.split(str, " ") - if fs.exists("/bin/"..split[1]) then - path="/bin/"..split[1] - elseif fs.exists("/bin/"..split[1]..".lua") then - path="/bin/"..split[1]..".lua" - end - if not path then - print("Program not found") - printInline("> ") - stopInput=false - else - local text = fs.readAllText(path) - local program, err = load(text, path) - if not program then - print(err) - printInline("> ") - end - proc = syscall.spawn(function(...) - syscall.open("/dev/tty/TTY1","r") - syscall.open("/dev/tty/TTY1","w") - syscall.open("/dev/null","w") - program(...) - end, path, nil, {table.unpack(split, 2)}) - end - str="" - end - else - str=str..input - printInline(input) - end - timeout=false - else - timeout=true - end - else - local exited, code = syscall.collect(proc) - if exited then - if code then - print("\nTask exited with code:\n"..tostring(code)) - end - printInline("> ") - stopInput=false - end - timeout=true - end - if timeout then - if stopInput then - sleep(.5) - else - sleep(.05) - end - end -end \ No newline at end of file diff --git a/Src/Hyperion-bash/bin/login b/Src/Hyperion-bash/bin/login index 2f4d4a9..9f65a52 100644 --- a/Src/Hyperion-bash/bin/login +++ b/Src/Hyperion-bash/bin/login @@ -1,7 +1,7 @@ --:Minify:-- -syscall.open("/dev/tty/TTY1","r") --stdin (fd 0) -syscall.open("/dev/tty/TTY1","w") --stdout (fd 1) -syscall.open("/dev/null","w") --stderr (fd 2) +syscall.open("/dev/tty/TTY1", "r") --stdin (fd 0) +syscall.open("/dev/tty/TTY1", "w") --stdout (fd 1) +syscall.open("/dev/null", "w") --stderr (fd 2) local fs = require("sys.fs") @@ -78,21 +78,18 @@ local function spawnShell(username, uid, shell, homedir) return false end - -- Spawn a wrapper that loads and runs the shell, reporting any error back - -- via exit code channel so we can display it local errFifo = {} local proc = syscall.spawn(function() syscall.setuid(uid) syscall.chdir(homedir) - syscall.setEnviron("HOME", homedir) - syscall.setEnviron("USER", username) + syscall.setEnviron("HOME", homedir) + syscall.setEnviron("USER", username) syscall.setEnviron("SHELL", shell) - syscall.setEnviron("PATH", "/bin/") + syscall.setEnviron("PATH", "/bin/") local shellFn, loadErr = load(shellText, "@" .. shell) if not shellFn then - -- Report load error via log and a recognizable exit code syscall.log("login: shell load error: " .. tostring(loadErr), "ERROR") syscall.exit(-1) return @@ -103,21 +100,7 @@ local function spawnShell(username, uid, shell, homedir) syscall.log("login: shell runtime error: " .. tostring(runErr), "ERROR") end end, username .. ":shell") - - while true do - local exited, code = syscall.collect(proc) - if exited then - if code then - syscall.devctl(1, "sfgc", 2) - syscall.write(1, "\nShell exited with code: " .. tostring(code) .. "\n") - syscall.write(1, "(Check /var/log/syslog.log for details)\n") - syscall.devctl(1, "sfgc", 1) - sleep(2) - end - return true - end - sleep(0.1) - end + syscall.exit(0) end local function doLogin() @@ -145,7 +128,7 @@ local function doLogin() if ok then local uid = syscall.auth_getuid(username) local pwent = uid and syscall.auth_getpasswd(uid) - local shell = (pwent and pwent.shell) or "/bin/hysh" + local shell = (pwent and pwent.shell) or "/bin/hysh" local homedir = (pwent and pwent.homedir) or "/" syscall.devctl(1, "sfgc", 3) diff --git a/Src/Hyperion-bash/bin/startup/runShell.lua b/Src/Hyperion-bash/bin/startup/runShell.lua deleted file mode 100644 index 67ea5f4..0000000 --- a/Src/Hyperion-bash/bin/startup/runShell.lua +++ /dev/null @@ -1,4 +0,0 @@ -local fs = require("sys.fs") -local bashStr = fs.readAllText("/bin/bash") -local bashFun = load(bashStr) -syscall.spawn(bashFun, "bash") \ No newline at end of file diff --git a/Src/Hyperion-bash/bin/su b/Src/Hyperion-bash/bin/su index 1517c62..70d0044 100644 --- a/Src/Hyperion-bash/bin/su +++ b/Src/Hyperion-bash/bin/su @@ -1,7 +1,6 @@ --:Minify:-- local fs = require("sys.fs") - -local targetUser = ({...})[1] or "root" +local targetUser = ({ ... })[1] or "root" local currentUid = syscall.getuid() local currentUser = syscall.getUsername(currentUid) or tostring(currentUid) @@ -26,7 +25,9 @@ else syscall.write(1, "\n") break elseif ch == "\b" then - if #pw > 0 then pw = pw:sub(1, -2); syscall.write(1, "\b \b") end + if #pw > 0 then + pw = pw:sub(1, -2); syscall.write(1, "\b \b") + end else pw = pw .. ch syscall.write(1, "*") @@ -46,13 +47,13 @@ if currentUid == 0 then syscall.setuid(targetUid) end -local pwent = syscall.auth_getpasswd(targetUid) -local shell = (pwent and pwent.shell) or "/bin/hysh" +local pwent = syscall.auth_getpasswd(targetUid) +local shell = (pwent and pwent.shell) or "/bin/hysh" local homedir = (pwent and pwent.homedir) or "/" syscall.chdir(homedir) -syscall.setEnviron("HOME", homedir) -syscall.setEnviron("USER", targetUser) +syscall.setEnviron("HOME", homedir) +syscall.setEnviron("USER", targetUser) syscall.setEnviron("SHELL", shell) local shellText = fs.readAllText(shell) @@ -63,10 +64,17 @@ if not shellText then end local shellFn, loadErr = load(shellText, "@" .. shell) + if not shellFn then print("su: cannot load shell: " .. tostring(loadErr)) syscall.exit(1) return end -shellFn() +local success, err = syscall.kill(syscall.getppid()) +if success then + syscall.spawn(shellFn, targetUser .. ":" .. shell, syscall.getEnviron()) + syscall.exit(0) +else + print("su: "..err) +end \ No newline at end of file diff --git a/Src/Hyperion-core/bin/login b/Src/Hyperion-core/bin/login deleted file mode 100644 index e69de29..0000000 diff --git a/Src/Hyperion-core/bin/su b/Src/Hyperion-core/bin/su deleted file mode 100644 index e69de29..0000000 diff --git a/Src/Hyperion-core/bin/sudo b/Src/Hyperion-core/bin/sudo deleted file mode 100644 index e69de29..0000000 diff --git a/Src/Hyperion-kernel/etc/passwd b/Src/Hyperion-kernel/etc/passwd index 2d4ba4c..434ccc5 100644 --- a/Src/Hyperion-kernel/etc/passwd +++ b/Src/Hyperion-kernel/etc/passwd @@ -1 +1 @@ -0:0:root:/root:/bin/bash \ No newline at end of file +0:0:root:/root:/bin/hysh \ No newline at end of file diff --git a/Src/Hyperion-kernel/lib/modules/Hyperion/45_hypervisor.kmod b/Src/Hyperion-kernel/lib/modules/Hyperion/45_hypervisor.kmod index a976753..e78f8ff 100644 --- a/Src/Hyperion-kernel/lib/modules/Hyperion/45_hypervisor.kmod +++ b/Src/Hyperion-kernel/lib/modules/Hyperion/45_hypervisor.kmod @@ -129,9 +129,6 @@ function sys.kill(pid) if not tasks[tostring(pid)] then return false, "Task does not exist" - elseif not isEqualToAny(tasks[tostring(pid)].pid, table.unpack(children)) and kernel.uid ~= 0 then - return false, "You do not own this task" - elseif tasks[tostring(pid)].status == "Z" then return false, "Task is already dead" @@ -148,9 +145,6 @@ function sys.stop(pid) if not tasks[tostring(pid)] then return false, "Task does not exist" - elseif not isEqualToAny(tasks[tostring(pid)].pid, table.unpack(children)) and kernel.uid ~= 0 then - return false, "You do not own this task" - elseif tasks[tostring(pid)].status ~= "R" then return false, "Cannot stop non running task" @@ -166,9 +160,6 @@ function sys.continue(pid) if not tasks[tostring(pid)] then return false, "Task does not exist" - elseif not isEqualToAny(tasks[tostring(pid)].pid, table.unpack(children)) and kernel.uid ~= 0 then - return false, "You do not own this task" - elseif tasks[tostring(pid)].status ~= "T" then return false, "Task is not stopped" diff --git a/build.py b/build.py new file mode 100644 index 0000000..e865e70 --- /dev/null +++ b/build.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python3 +""" +Usage: + python build.py [--arch cct|oc] [--release|--dev] + +Targets: + build + build-mini + build-test + build-mini-test + clean + +Arch flags: + --arch cct + --arch oc + +Release flags: + --release + --dev +""" + +import sys +import shutil +import argparse +import subprocess +from pathlib import Path + +PROJECT_ROOT = Path(__file__).resolve().parent +SRC_ROOT = PROJECT_ROOT / "Src" +TEST_ROOT = PROJECT_ROOT / "Test" +BUILD_ROOT = PROJECT_ROOT / "Build" + +ARCH_BOOT_DIR = { + "cct": Path("boot") / "cct", + "oc": Path("boot") / "oc", +} + + +def clean(): + if BUILD_ROOT.exists(): + print(f"Removing {BUILD_ROOT} ...") + shutil.rmtree(BUILD_ROOT) + else: + print("Nothing to clean.") + + +def process_root(src_root: Path, out_root: Path, minify: bool): + print(f"Building from {src_root}") + print(f"Output to {out_root}") + print() + + for pkg_dir in sorted(src_root.iterdir()): + if not pkg_dir.is_dir(): + continue + + print(f"== Package: {pkg_dir.name} ==") + + for src in sorted(pkg_dir.rglob("*")): + if not src.is_file(): + continue + + rel = src.relative_to(pkg_dir) + dst = out_root / rel + dst.parent.mkdir(parents=True, exist_ok=True) + + print(f" Processing: {src.relative_to(src_root)}") + + if minify and has_minify_header(src): + print(" > Minifying") + result = subprocess.run( + ["luamin", "-f", str(src)], + capture_output=True, text=True + ) + if result.returncode != 0: + print(f" ! luamin failed: {result.stderr.strip()}", file=sys.stderr) + sys.exit(1) + dst.write_text(result.stdout, encoding="utf-8") + else: + print(" > Copying") + shutil.copy2(src, dst) + + print() + + +def install_bootloader(arch: str, release: bool): + boot_dir = BUILD_ROOT / "$" / ARCH_BOOT_DIR[arch] + boot_lua = boot_dir / "boot.lua" + eeprom = boot_dir / "eeprom" + + for src in (boot_lua, eeprom): + if not src.exists(): + print(f" ! Bootloader file not found: {src}", file=sys.stderr) + sys.exit(1) + + print(f" Installing: boot.lua -> Build/boot.lua") + shutil.copy2(boot_lua, BUILD_ROOT / "boot.lua") + + eeprom_dst_name = "startup.lua" if release else "eeprom" + print(f" Installing: eeprom -> Build/{eeprom_dst_name}") + shutil.copy2(eeprom, BUILD_ROOT / eeprom_dst_name) + + +def has_minify_header(path: Path) -> bool: + try: + with path.open("r", encoding="utf-8", errors="ignore") as f: + for _ in range(3): + if "--:Minify:--" in f.readline(): + return True + except OSError: + pass + return False + + +def run_build(minify: bool, include_test: bool, arch: str | None, release: bool): + clean() + BUILD_ROOT.mkdir() + + out_root = BUILD_ROOT / "$" if arch else BUILD_ROOT + + process_root(SRC_ROOT, out_root, minify) + if include_test: + process_root(TEST_ROOT, out_root, minify) + + if arch: + print("Installing bootloader files ...") + install_bootloader(arch, release) + print() + + +def main(): + parser = argparse.ArgumentParser(description="HyperionOS build script") + parser.add_argument("target", choices=["build", "build-mini", "build-test", "build-mini-test", "clean"]) + parser.add_argument("--arch", choices=["cct", "oc"], default=None, + help="Target architecture (cct or oc)") + parser.add_argument("--release", dest="release", action="store_true", default=True, + help="Release build: eeprom placed as startup.lua (default)") + parser.add_argument("--dev", dest="release", action="store_false", + help="Dev build: boot.lua and eeprom copied unchanged") + + args = parser.parse_args() + + if args.target == "clean": + clean() + return + + minify = "mini" in args.target + include_test = "test" in args.target + + run_build(minify=minify, include_test=include_test, arch=args.arch, release=args.release) + print("Build complete.") + + +if __name__ == "__main__": + main() diff --git a/building.md b/building.md new file mode 100644 index 0000000..7219892 --- /dev/null +++ b/building.md @@ -0,0 +1,68 @@ +## Building + +### Linux / `make`-compatible systems + +Run: + +```bash +make build +``` + +Optional variables: + +* **`ARCH=`** + + * `cct` Build using the cct bootloader + * `oc` Build using the oc bootloader + +* **`DEV=1`** + + * Builds in development mode + * Bootloader does not start automatically on system startup + +If `DEV` is not specified: + +* Default is release mode +* Bootloader starts automatically on system startup + +**Examples** + +```bash +make build ARCH=cct +make build ARCH=oc DEV=1 +``` + +--- + +### Windows / Any system with Python 3.7+ + +Run: + +```bash +python build.py build +``` + +Optional arguments: + +* **`--arch {cct|oc}`** + Select bootloader + + * `cct` Use the cct bootloader + * `oc` Use the oc bootloader + +* **`--dev`** + + * Development mode + * Bootloader does not start automatically + +* **`--release`** (default) + + * Release mode + * Bootloader starts automatically + +**Examples** + +```bash +python build.py build --arch cct +python build.py build --arch oc --dev +``` diff --git a/scripts/build.ps1 b/scripts/build.ps1 deleted file mode 100644 index c2b45c8..0000000 --- a/scripts/build.ps1 +++ /dev/null @@ -1,44 +0,0 @@ -$testRoot = Join-Path $PSScriptRoot "..\src" -$buildRoot = Join-Path $PSScriptRoot "..\Build" - -$testRoot = Resolve-Path $testRoot - -# Clean Build folder -if (Test-Path $buildRoot) { - Remove-Item -LiteralPath $buildRoot -Recurse -Force -ErrorAction SilentlyContinue -} - -New-Item -ItemType Directory -Path $buildRoot | Out-Null - -Write-Host "Building from $testRoot" -Write-Host "Output to $buildRoot" -Write-Host "" - -# Each top-level folder in test/ -Get-ChildItem -Path $testRoot -Directory | ForEach-Object { - - $folderRoot = $_.FullName - Write-Host "== Package: $($_.Name) ==" - - # Walk files inside this folder - Get-ChildItem -Path $folderRoot -File -Recurse | ForEach-Object { - - $src = $_.FullName - $rel = $src.Substring($folderRoot.Length).TrimStart("\") - $dst = Join-Path $buildRoot $rel - $dstDir = Split-Path $dst - - if (-not (Test-Path $dstDir)) { - New-Item -ItemType Directory -Path $dstDir -Force | Out-Null - } - - Write-Host "Processing: $rel" - Write-Host " > Copying" - Copy-Item -LiteralPath $src -Destination $dst -Force - - } - - Write-Host "" -} - -Write-Host "Build complete." diff --git a/scripts/build.sh b/scripts/build.sh deleted file mode 100644 index 51c66cd..0000000 --- a/scripts/build.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash -set -e - -SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -TEST_ROOT="$(realpath "$SCRIPT_ROOT/../src")" -BUILD_ROOT="$SCRIPT_ROOT/../Build" - -if [[ -d "$BUILD_ROOT" ]]; then - rm -rf "$BUILD_ROOT" -fi -mkdir -p "$BUILD_ROOT" - -echo "Building from $TEST_ROOT" -echo "Output to $BUILD_ROOT" -echo "" - -for folder in "$TEST_ROOT"/*/; do - [[ -d "$folder" ]] || continue - - folder_root="$folder" - package_name="$(basename "$folder_root")" - echo "== Package: $package_name ==" - - find "$folder_root" -type f | while IFS= read -r src; do - rel="${src#$folder_root}" - dst="$BUILD_ROOT/$rel" - dst_dir="$(dirname "$dst")" - - if [[ ! -d "$dst_dir" ]]; then - mkdir -p "$dst_dir" - fi - - echo "Processing: $rel" - echo " > Copying" - cp -f "$src" "$dst" - done - - echo "" -done - -echo "Build complete." diff --git a/scripts/buildMini.ps1 b/scripts/buildMini.ps1 deleted file mode 100644 index 7e96e7d..0000000 --- a/scripts/buildMini.ps1 +++ /dev/null @@ -1,57 +0,0 @@ -$testRoot = Join-Path $PSScriptRoot "..\src" -$buildRoot = Join-Path $PSScriptRoot "..\Build" - -$testRoot = Resolve-Path $testRoot - -# Clean Build folder -if (Test-Path $buildRoot) { - Remove-Item -LiteralPath $buildRoot -Recurse -Force -ErrorAction SilentlyContinue -} - -New-Item -ItemType Directory -Path $buildRoot | Out-Null - -Write-Host "Building from $testRoot" -Write-Host "Output to $buildRoot" -Write-Host "" - -# Each top-level folder in test/ -Get-ChildItem -Path $testRoot -Directory | ForEach-Object { - - $folderRoot = $_.FullName - Write-Host "== Package: $($_.Name) ==" - - # Walk files inside this folder - Get-ChildItem -Path $folderRoot -File -Recurse | ForEach-Object { - - $src = $_.FullName - $rel = $src.Substring($folderRoot.Length).TrimStart("\") - $dst = Join-Path $buildRoot $rel - $dstDir = Split-Path $dst - - if (-not (Test-Path $dstDir)) { - New-Item -ItemType Directory -Path $dstDir -Force | Out-Null - } - - Write-Host "Processing: $rel" - - # Read first 3 lines - $header = Get-Content $src -TotalCount 3 -ErrorAction SilentlyContinue - - if ($header -match "--:Minify:--") { - Write-Host " > Minifying" - $content = luamin -f "$src" - - # UTF8 encoding without BOM because it breaks lua - $utf8NoBOM = New-Object System.Text.UTF8Encoding($false) - [System.IO.File]::WriteAllText($dst, $content, $utf8NoBOM) - } - else { - Write-Host " > Copying" - Copy-Item -LiteralPath $src -Destination $dst -Force - } - } - - Write-Host "" -} - -Write-Host "Build complete." diff --git a/scripts/buildMini.sh b/scripts/buildMini.sh deleted file mode 100644 index 37e40b3..0000000 --- a/scripts/buildMini.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -set -e - -SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -TEST_ROOT="$(realpath "$SCRIPT_ROOT/../src")" -BUILD_ROOT="$SCRIPT_ROOT/../Build" - -if [[ -d "$BUILD_ROOT" ]]; then - rm -rf "$BUILD_ROOT" -fi -mkdir -p "$BUILD_ROOT" - -echo "Building from $TEST_ROOT" -echo "Output to $BUILD_ROOT" -echo "" - -for folder in "$TEST_ROOT"/*/; do - [[ -d "$folder" ]] || continue - - folder_root="$folder" - package_name="$(basename "$folder_root")" - echo "== Package: $package_name ==" - - find "$folder_root" -type f | while IFS= read -r src; do - rel="${src#$folder_root}" - dst="$BUILD_ROOT/$rel" - dst_dir="$(dirname "$dst")" - - if [[ ! -d "$dst_dir" ]]; then - mkdir -p "$dst_dir" - fi - - echo "Processing: $rel" - - header="$(head -n 3 "$src" 2>/dev/null || true)" - - if echo "$header" | grep -q -- "--:Minify:--"; then - echo " > Minifying" - luamin -f "$src" > "$dst" - else - echo " > Copying" - cp -f "$src" "$dst" - fi - done - - echo "" -done - -echo "Build complete." diff --git a/scripts/buildMiniTest.ps1 b/scripts/buildMiniTest.ps1 deleted file mode 100644 index 61b7929..0000000 --- a/scripts/buildMiniTest.ps1 +++ /dev/null @@ -1,108 +0,0 @@ -$testRoot = Join-Path $PSScriptRoot "..\src" -$buildRoot = Join-Path $PSScriptRoot "..\Build" - -$testRoot = Resolve-Path $testRoot - -# Clean Build folder -if (Test-Path $buildRoot) { - Remove-Item -LiteralPath $buildRoot -Recurse -Force -ErrorAction SilentlyContinue -} - -New-Item -ItemType Directory -Path $buildRoot | Out-Null - -Write-Host "Building from $testRoot" -Write-Host "Output to $buildRoot" -Write-Host "" - -# Each top-level folder in test/ -Get-ChildItem -Path $testRoot -Directory | ForEach-Object { - - $folderRoot = $_.FullName - Write-Host "== Package: $($_.Name) ==" - - # Walk files inside this folder - Get-ChildItem -Path $folderRoot -File -Recurse | ForEach-Object { - - $src = $_.FullName - $rel = $src.Substring($folderRoot.Length).TrimStart("\") - $dst = Join-Path $buildRoot $rel - $dstDir = Split-Path $dst - - if (-not (Test-Path $dstDir)) { - New-Item -ItemType Directory -Path $dstDir -Force | Out-Null - } - - Write-Host "Processing: $rel" - - # Read first 3 lines - $header = Get-Content $src -TotalCount 3 -ErrorAction SilentlyContinue - - if ($header -match "--:Minify:--") { - Write-Host " > Minifying" - $content = luamin -f "$src" - - # UTF8 encoding without BOM because it breaks lua - $utf8NoBOM = New-Object System.Text.UTF8Encoding($false) - [System.IO.File]::WriteAllText($dst, $content, $utf8NoBOM) - } - else { - Write-Host " > Copying" - Copy-Item -LiteralPath $src -Destination $dst -Force - } - } - - Write-Host "" -} - -Write-Host "Build complete." - -$testRoot = Join-Path $PSScriptRoot "..\test" -$buildRoot = Join-Path $PSScriptRoot "..\Build" - -$testRoot = Resolve-Path $testRoot - -Write-Host "Building from $testRoot" -Write-Host "Output to $buildRoot" -Write-Host "" - -# Each top-level folder in test/ -Get-ChildItem -Path $testRoot -Directory | ForEach-Object { - - $folderRoot = $_.FullName - Write-Host "== Package: $($_.Name) ==" - - # Walk files inside this folder - Get-ChildItem -Path $folderRoot -File -Recurse | ForEach-Object { - - $src = $_.FullName - $rel = $src.Substring($folderRoot.Length).TrimStart("\") - $dst = Join-Path $buildRoot $rel - $dstDir = Split-Path $dst - - if (-not (Test-Path $dstDir)) { - New-Item -ItemType Directory -Path $dstDir -Force | Out-Null - } - - Write-Host "Processing: $rel" - - # Read first 3 lines - $header = Get-Content $src -TotalCount 3 -ErrorAction SilentlyContinue - - if ($header -match "--:Minify:--") { - Write-Host " > Minifying" - $content = luamin -f "$src" - - # UTF8 encoding without BOM because it breaks lua - $utf8NoBOM = New-Object System.Text.UTF8Encoding($false) - [System.IO.File]::WriteAllText($dst, $content, $utf8NoBOM) - } - else { - Write-Host " > Copying" - Copy-Item -LiteralPath $src -Destination $dst -Force - } - } - - Write-Host "" -} - -Write-Host "Build complete." diff --git a/scripts/buildMiniTest.sh b/scripts/buildMiniTest.sh deleted file mode 100644 index 4033d97..0000000 --- a/scripts/buildMiniTest.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash -set -e - -SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -build_from_root() { - local TEST_ROOT - TEST_ROOT="$(realpath "$1")" - local BUILD_ROOT="$SCRIPT_ROOT/../Build" - - if [[ -d "$BUILD_ROOT" ]]; then - rm -rf "$BUILD_ROOT" - fi - mkdir -p "$BUILD_ROOT" - - echo "Building from $TEST_ROOT" - echo "Output to $BUILD_ROOT" - echo "" - - for folder in "$TEST_ROOT"/*/; do - [[ -d "$folder" ]] || continue - - local package_name - package_name="$(basename "$folder")" - echo "== Package: $package_name ==" - - find "$folder" -type f | while IFS= read -r src; do - rel="${src#$folder}" - dst="$BUILD_ROOT/$rel" - dst_dir="$(dirname "$dst")" - - mkdir -p "$dst_dir" - - echo "Processing: $rel" - - header="$(head -n 3 "$src" 2>/dev/null || true)" - - if echo "$header" | grep -q -- "--:Minify:--"; then - echo " > Minifying" - luamin -f "$src" > "$dst" - else - echo " > Copying" - cp -f "$src" "$dst" - fi - done - - echo "" - done - - echo "Build complete." -} - -build_from_root "$SCRIPT_ROOT/../src" - -build_from_root "$SCRIPT_ROOT/../test" diff --git a/scripts/buildTest.ps1 b/scripts/buildTest.ps1 deleted file mode 100644 index 21dd6f4..0000000 --- a/scripts/buildTest.ps1 +++ /dev/null @@ -1,83 +0,0 @@ -$testRoot = Join-Path $PSScriptRoot "..\src" -$buildRoot = Join-Path $PSScriptRoot "..\Build" - -$testRoot = Resolve-Path $testRoot - -# Clean Build folder -if (Test-Path $buildRoot) { - Remove-Item -LiteralPath $buildRoot -Recurse -Force -ErrorAction SilentlyContinue -} - -New-Item -ItemType Directory -Path $buildRoot | Out-Null - -Write-Host "Building from $testRoot" -Write-Host "Output to $buildRoot" -Write-Host "" - -# Each top-level folder in test/ -Get-ChildItem -Path $testRoot -Directory | ForEach-Object { - - $folderRoot = $_.FullName - Write-Host "== Package: $($_.Name) ==" - - # Walk files inside this folder - Get-ChildItem -Path $folderRoot -File -Recurse | ForEach-Object { - - $src = $_.FullName - $rel = $src.Substring($folderRoot.Length).TrimStart("\") - $dst = Join-Path $buildRoot $rel - $dstDir = Split-Path $dst - - if (-not (Test-Path $dstDir)) { - New-Item -ItemType Directory -Path $dstDir -Force | Out-Null - } - - Write-Host "Processing: $rel" - Write-Host " > Copying" - Copy-Item -LiteralPath $src -Destination $dst -Force - - } - - Write-Host "" -} - -Write-Host "Build complete." - - -$testRoot = Join-Path $PSScriptRoot "..\test" -$buildRoot = Join-Path $PSScriptRoot "..\Build" - -$testRoot = Resolve-Path $testRoot - -Write-Host "Building from $testRoot" -Write-Host "Output to $buildRoot" -Write-Host "" - -# Each top-level folder in test/ -Get-ChildItem -Path $testRoot -Directory | ForEach-Object { - - $folderRoot = $_.FullName - Write-Host "== Package: $($_.Name) ==" - - # Walk files inside this folder - Get-ChildItem -Path $folderRoot -File -Recurse | ForEach-Object { - - $src = $_.FullName - $rel = $src.Substring($folderRoot.Length).TrimStart("\") - $dst = Join-Path $buildRoot $rel - $dstDir = Split-Path $dst - - if (-not (Test-Path $dstDir)) { - New-Item -ItemType Directory -Path $dstDir -Force | Out-Null - } - - Write-Host "Processing: $rel" - - Write-Host " > Copying" - Copy-Item -LiteralPath $src -Destination $dst -Force - } - - Write-Host "" -} - -Write-Host "Build complete." diff --git a/scripts/buildTest.sh b/scripts/buildTest.sh deleted file mode 100644 index c79351c..0000000 --- a/scripts/buildTest.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env bash -set -e - -SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -TEST_ROOT="$(realpath "$SCRIPT_ROOT/../src")" -BUILD_ROOT="$(realpath "$SCRIPT_ROOT/../Build" 2>/dev/null || echo "$SCRIPT_ROOT/../Build")" - -if [[ -d "$BUILD_ROOT" ]]; then - rm -rf "$BUILD_ROOT" -fi -mkdir -p "$BUILD_ROOT" - -echo "Building from $TEST_ROOT" -echo "Output to $BUILD_ROOT" -echo "" - -for folder in "$TEST_ROOT"/*/; do - [[ -d "$folder" ]] || continue - - package_name="$(basename "$folder")" - echo "== Package: $package_name ==" - - find "$folder" -type f | while read -r src; do - rel="${src#$folder}" - dst="$BUILD_ROOT/$rel" - dst_dir="$(dirname "$dst")" - - mkdir -p "$dst_dir" - - echo "Processing: $rel" - echo " > Copying" - cp -f "$src" "$dst" - done - - echo "" -done - -echo "Build complete." - -TEST_ROOT="$(realpath "$SCRIPT_ROOT/../test")" -BUILD_ROOT="$(realpath "$SCRIPT_ROOT/../Build" 2>/dev/null || echo "$SCRIPT_ROOT/../Build")" - -echo "Building from $TEST_ROOT" -echo "Output to $BUILD_ROOT" -echo "" - -for folder in "$TEST_ROOT"/*/; do - [[ -d "$folder" ]] || continue - - package_name="$(basename "$folder")" - echo "== Package: $package_name ==" - - find "$folder" -type f | while read -r src; do - rel="${src#$folder}" - dst="$BUILD_ROOT/$rel" - dst_dir="$(dirname "$dst")" - - mkdir -p "$dst_dir" - - echo "Processing: $rel" - echo " > Copying" - cp -f "$src" "$dst" - done - - echo "" -done - -echo "Build complete."