hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 3e04a9a48507f608097a38873a42ca5b5f1206d2
parent 0bfb86446fe627a941716c1e0f169ed2c69f5ca7
Author: Lorenz (xha) <me@xha.li>
Date:   Sat, 25 Nov 2023 15:18:03 +0100

cmd::hare: introduce platform.ha for adding platform-specific setttings

Signed-off-by: Lorenz (xha) <me@xha.li>

Diffstat:
Mcmd/hare/build.ha | 3++-
Acmd/hare/build/platform.ha | 30++++++++++++++++++++++++++++++
Mcmd/hare/build/types.ha | 4+++-
Mcmd/hare/build/util.ha | 11++++++-----
Mcmd/hare/error.ha | 2++
Mcmd/hare/main.ha | 3+++
6 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/cmd/hare/build.ha b/cmd/hare/build.ha @@ -37,6 +37,8 @@ fn build(name: str, cmd: *getopt::command) (void | error) = { yield ncpu; }, version = build::get_version(os::tryenv("HAREC", "harec"))?, + arch = arch.qbe_name, + platform = build::get_platform(os::sysname())?, ... }; defer build::ctx_finish(&ctx); @@ -133,7 +135,6 @@ fn build(name: str, cmd: *getopt::command) (void | error) = { os::exit(os::status::FAILURE); }; - ctx.arch = arch.qbe_name; ctx.cmds = ["", os::tryenv("HAREC", "harec"), os::tryenv("QBE", "qbe"), diff --git a/cmd/hare/build/platform.ha b/cmd/hare/build/platform.ha @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-3.0-only +// (c) Hare authors <https://harelang.org> + +export type platform = struct { + name: str, + // Do we always need to link with libc? (and use cc instead of ld) + need_libc: bool, + // Additional default flags for this platform. + default_flags: [NSTAGES][]str, +}; + +const platforms: [_]platform = [ + platform { + name = "Linux", + ... + }, + platform { + name = "FreeBSD", + ... + }, +]; + +export fn get_platform(name: str) (*platform | unknown_platform) = { + for (let i = 0z; i < len(platforms); i += 1) { + if (platforms[i].name == name) { + return &platforms[i]; + }; + }; + return name: unknown_platform; +}; diff --git a/cmd/hare/build/types.ha b/cmd/hare/build/types.ha @@ -12,7 +12,8 @@ use strings; export type error = !(exec::error | fs::error | io::error | module::error | path::error); -// a kind of cache file +export type unknown_platform = !str; + export type stage = enum { TD = 0, SSA, @@ -54,6 +55,7 @@ export type output = enum { export type context = struct { ctx: module::context, arch: str, + platform: *platform, goal: stage, defines: []ast::decl_const, libdirs: []str, diff --git a/cmd/hare/build/util.ha b/cmd/hare/build/util.ha @@ -75,7 +75,9 @@ fn get_deps(ctx: *context, t: *task) []str = { }; fn get_flags(ctx: *context, t: *task) ([]str | error) = { - let flags = switch (t.kind) { + let flags: []str = strings::dupall(ctx.platform.default_flags[t.kind]); + + let flags_env = switch (t.kind) { case stage::TD => abort(); case stage::SSA => yield "HARECFLAGS"; @@ -86,13 +88,12 @@ fn get_flags(ctx: *context, t: *task) ([]str | error) = { case stage::BIN => yield if (len(ctx.libs) > 0) "LDFLAGS" else "LDLINKFLAGS"; }; - let flags: []str = match (shlex::split(os::tryenv(flags, ""))) { + match (shlex::split(os::tryenv(flags_env, ""))) { case let s: []str => - yield s; + append(flags, s...); case shlex::syntaxerr => fmt::errorfln("warning: invalid shell syntax in ${}; ignoring", - flags)?; - yield []; + flags_env)?; }; switch (t.kind) { diff --git a/cmd/hare/error.ha b/cmd/hare/error.ha @@ -8,6 +8,7 @@ use io; use os::exec; use path; use strconv; +use cmd::hare::build; type error = !( exec::error | @@ -22,6 +23,7 @@ type error = !( unknown_type | output_failed | invalid_namespace | + build::unknown_platform | ); type unknown_arch = !str; diff --git a/cmd/hare/main.ha b/cmd/hare/main.ha @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only // (c) Hare authors <https://harelang.org> +use cmd::hare::build; use fmt; use fs; use getopt; @@ -115,6 +116,8 @@ export fn main() void = { fmt::fatal("Error:", strconv::strerror(e)); case let e: unknown_arch => fmt::fatalf("Error: Unknown arch: {}", e); + case let e: build::unknown_platform => + fmt::fatalf("Error: Unknown platform: {}", e); case unknown_output => fmt::fatal("Error: Can't guess output in root directory"); case let e: unknown_type =>