-
Notifications
You must be signed in to change notification settings - Fork 136
/
install-filcrypto
executable file
·329 lines (273 loc) · 12.5 KB
/
install-filcrypto
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
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
#!/usr/bin/env bash
# shellcheck disable=SC2155 enable=require-variable-braces
set -Exeo pipefail
auth_header=()
if [ -n "${GITHUB_TOKEN}" ]; then
auth_header=("-H" "Authorization: token ${GITHUB_TOKEN}")
fi
# set CWD to the root of filecoin-ffi
#
cd "$(dirname "${BASH_SOURCE[0]}")"
# tracks where the Rust sources are were we to build locally instead of
# downloading from GitHub Releases
#
rust_sources_dir="rust"
# an array of values passed as 'target-feature' to the Rust compiler if we're
# building an optimized libfilcrypto (which takes advantage of some perf-boosting
# instruction sets)
#
#optimized_release_rustc_target_features=$(jq -r '.[].rustc_target_feature' < "${rust_sources_dir}/rustc-target-features-optimized.json")
# each value in this area is checked against the "features" of the hosts CPU
# in order to determine if the host is suitable for an optimized release
#
cpu_features_required_for_optimized_release=$(jq -r '.[].check_cpu_for_feature | select(. != null)' < "${rust_sources_dir}/rustc-target-features-optimized.json")
main() {
local __release_flags=$(get_release_flags)
if [ "${FFI_BUILD_FROM_SOURCE}" != "1" ] && download_release_tarball __tarball_path "${rust_sources_dir}" "filecoin-ffi" "${__release_flags}"; then
local __tmp_dir=$(mktemp -d)
# silence shellcheck warning as the assignment happened in
# `download_release_tarball()`
# shellcheck disable=SC2154
# extract downloaded tarball to temporary directory
#
tar -C "${__tmp_dir}" -xzf "${__tarball_path}"
# copy build assets into root of filecoin-ffi
#
find -L "${__tmp_dir}" -type f -name filcrypto.h -exec cp -- "{}" . \;
find -L "${__tmp_dir}" -type f -name libfilcrypto.a -exec cp -- "{}" . \;
find -L "${__tmp_dir}" -type f -name filcrypto.pc -exec cp -- "{}" . \;
check_installed_files
(>&2 echo "[install-filcrypto/main] successfully installed prebuilt libfilcrypto")
else
(>&2 echo "[install-filcrypto/main] building libfilcrypto from local sources (dir = ${rust_sources_dir})")
# build libfilcrypto (and corresponding header and pkg-config)
#
build_from_source "${rust_sources_dir}" "${__release_flags}"
# copy from Rust's build directory (target) to root of filecoin-ffi
#
if [ "$(uname -s)" = "Darwin" ] && [ "$(uname -m)" = "x86_64" ]; then
find -L "${rust_sources_dir}/target/universal/release" -type f -name libfilcrypto.a -exec cp -- "{}" . \;
else
find -L "${rust_sources_dir}/target/release" -type f -name libfilcrypto.a -exec cp -- "{}" . \;
fi
find -L "${rust_sources_dir}" -type f -name filcrypto.h -exec cp -- "{}" . \;
find -L "${rust_sources_dir}" -type f -name filcrypto.pc -exec cp -- "{}" . \;
pwd
ls ./*filcrypto*
check_installed_files
(>&2 echo "[install-filcrypto/main] successfully built and installed libfilcrypto from source")
fi
}
download_release_tarball() {
local __resultvar=$1
local __rust_sources_path=$2
local __repo_name=$3
local __release_flags=$4
local __release_tags=$(git tag --points-at "$(git rev-parse HEAD)")
local __release_tag=$(echo "${__release_tags}" | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+(-\w+)?$' | head -n 1)
# If we're building from a commit that doesn't have a tag, we need to
# compile from source.
if [ -z "${__release_tag}" ]; then
(>&2 echo "[download_release_tarball] failed to determine release tag")
return 1
fi
local __release_tag_url="https://api.github.com/repos/filecoin-project/${__repo_name}/releases/tags/${__release_tag}"
# Download the non-optimized standard release.
release_flag_name="standard"
# TODO: This function shouldn't make assumptions about how these releases'
# names are constructed. Marginally less-bad would be to require that this
# function's caller provide the release name.
#
if [ "$(uname -s)" = "Darwin" ]; then
# For MacOS a universal library is used so naming convention is different
local __release_name="${__repo_name}-$(uname)-${release_flag_name}"
else
local __release_name="${__repo_name}-$(uname)-$(uname -m)-${release_flag_name}"
fi
(>&2 echo "[download_release_tarball] acquiring release @ ${__release_tag}")
local __release_response=$(curl "${auth_header[@]}" \
--retry 3 \
--location "${__release_tag_url}")
local __release_url=$(echo "${__release_response}" | jq -r ".assets[] | select(.name | contains(\"${__release_name}\")) | .url")
local __tar_path="/tmp/${__release_name}_$(basename "${__release_url}").tar.gz"
if [[ -z "${__release_url}" ]]; then
(>&2 echo "[download_release_tarball] failed to download release (tag URL: ${__release_tag_url}, response: ${__release_response})")
return 1
fi
local __asset_url=$(curl "${auth_header[@]}" \
--head \
--retry 3 \
--header "Accept:application/octet-stream" \
--location \
--output /dev/null \
-w "%{url_effective}" \
"${__release_url}")
if ! curl "${auth_header[@]}" --retry 3 --output "${__tar_path}" "${__asset_url}"; then
(>&2 echo "[download_release_tarball] failed to download release asset (tag URL: ${__release_tag_url}, asset URL: ${__asset_url})")
return 1
fi
# set $__resultvar (which the caller provided as $1), which is the poor
# man's way of returning a value from a function in Bash
#
eval "${__resultvar}='${__tar_path}'"
}
build_from_source() {
local __rust_sources_path=$1
local __release_flags=$2
local __repo_sha1=${FFI_GIT_COMMIT:-$(git rev-parse HEAD)}
local __repo_sha1_truncated="${__repo_sha1:0:16}"
(>&2 echo "building from source @ ${__repo_sha1_truncated}")
if ! [ -x "$(command -v cargo)" ]; then
(>&2 echo '[build_from_source] Error: cargo is not installed.')
(>&2 echo '[build_from_source] install Rust toolchain to resolve this problem.')
exit 1
fi
if ! [ -x "$(command -v rustup)" ]; then
(>&2 echo '[build_from_source] Error: rustup is not installed.')
(>&2 echo '[build_from_source] install Rust toolchain installer to resolve this problem.')
exit 1
fi
pushd "${__rust_sources_path}"
cargo --version
# In the past we were only able to build universal binaries on x86_64,
# for now we just keep that behaviour. This means that on aarch64 (e.g.
# Apple M1) it's a native, non-universal binary.
if [ "$(uname -s)" = "Darwin" ] && [ "$(uname -m)" = "x86_64" ]; then
# Rustup only installs the correct versions for the current
# architecture you're on. As we cross-compile to aarch64, we need to
# make sure that toolchain is installes as well.
rustup target add aarch64-apple-darwin
build="lipo"
else
build="build"
fi
# Check for specified GPU support.
if [ "${FFI_USE_CUDA_SUPRASEAL}" == "1" ]; then
# If SupraSeal is enabled, just use the `cuda-supraseal` feature and
# nothing else GPU related.
gpu_flags=",cuda-supraseal"
if [ ! "$(command -v nvcc)" ]; then
echo "WARNING: Cannot find nvcc for CUDA support."
echo "WARNING: For CUDA support, please ensure that the CUDA toolkit is properly installed."
echo "WARNING: After installation, nvcc must be in the system path."
echo ""
echo "WARNING: Defaulting to OpenCL GPU support(!!!)"
gpu_flags=",opencl"
fi
else
# Check if GPU usage is to be disabled.
if [ "${FFI_USE_GPU}" == "0" ]; then
gpu_flags=""
# Check if OpenCL support is specified or we're building on Darwin.
elif [ "${FFI_USE_OPENCL}" == "1" ] || [ "${FFI_PORTABLE}" == "1" ] || [ "$(uname -s)" = "Darwin" ]; then
gpu_flags=",opencl"
else
# If GPUs are enabled and SupraSeal is not, default to CUDA support
# where possible.
# First ensure that nvcc (as part of the CUDA toolkit) is available --
# if it's not warn that we are defaulting GPU to OpenCL instead.
gpu_flags=",cuda"
if [ ! "$(command -v nvcc)" ]; then
echo "WARNING: Cannot find nvcc for CUDA support."
echo "WARNING: For CUDA support, please ensure that the CUDA toolkit is properly installed."
echo "WARNING: After installation, nvcc must be in the system path."
echo ""
echo "WARNING: Defaulting to OpenCL GPU support(!!!)"
gpu_flags=",opencl"
fi
fi
fi
# Default to use multicore_sdr flags, unless specified to disable
use_multicore_sdr="multicore-sdr"
if [ "${FFI_USE_MULTICORE_SDR}" == "0" ]; then
use_multicore_sdr=""
fi
# By default the number or rows to discard of the TreeRLast can be set via
# `FIL_PROOFS_ROWS_TO_DISCARD`. When SupraSeal PC2 is used, then this
# number is fixed.
use_fixed_rows_to_discard=""
if [ "${FFI_USE_FIXED_ROWS_TO_DISCARD}" == "1" ]; then
use_fixed_rows_to_discard=",fixed-rows-to-discard"
fi
additional_flags=""
# Add feature specific rust flags as needed here.
if [ "${FFI_USE_BLST_PORTABLE}" == "1" ] || [ "${FFI_PORTABLE}" == "1" ]; then
additional_flags="${additional_flags} --no-default-features --features ${use_multicore_sdr},blst-portable${gpu_flags}${use_fixed_rows_to_discard}"
else
additional_flags="${additional_flags} --no-default-features --features ${use_multicore_sdr}${gpu_flags}${use_fixed_rows_to_discard}"
fi
echo "Using additional build flags: ${additional_flags}"
if [ -n "${__release_flags}" ]; then
RUSTFLAGS="-C target-feature=${__release_flags}" ./scripts/build-release.sh ${build} "${additional_flags}"
else
./scripts/build-release.sh ${build} "${additional_flags}"
fi
popd
}
get_release_flags() {
if [ "${FFI_PORTABLE}" == "1" ]; then
echo ""
return
fi
local __features=""
# determine where to look for CPU features
#
if [[ ! -f "/proc/cpuinfo" ]]; then
(>&2 echo "[get_release_flags] no /proc/cpuinfo file; falling back to Darwin feature detection")
__features=$(sysctl -a | grep machdep.cpu | tr '[:upper:]' '[:lower:]' | grep features)
else
#aarch64_uname=$(uname -a | grep aarch64)
x86_64_uname=$(uname -a | grep x86_64)
# shellcheck disable=SC2002
if [ -n "${x86_64_uname}" ]; then
__features=$(cat /proc/cpuinfo | grep flags | head -n 1)
else
# For now we assume aarch64. If another supported platform is added, explicitly check for it
__features=$(cat /proc/cpuinfo | grep Features | head -n 1)
fi
fi
# Maps cpu flag to rust flags (related to entries in rust/rustc-target-features-optimized.json)
if [ "$(uname -s)" = "Darwin" ] && [ "$(uname -m)" = "x86_64" ]; then
feature_map=("adx:+adx" "sha_ni:+sha" "sha2:+sha2" "avx2:+avx2" "sse4_2:+sse4.2" "sse4_1:+sse4.1")
else
feature_map=("adx:+adx" "sha_ni:+sha" "sha2:+sha2" "sse2:+sse2" "avx2:+avx2" "avx:+avx" "sse4_2:+sse4.2" "sse4_1:+sse4.1")
fi
target_features=""
# check for the presence of each required CPU feature
#
# shellcheck disable=SC2068 # the splitting is intentional
for x in ${cpu_features_required_for_optimized_release[@]}; do
current_feature=$(echo "${__features}" | grep -c "${x}")
if [ "1" = "${current_feature}" ]; then
for feature in "${feature_map[@]}"; do
key=${feature%%:*}
if [ "${key}" == "${x}" ]; then
val=${feature#*:}
if [ -z "${target_features}" ]; then
target_features="${val}"
else
target_features="${target_features},${val}"
fi
fi
done
fi
done
echo "${target_features}"
}
check_installed_files() {
pwd
ls ./*filcrypto*
if [[ ! -f "./filcrypto.h" ]]; then
(>&2 echo "[check_installed_files] failed to install filcrypto.h")
exit 1
fi
if [[ ! -f "./libfilcrypto.a" ]]; then
(>&2 echo "[check_installed_files] failed to install libfilcrypto.a")
exit 1
fi
if [[ ! -f "./filcrypto.pc" ]]; then
(>&2 echo "[check_installed_files] failed to install filcrypto.pc")
exit 1
fi
}
main "$@"; exit