2
0
MasterPassword/platform-independent/c/cli/build

242 lines
7.1 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# USAGE
# [targets='...'] [mpw_feature=0|1 ...] [CFLAGS='...'] [LDFLAGS='...'] ./build [-v|-d|-h|--] [cc arguments ...]
#
# By default, you should only need to run ./build
#
# -v: verbose mode, outputs state information and compiler commands.
# -d: debug build, modifies default build flags to produce binaries best suited for debugging.
# -h: show this usage information.
#
# You can customize the targets that are built using targets='...'. Use targets='all' to build all targets.
# By default, we only build the 'mpw' target.
# See targets_all for all possible targets as well as the features they support and require.
#
# Several features can be enabled or disabled using feature flags.
# See the Features section for an overview of the features, their default setting, their meaning and their dependencies.
# You will need to have each of the feature's dependencies installed for the build to succeed with that feature enabled.
#
# Finally, the C compiler can be tuned using CFLAGS, LDFLAGS and compiler arguments passed to the script.
#
# BUGS
# masterpassword@lyndir.com
#
# AUTHOR
# Maarten Billemont
#
cd "${BASH_SOURCE%/*}"
shopt -s extglob
set -e
### CONFIGURATION
verbose=0
# Options
while getopts :vdh opt; do
case $opt in
v) verbose=1 ;;
d) debug=1 ;;
h|?) sed -n '/^[^#]/q;p' "${BASH_SOURCE##*/}"; exit ;;
esac
done
shift "$(( OPTIND - 1 ))"
# Targets to build
targets_all=(
mpw # C CLI version of Master Password (needs: mpw_sodium, optional: mpw_color, mpw_json).
mpw-bench # C CLI Master Password benchmark utility (needs: mpw_sodium).
mpw-tests # C Master Password algorithm test suite (needs: mpw_sodium, mpw_xml).
)
targets_default='mpw' # Override with: targets='...' ./build
targets=${targets[*]:-$targets_default}
# Features
mpw_sodium=${mpw_sodium:-1} # Implement crypto functions with sodium (depends on libsodium).
mpw_json=${mpw_json:-1} # Support JSON-based user configuration format (depends on libjson-c).
mpw_color=${mpw_color:-1} # Colorized identicon (depends on libncurses).
mpw_xml=${mpw_xml:-1} # XML parsing (depends on libxml2).
# Default build flags
cflags=( -O3 $CFLAGS ); unset CFLAGS
ldflags=( $LDFLAGS ); unset LDFLAGS
if (( debug )); then
cflags+=( -O0 -g )
fi
# Version
if { mpw_version=$(git describe --match '*-cli*' --long --dirty) || mpw_version=$(<VERSION); } 2>/dev/null; then
cflags+=( -D"MP_VERSION=$mpw_version" )
fi
echo "Current mpw source version ${mpw_version:-<unknown>}..."
# Meta
if (( verbose )); then
echo "mpw_sodium=${mpw_sodium}, mpw_json=${mpw_json}, mpw_color=${mpw_color}, mpw_xml=${mpw_xml}"
echo "CFLAGS: ${cflags[*]}"
echo "LDFLAGS: ${ldflags[*]}"
echo "targets: ${targets[*]}"
fi
### TARGET: MPW
mpw() {
# dependencies
use_mpw_sodium required
use_mpw_color optional
use_mpw_json optional
# target
cflags=(
"${cflags[@]}"
# mpw paths
-I"../core/src" -I"src"
)
ldflags=(
"${ldflags[@]}"
)
# build
cc "${cflags[@]}" "$@" \
"../core/src/base64.c" "../core/src/aes.c" "../core/src/mpw-algorithm.c" \
"../core/src/mpw-algorithm_v0.c" "../core/src/mpw-algorithm_v1.c" "../core/src/mpw-algorithm_v2.c" "../core/src/mpw-algorithm_v3.c" \
"../core/src/mpw-types.c" "../core/src/mpw-util.c" "../core/src/mpw-marshal-util.c" "../core/src/mpw-marshal.c" "src/mpw-cli-util.c" \
"${ldflags[@]}" "src/mpw-cli.c" -o "mpw"
echo "done! You can now run ./mpw-cli-tests, ./install or use ./$_"
}
### TARGET: MPW-BENCH
mpw-bench() {
# dependencies
use_mpw_sodium required
# target
cflags=(
"${cflags[@]}"
# mpw paths
-I"../core/src" -I"src"
)
ldflags=(
"${ldflags[@]}"
)
# build
cc "${cflags[@]}" "$@" \
"../core/src/base64.c" "../core/src/aes.c" "../core/src/mpw-algorithm.c" \
"../core/src/mpw-algorithm_v0.c" "../core/src/mpw-algorithm_v1.c" "../core/src/mpw-algorithm_v2.c" "../core/src/mpw-algorithm_v3.c" \
"../core/src/mpw-types.c" "../core/src/mpw-util.c" \
"${ldflags[@]}" "src/mpw-bench.c" -o "mpw-bench"
echo "done! You can now use ./$_"
}
### TARGET: MPW-TESTS
mpw-tests() {
# dependencies
use_mpw_sodium required
use_mpw_xml required
# target
cflags=(
"${cflags[@]}"
# mpw paths
-I"../core/src" -I"src"
)
ldflags=(
"${ldflags[@]}"
)
# build
cc "${cflags[@]}" "$@" \
"../core/src/base64.c" "../core/src/aes.c" "../core/src/mpw-algorithm.c" \
"../core/src/mpw-algorithm_v0.c" "../core/src/mpw-algorithm_v1.c" "../core/src/mpw-algorithm_v2.c" "../core/src/mpw-algorithm_v3.c" \
"../core/src/mpw-types.c" "../core/src/mpw-util.c" "src/mpw-tests-util.c" \
"${ldflags[@]}" "src/mpw-tests.c" -o "mpw-tests"
echo "done! You can now use ./$_"
}
### TOOLS
haslib() {
cc -x c "${ldflags[@]}" -l"$1" -o /dev/null - <<< 'int main() { return 0; }' &>/dev/null
}
cc() (
(( verbose )) && set -x
if { hash llvm-gcc; } 2>/dev/null; then
llvm-gcc "$@"
elif { hash gcc; } 2>/dev/null; then
gcc -std=c11 "$@"
elif { hash clang; } 2>/dev/null; then
clang "$@"
else
echo >&2 "Need a compiler. Please install GCC or LLVM."
exit 1
fi
)
### DEPENDENCIES
use() {
local option=$1 requisite=$2 lib=$3; shift 3
local enabled=${!option}
if (( enabled )); then
if haslib "$lib"; then
for lib in "$lib" "$@"; do
haslib "$lib" && ldflags+=( -l"$lib" )
done
echo "INFO: Enabled $option (lib$lib)."
return 0
elif [[ $requisite == required ]]; then
echo >&2 "ERROR: $option was enabled but is missing $lib library. Please install this library before continuing."
exit 1
else
echo >&2 "WARNING: $option was enabled but is missing $lib library. Will continue with $option disabled!"
return 1
fi
elif [[ $requisite == required ]]; then
echo >&2 "ERROR: $option was required but is not enabled. Please enable the option or remove this target before continuing."
exit 1
else
echo "INFO: $option is supported but not enabled."
return 1
fi
}
use_mpw_sodium() {
local requisite=$1
use mpw_sodium "$requisite" sodium && cflags+=( -D"MPW_SODIUM=1" ) ||:
}
use_mpw_color() {
local requisite=$1
use mpw_color "$requisite" curses tinfo && cflags+=( -D"MPW_COLOR=1" ) ||:
}
use_mpw_json() {
local requisite=$1
use mpw_json "$requisite" json-c && cflags+=( -D"MPW_JSON=1" ) ||:
}
use_mpw_xml() {
local requisite=$1
use mpw_xml "$requisite" xml2 && cflags+=( $(xml2-config --cflags) ) ldflags+=( $(xml2-config --libs) ) ||:
}
### BUILD TARGETS
for target in "${targets_all[@]}"; do
if [[ $targets == 'all' || " $targets " = *" $target "* ]]; then
echo
echo "Building target: $target..."
( "$target" "$@" )
fi
done