about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--COPYING26
-rw-r--r--README142
2 files changed, 168 insertions, 0 deletions
diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..d745fba --- /dev/null +++ b/COPYING
@@ -0,0 +1,26 @@
1Copyright (C) Case Duckworth
2
3Redistribution and use in source and binary forms, with or without modification,
4are permitted provided that the following conditions are met:
5
61. Redistributions of source code must retain the above copyright notice, this
7list of conditions and the following disclaimer.
8
92. Redistributions in binary form must reproduce the above copyright notice,
10this list of conditions and the following disclaimer in the documentation and/or
11other materials provided with the distribution.
12
133. Neither the name of the copyright holder nor the names of its contributors
14may be used to endorse or promote products derived from this software without
15specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
18ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
21ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
diff --git a/README b/README new file mode 100644 index 0000000..93f1b6b --- /dev/null +++ b/README
@@ -0,0 +1,142 @@
1ok : a minimal build system in posix sh
2
3ok is a minimal build system that's kinda like make in that you plop a file
4describing your build in your project's folder, then run a system command that
5reads the file and builds the project. it's written in posix sh and is designed
6to be strictly more expressive than posix make, which is awful.
7
8[[ INSTALLING ]]
9
10ok is just a shell script, so you can mv or cp it to your $PATH. It requires a
11somewhat-modern posix-compliant shell (i am not going to figure out what
12"somewhat-modern" means), as well as the following utilities:
13
14- sed
15- grep
16- cut
17
18if you don't have these, congratulations! You are really doing something
19interesting with your system.
20
21[[ USING OK ]]
22
23If the project you're hacking on has an okfile (by default, ./ok), you can just
24run ok and it'll do whatever the author made the default target. You can also
25run ok with the following flags:
26
27- -h shows a help message, then exits
28- -q runs ok in "quiet" mode; that is, no messages are printed
29- -x runs ok with "set -x" turned on; this is a shell feature
30 that might help you debug some weirdness
31- -n runs ok in "dry-run" mode; that is, no recipes are run
32- -B run all targets as if they were "new," like make -B
33- -f FILE use FILE as the okfile instead of ./ok
34- -C DIR change to DIR before doing anything, like make -C
35
36ok -h will also print the targets it's found in the okfile, along with
37explanatory comments provided on the target's first lines. See the example
38provided below for an idea.
39
40[[ WRITING OKFILES ]]
41
42of course, the real part of using ok is writing the okfile. This section
43describes the format of that file, which is a shell script sourced by ok, to
44help you write good okfiles for your own projects.
45
46an okfile is simply a shell script where every function defined is a target.
47The first function in the script is the default target that runs if no target is
48specified. ok has a few utility functions to make writing targets easier:
49
50- ok : print, then run the command given after it on the command line. if -q
51 has been passed, suppress printing; if -n has been passed, suppress
52 running. if the command fails, ok will exit with 100 + the command's
53 exit code.
54
55- dep : define a dependency on the targets specified as arguments. the
56 dependencies will be run in the order of the command line before
57 continuing with the current recipe.
58
59- fr : define a series of file rules. See the next section for a description of
60 these.
61
62- allfiles : print all the files defined in the fr call.
63
64[[ FILE RULES (FR) ]]
65
66while writing shell functions is fine and dandy to simulate make's .PHONY rules,
67it does nothing for the main use of make: generating files from other files.
68The solution i landed on for ok was the fr function, which is short for file
69rules. This section describes the format of fr's input, as well as suggestions
70for use.
71
72fr reads lines from standard input, processes them, and outputs them to an
73frfile in the current directory (which can be safely deleted, and is in fact
74rebuilt on every invocation). I recommend using a heredoc for building the file
75rules, since that allows free-form text as well as programmatic rule generation
76(something make does not do).
77
78each line fr reads will be parsed as a TARGET, a JOB, and the JOB's DEPS. The
79TARGET is the target file to build, JOB is the job to run to build that file,
80and DEPS are all the dependencies of TARGET.
81
82DEPS can include both build and order dependencies. Build dependencies are
83appended to JOB as arguments, while order dependencies merely force TARGET to be
84built if it's newer than them. TODO: THERE IS A BUG IN THIS IMPLEMENTATION.
85ORDER DEPENDENCIES ARE CURRENTLY IGNORED.
86
87JOB should be a function defined in the okfile or a one-word command, since fr
88doesn't do any special $IFS magic. I recommend creating an ok function that
89encapsulates JOB's logic and including that in the fr block.
90
91[[ FR EXAMPLE ]]
92
93since fr is possibly the most complex thing to understand for ok, here is an
94example. This okfile is how i build a simple 'hello, world' program in C[1]:
95
96---------------------------------------------->8
97for c in *.c
98do echo "${c%.c}" build "$c"
99done | fr
100
101: "${CC:=cc}"
102
103default() { dep allfiles; }
104
105build() { # build an executable from a c source file
106 ok "$CC" "$1" -o "$TARGET"
107}
1088<----------------------------------------------
109
110as you can see, providing a heredoc to fr's input means i can build up the flies
111i want to build dynamically, rather than having to update the okfile every time.
112This fr invocation produces the following file[2]:
113
114---------------------------------------------->8
115hello ok build hello.c
1168<----------------------------------------------
117
118in this simple example, i could've written this just as well:
119
120---------------------------------------------->8
121fr<<..
122hello build hello.c
123..
1248<----------------------------------------------
125
126you can depend on all files that need building using the 'allfiles' target, so
127it's a good idea to put a 'dep allfiles' somewhere in your build functions. you
128can see it above in the 'default' rule.
129
130[[ COPYING AND CONTRIBUTING ]]
131
132ok is distributed under a standard BSD 3-clause license. Contributions are
133welcome; feel free to email me[3] with feedback, questions, or patches.
134
135[[ INSPIRATION ]]
136
137thanks to akkartik, whose basic-build[4] gave me the inspiration for ok.
138
139[1] https://www.helloworldin.com/c.html, e.g.
140[2] https://www.acdw.net/.fr
141[3] mailto:git@acdw.net
142[4] https://git.sr.ht/~akkartik/basic-build \ No newline at end of file