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 'bin = %s\n' "$target"
32printf 'cc = $${CC:-cc}\n'
33printf 'cflags = $${CFLAGS:--O2 -std=c99}\n'
34printf 'ldflags = $${LDFLAGS:-}\n'
35printf 'libs = $${LIBS:-}\n'
36printf 'prefix = $${PREFIX:-/usr/local}\n'
37printf 'destdir = $${DESTDIR:-}\n'
38printf 'bindir = $${BINDIR:-$${DESTDIR:-}$${PREFIX:-/usr/local}/bin}\n'
39printf '\n'
40printf 'rule cc\n'
41printf ' command = $cc $cflags -MMD -MF $out.d -c -o $out $in\n'
42printf ' deps = gcc\n'
43printf ' depfile = $out.d\n'
44printf ' description = cc $out\n'
45printf '\n'
46printf 'rule link\n'
47printf ' command = $cc $ldflags -o $out $in $libs\n'
48printf ' description = link $out\n'
49printf '\n'
50printf 'rule install\n'
51printf ' command = mkdir -p $bindir && cp $in $bindir/\n'
52printf ' description = install $bin\n'
53printf '\n'
54
55while IFS= read -r src; do
56 [ -n "$src" ] || continue
57 case $src in
58 *.c) ;;
59 *) continue ;;
60 esac
61 obj=${src%.c}.o
62 printf 'build %s: cc %s\n' "$obj" "$src"
63 if [ $first -eq 1 ]; then
64 objs=$obj
65 first=0
66 else
67 objs="$objs $obj"
68 fi
69done
70
71if [ $first -eq 1 ]; then
72 printf '%s: no .c files on stdin\n' "${0##*/}" >&2
73 exit 1
74fi
75
76printf '\n'
77printf 'build $bin: link %s\n' "$objs"
78printf 'build all: phony $bin\n'
79printf 'build install: install $bin\n'
80printf '\n'
81printf 'default all\n'