ref: 378bae2d4f790c8ed89e3c0f502be7d728791bec
parent: c75555ca9951a5433703c0bb70f6a7ff6d0dfb1d
author: Quentin Rameau <quinq@fifth.space>
date: Sat Jun 4 08:48:53 EDT 2016
[driver] add linking support Use gcc for now replace it with ld later.
--- a/driver/posix/scc.c
+++ b/driver/posix/scc.c
@@ -21,6 +21,7 @@
CC2,
QBE,
AS,
+ LD,
TEE,
NR_TOOLS,
};
@@ -37,11 +38,14 @@
[CC2] = { .bin = "cc2", .cmd = PREFIX "/libexec/scc/", },
[QBE] = { .bin = "qbe", .cmd = "qbe", },
[AS] = { .bin = "as", .cmd = "as", },
+ [LD] = { .bin = "gcc", .cmd = "gcc", }, /* TODO replace with ld */
[TEE] = { .bin = "tee", .cmd = "tee", },
};
char *argv0;
static char *arch;
+static char *tmpobjs[NARGS - 2];
+static int nobjs;
static int failedtool = NR_TOOLS;
static int Eflag, Sflag, kflag;
@@ -89,6 +93,10 @@
t->nargs = 2;
t->args[1] = "-o";
break;
+ case LD:
+ t->nargs = 2;
+ t->args[1] = "-o";
+ break;
default:
break;
}
@@ -128,8 +136,18 @@
return new;
}
+static void
+addarg(int tool, char *arg) {
+ struct tool *t = &tools[tool];
+
+ if (t->nargs >= NARGS - 3) /* 3: argv0, filename, NULL terminator */
+ die("scc: too many parameters given");
+
+ t->args[++t->nargs] = arg;
+}
+
static int
-settool(int tool, char *input, int output)
+settool(int tool, char *input, int nexttool)
{
struct tool *t = &tools[tool];
int fds[2], proxiedtool;
@@ -141,8 +159,14 @@
t->outfile = outfilename(input, "o");
t->args[2] = t->outfile;
break;
+ case LD:
+ if (!t->outfile) {
+ t->outfile = "a.out";
+ t->args[2] = t->outfile;
+ }
+ break;
case TEE:
- switch (output) {
+ switch (nexttool) {
case CC2:
proxiedtool = CC1;
ext = "ir"; break;
@@ -168,7 +192,7 @@
t->args[t->nargs + 1] = input;
}
- if (output < NR_TOOLS) {
+ if (nexttool < NR_TOOLS && nexttool != LD) {
if (pipe(fds))
die("scc: pipe: %s", strerror(errno));
t->out = fds[1];
@@ -241,38 +265,68 @@
}
static void
+linkobjs(void)
+{
+ int i;
+
+ settool(inittool(LD), NULL, NR_TOOLS);
+
+ for (i = 0; tmpobjs[i] && i < nobjs; ++i)
+ addarg(LD, tmpobjs[i]);
+
+ spawn(LD);
+
+ checktool(LD);
+
+ if (!kflag) {
+ for (i = 0; i < nobjs; ++i)
+ unlink(tmpobjs[i]);
+ }
+
+ return;
+}
+
+static void
build(char *file)
{
- int i, tool, out, keepfile;
- static int preout;
+ int i, tool, nexttool, keepfile;
+ int backtool;
- for (tool = toolfor(file); tool < NR_TOOLS; tool = out) {
+ for (tool = toolfor(file); tool < NR_TOOLS; tool = nexttool) {
keepfile = 0;
switch (tool) {
case CC1:
- out = Eflag ? NR_TOOLS : CC2;
+ nexttool = Eflag ? NR_TOOLS : CC2;
if (!Eflag)
keepfile = kflag;
break;
case CC2:
if (!arch || strcmp(arch, "qbe")) {
- out = Sflag ? NR_TOOLS : AS;
+ nexttool = Sflag ? NR_TOOLS : AS;
keepfile = (Sflag || kflag);
} else {
- out = QBE;
+ nexttool = QBE;
keepfile = kflag;
}
break;
case QBE:
- out = Sflag ? NR_TOOLS : AS;
+ nexttool = Sflag ? NR_TOOLS : AS;
keepfile = (Sflag || kflag);
break;
case AS:
- out = NR_TOOLS;
+ backtool = AS;
+ nexttool = LD;
break;
+ case LD:
+ if (backtool == AS)
+ tmpobjs[nobjs++] = xstrdup(tools[AS].outfile);
+ else
+ addarg(LD, file);
+ nexttool = NR_TOOLS;
+ continue;
case TEE:
- out = preout;
+ nexttool = backtool;
break;
default:
break;
@@ -279,11 +333,11 @@
}
if (keepfile) {
- preout = out;
- out = TEE;
+ backtool = nexttool;
+ nexttool = TEE;
}
- spawn(settool(inittool(tool), file, out));
+ spawn(settool(inittool(tool), file, nexttool));
}
for (i = 0; i < NR_TOOLS; ++i)
@@ -290,22 +344,14 @@
checktool(i);
for (i = 0; i < NR_TOOLS; ++i) {
- free(tools[i].outfile);
- tools[i].outfile = NULL;
+ if (i != LD) {
+ free(tools[i].outfile);
+ tools[i].outfile = NULL;
+ }
}
}
static void
-addarg(int tool, char *arg) {
- struct tool *t = &tools[tool];
-
- if (t->nargs >= NARGS - 3) /* 3: argv0, filename, NULL terminator */
- die("scc: too many parameters given");
-
- t->args[++t->nargs] = arg;
-}
-
-static void
usage(void)
{
die("usage: %s [-E|-kS] [-m arch] [-D macro[=val]]... "
@@ -357,6 +403,9 @@
for (; *argv; ++argv)
build(*argv);
+
+ if (!(Eflag || Sflag))
+ linkobjs();
return 0;
}