added 'new' functionality and reworked colors
This commit is contained in:
parent
a24e95fbb6
commit
1e31497a15
1 changed files with 119 additions and 17 deletions
136
cbuild.sh
136
cbuild.sh
|
@ -2,10 +2,10 @@
|
|||
|
||||
# Written by Noah Swerhun
|
||||
# https://noahsw.xyz
|
||||
# Development: https://git.noahsw.xyz/cbuild.sh/log.html
|
||||
# Development: https://git.noahsw.xyz/cbuild.sh/log.html
|
||||
|
||||
# --- USER CONFIG ---
|
||||
CC="gcc"
|
||||
# --- USER CONFIG ---
|
||||
CC="gcc"
|
||||
CFLAGS="-Wall -Wpedantic"
|
||||
LDFLAGS=""
|
||||
LDLIBS=""
|
||||
|
@ -13,19 +13,29 @@ TARGET="a.out"
|
|||
SRCDIR="src"
|
||||
OBJDIR="obj"
|
||||
MAKEFILE=".makefile"
|
||||
|
||||
HEADER_DIR="include"
|
||||
# -------------------
|
||||
|
||||
PROG_COMMAND="./cbuild.sh __progress__"
|
||||
SRC="$(find ${SRCDIR} -name '*\.c')"
|
||||
OBJ="$(find ${SRCDIR} -name '*\.c' |
|
||||
SRC="$(find ${SRCDIR} -name '*\.c' 2> /dev/null)"
|
||||
OBJ="$(find ${SRCDIR} -name '*\.c' 2> /dev/null |
|
||||
sed "s/${SRCDIR}\//${OBJDIR}\//" |
|
||||
sed "s/\.c$/.o/" |
|
||||
tr '\n' ' ')"
|
||||
|
||||
srcnum="$(find ${SRCDIR} -name '*\.c' -exec printf %c {} + | wc -c)"
|
||||
srcnum="$(find ${SRCDIR} -name '*\.c' -exec printf %c {} + 2> /dev/null | wc -c)"
|
||||
|
||||
clear_formatting="\033[0m"
|
||||
bold="\033[1m"
|
||||
info_color="\033[34m" # default: "\033[34m" - blue
|
||||
err_color="\033[31m" # default: "\033[31m" - red
|
||||
build_progress_color="\033[35m" # default: "\033[35m" - magenta
|
||||
build_info_color="\033[32m" # default: "\033[32m" - green
|
||||
link_info_color="\033[36m" # default: "\033[36m" - cyan
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
less <<EOF
|
||||
cbuild.sh: A simple, customizable, automated, and portable build script for C
|
||||
projects. This script works by automatically detecting .c source files in
|
||||
SRCDIR, generating a makefile, compiling them into objects in OBJDIR, and
|
||||
|
@ -44,18 +54,34 @@ Customization:
|
|||
(default: src)
|
||||
OBJDIR the directory where compiled objects will be placed. (default: obj)
|
||||
MAKEFILE the filename of the generated makefile (default: .makefile)
|
||||
|
||||
HEADER_DIR the directory in which header files will be placed by the 'new'
|
||||
command. Note that this is relative to SRCDIR. Setting this to
|
||||
'.' means headers will be placed in the same directory as
|
||||
source files. Setting this to 'include' means headers will be
|
||||
placed in SRCDIR/include. (defualt: include)
|
||||
|
||||
Usage:
|
||||
./cbuild.sh [COMMAND]
|
||||
|
||||
COMMAND:
|
||||
--help display this help message
|
||||
build generate the makefile, compile objects and link target.
|
||||
clean remove makefile, objects, and target.
|
||||
buildcn clean, and then build.
|
||||
generate ONLY generate the makefile.
|
||||
run [ARGS] build, then execute TARGET with arguments ARGS.
|
||||
init equivalent to 'new module main' (see below).
|
||||
dryrun print all commands that will be executed during the build process
|
||||
to stdout.
|
||||
|
||||
new header [NAME] [...]
|
||||
generate a header file with name NAME in HEADER_DIR. Multiple
|
||||
NAMEs may be provided. Including '.h' in NAME is optional.
|
||||
|
||||
new module [NAME] [...]
|
||||
generate a new source file NAME.c in SRCDIR and a new header
|
||||
NAME.h in HEADER_DIR. Multiple NAMEs may be provided.
|
||||
EOF
|
||||
}
|
||||
|
||||
|
@ -70,11 +96,15 @@ export_vars() {
|
|||
}
|
||||
|
||||
info() {
|
||||
printf "[34;1m[*][21m %s[0m\n" "$@"
|
||||
printf "${info_color}${bold}[*]${clear_formatting}\
|
||||
${info_color} %s${clear_formatting} %s${info_color} %s${clear_formatting}\n" \
|
||||
"${1}" "${2}" "${3}"
|
||||
}
|
||||
|
||||
err() {
|
||||
printf "[31;1m[!][21m %s[0m\n" "$@"
|
||||
printf "${err_color}${bold}[!]${clear_formatting}\
|
||||
${err_color} %s${clear_formatting} %s${err_color} %s${clear_formatting}\n" \
|
||||
"${1}" "${2}" "${3}"
|
||||
}
|
||||
|
||||
gen_makefile() {
|
||||
|
@ -124,7 +154,7 @@ build() {
|
|||
export_vars
|
||||
make -f "${MAKEFILE}" -e "${TARGET}" -n | grep -c "^${CC}" > .cbuild_prog.tmp
|
||||
if [ "$(cat .cbuild_prog.tmp)" = 0 ]; then
|
||||
info "Target [0m${TARGET}[34m up to date"
|
||||
info "Target" "${TARGET}" "up to date"
|
||||
rm .cbuild_prog.tmp
|
||||
return 0;
|
||||
fi
|
||||
|
@ -150,9 +180,9 @@ clean() {
|
|||
run() {
|
||||
build || exit $?
|
||||
args="$@"
|
||||
info "Running [0m./${TARGET} ${args}"
|
||||
info "Running" "./${TARGET} ${args}"
|
||||
"./${TARGET}" $@ ||
|
||||
err "Run FAILURE [0m./${TARGET}[31m returned $?"
|
||||
err "Run FAILURE" "./${TARGET}" "returned $?"
|
||||
}
|
||||
|
||||
dry_run() {
|
||||
|
@ -161,17 +191,86 @@ dry_run() {
|
|||
make -f "${MAKEFILE}" -e "${TARGET}" -n
|
||||
}
|
||||
|
||||
new() {
|
||||
case $1 in
|
||||
header)
|
||||
shift 1
|
||||
for arg in $@; do
|
||||
if [ "${arg}" != "__MODULE__" ]; then
|
||||
path="${SRCDIR}/${HEADER_DIR}/${arg%.h}.h"
|
||||
clean_path="${path//.\//}"
|
||||
macro="$(basename ${clean_path} .h | tr '[a-z]' '[A-Z]')"
|
||||
[ ! -d "$(dirname ${clean_path})" ] &&
|
||||
mkdir -p "$(dirname ${clean_path})"
|
||||
if [ ! -f "${clean_path}" ]; then
|
||||
cat > "${clean_path}" <<EOF
|
||||
#ifndef ${macro}_H
|
||||
#define ${macro}_H
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
EOF
|
||||
else
|
||||
[ "${2}" != "__MODULE__" ] &&
|
||||
err "Header" "${clean_path}" "already exists"
|
||||
fi
|
||||
|
||||
[ "${2}" != "__MODULE__" ] &&
|
||||
info "Created header" "${clean_path}"
|
||||
fi
|
||||
done
|
||||
;;
|
||||
module)
|
||||
shift 1
|
||||
for arg in $@; do
|
||||
./cbuild.sh new header "${arg}" '__MODULE__'
|
||||
path="${SRCDIR}/${arg}.c"
|
||||
if [ "${HEADER_DIR}" = "." ]; then
|
||||
include="./$(basename ${arg}).h"
|
||||
else
|
||||
include="$(dirname ${path#${SRCDIR}/} |
|
||||
sed -e 's/\/[A-z]*/\/../g' \
|
||||
-e 's/[A-z]*\//..\//' \
|
||||
-e 's/^[A-z]*$/../')/${HEADER_DIR}/${arg}.h"
|
||||
fi
|
||||
[ ! -d "$(dirname ${path})" ] &&
|
||||
mkdir -p "$(dirname ${path})"
|
||||
if [ ! -f "${path}" ]; then
|
||||
cat > "${path}" <<EOF
|
||||
#include "${include}"
|
||||
|
||||
EOF
|
||||
[ "${arg}" != "main" ] && echo >> "${path}" ||
|
||||
cat >> "${path}" <<EOF
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
else
|
||||
err "Module" "${path%.c}" "already exists"
|
||||
return 1
|
||||
fi
|
||||
|
||||
info "Created module" "${path%.c}"
|
||||
done
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
__progress__() {
|
||||
ntargets=$(cat .cbuild_prog.tmp)
|
||||
export_vars
|
||||
rtargets="$(make -f "${MAKEFILE}" -e "${TARGET}" -n | grep -c "^${CC}")"
|
||||
targetno=$((${ntargets} - ${rtargets} + 1))
|
||||
if [ "${1}" = "object" ]; then
|
||||
printf '[35;1m[%3d/%d][0m ' "${targetno}" "${ntargets}"
|
||||
printf '[32mBuilding[0m '
|
||||
printf "${build_progress_color}${bold}[%3d/%d]${clear_formatting} " \
|
||||
"${targetno}" "${ntargets}"
|
||||
printf "${build_info_color}Building${clear_formatting} "
|
||||
elif [ "${1}" = "link" ]; then
|
||||
printf '[36;1m[%3d/%d][0m ' "${targetno}" "${ntargets}"
|
||||
printf '[36;1mLinking[0m '
|
||||
printf "${link_info_color}${bold}[%3d/%d]${clear_formatting} " "${targetno}" "${ntargets}"
|
||||
printf "${link_info_color}${bold}Linking${clear_formatting} "
|
||||
fi
|
||||
|
||||
echo "${2}"
|
||||
|
@ -184,6 +283,9 @@ case $1 in
|
|||
generate) gen_makefile && info "Done";;
|
||||
run) shift 1 && run $@;;
|
||||
dryrun) dry_run;;
|
||||
new) shift 1 && new $@;;
|
||||
init) new module main;;
|
||||
-h|--help|help) usage;;
|
||||
__progress__) __progress__ "${2}" "${3}";;
|
||||
*) usage;;
|
||||
*) echo "Invalid command. Try --help";;
|
||||
esac
|
||||
|
|
Loading…
Reference in a new issue