commit 8de17d48a084c79889db0be5bf68da22d65584e8
parent 8ce3a83e5a7de9348b55ed9f7ddcb4de0e51c82a
Author: Quentin Rameau <quinq@fifth.space>
Date: Sat, 4 Jun 2016 12:48:53 +0200
[driver] add linking support
Use gcc for now replace it with ld later.
Diffstat:
M | driver/posix/scc.c | | | 103 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------- |
1 file changed, 76 insertions(+), 27 deletions(-)
diff --git a/driver/posix/scc.c b/driver/posix/scc.c
@@ -21,6 +21,7 @@ enum {
CC2,
QBE,
AS,
+ LD,
TEE,
NR_TOOLS,
};
@@ -37,11 +38,14 @@ static struct tool {
[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 @@ inittool(int tool)
t->nargs = 2;
t->args[1] = "-o";
break;
+ case LD:
+ t->nargs = 2;
+ t->args[1] = "-o";
+ break;
default:
break;
}
@@ -128,8 +136,18 @@ outfilename(char *path, char *ext)
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 @@ settool(int tool, char *input, int output)
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 @@ settool(int tool, char *input, int output)
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,71 +265,93 @@ checktool(int tool)
}
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;
}
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)
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]]... "
@@ -358,5 +404,8 @@ main(int argc, char *argv[])
for (; *argv; ++argv)
build(*argv);
+ if (!(Eflag || Sflag))
+ linkobjs();
+
return 0;
}