diff options
author | Thomas Voss <mail@thomasvoss.com> | 2024-09-15 17:50:56 +0200 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2024-09-15 17:50:56 +0200 |
commit | 7a84b8a6422f5714751e42292115e60111894511 (patch) | |
tree | 491c83d298563f72006325cb703fa4960892aa7a /make.c | |
parent | 558b83ac8016f45237549b6c4531d2c0c5bea007 (diff) |
Bump CBS to the newest version
Diffstat (limited to 'make.c')
-rw-r--r-- | make.c | 294 |
1 files changed, 147 insertions, 147 deletions
@@ -1,54 +1,65 @@ +#ifdef __STDC_NO_ATOMICS__ +# error "Atomics aren’t supported" +#endif + #define _GNU_SOURCE #include <errno.h> -#if __has_include(<features.h>) -# include <features.h> -#endif #include <glob.h> +#include <libgen.h> +#include <stdarg.h> +#include <stdatomic.h> +#include <stdint.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#define CBS_PTHREAD +#if __has_include(<features.h>) +# include <features.h> +#endif + #include "cbs.h" -#define CC "cc" #define LIBNAME "libmlib" - -#define CFLAGS_ALL WARNINGS, "-pipe", "-std=c23", "-Iinclude" GLIB_EXTRAS -#define CFLAGS_DBG "-g", "-ggdb3", "-O0", "-fsanitize=address,undefined" -#define CFLAGS_RLS "-O3", "-flto", "-DNDEBUG" NOT_APPLE_EXTRAS - -#define WARNINGS \ - "-Wall", "-Wextra", "-Wpedantic", "-Werror", "-Wno-attributes", "-Wvla", \ - "-Wno-pointer-sign", "-Wno-parentheses" - +#define flagset(o) (flags & UINT32_C(1)<<(o)-'a') + +[[noreturn, gnu::format(printf, 1, 2)]] +static void err(const char *, ...); +static void cc(void *); + +static atomic_int rv; +static uint32_t flags; +static const char *argv0; + +static char *cflags_req[] = { + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wvla", + "-Wno-attributes", + "-Wno-pointer-sign", + "-Wno-parentheses", + "-Iinclude", + "-pipe", + "-std=c23", #ifdef __GLIBC__ -# define GLIB_EXTRAS , "-D_GNU_SOURCE" -#else -# define GLIB_EXTRAS + "-D_GNU_SOURCE", #endif - -#ifndef __APPLE__ -# define NOT_APPLE_EXTRAS , "-march=native", "-mtune=native" -#else -# define NOT_APPLE_EXTRAS -#endif - -#define CMDRC(c) \ - do { \ - int ec; \ - if ((ec = cmdexec(c)) != EXIT_SUCCESS) \ - diex("%s terminated with exit-code %d", *(c)._argv, ec); \ - cmdclr(&(c)); \ - } while (false) - -#define flagset(o) (flags & (1 << ((o) - 'a'))) -#define streq(x, y) (!strcmp(x, y)) - -static int globerr(const char *, int); -static void work(void *); - -static unsigned long flags; +}; + +static char *cflags_dbg[] = { + "-fsanitize=address,undefined", + "-ggdb3", + "-O0", +}; + +static char *cflags_rls[] = { + "-DNDEBUG", + "-flto", + "-march=native", + "-mtune=native", + "-O3", +}; int main(int argc, char **argv) @@ -58,140 +69,129 @@ main(int argc, char **argv) cbsinit(argc, argv); rebuild(); - while ((opt = getopt(argc, argv, "afj:prs")) != -1) { + argv0 = basename(argv[0]); + + while ((opt = getopt(argc, argv, "afj:rs")) != -1) { switch (opt) { case '?': fprintf(stderr, - "Usage: %s [-j procs] [-afprs]\n" - " %s clean | gen | test\n", - *argv, *argv); + "Usage: %s [-j procs] [-afrs]\n" + " %s clean | gen | test\n", + *argv, *argv); exit(EXIT_FAILURE); case 'j': procs = atoi(optarg); break; default: - flags |= 1 << (opt - 'a'); + flags |= UINT32_C(1) << opt-'a'; } } + if (!flagset('a') && !flagset('s')) + flags |= 1 << 'a'-'a'; + argc -= optind; argv += optind; if (argc >= 1) { - cmd_t c = {}; - if (streq(*argv, "clean")) { - cmdadd(&c, "find", ".", "(", "-name", "*.[ao]", "-or", "-name", - "*.so", ")", "-delete"); - } else if (streq(*argv, "gen")) { - cmdadd(&c, "find", "gen", "-mindepth", "2", "-type", "f", - "-executable", "-not", "(", "-name", "scale", "-or", "-name", - "bool-props.py", "-or", "-name", "wdth.c", ")", "-exec", - "{}", ";"); - } else if (streq(*argv, "test")) - cmdadd(&c, "./test/run-tests"); - else if (streq(*argv, "manstall")) - diex("TODO: not implemented"); - else - diex("invalid subcommand — ‘%s’", *argv); - cmdput(c); - CMDRC(c); - } else { - if (!flagset('a') && !flagset('s')) - flags |= 1 << ('a' - 'a'); - - cmd_t c = {}; - glob_t g; - tpool_t tp; - - if (glob("lib/*/*.c", 0, globerr, &g)) - die("glob"); - if (glob("lib/unicode/*/*.c", GLOB_APPEND, globerr, &g)) - die("glob"); - - if (procs == -1 && (procs = nproc()) == -1) { - if (errno) - die("nproc"); - procs = 8; - } + return EXIT_SUCCESS; + } - tpinit(&tp, procs); - for (size_t i = 0; i < g.gl_pathc; i++) - tpenq(&tp, work, g.gl_pathv[i], nullptr); - tpwait(&tp); - tpfree(&tp); - - for (size_t i = 0; i < g.gl_pathc; i++) - g.gl_pathv[i][strlen(g.gl_pathv[i]) - 1] = 'o'; - - if (flagset('a') - && (flagset('f') - || foutdatedv(LIBNAME ".a", (const char **)g.gl_pathv, - g.gl_pathc))) - { - cmdadd(&c, "ar", "rcs", LIBNAME ".a"); - cmdaddv(&c, g.gl_pathv, g.gl_pathc); - if (flagset('p')) - cmdput(c); - else - fprintf(stderr, "AR\t%s\n", LIBNAME ".a"); - CMDRC(c); - } + glob_t g; + if (glob("lib/*/*.c", 0, nullptr, &g)) + err("glob:"); + if (glob("lib/unicode/*/*.c", GLOB_APPEND, nullptr, &g)) + err("glob:"); - if (flagset('s') - && (flagset('f') - || foutdatedv(LIBNAME ".so", (const char **)g.gl_pathv, - g.gl_pathc))) - { - struct strv sv = {}; - env_or_default(&sv, "CC", CC); - cmdaddv(&c, sv.buf, sv.len); - cmdadd(&c, "-shared", "-o", LIBNAME ".so"); - cmdaddv(&c, g.gl_pathv, g.gl_pathc); - if (flagset('p')) - cmdput(c); - else - fprintf(stderr, "CC\t%s\n", LIBNAME ".so"); - CMDRC(c); + if (procs == -1 && (procs = nproc()) == -1) { + if (errno != 0) + err("nproc:"); + procs = 1; + } + + tpool tp; + tpinit(&tp, procs); + for (size_t i = 0; i < g.gl_pathc; i++) + tpenq(&tp, cc, g.gl_pathv[i], nullptr); + tpwait(&tp); + tpfree(&tp); + + if (rv != EXIT_SUCCESS) + exit(rv); + + for (size_t i = 0; i < g.gl_pathc; i++) + g.gl_pathv[i][strlen(g.gl_pathv[i]) - 1] = 'o'; + + if (flagset('a') && (flagset('f') || foutdated(LIBNAME ".a", g.gl_pathv, g.gl_pathc))) + { + struct strs cmd = {}; + strspushl(&cmd, "ar", "rcs", LIBNAME ".a"); + strspush(&cmd, g.gl_pathv, g.gl_pathc); + cmdput(cmd); + if (cmdexec(cmd) != EXIT_FAILURE) { + rv = EXIT_FAILURE; + goto out; } + strsfree(&cmd); + } - globfree(&g); + if (flagset('s') && (flagset('f') || foutdated(LIBNAME ".so", g.gl_pathv, g.gl_pathc))) + { + struct strs cmd = {}; + strspushenvl(&cmd, "CC", "cc"); + strspushl(&cmd, "-shared", "-o", LIBNAME ".so"); + strspush(&cmd, g.gl_pathv, g.gl_pathc); + cmdput(cmd); + if (cmdexec(cmd) != EXIT_FAILURE) + rv = EXIT_FAILURE; + strsfree(&cmd); } - return EXIT_SUCCESS; +out: + globfree(&g); + return rv; } void -work(void *p) +cc(void *_arg) { - char *dst, *src = p; - cmd_t c = {}; - struct strv sv = {}; - - if (!(dst = strdup(src))) - die("strdup"); - dst[strlen(dst) - 1] = 'o'; - - if (flagset('f') || foutdated(dst, src)) { - env_or_default(&sv, "CC", CC); - if (flagset('r')) - env_or_default(&sv, "CFLAGS", CFLAGS_RLS); - else - env_or_default(&sv, "CFLAGS", CFLAGS_DBG); - cmdaddv(&c, sv.buf, sv.len); - cmdadd(&c, CFLAGS_ALL, "-fPIC", "-o", dst, "-c", src); - if (flagset('p')) - cmdput(c); - else - fprintf(stderr, "CC\t%s\n", dst); - CMDRC(c); - } - - free(dst); + char *arg = _arg; + char *obj = swpext(arg, "o"); + + if (!flagset('f') && !foutdatedl(obj, arg)) + goto out; + + struct strs cmd = {}; + strspushenvl(&cmd, "CC", "cc"); + strspush(&cmd, cflags_req, lengthof(cflags_req)); + if (flagset('r')) + strspushenv(&cmd, "CFLAGS", cflags_rls, lengthof(cflags_rls)); + else + strspushenv(&cmd, "CFLAGS", cflags_dbg, lengthof(cflags_dbg)); + strspushl(&cmd, "-fPIC", "-o", obj, "-c", arg); + cmdput(cmd); + + if (cmdexec(cmd) != EXIT_SUCCESS) + rv = EXIT_FAILURE; + + strsfree(&cmd); +out: + free(obj); } -int -globerr(const char *s, int e) +void +err(const char *fmt, ...) { - errno = e; - die("glob: %s", s); + va_list ap; + va_start(ap, fmt); + int save = errno; + flockfile(stderr); + fprintf(stderr, "%s: ", argv0); + vfprintf(stderr, fmt, ap); + if (fmt[strlen(fmt) - 1] == ':') + fprintf(stderr, " %s", strerror(save)); + fputc('\n', stderr); + funlockfile(stderr); + va_end(ap); + exit(EXIT_FAILURE); } |