build 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #!/bin/sh
  2. # Build script for the project.
  3. # For details on the basic form of this script, see https://git.sr.ht/~akkartik/basic-build/tree/master/Readme.md
  4. set -e # stop immediately on error
  5. ## prologue: environment defaults
  6. test "$CC" || export CC=cc
  7. test "$CFLAGS" || export CFLAGS="-g -O3"
  8. # some additional flags for safety
  9. export CFLAGS="$CFLAGS -std=c99 -Wall -Wextra -ftrapv -fno-strict-aliasing"
  10. ## helpers
  11. # {{{
  12. # noisily signal success if $1 is older than _any_ of the remaining args
  13. older_than() {
  14. local target=$1
  15. shift
  16. if [ ! -e $target ]
  17. then
  18. echo "updating $target" >&2
  19. return 0 # success
  20. fi
  21. local f
  22. for f in $*
  23. do
  24. if [ $f -nt $target ]
  25. then
  26. echo "updating $target" >&2
  27. return 0 # success
  28. fi
  29. done
  30. return 1 # failure
  31. }
  32. # noisily switch directories, as a sort of section heading to group older_than blocks
  33. noisy_cd() {
  34. cd $1
  35. echo "-- `pwd`" >&2
  36. }
  37. # redirect to $1, unless it's already identical
  38. update() {
  39. if [ ! -e $1 ]
  40. then
  41. cat > $1
  42. else
  43. cat > $1.tmp
  44. diff -q $1 $1.tmp >/dev/null && rm $1.tmp || mv $1.tmp $1
  45. fi
  46. }
  47. # }}}
  48. ## body: things to generate, what they depend on, and how to generate them from their dependencies
  49. # auto-generate a list of function prototypes
  50. grep -h "^[^ #].*) {" *.c |sed 's/ {.*/;/' |update function_list
  51. # auto-generate a list of test names
  52. grep -h "^\s*void test_" *.c |sed 's/^\s*void \(.*\)(void) {.*/\1,/' |update test_list
  53. grep -h "^\s*void test_" *.c |sed 's/^\s*void \(.*\)(void) {.*/"\1",/' |update test_name_list
  54. older_than a.out *.c *.h function_list test_list test_name_list && {
  55. $CC $CFLAGS *.c
  56. }
  57. ## epilogue
  58. # if we got to the end, signal success
  59. # otherwise you incorrectly signal failure when the final target is not older_than its dependencies
  60. exit 0