aboutsummaryrefslogtreecommitdiffhomepage
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c710
1 files changed, 0 insertions, 710 deletions
diff --git a/main.c b/main.c
deleted file mode 100644
index 9710814..0000000
--- a/main.c
+++ /dev/null
@@ -1,710 +0,0 @@
-#include "common.h"
-#include "version.h"
-#include "hostconfig.h" /* run ./configure */
-#include "obj/obj.h"
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <unistd.h>
-#include <time.h>
-
-struct option ccopt;
-struct cinclpaths cinclpaths[5];
-
-static void
-addinclpath(int ord, const char *path)
-{
- struct inclpath *p = alloc(&globarena, sizeof *p, 0);
- assert((uint)ord < countof(cinclpaths));
- p->path = path;
- p->next = NULL;
- if (cinclpaths[ord].list) {
- *cinclpaths[ord].tail = p;
- } else {
- cinclpaths[ord].list = p;
- }
- cinclpaths[ord].tail = &p->next;
-}
-
-/* parse an argument of the form 'opt=abcd'
- * e.g. arg="foo=bar123"; opt="foo"; returns "bar123" */
-static const char *
-optval(const char *arg, const char *opt)
-{
- uint n1 = strlen(arg), n2 = strlen(opt);
- if (n1 < n2+1 || memcmp(arg, opt, n2) != 0 || arg[n2] != '=')
- return NULL;
- return arg + n2 + 1;
-}
-
-/* "foo.bar" -> "bar"; ".dotfile" -> "" */
-static const char *
-fileext(const char *path)
-{
- const char *dot = NULL;
- assert(path && *path && "empty");
-
- for (++path; *path; ++path) {
- if (*path == '.') dot = path;
- }
- return dot ? dot+1 : "";
-}
-
-enum inft { IFTauto, IFTc, IFTasm, IFTobj, IFTar, IFTdll };
-
-static enum inft
-ftdetect(const char *s)
-{
- const char *ext = fileext(s);
- if (!strcmp(ext, "c")) return IFTc;
- if (!strcmp(ext, "o")) return IFTobj;
- if (!strcmp(ext, "a")) return IFTar;
- if (!strcmp(ext, "s")) return IFTasm;
- if (!strcmp(ext, "so")) return IFTdll;
- warn(NULL, "assuming %'s is C source file", s);
- return IFTc;
-}
-
-static union {
- struct arena a;
- char mem[sizeof(struct arena) + (1<<10)];
-} _arenamem;
-struct arena *globarena = &_arenamem.a;
-
-/* withext("x/y.c", "o") -> "y.o"; withext("f9", "s") -> "f9.s" */
-static const char *
-withext(const char *path, const char *ext)
-{
- char *res;
- size_t len;
- const char *oext, *file = path;
-
- while (*path)
- if (*path++ == '/')
- file = path;
- assert(*file && "no filename");
- oext = fileext(file);
- if (!*oext)
- len = strlen(file);
- else
- len = oext - file - 1;
- res = alloc(&globarena, len + 1 + (ext ? strlen(ext) + 1 : 0), 1);
- memcpy(res, file, len);
- if (ext) {
- res[len] = '.';
- memcpy(res + len + 1, ext, strlen(ext));
- } else {
- res[len] = 0;
- }
- return res;
-}
-
-struct infile {
- enum inft ft;
- const char *path, *temp;
-};
-static struct infile infilebuf[16];
-static struct task {
- enum outft { OFTexe, OFTdll, OFTobj, OFTasm, OFTc } outft;
- const char *out;
- const char *targ;
- vec_of(struct infile) inf;
- char **runargs;
- vec_of(const char *) linkargs;
- bool verbose, run, syntaxonly;
-} task = { .inf = VINIT(infilebuf, countof(infilebuf)) };
-
-static void prihelp(void);
-
-static void
-optparse(char **args)
-{
- const char *arg, *x;
- enum inft ft = IFTauto;
-
- while ((arg = *++args)) {
- if (*arg++ != '-' || !*arg) {
- vpush(&task.inf, ((struct infile) {
- ft ? ft : ftdetect(arg-1),
- arg[-1] != '-' ? arg-1 : "/dev/stdin"
- }));
- ft = IFTauto;
- if (task.run) {
- task.runargs = args+1;
- return;
- }
- continue;
- }
- int cinclord;
- if (!strcmp(arg, "help") || !strcmp(arg, "h") || !strcmp(arg, "-help")) {
- prihelp();
- exit(0);
- } else if (!strcmp(arg, "dumpmachine")) {
- pfmt("%s\n", HOST_TRIPLE);
- exit(0);
- } else if (!strcmp(arg, "-version")) {
- pfmt("antcc version "ANTCC_VERSION_STR"\n"
- "target: "HOST_TRIPLE"\n"
- "include paths: "XSTR(HOST_INCLUDE_DIRS)"\n"
- "host cc for linking: " HOST_CC "\n");
- exit(0);
- } else if (!strcmp(arg, "dumpversion")) {
- pfmt("%s\n", ANTCC_VERSION_STR);
- exit(0);
- } else if ((x = optval(arg, "std"))) {
- if (!strcmp(x, "c89") || !strcmp(x, "c90")) ccopt.cstd = STDC89;
- else if (!strcmp(x, "c99")) ccopt.cstd = STDC99;
- else if (!strcmp(x, "c11")) ccopt.cstd = STDC11;
- else if (!strcmp(x, "c2x")) ccopt.cstd = STDC23;
- else if (!strcmp(x, "c23")) ccopt.cstd = STDC23;
- else goto Bad;
- } else if (!strcmp(arg, "pedantic")) {
- ccopt.pedant = 1;
- } else if (!strcmp(arg, "trigraphs")) {
- ccopt.trigraph = 1;
- } else if (*arg == 'd' && arg[1]) {
- /* see common.h§struct option */
- while (*++arg) switch (*arg | 32) {
- case 'p': ccopt.dbg.p = 1; break;
- case 'a': ccopt.dbg.a = 1; break;
- case 'm': ccopt.dbg.m = 1; break;
- case 'o': ccopt.dbg.o = 1; break;
- case 's': ccopt.dbg.s = 1; break;
- case 'i': ccopt.dbg.i = 1; break;
- case 'y': ccopt.dbg.y = 1; break;
- case 'l': ccopt.dbg.l = 1; break;
- case 'r': ccopt.dbg.r = 1; break;
- default: warn(NULL, "-d: invalid debug flag %'c", *arg);
- }
- } else if (*arg == 'o') {
- if (arg[1]) task.out = arg+1;
- else if (args[1]) task.out = *++args;
- else fatal(NULL, "missing path after `-o`");
- } else if (!strcmp(arg, "fsyntax-only")) {
- task.syntaxonly = 1;
- } else if (*arg == 'f') {
- /* -fabc / -fno-abc flags */
- const char *flag = arg+1;
- bool set = 1;
- if (!strncmp(flag, "no-", 3)) {
- set = 0;
- flag += 3;
- }
- if (!strcmp(flag, "pie") || !strcmp(flag, "PIE")) ccopt.pie = set;
- else if (!strcmp(flag, "pic") || !strcmp(flag, "PIC")) ccopt.pic = set;
- else goto Bad;
- } else if (!strcmp(arg, "target") || !strcmp(arg, "-target")) {
- const char *s = *++args;
- if (!s) fatal(NULL, "missing target name");
- task.targ = s;
- } else if (*arg == 'l' || *arg == 'L' || *arg == 'B' || !strcmp(arg, "shared") || !strcmp(arg, "pthread")) {
- vpush(&task.linkargs, arg-1);
- } else if (!strcmp(arg, "v") || !strcmp(arg, "-verbose")) {
- task.verbose = 1;
- } else if (!strcmp(arg, "c")) {
- task.outft = OFTobj;
- } else if (!strcmp(arg, "E")) {
- task.outft = OFTc;
- } else if (!strcmp(arg, "xc")) {
- ft = IFTc;
- } else if (!strcmp(arg, "xo")) {
- ft = IFTobj;
- } else if (!strcmp(arg, "run")) {
- task.run = 1;
- if (task.inf.n > 0) {
- task.runargs = args+1;
- return;
- }
- } else if (*arg == 'g') {
- /* TODO debug info */
- } else if (*arg == 'O') {
- char o = arg[1];
- if (!o || o == 'g') ccopt.o = 0; /* default opts */
- else if (o == '1' || o == 's' || o == 'z') ccopt.o = OPT1;
- else if ((uint)o - '1' < 9) ccopt.o = OPT2;
- else if (o == '0') ccopt.o = OPT0;
- else goto Bad;
- } else if (*arg == 'D' || *arg == 'U') {
- void cpppredef(bool undef, const char *cmd);
- const char *def = arg[1] ? arg+1 : *++args;
- if (!def) fatal(NULL, "macro name missing after `-%c`", *arg);
- cpppredef(*arg == 'U', def);
- } else if (*arg == 'O') {
- /* TODO optimization level */
- } else if (*arg == 'I' || !strcmp(arg, "-include-directory")) {
- const char *p;
- cinclord = CINCL_I;
- if (*arg == 'I' && arg[1]) p = arg+1;
- else CIncl: p = *++args;
- if (!p) fatal(NULL, "missing path after `%s`", arg-1);
- addinclpath(cinclord, p);
- } else if (!strcmp(arg, "iquote")) {
- cinclord = CINCL_iquote;
- goto CIncl;
- } else if (!strcmp(arg, "isystem")) {
- cinclord = CINCL_isystem;
- goto CIncl;
- } else if (!strcmp(arg, "idirafter")) {
- cinclord = CINCL_idirafter;
- goto CIncl;
- } else if (!strcmp(arg, "nostdinc") || !strcmp(arg, "-no-standard-includes")) {
- cinclpaths[CINCLsys].list = NULL;
- } else if (*arg == 'M') {
- ++arg;
- if (*arg == 'F' || *arg == 'T' || *arg == 'Q') {
- const char *p = arg[1] ? arg+1 : *++args;
- if (!p) fatal(NULL, "missing path after `-M%c`", *arg);
- }
- /* TODO depfiles */
- } else if (*arg == 'W') {
- if (!strcmp(arg+1, "error")) {
- ccopt.werror = 1;
- }
- /* TODO warning switches */
- } else if (*arg == 'w') {
- ccopt.wnone = 1;
- /* TODO warning switches */
- } else Bad: warn(NULL, "unrecognized option: %'s", arg-1);
- }
-
- if (task.inf.n == 0) fatal(NULL, "no input files");
-
- if (!task.out && !task.syntaxonly) {
- switch (task.outft) {
- case OFTdll:
- case OFTexe: if (!task.run) task.out = "a.out"; break;
- case OFTasm: task.out = withext(task.inf.p[0].path, "s"); break;
- case OFTobj: task.out = withext(task.inf.p[0].path, "o"); break;
- case OFTc: break;
- }
- }
- if (!in_range(task.outft, OFTexe, OFTdll) && task.outft != OFTc && task.inf.n > 1)
- fatal(NULL, "too many input files");
-}
-
-static const char *
-tempfile(const char *path, const char *ext)
-{
- int id;
- static int id2;
- static char sbuf[1024];
- const char *tmpdir;
- const char *file = path;
- struct wbuf fbuf = MEMBUF(sbuf, sizeof sbuf);
-
- tmpdir = getenv("TMPDIR");
- tmpdir = tmpdir ? tmpdir : "/tmp";
- id = getpid();
- id = id < 0 ? time(NULL) : id;
-
- while (*path)
- if (*path++ == '/')
- file = path;
- bfmt(&fbuf, "%s/antcc-%x@%u@", tmpdir, id, id2++);
- while (*file++) {
- char c = file[-1];
- if (in_range(c, 'a', 'z') || in_range(c, 'A', 'Z') || in_range(c, '0', '9')
- || c == '_' || c == '-')
- {
- ioputc(&fbuf, c);
- } else if (c == '.') break;
- else ioputc(&fbuf, '_');
- }
- bfmt(&fbuf, "%s%s", &"."[!ext], ext ? ext : "");
- ioputc(&fbuf, 0);
- assert(!fbuf.err);
- return alloccopy(&globarena, fbuf.buf, fbuf.len, 1);
-}
-
-static int cc1(const char *out, const char *in);
-
-static const char *tempout;
-static pid_t rootp;
-static void
-mktemps(void) {
- rootp = getpid();
- for (int i = 0; i < task.inf.n; ++i) {
- if (task.inf.p[i].ft == IFTc)
- task.inf.p[i].temp = tempfile(task.inf.p[i].path, "o");
- }
- if (!task.out)
- task.out = tempout = tempfile(task.inf.n > 1 ? "run" : withext(task.inf.p[0].path, NULL), NULL);
-}
-
-static void
-cleantemps(void)
-{
- if (getpid() != rootp) return;
- for (int i = 0; i < task.inf.n; ++i) {
- if (task.inf.p[i].temp) {
- unlink(task.inf.p[i].temp);
- task.inf.p[i].temp = NULL;
- }
- }
- if (tempout)
- unlink(tempout), tempout = NULL;
-}
-static void
-sigcleantemps(int _)
-{
- cleantemps();
-}
-
-static void
-compileobjs(void)
-{
- int wstat;
- pid_t p;
-
- if (!ccopt.dbg.any && !task.syntaxonly) mktemps();
- for (int i = 0; i < task.inf.n; ++i) {
- enum inft ft = task.inf.p[i].ft;
- if (ft == IFTc) {
- if ((p = fork()) < 0) {
- error(NULL, "fork(): %s\n", strerror(errno));
- exit(1);
- } else if (p == 0) {
- exit(cc1(task.inf.p[i].temp, task.inf.p[i].path));
- }
- waitpid(p, &wstat, 0);
- if (!WIFEXITED(wstat)) exit(127);
- if (WEXITSTATUS(wstat) != 0) {
- cleantemps();
- exit(WEXITSTATUS(wstat));
- }
- } else if (ft == IFTobj || ft == IFTar || ft == IFTdll) {
- // passthru
- } else assert(!"not obj");
- }
- if (!ccopt.dbg.any && !task.syntaxonly) {
- atexit(cleantemps);
- signal(SIGINT, sigcleantemps);
- signal(SIGABRT, sigcleantemps);
- signal(SIGILL, sigcleantemps);
- }
-}
-
-#include <fcntl.h>
-
-static bool
-hasprog(const char *prog)
-{
- pid_t p;
- if ((p = fork()) < 0) {
- return 0;
- } else if (p == 0) {
- int nulfd = open("/dev/null", O_WRONLY);
- if (nulfd < 0) return 0;
- for (int fd = 0; fd <= 2; ++fd) {
- dup2(fd, nulfd);
- close(fd);
- }
- const char *cmd[] = {prog, NULL};
- if (execvp(*cmd, (char **)cmd)) {
- close(nulfd);
- error(NULL, "execvp: %s", strerror(errno));
- exit(125);
- }
- }
- int wstat;
- waitpid(p, &wstat, 0);
- if (!WIFEXITED(wstat)) return 0;
- return WEXITSTATUS(wstat) < 125;
-}
-
-static bool
-iscrosscc(void)
-{
- return target.os != HOST_OS || target.arch != HOST_ARCH || target.abi != HOST_ABI;
-}
-
-struct cmdargs { vec_of(const char *); };
-
-static void
-findlinkcmd(struct cmdargs *cmd)
-{
- if (task.targ && iscrosscc()) {
- /* try to find a cross compiling toolchain, e.g. aarch64-linux-gnu-gcc */
- static const char *ccs[] = {"cc", "gcc", "clang"};
- char cross[1024];
- for (int i = 0; i < countof(ccs); ++i) {
- struct wbuf wbuf = MEMBUF(cross, sizeof cross);
- int n = bfmt(&wbuf, "%s-%s", task.targ, ccs[i]);
- assert(n < sizeof cross-1);
- cross[n] = 0;
- if (hasprog(cross)) {
- vpush(cmd, alloccopy(&globarena, cross, n, 1));
- return;
- }
- }
- /* zig cc fallback, which works great as cross compiler toolchain */
- if (hasprog("zig")) {
- vpush(cmd, "zig");
- vpush(cmd, "cc");
- vpush(cmd, "-target");
- vpush(cmd, task.targ);
- } else {
- fatal(NULL, "cannot link to cross-compilation target: no appropiate toolchain installed");
- }
- } else {
- vpush(cmd, HOST_CC);
- }
-}
-
-static int
-dolink(void)
-{
- const char *cmdbuf[100];
- pid_t p;
- int wstat;
- struct cmdargs cmd = VINIT(cmdbuf, countof(cmdbuf));
-
- findlinkcmd(&cmd);
- if (!strcmp(cmd.p[0], "zig")) {
- note(NULL, "using 'zig cc' as a cross-compiler");
- }
- if (task.outft == OFTdll) {
- vpush(&cmd, "-shared");
- } else if (task.outft == OFTexe) {
- vpush(&cmd, ccopt.pie ? "-pie" : "-no-pie");
- }
- vpush(&cmd, "-o");
- vpush(&cmd, task.out);
- assert(task.inf.n > 0);
- for (int i = 0; i < task.inf.n; ++i) {
- const char *o;
- switch (task.inf.p[i].ft) {
- case IFTc: o = task.inf.p[i].temp; break;
- case IFTobj: case IFTar: case IFTdll:
- o = task.inf.p[i].path; break;
- default: assert(!"link obj?");
- }
- vpush(&cmd, o);
- }
- vpushn(&cmd, task.linkargs.p, task.linkargs.n);
- if (task.verbose) {
- efmt("> ");
- for (int i = 0; i < cmd.n; ++i)
- efmt("%s ", cmd.p[i]);
- efmt("\n");
- }
- vpush(&cmd, NULL);
- if ((p = fork()) < 0) {
- error(NULL, "fork: %s\n", strerror(errno));
- exit(1);
- } else if (p == 0) {
- if (execvp(cmd.p[0], (char **)cmd.p)) {
- error(NULL, "execvp: %s\n", strerror(errno));
- exit(1);
- }
- }
- vfree(&cmd);
- waitpid(p, &wstat, 0);
- if (!WIFEXITED(wstat)) return 127;
- if (WEXITSTATUS(wstat) != 0) {
- error(NULL, "link command failed");
- return 1;
- }
- return 0;
-}
-
-static int
-dorun(void)
-{
- if (target.arch != HOST_ARCH || target.os != HOST_OS) {
- warn(NULL, "'-run' with cross-compiled binary");
- }
- if (task.verbose) {
- efmt("> exec %s", task.out);
- for (char **s = task.runargs; *s; ++s)
- efmt(" %s", *s);
- efmt("\n");
- }
-#if _POSIX_C_SOURCE >= 200809L
- /* use fexecve */
- int fexecve(int fd, char *const argv[], char *const envp[]);
- int fd = open(task.out, O_RDONLY);
- if (fd < 0) {
- error(NULL, "open: %s\n", strerror(errno));
- return 1;
- }
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
- error(NULL, "fcntl: %s\n", strerror(errno));
- return 1;
- }
- cleantemps();
- extern char **environ;
- fexecve(fd, task.runargs - 1, environ);
- error(NULL, "fexecv: %s\n", strerror(errno));
- return 1;
-#else
- pid_t p;
- if ((p = fork()) < 0) {
- error(NULL, "fork(): %s\n", strerror(errno));
- exit(1);
- } else if (p == 0) {
- if (!execv(task.out, task.runargs - 1)) {
- error(NULL, "execv(): %s\n", strerror(errno));
- exit(1);
- }
- }
- int wstat;
- waitpid(p, &wstat, 0);
- if (!WIFEXITED(wstat)) return 127;
- return WEXITSTATUS(wstat);
-#endif
-}
-
-static int
-driver(void)
-{
- void cpp(struct wbuf *, const char *);
- if (task.verbose)
- efmt("# Target: %s\n", task.targ ? task.targ : HOST_TRIPLE);
- if (task.syntaxonly)
- task.out = "/dev/null"; // HACK
- if (task.outft == OFTobj) {
- assert(task.inf.n == 1);
- if (task.inf.p[0].ft != IFTc)
- fatal(NULL, "not a C source file: %s", task.inf.p[0].path);
- return cc1(task.out, task.inf.p[0].path);
- } else if (task.outft == OFTc) {
- struct wbuf _buf = {0}, *buf = &bstdout;
- if (task.out) {
- buf = &_buf;
- buf->buf = alloc(&globarena, buf->cap = 1<<12, 1);
- buf->fd = open(task.out, O_CREAT | O_TRUNC | O_WRONLY, 0777);
- if (buf->fd < 0) {
- error(NULL, "open(%'s): %s", task.out, strerror(errno));
- return 1;
- }
- }
- bool ok = 1;
- if (!task.out && task.inf.n == 1)
- cpp(buf, task.inf.p[0].path);
- else for (int i = 0; i < task.inf.n; ++i) {
- pid_t p;
- int wstat;
-
- if ((p = fork()) < 0) {
- error(NULL, "fork(): %s\n", strerror(errno));
- ok = 0;
- } else if (p == 0) {
- cpp(buf, task.inf.p[i].path);
- exit(0);
- }
- waitpid(p, &wstat, 0);
- if (!WIFEXITED(wstat)) ok = 0;
- ok = ok && WEXITSTATUS(wstat) == 0;
- }
- ioflush(buf);
- if (task.out)
- close(buf->fd);
- return ok ? 0 : 1;
- } else if (task.outft == OFTexe || task.outft == OFTdll) {
- compileobjs();
- if (ccopt.dbg.any || task.syntaxonly) return 0;
- if (!task.run) return dolink();
- int st = dolink();
- if (st == 0) st = dorun();
- return st;
- }
- assert(0);
-}
-
-static int
-cc1(const char *out, const char *in)
-{
- void ccomp(const char *);
- extern int nerror;
-
- if (task.verbose) efmt("cc1(/*out*/ %'s, /*in*/ %'s)\n", out, in);
- if (!ccopt.dbg.any && !task.syntaxonly) objini(in, out);
- ccomp(in);
- if (!ccopt.dbg.any && !task.syntaxonly && !nerror) objfini();
- return !!nerror;
-}
-
-static void
-detectcolor(void)
-{
- const char *s;
- if (!isatty(STDERR_FILENO)
- || ((s = getenv("NO_COLOR")) && *s)
- || ((s = getenv("TERM")) && !strcmp(s, "dumb")))
- ccopt.nocolor = 1;
-}
-
-static void
-sysinclpaths(void)
-{
- static const char *paths[] = {
- HOST_INCLUDE_DIRS
- };
- for (int i = 0; i < countof(paths); ++i)
- addinclpath(CINCLsys, paths[i]);
-}
-
-static void
-prihelp(void)
-{
- pfmt("antcc version "ANTCC_VERSION_STR"\n"
- "Usage: antcc [options] infile(s)...\n"
- " antcc [options] -run infile [arguments...]\n"
- " antcc [options] infile(s)... -run [arguments...]\n"
- "Options:\n"
- " -help \tPrint this help message\n"
- " -std=<..> \tSet C standard (c89, c99, c11, c23)\n"
- " -pedantic \tWarnings for strict standards compliance\n"
- " -d{pamyosilr} \tDebug print IR after {parse, abi, mem, inlining, opts, stack, isel, live, rega}\n"
- " -o <file> \tPlace the output into <file>\n"
- " -v \tVerbose output\n"
- " -c \tEmit object file but do not link\n"
- " -run \tRun compiled sources\n"
- " -Idir \tAdd include path\n"
- " -Dsym[=val] \tDefine macro\n"
- " -Usym \tUndefine macro\n"
- " -E \tPreprocess only\n"
- " -llib \tLink with library\n"
- " -fpie \tEmit code for position independent executable\n"
- " -fpic \tEmit position independent code\n"
- " -O<..> \tSet optimization level (0|g|1|2|s|z) (default: -Og)\n"
- " -x<c|o> \tSpecify type of next input file (C, object)\n"
- " -W[...] \tTurn on warnings (stub)\n"
- " -Werror \tTurn warnings into errors\n"
- " -w \tSuppress warnings\n"
- " --version \tPrint version\n"
- );
-}
-
-int
-main(int argc, char **argv)
-{
- globarena->cap = sizeof(_arenamem.mem) - sizeof(struct arena);
-
- ioinit();
- /* setup defaults */
- detectcolor();
- sysinclpaths();
- ccopt.cstd = STDC11;
- ccopt.pie = 1;
- ccopt.dbgout = &bstdout;
-
- /* parse cli ags */
- if (argc == 1) {
- prihelp();
- return 1;
- }
- optparse(argv);
-
- /* global init */
- targ_init(task.targ);
- if (!target.arch)
- fatal(NULL, "unsupported target: %s", task.targ ? task.targ : HOST_TRIPLE);
-
- return driver();
-}
-
-/* vim:set ts=3 sw=3 expandtab: */