Advertisement
drankinatty

gcc build script (alias to 'g')

Nov 26th, 2015
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 4.85 KB | None | 0 0
  1. #!/bin/bash --norc
  2.  
  3. ## script to build c-source files with gcc allowing minimal cli input. There are
  4. #  two required arguments: an output file <ofile> and the c-source <file.c>. The
  5. #  default usage is:
  6. #
  7. #   $ ./bgc.sh <ofile> <file.c>  (calls: gcc -Wall -o bin/<ofile> <file.c>)
  8. #
  9. #  The output executable is place in the ./bin directory. It is created as needed.
  10. #
  11. #  An option to log gcc output is provided through '-log'. All remaining arguments
  12. #  are taken to be additional cflags. If '-log' is provided, then the compile log
  13. #  is place in ./log/<ofile>_gcc.log. The ./log dir is created as needed. Example:
  14. #
  15. #   $ ./bgc.sh <ofile> <file.c> -Wextra -log -Wunused -Werror
  16. #
  17. #     gcc -Wall -Wextra -Wunused -Werror -o bin/<ofile> <file.c> 1>&2 \
  18. #     | tee -a log/<ofile>_gcc.log
  19. #
  20. #  If the file './bldflags' exists in the present directory, its contents are
  21. #  read into the script as additional flags to pass to gcc. It is intended to
  22. #  provide a simple way of specifying additional libraries common to the source
  23. #  files to be built. (e.g. -lssl -lcrypto)
  24. #
  25. #  an alias g='./bgc.sh' further reduces typing (pick your favorite letter)
  26. #
  27. #  you can create a 'bldflags' file in the present working directory that
  28. #  hold additional directives for gcc. For using custom libraries of your
  29. #  own making, the following bldflags file will allow automatic header
  30. #  inclusion and library inclusion via rpath from non-std directories:
  31. #
  32. #  -I/home/david/inc -L/home/david/lib -Wl,-rpath=/home/david/lib
  33. #
  34.  
  35. function help {
  36.   local ecode=${2:-0}
  37.  
  38.   [[ -n $1 ]] && printf "\n $1\n" >&2
  39.  
  40. cat >&2 << helpMessage
  41.  
  42.   Usage: ${0##*/} <ofile> <file.c> [ <cflags> ... --log [ \$(<./bldflags)]]
  43.  
  44.     ${0##*/} calls 'gcc -Wall -o <ofile> <file.c> <cflags> <\$(<./bldflags)>'
  45.     If the file './bldflags' exists in the present directory, its contents are
  46.     read into the script as additional flags to pass to gcc. It is intended to
  47.     provide a simple way of specifying additional libraries common to the source
  48.     files to be built. (e.g. -lssl -lcrypto).
  49.  
  50.     If the -log option is given, then the compile string and compiler ouput are
  51.     written to a long file in ./log/<ofile>_gcc.log
  52.  
  53.   Options:
  54.  
  55.     -h  |  --help  program help (this file)
  56.     -l  |  --log   write compile string and compiler ouput to ./log/<ofile>_gcc.log
  57.  
  58. helpMessage
  59.  
  60.   exit $ecode
  61. }
  62.  
  63. function usage {
  64.   local ecode=${2:-0}
  65.  
  66.   [[ -n $1 ]] && printf "\n $1\n" >&2
  67.  
  68.   printf "\n  Usage: %s <ofile> <file.c> [ <cflags> ... --log [ \$(<./bldflags)]]\n\n" "${0##*/}"
  69.  
  70.   exit $ecode
  71. }
  72.  
  73. logfn="log/${1}_gcc.log"
  74. tstamp="$(date '+%b %e %T')"
  75. mklog=-1
  76. numargs="${#@}"
  77. debug=0
  78. opt=""
  79. cflags="-Wall -Wextra -pedantic -finline-functions -std=gnu11"
  80.  
  81. ## get gcc version for -0fast options check
  82. gccv=$(gcc --version |
  83.        head -n1 |
  84.        sed -e 's/^.*\([0-9][.][0-9][.][0-9]\).*$/\1/')
  85. gccvn=${gccv//./}   ## convert version to number (e.g. 5.2.0 -> 520)
  86.  
  87. ## test for help and log flags and parse remaining args as cflags
  88. for i in $*; do
  89.     test "$i" = "-h" || test "$i" = "--help" && help
  90.     test "$i" = "-l" || test "$i" = "--log" && mklog=0
  91.     test "$i" = "-g" && debug=1
  92.     test "${i:0:2}" = "-O" && opt="$i"
  93. done
  94.  
  95. test -n "$1" && test -n "$2" || usage "error: insufficient input" 1
  96. test "${2//*\.}" = "c" || usage "error: invalid input, '$2' is not a C-file (.c)" 1
  97. test -f "$2" || usage "error: file not found '$2'" 1
  98. if test -z "$opt" ; then
  99.     if test $gccvn -ge 460 ; then   ## check gcc version >= 4.6.0 for -0fast options
  100.         test "$debug" -eq 1 || cflags="${cflags} -Ofast"
  101.     else
  102.         test "$debug" -eq 1 || cflags="${cflags} -O3"
  103.     fi
  104. fi
  105.  
  106. if test "$mklog" -eq -1; then
  107.     test "$numargs" -gt 2 && cflags="${cflags} ${@:3}"
  108. elif test "$numargs" -ge 3; then
  109.     for i in "${@:3}"; do
  110.         test "$i" = "-l" && continue
  111.         test "$i" = "--log" && continue
  112.         cflags="${cflags} $i"
  113.     done
  114. fi
  115.  
  116. ## if "./bldflags" exist, read contents into ldflags
  117. test -f "./bldflags" && ldflags="$(<./bldflags)"
  118.  
  119. ## test for file bin, move if exists, create bin dir
  120. test -f "bin" && mv "bin" "bin.sav"
  121. mkdir -p "bin"
  122.  
  123. ## provide $cflags for any additional options or flags desired
  124. #  $cflags must be unquoted to prevent resolving to "" when empty
  125. #  and should remain uninitialized unless and until set
  126. if test "$mklog" -eq 0; then
  127.  
  128.     ## test for file log, move if exists, create log dir
  129.     test -f "log" && mv "log" "log.sav"
  130.     mkdir -p "log"
  131.  
  132.     printf -- "--\n  gcc $cflags -o bin/%s %s $ldflags | tee -a %s\n--\n" "$1" "$2" "$logfn"
  133.     printf "  %s  gcc %s -o bin/%s %s %s\n" "$tstamp" "$cflags" "$1" "$2" "$ldflags" | tee -a "$logfn"
  134.     gcc $cflags -o "bin/$1" "$2" $ldflags 2>&1 | tee -a "$logfn"
  135. else
  136.     printf -- "--\n  gcc $cflags -o bin/%s %s $ldflags\n--\n" "$1" "$2"
  137.     gcc $cflags -o "bin/$1" "$2" $ldflags
  138. fi
  139.  
  140. exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement