mirror of
https://gitlab.com/spectre.app/cli.git
synced 2024-11-01 02:41:44 +01:00
26c01a5eaa
[IMPROVED] Using pkg-config we can more reliably find and use installed dependency libraries on the system.
250 lines
7.7 KiB
Bash
Executable file
250 lines
7.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
#
|
|
# USAGE
|
|
# [targets='...'] [spectre_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 'spectre' 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
|
|
# support@spectre.app
|
|
#
|
|
# 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=(
|
|
spectre # C CLI version of Spectre (needs: spectre_sodium, optional: spectre_color, spectre_json).
|
|
spectre-bench # C CLI Spectre benchmark utility (needs: spectre_sodium).
|
|
spectre-tests # C Spectre algorithm test suite (needs: spectre_sodium, spectre_xml).
|
|
)
|
|
targets_default='spectre' # Override with: targets='...' ./build
|
|
targets=${targets[*]:-$targets_default}
|
|
|
|
# Features
|
|
spectre_sodium=${spectre_sodium:-1} # Implement crypto functions with sodium (depends on libsodium).
|
|
spectre_json=${spectre_json:-1} # Support JSON-based user configuration format (depends on libjson-c).
|
|
spectre_color=${spectre_color:-1} # Colorized identicon (depends on libncurses).
|
|
spectre_xml=${spectre_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 { spectre_version=$(git describe --match '*-cli*' --long --dirty) || spectre_version=$(<VERSION); } 2>/dev/null; then
|
|
cflags+=( -D"MP_VERSION=$spectre_version" )
|
|
fi
|
|
echo "Current spectre source version ${spectre_version:-<unknown>}..."
|
|
|
|
# Meta
|
|
if (( verbose )); then
|
|
echo "spectre_sodium=${spectre_sodium}, spectre_json=${spectre_json}, spectre_color=${spectre_color}, spectre_xml=${spectre_xml}"
|
|
echo "CFLAGS: ${cflags[*]}"
|
|
echo "LDFLAGS: ${ldflags[*]}"
|
|
echo "targets: ${targets[*]}"
|
|
fi
|
|
|
|
|
|
### TARGET: SPECTRE
|
|
spectre() {
|
|
# dependencies
|
|
use_spectre_sodium required
|
|
use_spectre_color optional
|
|
use_spectre_json optional
|
|
|
|
# target
|
|
cflags=(
|
|
"${cflags[@]}"
|
|
|
|
# spectre paths
|
|
-I"api/c" -I"src"
|
|
)
|
|
ldflags=(
|
|
"${ldflags[@]}"
|
|
)
|
|
|
|
# build
|
|
cc "${cflags[@]}" "$@" \
|
|
"api/c/aes.c" "api/c/spectre-algorithm.c" \
|
|
"api/c/spectre-algorithm_v0.c" "api/c/spectre-algorithm_v1.c" "api/c/spectre-algorithm_v2.c" "api/c/spectre-algorithm_v3.c" \
|
|
"api/c/spectre-types.c" "api/c/spectre-util.c" "api/c/spectre-marshal-util.c" "api/c/spectre-marshal.c" "src/spectre-cli-util.c" \
|
|
"${ldflags[@]}" "src/spectre-cli.c" -o "spectre"
|
|
echo "done! You can now run ./spectre-cli-tests, ./install or use ./$_"
|
|
}
|
|
|
|
|
|
### TARGET: SPECTRE-BENCH
|
|
spectre-bench() {
|
|
# dependencies
|
|
use_spectre_sodium required
|
|
|
|
# target
|
|
cflags=(
|
|
"${cflags[@]}"
|
|
|
|
# spectre paths
|
|
-I"api/c" -I"src"
|
|
)
|
|
ldflags=(
|
|
"${ldflags[@]}"
|
|
)
|
|
|
|
# build
|
|
cc "${cflags[@]}" "$@" \
|
|
"api/c/aes.c" "api/c/spectre-algorithm.c" \
|
|
"api/c/spectre-algorithm_v0.c" "api/c/spectre-algorithm_v1.c" "api/c/spectre-algorithm_v2.c" "api/c/spectre-algorithm_v3.c" \
|
|
"api/c/spectre-types.c" "api/c/spectre-util.c" \
|
|
"${ldflags[@]}" "src/spectre-bench.c" -o "spectre-bench"
|
|
echo "done! You can now use ./$_"
|
|
}
|
|
|
|
|
|
### TARGET: SPECTRE-TESTS
|
|
spectre-tests() {
|
|
# dependencies
|
|
use_spectre_sodium required
|
|
use_spectre_xml required
|
|
|
|
# target
|
|
cflags=(
|
|
"${cflags[@]}"
|
|
|
|
# spectre paths
|
|
-I"api/c" -I"src"
|
|
)
|
|
ldflags=(
|
|
"${ldflags[@]}"
|
|
)
|
|
|
|
# build
|
|
cc "${cflags[@]}" "$@" \
|
|
"api/c/aes.c" "api/c/spectre-algorithm.c" \
|
|
"api/c/spectre-algorithm_v0.c" "api/c/spectre-algorithm_v1.c" "api/c/spectre-algorithm_v2.c" "api/c/spectre-algorithm_v3.c" \
|
|
"api/c/spectre-types.c" "api/c/spectre-util.c" "src/spectre-tests-util.c" \
|
|
"${ldflags[@]}" "src/spectre-tests.c" -o "spectre-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 "$CC"; } 2>/dev/null; then
|
|
"$CC" -std=c11 "$@"
|
|
elif { hash clang; } 2>/dev/null; then
|
|
clang -std=c11 "$@"
|
|
elif { hash llvm-gcc; } 2>/dev/null; then
|
|
llvm-gcc -std=c11 "$@"
|
|
elif { hash gcc; } 2>/dev/null; then
|
|
gcc -std=c11 "$@"
|
|
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} found=0 _cflags _ldflags
|
|
|
|
if (( enabled )); then
|
|
for lib in "$lib" "$@"; do
|
|
if _cflags=$(pkg-config --cflags "$lib" 2>/dev/null) && _ldflags=$(pkg-config --libs "$lib" 2>/dev/null); then
|
|
cflags+=( $_cflags ) ldflags+=( $_ldflags ); found=1
|
|
elif _cflags=$(pkg-config --cflags "lib$lib" 2>/dev/null) && _ldflags=$(pkg-config --libs "lib$lib" 2>/dev/null); then
|
|
cflags+=( $_cflags ) ldflags+=( $_ldflags ); found=1
|
|
elif haslib "$lib"; then
|
|
ldflags+=( -l"$lib" ); found=1
|
|
fi
|
|
done
|
|
|
|
if (( found )); then
|
|
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_spectre_sodium() {
|
|
local requisite=$1
|
|
use spectre_sodium "$requisite" sodium && cflags+=( -D"SPECTRE_SODIUM=1" ) ||:
|
|
}
|
|
use_spectre_color() {
|
|
local requisite=$1
|
|
use spectre_color "$requisite" curses tinfo && cflags+=( -D"SPECTRE_COLOR=1" ) ||:
|
|
}
|
|
use_spectre_json() {
|
|
local requisite=$1
|
|
use spectre_json "$requisite" json-c && cflags+=( -D"SPECTRE_JSON=1" ) ||:
|
|
}
|
|
use_spectre_xml() {
|
|
local requisite=$1
|
|
use spectre_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
|