-
Notifications
You must be signed in to change notification settings - Fork 1
/
build
executable file
·252 lines (215 loc) · 7.79 KB
/
build
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#!/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
#
# 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 _cflags=$("$lib-config" --cflags 2>/dev/null) && _ldflags=$("$lib-config" --libs 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 ||:
}
### BUILD TARGETS
for target in "${targets_all[@]}"; do
if [[ $targets == 'all' || " $targets " = *" $target "* ]]; then
echo
echo "Building target: $target..."
( "$target" "$@" )
fi
done