main
gen
1#!/bin/sh
2# gen is a small generator for ninja build files. before i was hand writing them, but this makes it
3# pretty easy. it takes a list of files from stdin and a target as an argument, soyou can do something
4# like:
5#
6# find. -name '*.c' | gen binary
7#
8# and that will generate ninja to build the binary. you can edit the variables at the top of the file
9# to add any libraries you link, or edit cflags, etc. its's quite simplistic, so it only really works
10# for simple projects with a few C files and a single target. the ninja files are simple enough for
11# users to edit to their liking, so you can just generate them once and ship the generated files.
12#
13# it only works for C sources, and dependency tracking is handled by the compiler. cleaning is handled
14# by ninja, eg 'ninja -t clean'
15
16set -eu
17
18if [ "$#" -ne 1 ]; then
19 printf 'usage: %s target\n' "${0##*/}" >&2
20 exit 2
21fi
22
23target=$1
24objs=
25first=1
26printf "# i know this is a ninja file, but you're allowed to edit it.\n"
27printf "# you can also pass things on the command line if you like, eg\n"
28printf "#\n"
29printf "# CC=clang ninja\n"
30printf "\n"
31printf 'cc = $${CC:-cc}\n'
32printf 'cflags = $${CFLAGS:--O2 -std=c99}\n'
33printf 'ldflags = $${LDFLAGS:-}\n'
34printf 'libs = $${LIBS:-}\n'
35printf 'prefix = $${PREFIX:-/usr/local}\n'
36printf 'destdir = $${DESTDIR:-}\n'
37printf 'bindir = $${BINDIR:-$${DESTDIR:-}$${PREFIX:-/usr/local}/bin}\n'
38printf '\n'
39printf 'rule cc\n'
40printf ' command = $cc $cflags -MMD -MF $out.d -c -o $out $in\n'
41printf ' deps = gcc\n'
42printf ' depfile = $out.d\n'
43printf ' description = cc $out\n'
44printf '\n'
45printf 'rule link\n'
46printf ' command = $cc $ldflags -o $out $in $libs\n'
47printf ' description = link $out\n'
48printf '\n'
49printf 'rule install\n'
50printf ' command = mkdir -p $bindir && cp %s $bindir/\n' "$target"
51printf ' description = install %s\n' "$target"
52printf '\n'
53
54while IFS= read -r src; do
55 [ -n "$src" ] || continue
56 case $src in
57 *.c) ;;
58 *) continue ;;
59 esac
60 obj=${src%.c}.o
61 printf 'build %s: cc %s\n' "$obj" "$src"
62 if [ $first -eq 1 ]; then
63 objs=$obj
64 first=0
65 else
66 objs="$objs $obj"
67 fi
68done
69
70if [ $first -eq 1 ]; then
71 printf '%s: no .c files on stdin\n' "${0##*/}" >&2
72 exit 1
73fi
74
75printf '\n'
76printf 'build %s: link %s\n' "$target" "$objs"
77printf 'build all: phony %s\n' "$target"
78printf 'build install: install %s\n' "$target"
79printf '\n'
80printf 'default all\n'