Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash --norc
- ## script to build c-source files with gcc allowing minimal cli input. There are
- # two required arguments: an output file <ofile> and the c-source <file.c>. The
- # default usage is:
- #
- # $ ./bgc.sh <ofile> <file.c> (calls: gcc -Wall -o bin/<ofile> <file.c>)
- #
- # The output executable is place in the ./bin directory. It is created as needed.
- #
- # An option to log gcc output is provided through '-log'. All remaining arguments
- # are taken to be additional cflags. If '-log' is provided, then the compile log
- # is place in ./log/<ofile>_gcc.log. The ./log dir is created as needed. Example:
- #
- # $ ./bgc.sh <ofile> <file.c> -Wextra -log -Wunused -Werror
- #
- # gcc -Wall -Wextra -Wunused -Werror -o bin/<ofile> <file.c> 1>&2 \
- # | tee -a log/<ofile>_gcc.log
- #
- # If the file './bldflags' exists in the present directory, its contents are
- # read into the script as additional flags to pass to gcc. It is intended to
- # provide a simple way of specifying additional libraries common to the source
- # files to be built. (e.g. -lssl -lcrypto)
- #
- # an alias g='./bgc.sh' further reduces typing (pick your favorite letter)
- #
- # you can create a 'bldflags' file in the present working directory that
- # hold additional directives for gcc. For using custom libraries of your
- # own making, the following bldflags file will allow automatic header
- # inclusion and library inclusion via rpath from non-std directories:
- #
- # -I/home/david/inc -L/home/david/lib -Wl,-rpath=/home/david/lib
- #
- function help {
- local ecode=${2:-0}
- [[ -n $1 ]] && printf "\n $1\n" >&2
- cat >&2 << helpMessage
- Usage: ${0##*/} <ofile> <file.c> [ <cflags> ... --log [ \$(<./bldflags)]]
- ${0##*/} calls 'gcc -Wall -o <ofile> <file.c> <cflags> <\$(<./bldflags)>'
- If the file './bldflags' exists in the present directory, its contents are
- read into the script as additional flags to pass to gcc. It is intended to
- provide a simple way of specifying additional libraries common to the source
- files to be built. (e.g. -lssl -lcrypto).
- If the -log option is given, then the compile string and compiler ouput are
- written to a long file in ./log/<ofile>_gcc.log
- Options:
- -h | --help program help (this file)
- -l | --log write compile string and compiler ouput to ./log/<ofile>_gcc.log
- helpMessage
- exit $ecode
- }
- function usage {
- local ecode=${2:-0}
- [[ -n $1 ]] && printf "\n $1\n" >&2
- printf "\n Usage: %s <ofile> <file.c> [ <cflags> ... --log [ \$(<./bldflags)]]\n\n" "${0##*/}"
- exit $ecode
- }
- logfn="log/${1}_gcc.log"
- tstamp="$(date '+%b %e %T')"
- mklog=-1
- numargs="${#@}"
- debug=0
- opt=""
- cflags="-Wall -Wextra -pedantic -finline-functions -std=gnu11"
- ## get gcc version for -0fast options check
- gccv=$(gcc --version |
- head -n1 |
- sed -e 's/^.*\([0-9][.][0-9][.][0-9]\).*$/\1/')
- gccvn=${gccv//./} ## convert version to number (e.g. 5.2.0 -> 520)
- ## test for help and log flags and parse remaining args as cflags
- for i in $*; do
- test "$i" = "-h" || test "$i" = "--help" && help
- test "$i" = "-l" || test "$i" = "--log" && mklog=0
- test "$i" = "-g" && debug=1
- test "${i:0:2}" = "-O" && opt="$i"
- done
- test -n "$1" && test -n "$2" || usage "error: insufficient input" 1
- test "${2//*\.}" = "c" || usage "error: invalid input, '$2' is not a C-file (.c)" 1
- test -f "$2" || usage "error: file not found '$2'" 1
- if test -z "$opt" ; then
- if test $gccvn -ge 460 ; then ## check gcc version >= 4.6.0 for -0fast options
- test "$debug" -eq 1 || cflags="${cflags} -Ofast"
- else
- test "$debug" -eq 1 || cflags="${cflags} -O3"
- fi
- fi
- if test "$mklog" -eq -1; then
- test "$numargs" -gt 2 && cflags="${cflags} ${@:3}"
- elif test "$numargs" -ge 3; then
- for i in "${@:3}"; do
- test "$i" = "-l" && continue
- test "$i" = "--log" && continue
- cflags="${cflags} $i"
- done
- fi
- ## if "./bldflags" exist, read contents into ldflags
- test -f "./bldflags" && ldflags="$(<./bldflags)"
- ## test for file bin, move if exists, create bin dir
- test -f "bin" && mv "bin" "bin.sav"
- mkdir -p "bin"
- ## provide $cflags for any additional options or flags desired
- # $cflags must be unquoted to prevent resolving to "" when empty
- # and should remain uninitialized unless and until set
- if test "$mklog" -eq 0; then
- ## test for file log, move if exists, create log dir
- test -f "log" && mv "log" "log.sav"
- mkdir -p "log"
- printf -- "--\n gcc $cflags -o bin/%s %s $ldflags | tee -a %s\n--\n" "$1" "$2" "$logfn"
- printf " %s gcc %s -o bin/%s %s %s\n" "$tstamp" "$cflags" "$1" "$2" "$ldflags" | tee -a "$logfn"
- gcc $cflags -o "bin/$1" "$2" $ldflags 2>&1 | tee -a "$logfn"
- else
- printf -- "--\n gcc $cflags -o bin/%s %s $ldflags\n--\n" "$1" "$2"
- gcc $cflags -o "bin/$1" "$2" $ldflags
- fi
- exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement