hare

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

commit 900234ef10b3d17b84430fee266a5b40249d5173
parent 44e5d7f95a09ec1c5d6b5e97b4f202da0270ac4e
Author: Alexey Yerin <yyp@disroot.org>
Date:   Wed, 17 Nov 2021 20:00:11 +0300

cmd/hare: implement -l

If any libraries are linked, C compiler is used as linker and +libc is
assumed. --gc-sections is also disabled due to interface differences
between cc and ld.

Signed-off-by: Alexey Yerin <yyp@disroot.org>

Diffstat:
Mcmd/hare/plan.ha | 5++++-
Mcmd/hare/schedule.ha | 13+++++++++++--
Mcmd/hare/subcmds.ha | 36++++++++++++++++++++++++++++++------
3 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/cmd/hare/plan.ha b/cmd/hare/plan.ha @@ -42,11 +42,12 @@ type plan = struct { scheduled: []*task, complete: []*task, script: str, + libs: []str, environ: [](str, str), modmap: [64][]modcache, }; -fn mkplan(ctx: *module::context) plan = { +fn mkplan(ctx: *module::context, libs: []str) plan = { const rtdir = match (module::lookup(ctx, ["rt"])) { case err: module::error => fmt::fatal("Error resolving rt: {}", module::strerror(err)); @@ -80,6 +81,7 @@ fn mkplan(ctx: *module::context) plan = { environ = alloc([ (strings::dup("HARECACHE"), strings::dup(ctx.cache)), ]), + libs = libs, ... }; }; @@ -109,6 +111,7 @@ fn plan_finish(plan: *plan) void = { free(plan.environ); free(plan.script); + free(plan.libs); for (let i = 0z; i < len(plan.modmap); i += 1) { free(plan.modmap[i]); diff --git a/cmd/hare/schedule.ha b/cmd/hare/schedule.ha @@ -64,13 +64,19 @@ fn sched_ld(plan: *plan, output: str, depend: *task...) *task = { output = output, depend = mkdepends(depend...), cmd = alloc([ - os::tryenv("LD", "ld"), - "--gc-sections", + // C compiler is used as linker if we -l something + os::tryenv("LD", + if (len(plan.libs) > 0) "cc" else "ld"), "-T", plan.script, "-o", output, ]), }); + // Using --gc-sections will not work when using cc as the linker + if (len(plan.libs) == 0) { + append(task.cmd, "--gc-sections"); + }; + let archives: []str = []; defer free(archives); @@ -82,6 +88,9 @@ fn sched_ld(plan: *plan, output: str, depend: *task...) *task = { }; }; append(task.cmd, archives...); + for (let i = 0z; i < len(plan.libs); i += 1) { + append(task.cmd, strings::concat("-l", plan.libs[i])); + }; append(plan.scheduled, task); return task; }; diff --git a/cmd/hare/subcmds.ha b/cmd/hare/subcmds.ha @@ -87,6 +87,7 @@ fn build(args: []str) void = { let output = ""; let goal = goal::EXE; let defines: []str = []; + let libs: []str = []; for (let i = 0z; i < len(cmd.opts); i += 1) { let opt = cmd.opts[i]; switch (opt.0) { @@ -99,7 +100,7 @@ fn build(args: []str) void = { case 'j' => abort(); // TODO case 'l' => - abort(); // TODO + append(libs, opt.1); case 'o' => output = opt.1; case 't' => @@ -133,10 +134,17 @@ fn build(args: []str) void = { os::exit(1); }; + if (len(libs) > 0) { + append(tags, module::tag { + mode = module::tag_mode::INCLUSIVE, + name = strings::dup("libc"), + }); + }; + const ctx = module::context_init(tags, defines, HAREPATH); defer module::context_finish(&ctx); - const plan = mkplan(&ctx); + const plan = mkplan(&ctx, libs); defer plan_finish(&plan); const ver = match (module::scan(&ctx, input)) { @@ -213,6 +221,7 @@ fn run(args: []str) void = { let verbose = false; let defines: []str = []; + let libs: []str = []; for (let i = 0z; i < len(cmd.opts); i += 1) { let opt = cmd.opts[i]; switch (opt.0) { @@ -223,7 +232,7 @@ fn run(args: []str) void = { case 'j' => abort(); // TODO case 'l' => - abort(); // TODO + append(libs, opt.1); case 't' => abort(); // TODO case 'T' => @@ -254,10 +263,17 @@ fn run(args: []str) void = { runargs = cmd.args[1..]; }; + if (len(libs) > 0) { + append(tags, module::tag { + mode = module::tag_mode::INCLUSIVE, + name = strings::dup("libc"), + }); + }; + const ctx = module::context_init(tags, defines, HAREPATH); defer module::context_finish(&ctx); - const plan = mkplan(&ctx); + const plan = mkplan(&ctx, libs); defer plan_finish(&plan); const ver = match (module::scan(&ctx, input)) { @@ -369,6 +385,7 @@ fn test(args: []str) void = { let output = ""; let verbose = false; let defines: []str = []; + let libs: []str = []; for (let i = 0z; i < len(cmd.opts); i += 1) { const opt = cmd.opts[i]; switch (opt.0) { @@ -379,7 +396,7 @@ fn test(args: []str) void = { case 'j' => abort(); // TODO case 'l' => - abort(); // TODO + append(libs, opt.1); case 't' => abort(); // TODO case 'o' => @@ -412,10 +429,17 @@ fn test(args: []str) void = { runargs = cmd.args[1..]; }; + if (len(libs) > 0) { + append(tags, module::tag { + mode = module::tag_mode::INCLUSIVE, + name = strings::dup("libc"), + }); + }; + const ctx = module::context_init(tags, defines, HAREPATH); defer module::context_finish(&ctx); - const plan = mkplan(&ctx); + const plan = mkplan(&ctx, libs); defer plan_finish(&plan); const ver = match (module::scan(&ctx, input)) {