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:
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)) {