github.com/zyedidia/knit@v1.1.2-0.20230901152954-f7d4e39a0e24/docs/knit.md (about) 1 ## Rules 2 3 A rule consists of four parts: 4 5 * Targets: a list of values that are generated by this rule. 6 * Prereqs: a list of values that must be generated before this rule can be 7 executed. 8 * Attributes: a list of flags that customize how this rule is interpreted. 9 * Recipe: a list of commands that are run to execute the rule. 10 11 The syntax for a rule is 12 13 ``` 14 targets:attributes: prereqs 15 recipe 16 ``` 17 18 If the rule has no attributes, it may be omitted, leaving just `targets: 19 prereqs` on the first line. 20 21 When a rule is embedded in Lua, it is prefixed with a `$`: 22 23 ``` 24 $ targets:attributes: prereqs 25 recipe 26 ``` 27 28 The rule continues until it is de-indented to the original indentation of the 29 `$`. 30 31 Direct rules are rules where the targets and prereqs are explicit names of 32 values. For example, 33 34 ``` 35 foo.o: foo.c 36 gcc -c foo.c -o foo.o 37 ``` 38 39 Specifies that the file `foo.o` is built from `foo.c`, using the command `gcc 40 -c foo.c -o foo.o`. 41 42 Within a rule, `#` denotes the start of a comment. Outside of rules, `--` is 43 the start of a comment (the standard Lua syntax). 44 45 ### Meta rules 46 47 A meta rule is a special rule that describes a generic way to create direct 48 rules. The meta rule describes how to match targets and prereqs into a direct 49 rule. For example, a `%` meta rule uses `%` to match any sequence of 50 characters. 51 52 Thus the meta rule 53 54 ``` 55 %.o: %.c 56 ... 57 ``` 58 59 describes that a direct rule 60 61 ``` 62 foo.o: foo.c 63 ... 64 ``` 65 66 could be created. This direct rule would be created if another rule needed 67 `foo.o` to be generated. 68 69 Meta rules may also specify the match by using regular expressions, if the `R` 70 attribute is provided. For example: 71 72 ``` 73 foo-(.*)-(.*).tar.gz:R: $1/$2/foo 74 ... 75 ``` 76 77 could create a direct rule 78 79 ``` 80 foo-linux-amd64.tar.gz: linux/amd64/foo 81 ... 82 ``` 83 84 ### Attributes 85 86 Knit supports the following attributes: 87 88 * `Q` (quiet): do not print this rule's recipe when executing. 89 * `R` (regex): this meta rule uses regular expression matching. 90 * `V` (virtual): the value this rule generates is not a file, just a name. 91 * `M` (no meta): this rule's targets cannot be matched by meta rules. 92 * `E` (non-stop): this rule does not stop if one of its commands fails. 93 * `B` (build): this rule must always be built (it is always out-of-date). 94 * `L` (linked): this rule always runs if an out-of-date sub-rule requires it as 95 a prereq. 96 * `O` (order-only): this rule's prereqs are not considered automatically 97 up-to-date even if this rule is up-to-date. 98 * `D[depfile]` (dependency): include `depfile` as an additional list of 99 dependencies for this rule. 100 101 The `D` attribute takes an argument. It is used for including `.d` files for 102 C headers. For example, this rule 103 104 ``` 105 $ %.o:D[%.d]: %.c 106 gcc -MMD -c $input -o $output 107 ``` 108 109 specifies that it should read the file `%.d` as a rule file and include any 110 additional rules (without recipes) as dependencies for the current rule. If the 111 file does not exist it is ignored, and any rules from the file that can't be 112 satisfied are ignored instead of returned as errors. 113 114 Attributes can also be applied to particular prerequisites rather than to an 115 entire rule, using the syntax `prereq[attributes]`. For example: 116 117 ``` 118 foo:V: 119 echo foo 120 bar:V: foo[Q] 121 echo bar 122 ``` 123 124 The `foo` rule will be quiet only when used as a prerequisite to the `bar` 125 rule. 126 127 Some attributes can only be applied in this way: 128 129 * `I` (implicit): this prereq does not appear in `$input`. 130 131 The `[...][attributes]` syntax can be used to apply attributes to groups of 132 prerequisites. For example, in the following rule all three prerequisites are 133 implicit. 134 135 ``` 136 foo: [a b c][I] 137 ... 138 ``` 139 140 ### Recipes 141 142 A recipe is a list of commands to execute, each separated by a newline. They 143 are executed within the `sh` shell. Each command is executed in a separate 144 process, spawned with `sh -c <cmd>`. One implication of this is that a `cd` 145 command will not persist to future commands. If you wish to run multiple 146 commands in the same shell, you should use the shell's features (`&&`, `||`, or 147 `;`) for this. For example, `cd foo; cat bar.txt`. Note that you can use `\` to 148 escape newlines, so that one command can span multiple lines in the recipe. 149 150 Recipes may use variables that will be expanded before the recipe executes. 151 Variables are written with `$var`, or full Lua expressions can be written with 152 `$(expr)`. Variables/expressions are expanded eagerly when the rule is created. 153 If expansion causes an error, the expansion is delayed until rule evaluation 154 (when special build variables are available). You can use `$$` to escape a 155 dollar sign. For example, the recipe `echo $$PWD` will echo the environment 156 variable `PWD`, while `echo $PWD` would attempt to replace `$PWD` with the Lua 157 variable `PWD` when the rule is elaborated. 158 159 Some special variables are available during recipe expansion: 160 161 * `input`: a string of rule's prereqs. 162 * `inputs`: an array of this rule's prereqs. 163 * `output`: a string of this rule's targets. 164 * `outputs`: an array of this rule's targets. 165 * `match`: the value captured with `%` in a meta rule. 166 * `matches`: a list of matches captured by a regular expression meta rule. 167 * `dep`: the name of the dependency file (if it exists) for the rule, defined 168 by the `D[...]` attribute. 169 170 When a rule is encountered, `$` expressions are immediately expanded. If 171 expansion fails, expansion is re-tried when the rule is evaluated (once the 172 inputs/outputs are known). 173 174 Lua expressions should not mix uses of special build variables and Lua local 175 variables. Local variables are only available during immediate expansion, and 176 special build variables are only available during lazy expansion. This 177 constraint may be relaxed in the future if it turns out to be a useful feature. 178 179 ### Out-of-date calculation 180 181 To determine if a rule must be re-run, Knit computes whether its output is 182 up-to-date or not. There are two mechanisms for this: a hash-based one and a 183 timestamp-based one. By default, Knit uses the hash-based mechanism: if a 184 file's hash has changed since the previous build, it is considered out-of-date, 185 and all rules that depend on it must be re-run. When depending on a directory, 186 its hash is the recursive hash of all files within it. The hash-based method is 187 good for small builds, but can become too slow for large builds. In those cases 188 you can disable hashing and use the timestamp-based calculation. 189 190 When hashing is disabled, Knit uses a similar computation to Make that is based 191 on file modification times. If a rule's prerequisites refer to files that have 192 been modified more recently (according to the system's file modification 193 timestamp) than the output file, then the rule is determined to be out-of-date 194 and must be re-run. Other factors may also cause a rule to be re-run, such as 195 if its recipe has changed, or if it has a rebuild attribute. If the file refers 196 to a directory, the system's timestamp is not used. Instead, the modification 197 time of a directory is the timestamp of the most recently modified file in it 198 (or in any sub-directory). Depending on a very large directory may hinder 199 performance. 200 201 Hashing can be disabled on a per-project basis or globally by using the 202 `.knit.toml` configuration file, described the "Configuration" section of this 203 documentation. 204 205 ## Knitfiles 206 207 A Knitfile is a Lua 5.1 program with additional support for rule expressions. 208 The Knitfile ultimately must return a "buildset" -- a list of build rules that 209 are used to construct the build graph. 210 211 A rule is defined in Lua with the `$` syntax: 212 213 ``` 214 $ targets:attributes: prereqs 215 ... 216 ``` 217 218 A rule expression may be assigned to a variable 219 220 ``` 221 local rule = $ foo.o: foo.c 222 gcc -c $input -o $output 223 ``` 224 225 More often, rule expressions are gathered together in a Lua table: 226 227 ``` 228 local rules = { 229 $ foo.o: foo.c 230 gcc -c $input -o $output 231 $ foo: foo.o 232 gcc $input -o $output 233 } 234 ``` 235 236 When you run `knit`, Knit will automatically look for a file called `Knitfile` 237 or `knitfile` (or you can specify a custom name with `-f`). Knit will look in 238 the current directory, and up to ancestor directories if one does not exist in 239 the current directory. This allows you to execute the build from anywhere in 240 your project without fragmenting the build system with multiple Knitfiles. You 241 can still make directory-specific targets that are namespaced relative to that 242 directory with sub-builds. 243 244 If you run `knit foo.o` from the `foo` directory, and there is a file 245 `../Knitfile` that defines a rule for building `foo/foo.o`, Knit will 246 automatically figure out that you mean to build `foo/foo.o` (relative to `..`), 247 since you specified `foo.o` (relative to `foo`). In other words, building 248 sub-files just works. 249 250 Likewise, if you run `knit all` from the `foo` directory, and the `all` rule 251 is only defined for the root directory, Knit will automatically use that rule 252 instead of trying to use `foo/all`. 253 254 ### Deviations from Lua 5.1 255 256 There are some differences between Knit Lua and Lua 5.1: 257 258 * Knit supports `$` for creating rules. 259 * Knit supports `:=` for creating raw strings. 260 * Knit will give an error message when attempting to access an undeclared 261 variable, whereas Lua 5.1 will just return nil for the value. 262 263 ## Rulesets 264 265 A table of rules can be converted into a "ruleset" by using the special `r` 266 function, which converts the table into a Lua "userdata" object representing a 267 list of build rules. 268 269 270 ``` 271 local ruleset = r{ 272 $ foo.o: foo.c 273 gcc -c $input -o $output 274 $ foo: foo.o 275 gcc $input -o $output 276 } 277 ``` 278 279 Note that two rulesets may be combined with the `+` operator. 280 281 ``` 282 ruleset = ruleset + r{ 283 $ build:V: foo 284 } 285 ``` 286 287 ## Buildsets 288 289 A buildset is a set of rules associated with a particular directory. A buildset 290 may also contain other buildsets (rules from other directories). All rules in 291 the buildset are executed relative to its directory. A buildset can be 292 constructed by using the special `b` function, which constructs a buildset from 293 a table of rules, rulesets, or other buildsets. 294 295 ``` 296 local buildset = b{ 297 $ foo.o: foo.c 298 gcc -c $input -o $output 299 $ foo: foo.o 300 gcc $input -o $output 301 } 302 ``` 303 304 By default the buildset's directory is the current working directory when it is 305 constructed. A second argument may also be passed to `b` to directly specify the 306 build directory. 307 308 ``` 309 local buildset = b({ 310 $ foo.o: foo.c 311 gcc -c $input -o $output 312 $ foo: foo.o 313 gcc $input -o $output 314 }, "directory") 315 ``` 316 317 A buildset must be returned by the Knitfile for a build to take place. When a 318 buildset is returned, knit expands it and all the buildsets that it returns 319 into the full set of rules, where each rule is relative to the buildset 320 directory that it came from. Rules may have cross-buildset dependencies. 321 322 These facilities for making rules relative to directories are for enabling 323 sub-builds, discussed in the next section. 324 325 ### Sub-builds 326 327 A build may use several buildsets. 328 329 For example: 330 331 ```lua 332 -- this buildset is relative to the "libfoo" directory 333 local foorules = b({ 334 $ foo.o: foo.c 335 gcc -c $input -o $output 336 }, "libfoo") 337 338 return b{ 339 $ prog.o: prog.c 340 gcc -c $input -o $output 341 -- libfoo/foo.o is automatically resolved to correspond to the rule in foorules 342 $ prog: prog.o libfoo/foo.o 343 gcc $input -o $output 344 345 -- include the foorules buildset 346 foorules 347 } 348 ``` 349 350 This Knitfile assumes the build consists of `prog.c` and `libfoo/foo.c`. It 351 builds `libfoo/foo.o` using a sub-build and automatically determines that the 352 `foorules` buildset contains the rule for building `libfoo/foo.o`. Note that 353 the recipe for `foo.o` is run in the `libfoo` directory. Including a buildset 354 inside another will automatically including all of its rules namespaced into 355 the directory that the buildset came from. 356 357 It is also useful to combine sub-builds with the `include(x)` function, which 358 runs the knit program `x` from the directory where it exists, and returns the 359 value that `x` produces. This means you can easily use a sub-directory's 360 Knitfile to create a buildset for use in a sub-build. 361 362 For example, for the previous build we could use the following file system 363 structure: 364 365 `libfoo/build.knit` contains: 366 367 ```lua 368 -- this buildset's directory will be the current working directory 369 return b{ 370 $ foo.o: foo.c 371 gcc -c $input -o $output 372 } 373 ``` 374 375 `Knitfile` contains: 376 377 ```lua 378 return b{ 379 $ prog.o: prog.c 380 gcc -c $input -o $output 381 -- libfoo/foo.o is automatically resolved to correspond to the rule in foorules 382 $ prog: prog.o libfoo/foo.o 383 gcc $input -o $output 384 385 -- include the libfoo rules: this will change directory into libfoo, execute 386 -- build.knit, and change back to the current directory, thus giving us a buildset 387 -- for the libfoo directory automatically 388 include("libfoo/build.knit") 389 } 390 ``` 391 392 Note that since knit looks upwards for the nearest Knitfile, you can run `knit 393 foo.o` from inside `libfoo`, and knit will correctly build `libfoo/foo.o`. 394 395 Since managing the current working directory is important for easily creating 396 buildsets that automatically reference the correct directory, there are several 397 functions for this: 398 399 * `include(x)`: runs a Lua file from the directory where it exists. 400 * `dcall(fn, args)`: calls a Lua function from the directory where it is defined. 401 * `dcallfrom(dir, fn, args)`: calls a Lua function from a specified directory. 402 * `rel(files)`: makes all input files relative to the build's root directory. 403 404 ## Configuration 405 406 Knit will search the current directory for a Knitfile called `knitfile` or 407 `Knitfile`. If one is not found, it will use the Knitfile in 408 `~/.config/knit/Knitfile.def`, or if that does not exist it will throw an 409 error. 410 411 Several options are available as command-line flags. They may also be specified 412 in a `.knit.toml` file. Knit will search upwards from the current directory 413 for `.knit.toml` files, and use the options set in those files. It will also 414 search `~/.config/knit/.knit.toml`. 415 416 The default set of flags is: 417 418 ```toml 419 knitfile = "knitfile" 420 ncpu = 8 # depends on the number of logical cores on your machine 421 dryrun = false 422 directory = "" 423 always = false 424 quiet = false 425 style = "basic" 426 cache = "" 427 hash = true 428 updated = [] 429 root = false 430 keepgoing = false 431 shell = "sh" 432 ``` 433 434 ## Sub-tools 435 436 Running `knit [TARGET]` will create a build graph for the target. By default, 437 knit will then execute that build graph. Using the `-t TOOL` option, you may 438 specify a sub-tool to run instead of building: 439 440 * `list` - list all available tools 441 * `graph` - print build graph in specified format: text, tree, dot, pdf 442 * `clean` - remove all files produced by the build 443 * `targets` - list all targets (pass 'virtual' for just virtual targets) 444 * `compdb` - output a compile commands database 445 * `commands` - output the build commands (formats: knit, json, make, ninja, shell) 446 * `status` - lists dependencies and whether they are up-to-date 447 * `path` - shows the path of the current knitfile 448 449 The special target `:all` depends on every target in the build. Thus `knit :all 450 -t targets` will list all targets. 451 452 Some examples are shown below. 453 454 ### Automatic cleaning 455 456 ``` 457 knit target -t clean 458 ``` 459 460 ### Output a shell script for the build 461 462 ``` 463 knit target -t commands shell 464 ``` 465 466 ### Output a Ninja build file 467 468 ``` 469 knit target -t commands ninja 470 ``` 471 472 ### Output a compile commands database 473 474 ``` 475 knit target -t compdb 476 ``` 477 478 ### Output a PDF build graph 479 480 ``` 481 knit target -t graph pdf > graph.pdf 482 ``` 483 484 ## Special rules 485 486 Knit automatically defines two special rules: `:all` and `:build`. 487 488 The `:all` rule depends on all possible targets in the build (except those 489 attainable only from meta-rules). For example `knit :all -t targets` will list 490 all possible targets, and `knit :all -t clean` will clean all possible outputs. 491 492 The `:build` rule is the root rule of the build and depends on all requested 493 targets. For example `knit a b c` will generate a `:build` rule that depends on 494 `a`, `b`, and `c`. In general, you should never refer to the `:build` rule 495 since doing so will usually create a build cycle. 496 497 ## Default rule 498 499 If you run `knit` without a target, Knit will build the first non-meta rule. 500 501 ## Rule priority 502 503 If several rules with recipes that could be used to build a file, Knit uses the 504 last one. In other words, defining a rule later will override previous 505 definitions of a rule. However, if a later rule does not have a recipe, it will 506 not override the rule for the target, but instead just add the new 507 prerequisites for that target to the previous rule. 508 509 If several rules from different buildsets could be used to build a target, the 510 rule from the buildset for the target's directory is attempted first. If it 511 does not exist, then rules are attempted from all other buildsets and the first 512 buildset to have a matching rule is used. If a meta-rule is used, it is 513 attmpted in the current buildset before looking in other buildsets. 514 515 ## Built-in Lua syntax 516 517 * `$ ...`: creates a rule. The rule is formatted using string interpolation. 518 The rule continues until indentation returns to the level of the `$`. 519 520 * `x := ...`: creates a string without quotes. The string value continues until 521 the end of the line, and is automatically formatted using string 522 interpolation. 523 524 Both of these expressions are implicitly terminated with a `;`, allowing them 525 to be used in tables. 526 527 ## Built-in Lua functions 528 529 Note: several functions throw errors. Use the built-in Lua `pcall` function to 530 perform error handling. `local ok, result = pcall(fn, args)` returns whether 531 there was an error during the execution of `fn(args)`. The `result` variable 532 will contain the result, or the error value. 533 534 * `rule(rule)`: define a rule. The `$` syntax is shorthand for this function. 535 536 * `rulefile(file)`: define a rule by reading it from `file`. Throws an error if 537 the file does not exist. 538 539 * `include(file)`: run a Knitfile from its directory (changes the 540 current working directory while the file is being executed) and return the 541 generated ruleset. Throws an error if `file` does not exist. 542 543 * `dcall(fn, args)`: call `fn(args)` from the directory where `fn` is defined. 544 545 * `dcallfrom(dir, fn, args)`: call `fn(args)` from `dir`. 546 547 * `rel(files)`: make all paths in the table `files` relative to the build root 548 (the location of the Knitfile). 549 550 * `r{$ ...}`, `r({...})`: turn a table of rules into a ruleset. 551 552 * `b{...}`, b({...}, dir): turn a table of rules, rulesets, or buildsets 553 into a buildset associated with directory `dir`. `dir` is optional, and if 554 not specified will be the current working directory. 555 556 * `tobool(value)` bool: convert an arbitrary value to a boolean. A nil value 557 will return nil, the strings `false`, `off`, or `0` will become false. A 558 boolean will not be converted. Anything else will be true. 559 560 * `eval(code)`: evaluates a Lua expression in the global scope 561 and returns the result. Throws an error if the code has an error. 562 563 * `f"..."`, `f(s)`: formats a string using `$var` or `$(expr)` to 564 expand variables/expressions. Throws an error if the variable does not exist, 565 or the expression has an error. 566 567 * `expand(s)`: formats a string in the same way as `f`, but if there is an 568 error, it does not expand that particular `$...` expression. 569 570 * `use(pkg)`: imports all fields of `pkg` into the global namespace. Meant to 571 be used with `require`: `use(require("knit"))`. 572 573 * `sel(cond, a, b)`: if `cond` is true return `a`, otherwise return `b`. 574 575 * `choose(a, b, c...)`: return the first value in the list of arguments that is 576 not nil. 577 578 * `r{} + r{}`: you may use the `+` operator to combine rulesets together. 579 580 * `b{} + val`: you may use the `+` operator to combine buildsets with 581 rules/rulesets/buildsets. 582 583 * `{s} + {s}`: string tables returned by knit functions can be added together. 584 585 ## The `knit` Lua package 586 587 The `knit` package can be imported with `require("knit")`, and provides the following functions: 588 589 * `repl(in, patstr, repl)`: replace all occurrences of the Go regular 590 expression `patstr` with `repl` within the array `in`. Throws an error if 591 there is an error with `patstr`. 592 593 * `extrepl(in, ext, repl)`: replace all occurrences of the literal string `ext` 594 as a suffix with `repl` within the array `in`. 595 596 * `glob(pat)`: return all files in the current working directory that match the 597 glob `pat`. 598 599 * `suffix(in, suffix)`: add the string `suffix` to the end of every string in 600 the array `in`, and return the new array. 601 602 * `prefix(in, prefix)`: add the string `prefix` to the beginning of every 603 string in the array `in`, and return the new array. 604 605 * `filterout(in, exclude)`: returns a new table containing all the elements of 606 `in`, except those in `exclude`. 607 608 * `shell(cmd) string`: execute a command with the shell and return its 609 output. Throws an error if the command exits with an error. 610 611 * `trim(s)`: trim leading and trailing whitespace from a string. 612 613 * `abs(path)`: return the absolute path of a path. 614 615 * `dir(path)`: return the directory part of a path. 616 617 * `base(path)`: return the basename of a path. 618 619 * `os`: a string containing the operating system name. 620 621 * `arch`: a string containing the machine architecture name. 622 623 * `flags`: a struct containing the values of the flags when Knit was invoked. 624 See https://pkg.go.dev/github.com/zyedidia/knit#Flags. 625 626 * `addpath(p)`: adds the path `p` to the global require path. Files with ending 627 with `.lua` or `.knit` are added. 628 629 * `knit(flags)`: executes the shell command `knit flags` (where `flags` is a 630 string of CLI arguments) using the current instance of Knit. 631 632 ## CLI and environment variables 633 634 Variables may be set at the command-line when invoking Knit with the syntax 635 `var=value`. These variables will be available in the Knitfile in the `cli` 636 table. Environment variables are similarly available in the `env` table.