Created
May 5, 2020 01:10
-
-
Save garettbass/292013912430b99f126f6cd34188f8bb to your computer and use it in GitHub Desktop.
This is the bash script I run to build C/C++ projects on Windows & macOS.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env | |
CMDLINE="$0 $@" | |
#------------------------------------------------------------------------------- | |
function usage { | |
echo "Usage:" | |
echo "" | |
echo " sh $0 [options] <sources> [-- ...]" | |
echo "" | |
echo "Options:" | |
echo "" | |
echo " -std=<...> Set C/C++ standard, e.g " | |
echo " -D<...>[=...] Define preprocessor macro, e.g.: -DNDEBUG=1" | |
echo " -O<...> Set optimization level, e.g.: -O0, -O1, -O2, -O3, -Ofast, -Os" | |
echo " -g Generate debug symbols." | |
echo " -o <dir> Set output directory." | |
echo " -v Enable verbose output." | |
echo " -x <ext> Specify source language, e.g.: -x c, -x c++" | |
echo " --clean Delete build artifacts." | |
echo " --clear Clear the terminal before building." | |
echo " -- Run the compiled app, passing along remaining arguments." | |
echo "" | |
} | |
#------------------------------------------------------------------------------- | |
function realpath { | |
local path="${1//\\//}" | |
if [ "$path" == "." ]; then | |
echo "$(pwd)" | |
elif [ "$path" == ".." ]; then | |
echo "$(dirname "$(pwd)")" | |
else | |
echo "$(cd "$(dirname "$path")"; pwd)/$(basename "$path")" | |
fi | |
} | |
#------------------------------------------------------------------------------- | |
CFLAGS="$CFLAGS -Wall -Werror -Wfatal-errors -Wno-comment -Wno-unused-variable" | |
SOURCES=() | |
while [ $# -gt 0 ]; do | |
case $1 in | |
-h|--help) | |
usage | |
exit 1 | |
;; | |
-g) | |
CFLAGS="$CFLAGS $1" | |
shift | |
;; | |
-D*|-f*|-I*|-O*|-std=*|-W*) | |
CFLAGS="$CFLAGS $1" | |
shift | |
;; | |
-x) | |
CFLAGS="$CFLAGS $1 $2" | |
shift | |
shift | |
;; | |
-o) | |
APP_BUILD_ROOT="$2" | |
shift | |
shift | |
;; | |
-t|--time) | |
TIME=YES | |
shift | |
;; | |
-v|--verbose) | |
VERBOSE=YES | |
shift | |
;; | |
--clean) | |
CLEAN=YES | |
shift | |
;; | |
--clear) | |
CLEAR=YES | |
shift | |
;; | |
--) | |
RUN=YES | |
shift | |
break | |
;; | |
-*) | |
echo "unrecognized option: $1" | |
echo "" | |
usage | |
exit 1 | |
;; | |
*) | |
SOURCE="$(realpath $1)" | |
SOURCES+=("$SOURCE") | |
shift | |
;; | |
esac | |
done | |
if [ ! $SOURCES ]; then | |
usage | |
exit 1 | |
fi | |
#------------------------------------------------------------------------------- | |
if [ $CLEAR ]; then | |
clear | |
fi | |
#------------------------------------------------------------------------------- | |
bold=$(tput bold) | |
normal=$(tput sgr0) | |
function hline { | |
printf '%*s' "${COLUMNS:-$(tput cols)}" '' | tr ' ' _ | |
} | |
#------------------------------------------------------------------------------- | |
function verbose { | |
if [ $VERBOSE ]; then | |
echo "$@" | \ | |
sed 's/ -/ \\\n -/g' | \ | |
sed 's/ \// \\\n \//g' | |
fi | |
} | |
#------------------------------------------------------------------------------- | |
verbose "$CMDLINE" | |
#------------------------------------------------------------------------------- | |
APP_MAIN="${SOURCES[0]}" | |
APP_NAME="$(basename ${APP_MAIN%.*})" | |
APP_BUILD_ROOT="${APP_BUILD_ROOT:=$(dirname $APP_MAIN)/build}" | |
APP_SCRIPTS_DIR="$(realpath $(dirname $0))" | |
APP_TEMPLATES_DIR="$(dirname $APP_SCRIPTS_DIR)/templates" | |
case $(uname | tr '[:upper:]' '[:lower:]') in | |
darwin*) | |
APP_BUILD_OS=macos | |
APP_BUILD_DIR="$APP_BUILD_ROOT/macos/$APP_NAME.app" | |
APP_BIN="$APP_BUILD_DIR/Contents/MacOS/$APP_NAME" | |
;; | |
linux*) | |
APP_BUILD_OS=linux | |
echo "unsupported operating system" | |
exit 1 | |
;; | |
msys*|mingw*) | |
APP_BUILD_OS=windows | |
APP_BUILD_DIR="$APP_BUILD_ROOT/windows/$APP_NAME" | |
APP_BIN="$APP_BUILD_DIR/$APP_NAME.exe" | |
CFLAGS="${CFLAGS} -D_CRT_SECURE_NO_WARNINGS" | |
CLANG_CFLAGS="${CLANG_CFLAGS} -fuse-ld=lld" | |
;; | |
*) | |
echo "unsupported operating system" | |
exit 1 | |
;; | |
esac | |
#------------------------------------------------------------------------------- | |
function execute { | |
verbose "$@" | |
if [ $TIME ]; then | |
time --format="${bold}took %Es${normal}\n" "$@" || exit $? | |
else | |
"$@" || exit $? | |
fi | |
if [ $VERBOSE ]; then | |
printf "${bold}\e[32m\xE2\x9C\x93 OK\e[39m${normal}\n" | |
fi | |
} | |
#------------------------------------------------------------------------------- | |
# ensure $APP_BUILD_DIR exists | |
[ -d "$APP_BUILD_DIR" ] || execute mkdir -p "$APP_BUILD_DIR" | |
#------------------------------------------------------------------------------- | |
# copy template content into build dir | |
APP_TEMPLATE_DIR="$APP_TEMPLATES_DIR/$APP_BUILD_OS/." | |
[ -d "$APP_TEMPLATE_DIR" ] && execute cp -rf "$APP_TEMPLATE_DIR" "$APP_BUILD_DIR/" | |
#------------------------------------------------------------------------------- | |
# CC="${CC:=$(command -v cc || command -v gcc || command -v clang)}" | |
CC="${CC:=$(command -v clang)}" | |
# echo CC:"$CC" | |
case $CC in | |
*clang*) | |
CFLAGS="$CFLAGS $CLANG_CFLAGS" | |
;; | |
esac | |
case $($CC --version | tr '[:upper:]' '[:lower:]') in | |
*msys*) | |
CFLAGS="$CFLAGS -Wl,--subsystem,windows" | |
;; | |
esac | |
#------------------------------------------------------------------------------- | |
for SOURCE in "${SOURCES[@]}"; do | |
CFLAGS="$CFLAGS $SOURCE" | |
done | |
execute "$CC" $CFLAGS -o"$APP_BIN" | |
# hline | |
#------------------------------------------------------------------------------- | |
if [ $RUN ]; then | |
echo $'' | |
execute "$APP_BIN" "$@" | |
# echo "$APP_BIN" returned "$?" | |
fi | |
#------------------------------------------------------------------------------- | |
if [ $CLEAN ]; then | |
execute rm -rf "$APP_BUILD_ROOT" | |
fi | |
#------------------------------------------------------------------------------- | |
exit | |
#------------------------------------------------------------------------------- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
hello.cpp
terminal
> sh hello.cpp -- hello world