make.c (2805B)
1 /* 2 * Public POSIX make API and engine amalgamation. See <kit/make.h>. 3 * 4 * The engine ported from pdpmake is split across several src/make fragments for 5 * readability but compiled as ONE translation unit: this file includes each one, 6 * so every engine function has internal (static) linkage and none of pdpmake's 7 * generic names escapes into libkit. kit_make_run establishes the setjmp target 8 * that the engine's fatal-error path (mk_error/mk_exit) longjmps back to, then 9 * maps the make exit status into KitMakeResult. 10 */ 11 12 #include <kit/make.h> 13 14 #include "make/make.h" 15 16 /* Engine fragments (all `static`; compiled only here). */ 17 #include "make/utils.c" /* IWYU pragma: keep */ 18 #include "make/macro.c" /* IWYU pragma: keep */ 19 #include "make/target.c" /* IWYU pragma: keep */ 20 #include "make/modtime.c" /* IWYU pragma: keep */ 21 #include "make/rules.c" /* IWYU pragma: keep */ 22 #include "make/check.c" /* IWYU pragma: keep */ 23 #include "make/input.c" /* IWYU pragma: keep */ 24 #include "make/build.c" /* IWYU pragma: keep */ 25 #include "make/run.c" /* IWYU pragma: keep */ 26 27 static uint32_t make_opts_from_flags(uint32_t flags) { 28 uint32_t o = 0; 29 if (flags & KIT_MAKE_F_ENV_OVERRIDE) o |= OPT_e; 30 if (flags & KIT_MAKE_F_IGNORE_ERR) o |= OPT_i; 31 if (flags & KIT_MAKE_F_KEEP_GOING) o |= OPT_k; 32 if (flags & KIT_MAKE_F_DRY_RUN) o |= OPT_n; 33 if (flags & KIT_MAKE_F_PRINT_DB) o |= OPT_p; 34 if (flags & KIT_MAKE_F_QUESTION) o |= OPT_q; 35 if (flags & KIT_MAKE_F_NO_BUILTINS) o |= OPT_r; 36 if (flags & KIT_MAKE_F_SILENT) o |= OPT_s; 37 if (flags & KIT_MAKE_F_TOUCH) o |= OPT_t; 38 return o; 39 } 40 41 KitStatus kit_make_run(const KitContext* ctx, const KitMakeHost* host, 42 const KitMakeOptions* opts, KitMakeResult* result) { 43 MakeCtx mc; 44 45 if (!ctx || !ctx->heap || !host || !opts || !result) return KIT_INVALID; 46 if (!host->mtime || !host->exec || !host->exec->spawn || !host->exec->wait || 47 !host->touch || !host->remove_file) 48 return KIT_INVALID; 49 50 result->exit_code = 2; 51 52 memset(&mc, 0, sizeof mc); 53 mc.ctx = ctx; 54 mc.host = host; 55 mc.mkopts = opts; 56 mc.out = opts->out; 57 mc.err = opts->err; 58 /* mc.env (KitExecKV pairs) is built by mk_build_child_env before recipes run; 59 * until then it is NULL (from the memset). */ 60 mc.ambient = opts->env; 61 mc.root = opts->curdir; 62 mc.shell = opts->shell ? opts->shell : "/bin/sh"; 63 mc.myname = "make"; 64 mc.posix_level = DEFAULT_POSIX_LEVEL; 65 mc.posix = (opts->flags & KIT_MAKE_F_POSIX) != 0; 66 mc.opts = make_opts_from_flags(opts->flags); 67 68 arena_init(&mc.arena, (Heap*)ctx->heap, 64u * 1024u); 69 70 /* mc's address is taken (setjmp/&mc), so its fields survive the longjmp. */ 71 if (setjmp(mc.jmpbuf) == 0) mc.exit_code = mk_run(&mc); 72 73 result->exit_code = mc.exit_code; 74 arena_fini(&mc.arena); 75 return KIT_OK; 76 }