From 4ba88a7c83c2809bf6b71176ef4d347088d996b9 Mon Sep 17 00:00:00 2001 From: Trent Huber Date: Mon, 14 Apr 2025 19:48:26 -0400 Subject: [PATCH] Change location of lflags, final touches --- cbs.c | 99 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 56 insertions(+), 43 deletions(-) diff --git a/cbs.c b/cbs.c index 24359f0..706d0eb 100644 --- a/cbs.c +++ b/cbs.c @@ -7,6 +7,12 @@ #include #include +#ifdef __APPLE__ +#define DYEXT ".dylib" +#else +#define DYEXT ".so" +#endif + extern char **environ; char **cflags, **lflags; @@ -24,17 +30,17 @@ void error(char *fmt, ...) { exit(EXIT_FAILURE); } -void *alloc(size_t size) { +void *alloc(size_t s) { void *r; - if (!(r = malloc(size))) error("Memory allocation"); + if (!(r = malloc(s))) error("Memory allocation"); return r; } char *extend(char *path, char *ext) { - char *bp, *ep, *rp, *tp; - int d, b, e, l; + char *bp, *ep, *r, *p; + size_t d, b, l, e; if (!path) return NULL; @@ -42,30 +48,32 @@ char *extend(char *path, char *ext) { d = bp - path; b = (ep = strrchr(bp, '.')) ? ep - bp : (ep = ext, strlen(bp)); if (*ext == '!') ep = ext + 1; + l = strcmp(ep, ".a") == 0 || strcmp(ep, DYEXT) == 0 ? 3 : 0; e = strlen(ep); - l = strncmp(ep, ".a", e) == 0 || strncmp(ep, ".dylib", e) == 0 ? 3 : 0; - tp = rp = alloc(d + l + b + e + 1); - tp = stpncpy(tp, path, d); - tp = stpncpy(tp, "lib", l); - tp = stpncpy(tp, bp, b); - stpncpy(tp, ep, e + 1); + p = r = alloc(d + l + b + e + 1); + p = stpncpy(p, path, d); + p = stpncpy(p, "lib", l); + p = stpncpy(p, bp, b); + strcpy(p, ep); - return rp; + return r; } int modified(char *target, char *dep) { struct stat tstat, dstat; - if (stat(target, &tstat) == -1 && errno != ENOENT) + if (stat(target, &tstat) == -1) { + if (errno == ENOENT) return !(errno = 0); error("Unable to stat `%s'", target); + } if (stat(dep, &dstat) == -1) error("Unable to stat `%s'", dep); - return errno == ENOENT || tstat.st_mtime < dstat.st_mtime; + return tstat.st_mtime < dstat.st_mtime; } void run(char *path, char **args, char *what, char *who) { - int i; + size_t i; for (i = 0; args[i]; ++i) printf("%s ", args[i]); printf("\n"); @@ -74,7 +82,7 @@ void run(char *path, char **args, char *what, char *who) { error("Unable to run %s of `%s'", what, who); } -void await(int cpid, char *what, char *who) { +void await(pid_t cpid, char *what, char *who) { int status; if (cpid == -1) error("Unable to delegate the %s of `%s'", what, who); @@ -85,23 +93,23 @@ void await(int cpid, char *what, char *who) { } void compile(char *src, ...) { - int fn, cpid; + size_t f; char **args, **p, *obj, *dep; va_list deps; + pid_t cpid; - fn = 0; - if (cflags) while (cflags[fn]) ++fn; - p = args = alloc((5 + fn + 1) * sizeof*args); + if (f = 0, cflags) while (cflags[f]) ++f; + p = args = alloc((5 + f + 1) * sizeof*args); *p++ = "cc"; - if (cflags) for (fn = 0; cflags[fn]; *p++ = cflags[fn++]); + if (cflags) for (f = 0; cflags[f]; *p++ = cflags[f++]); *p++ = "-c"; *p++ = "-o"; *p++ = obj = extend(src, "!.o"); *p++ = src = extend(src, ".c"); *p = NULL; - dep = strdup(src); + dep = src; va_start(deps, src); do if (modified(obj, dep)) { if ((cpid = fork()) == 0) run("/usr/bin/cc", args, "compilation", src); @@ -110,62 +118,67 @@ void compile(char *src, ...) { } while (free(dep), dep = extend(va_arg(deps, char *), ".h")); va_end(deps); - free(src); free(obj); free(args); } void load(char type, char *target, char *obj, ...) { - int fn, vn, cpid; va_list count, objs; - char **args, **p, *path, **o; + size_t o, f; + char **args, **p, *path, **fp, **a; + pid_t cpid; - fn = 0; - if (lflags) while (lflags[fn]) ++fn; va_start(count, obj); va_copy(objs, count); - for (vn = 0; va_arg(count, char *); ++vn); + for (o = 1; va_arg(count, char *); ++o); va_end(count); - p = args = alloc((5 + fn + vn + 1) * sizeof*args); + if (f = 0, lflags) while (lflags[f]) ++f; + args = alloc((4 + o + f + 1) * sizeof*args); - path = "/usr/bin/cc"; - *p++ = "cc"; + p = args + 1; switch (type) { case 'd': - *p++ = "-dynamiclib"; + *p++ = "-shared"; + target = extend(target, DYEXT); case 'x': - if (lflags) for (fn = 0; lflags[fn]; *p++ = lflags[fn++]); + path = "/usr/bin/cc"; + *args = "cc"; *p++ = "-o"; - *p++ = target = type == 'd' ? extend(target, ".dylib") : strdup(target); + fp = p + o + 1; + a = args + 3; break; case 's': path = "/usr/bin/ar"; - *(p - 1) = "ar"; + *args = "ar"; *p++ = "-r"; - *p++ = target = extend(target, ".a"); + fp = p; + a = p += f; + target = extend(target, ".a"); break; default: error("Unknown linking type `%c'", type); } - o = p; - *o++ = extend(obj, ".o"); - while ((*o++ = extend(va_arg(objs, char *), ".o"))); + *p++ = target; + *p++ = extend(obj, ".o"); + while ((*p = extend(va_arg(objs, char *), ".o"))) ++p; va_end(objs); + if (lflags) for (f = 0; lflags[f]; *fp++ = lflags[f++]); + if (fp > p) *fp = NULL; + fp = p; - o = p; - while (*o) if (modified(target, *o++)) { + p -= o; + while (o--) if (modified(target, *p++)) { if ((cpid = fork()) == 0) run(path, args, "linking", target); await(cpid, "linking", target); break; } - while (*p) free(*p++); - free(target); + while (a != fp) free(*a++); free(args); } void build(char *path) { - int cpid; + pid_t cpid; if (path) { if ((cpid = fork())) { -- 2.51.0