make.h (11712B)
1 #ifndef KIT_MAKE_INTERNAL_H 2 #define KIT_MAKE_INTERNAL_H 3 4 /* 5 * Internal header for the make engine ported from the public-domain pdpmake 6 * (rmyorston/pdpmake). 7 * 8 * Amalgamation. The engine is compiled as ONE translation unit: src/api/make.c 9 * includes each engine fragment (src/make/<part>.c) after this header. Every 10 * engine function is `static`, so none of pdpmake's generic names (error, 11 * input, make, target, ...) escapes into libkit's symbol space. 12 * 13 * No global state. Every pdpmake global now lives in MakeCtx, which is threaded 14 * as the first parameter `mc` of every engine function that touches shared 15 * state. The read-only option predicates below (dryrun, silent, ...) are the 16 * one sanctioned convenience macro family; they read mc->opts and therefore 17 * require `mc` to be in scope (it always is -- it is the first parameter). 18 * 19 * No libc/OS calls. Memory comes from an arena (mk_alloc et al.); makefile and 20 * archive bytes are read through KitContext.file_io; recipe execution, file 21 * modification times, touch, and remove arrive through the KitMakeHost vtable; 22 * output goes to KitWriter sinks; a fatal error longjmps back to kit_make_run 23 * instead of calling exit(). 24 */ 25 26 #include <kit/core.h> 27 #include <kit/make.h> 28 29 #include <ctype.h> 30 #include <limits.h> 31 #include <setjmp.h> 32 #include <stdarg.h> 33 #include <stdbool.h> 34 #include <stddef.h> 35 #include <stdint.h> 36 #include <stdio.h> 37 #include <string.h> 38 39 #include "core/arena.h" 40 41 /* pdpmake feature selection: extensions + POSIX-2024 both on (its defaults). */ 42 #define ENABLE_FEATURE_MAKE_EXTENSIONS 1 43 #define ENABLE_FEATURE_MAKE_POSIX_2024 1 44 #define IF_FEATURE_MAKE_EXTENSIONS(...) __VA_ARGS__ 45 #define IF_NOT_FEATURE_MAKE_EXTENSIONS(...) 46 #define IF_FEATURE_MAKE_POSIX_2024(...) __VA_ARGS__ 47 #define IF_NOT_FEATURE_MAKE_POSIX_2024(...) 48 49 #define STD_POSIX_2017 0 50 #define STD_POSIX_2024 1 51 #define DEFAULT_POSIX_LEVEL STD_POSIX_2024 52 53 #ifndef TRUE 54 #define TRUE (1) 55 #define FALSE (0) 56 #endif 57 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 58 59 #define HTABSIZE 199 60 61 /* ---- data structures (verbatim from pdpmake, layout preserved) ----------- */ 62 63 /* A file, either to be made or pre-existing. A timespec models the mtime; the 64 * host reports mtime in ns, which mk_modtime splits into sec/nsec. */ 65 struct mk_timespec { 66 int64_t tv_sec; 67 int64_t tv_nsec; 68 }; 69 70 struct name { 71 struct name* n_next; /* next in hash chain */ 72 char* n_name; 73 struct rule* n_rule; /* rules to build this */ 74 struct mk_timespec n_tim; 75 uint16_t n_flag; 76 }; 77 78 #define N_DOING 0x01 /* being built */ 79 #define N_DONE 0x02 /* looked at */ 80 #define N_TARGET 0x04 /* is a target */ 81 #define N_PRECIOUS 0x08 /* precious */ 82 #define N_DOUBLE 0x10 /* double-colon target */ 83 #define N_SILENT 0x20 /* build silently */ 84 #define N_IGNORE 0x40 /* ignore build errors */ 85 #define N_SPECIAL 0x80 /* special target */ 86 #define N_MARK 0x100 /* mark for deduplication */ 87 #define N_PHONY 0x200 /* phony target */ 88 #define N_INFERENCE 0x400 /* inference rule */ 89 90 struct rule { 91 struct rule* r_next; 92 struct depend* r_dep; /* prerequisites */ 93 struct cmd* r_cmd; /* commands */ 94 }; 95 96 struct depend { 97 struct depend* d_next; 98 struct name* d_name; 99 int d_refcnt; 100 }; 101 102 struct cmd { 103 struct cmd* c_next; 104 char* c_cmd; 105 int c_refcnt; 106 const char* c_makefile; 107 int c_dispno; 108 }; 109 110 struct macro { 111 struct macro* m_next; 112 char* m_name; 113 char* m_val; 114 bool m_immediate; /* set with ::= */ 115 bool m_flag; /* infinite-loop guard */ 116 uint8_t m_level; /* level at which created */ 117 }; 118 119 /* Flags to mk_setmacro (packed into the level argument). */ 120 #define M_IMMEDIATE 0x08 121 #define M_VALID 0x10 122 #define M_ENVIRON 0x20 123 124 /* .PRAGMA bits. Order must match p_name[] in target.c. */ 125 enum { 126 BIT_MACRO_NAME = 0, 127 BIT_TARGET_NAME, 128 BIT_COMMAND_COMMENT, 129 BIT_EMPTY_SUFFIX, 130 BIT_POSIX_2017, 131 BIT_POSIX_2024, 132 BIT_POSIX_202X, 133 134 P_MACRO_NAME = (1 << BIT_MACRO_NAME), 135 P_TARGET_NAME = (1 << BIT_TARGET_NAME), 136 P_COMMAND_COMMENT = (1 << BIT_COMMAND_COMMENT), 137 P_EMPTY_SUFFIX = (1 << BIT_EMPTY_SUFFIX) 138 }; 139 140 /* Option bits (mc->opts). The public KIT_MAKE_F_* flags map onto these in 141 * run.c; the extra bits (precious/phony/include/make) are engine-internal. */ 142 enum { 143 OPTBIT_e = 0, 144 OPTBIT_i, 145 OPTBIT_k, 146 OPTBIT_n, 147 OPTBIT_q, 148 OPTBIT_r, 149 OPTBIT_s, 150 OPTBIT_t, 151 OPTBIT_p, 152 OPTBIT_precious, 153 OPTBIT_phony, 154 OPTBIT_include, 155 OPTBIT_make, 156 157 OPT_e = (1 << OPTBIT_e), 158 OPT_i = (1 << OPTBIT_i), 159 OPT_k = (1 << OPTBIT_k), 160 OPT_n = (1 << OPTBIT_n), 161 OPT_q = (1 << OPTBIT_q), 162 OPT_r = (1 << OPTBIT_r), 163 OPT_s = (1 << OPTBIT_s), 164 OPT_t = (1 << OPTBIT_t), 165 OPT_p = (1 << OPTBIT_p), 166 OPT_precious = (1 << OPTBIT_precious), 167 OPT_phony = (1 << OPTBIT_phony), 168 OPT_include = (1 << OPTBIT_include), 169 OPT_make = (1 << OPTBIT_make) 170 }; 171 172 /* make() return status. */ 173 #define MAKE_FAILURE 0x01 174 #define MAKE_DIDSOMETHING 0x02 175 176 /* Conditional-directive nesting (ifdef/ifeq...). */ 177 #define MK_IF_MAX 10 178 179 /* An input source for the parser: either an in-memory makefile buffer (data != 180 * NULL, read line by line from pos) or, when data == NULL, the built-in rules 181 * generated by mk_getrules. */ 182 typedef struct MakeSource { 183 const char* data; 184 size_t len; 185 size_t pos; 186 } MakeSource; 187 188 /* The engine context: every former pdpmake global, plus the injected host. */ 189 typedef struct MakeCtx { 190 /* injected substrate */ 191 const KitContext* ctx; /* heap / file_io / diag / now (borrowed) */ 192 const KitMakeHost* host; /* mtime / run_recipe / capture / touch / remove */ 193 const KitMakeOptions* mkopts; /* makefiles / targets / macros / flags */ 194 Arena arena; /* all engine allocations */ 195 KitWriter* out; /* stdout: recipe echo, -p, -n */ 196 KitWriter* err; /* stderr: make diagnostics */ 197 198 /* error handling: mk_error/mk_exit longjmp here; kit_make_run reads code */ 199 jmp_buf jmpbuf; 200 int exit_code; 201 202 /* recipe launch context */ 203 const KitExecKV* env; /* child env for recipes (KitExecKV pairs, run.c) */ 204 size_t nenv; 205 const char* const* ambient; /* borrowed ambient NAME=VALUE (from options) */ 206 const char* root; /* absolute working dir: path root, recipe cwd, $(CURDIR) */ 207 const char* shell; /* recipe shell (SHELL macro, default /bin/sh) */ 208 209 /* former globals */ 210 struct name* namehead[HTABSIZE]; 211 struct macro* macrohead[HTABSIZE]; 212 struct name* firstname; /* default goal */ 213 struct name* target; /* target currently being built (for remove) */ 214 uint32_t opts; 215 int lineno; 216 int dispno; 217 struct cmd* curr_cmd; 218 const char* makefile; /* current makefile name (diagnostics) */ 219 const char* myname; /* "make" */ 220 bool posix; 221 bool seen_first; 222 unsigned char pragma; 223 unsigned char posix_level; 224 225 /* conditional-directive state (was file statics in input.c) */ 226 uint8_t clevel; 227 uint8_t cstate[MK_IF_MAX + 1]; 228 229 /* built-in rules generator state (was function statics in rules.c) */ 230 const char* rulepos; 231 int rule_idx; 232 } MakeCtx; 233 234 /* Read-only option predicates. Require `mc` in scope (always the first 235 * parameter of an engine function). */ 236 #define useenv (mc->opts & OPT_e) 237 #define ignore (mc->opts & OPT_i) 238 #define errcont (mc->opts & OPT_k) 239 #define dryrun (mc->opts & OPT_n) 240 #define print (mc->opts & OPT_p) 241 #define quest (mc->opts & OPT_q) 242 #define norules (mc->opts & OPT_r) 243 #define silent (mc->opts & OPT_s) 244 #define dotouch (mc->opts & OPT_t) 245 #define precious (mc->opts & OPT_precious) 246 #define doinclude (mc->opts & OPT_include) 247 #define domake (mc->opts & OPT_make) 248 249 #define POSIX_2017 (mc->posix && mc->posix_level == STD_POSIX_2017) 250 251 /* Character-class predicates for names. */ 252 #define ispname(c) (isalpha(c) || isdigit(c) || (c) == '.' || (c) == '_') 253 #define isfname(c) (ispname(c) || (c) == '-') 254 255 /* ---- memory + diagnostics + output helpers (utils.c) --------------------- */ 256 257 static void* mk_alloc(MakeCtx* mc, size_t n); 258 static void* mk_realloc(MakeCtx* mc, void* p, size_t oldn, size_t newn); 259 static char* mk_strdup(MakeCtx* mc, const char* s); 260 static char* mk_strndup(MakeCtx* mc, const char* s, size_t n); 261 static char* mk_concat3(MakeCtx* mc, const char* a, const char* b, 262 const char* c); 263 static char* mk_appendword(MakeCtx* mc, const char* str, const char* word); 264 265 #define MK_NORETURN __attribute__((noreturn)) 266 static void mk_exit(MakeCtx* mc, int code) MK_NORETURN; /* longjmp, no message */ 267 static void mk_error(MakeCtx* mc, const char* fmt, ...) 268 MK_NORETURN; /* message + mk_exit(2) */ 269 static void mk_warning(MakeCtx* mc, const char* fmt, ...); 270 static void mk_diagnostic(MakeCtx* mc, const char* fmt, ...); 271 static void mk_error_unexpected(MakeCtx* mc, const char* s) MK_NORETURN; 272 static void mk_error_in_inference_rule(MakeCtx* mc, const char* s) MK_NORETURN; 273 static void mk_error_not_allowed(MakeCtx* mc, const char* s, const char* t) 274 MK_NORETURN; 275 276 static void mk_out(MakeCtx* mc, const char* s); /* to mc->out */ 277 static void mk_out_bytes(MakeCtx* mc, const char* p, size_t n); 278 static void mk_outc(MakeCtx* mc, char c); 279 static void mk_outf(MakeCtx* mc, const char* fmt, ...); /* to mc->out */ 280 281 static unsigned mk_getbucket(const char* name); 282 283 /* Resolve `name` against mc->root (a relative name gets joined to root; an 284 * absolute name or a NULL root is returned unchanged). Used for every path the 285 * engine hands to a host file op, so make never chdir()s. */ 286 static const char* mk_path(MakeCtx* mc, const char* name); 287 288 /* ---- macro.c ------------------------------------------------------------- */ 289 static struct macro* mk_getmp(MakeCtx* mc, const char* name); 290 static void mk_setmacro(MakeCtx* mc, const char* name, const char* val, 291 int level); 292 293 /* ---- target.c ------------------------------------------------------------ */ 294 static struct depend* mk_newdep(MakeCtx* mc, struct name* np, 295 struct depend* dphead); 296 static struct cmd* mk_newcmd(MakeCtx* mc, char* str, struct cmd* cphead); 297 static struct name* mk_findname(MakeCtx* mc, const char* name); 298 static struct name* mk_newname(MakeCtx* mc, const char* name); 299 static struct cmd* mk_getcmd(struct name* np); 300 static void mk_freerules(struct rule* rp); 301 static int mk_is_valid_target(MakeCtx* mc, const char* name); 302 static void mk_set_pragma(MakeCtx* mc, const char* name); 303 static void mk_addrule(MakeCtx* mc, struct name* np, struct depend* dp, 304 struct cmd* cp, int flag); 305 306 /* ---- check.c ------------------------------------------------------------- */ 307 static void mk_print_details(MakeCtx* mc); 308 309 /* ---- rules.c ------------------------------------------------------------- */ 310 static char* mk_suffix(const char* name); 311 static char* mk_has_suffix(MakeCtx* mc, const char* name, const char* suffix); 312 static struct name* mk_dyndep(MakeCtx* mc, struct name* np, 313 struct rule* infrule, const char** ptsuff); 314 static char* mk_getrules(MakeCtx* mc, char* s, int size); 315 316 /* ---- input.c ------------------------------------------------------------- */ 317 static char* mk_expand_macros(MakeCtx* mc, const char* str, int except_dollar); 318 static const char* mk_is_suffix(MakeCtx* mc, const char* s); 319 static void mk_input(MakeCtx* mc, MakeSource* src, int ilevel); 320 321 /* ---- modtime.c ----------------------------------------------------------- */ 322 static char* mk_splitlib(MakeCtx* mc, const char* name, char** member); 323 static void mk_modtime(MakeCtx* mc, struct name* np); 324 325 /* ---- build.c ------------------------------------------------------------- */ 326 static void mk_remove_target(MakeCtx* mc); 327 static int mk_make(MakeCtx* mc, struct name* np, int level); 328 329 /* ---- run.c --------------------------------------------------------------- */ 330 static int mk_run(MakeCtx* mc); 331 332 #endif