-
Notifications
You must be signed in to change notification settings - Fork 50
/
build_linux_deps.sh
367 lines (294 loc) · 11.9 KB
/
build_linux_deps.sh
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
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
#!/usr/bin/env bash
############## helpful commands ##############
### to read header of .elf file
#readelf -h install32/lib/libcurl.a
### list all options availble in a CMAKE project, everything prefixed with CMAKE_ are specific to CMAKE system
#cmake -LAH
### list all exports in a shared lib
# https://linux.die.net/man/1/nm
#nm -D --defined-only libsteam.so | grep " T "
if [ "$(id -u)" -ne 0 ]; then
echo "Please run as root" >&2
exit 1
fi
# common stuff
script_dir=$( cd -- "$( dirname -- "${0}" )" &> /dev/null && pwd )
deps_dir="$script_dir/build/deps/linux"
third_party_dir="$script_dir/third-party"
third_party_deps_dir="$third_party_dir/deps/linux"
third_party_common_dir="$third_party_dir/deps/common"
mycmake="$third_party_deps_dir/cmake/bin/cmake"
deps_archives=(
"libssq/libssq.tar.gz"
"zlib/zlib.tar.gz"
"curl/curl.tar.gz"
"protobuf/protobuf.tar.gz"
"mbedtls/mbedtls.tar.gz"
)
# < 0: deduce, > 1: force
PARALLEL_THREADS_OVERRIDE=-1
VERBOSITY=''
INSTALL_PACKAGES_ONLY=0
for (( i=1; i<=$#; i++ )); do
var="${!i}"
if [[ "$var" = "-j" ]]; then
i=$((i+1))
PARALLEL_THREADS_OVERRIDE="${!i}"
[[ "$PARALLEL_THREADS_OVERRIDE" =~ ^[0-9]+$ ]] || {
echo "[X] Invalid arg after -j, expected a number" >&2;
exit 1;
}
#echo "[?] Overriding parralel build jobs count with $PARALLEL_THREADS_OVERRIDE"
elif [[ "$var" = "-verbose" ]]; then
VERBOSITY='-v'
elif [[ "$var" = "-packages_only" ]]; then
INSTALL_PACKAGES_ONLY=1
else
echo "[X] Invalid arg: $var" >&2
exit 1
fi
done
last_code=0
############## required packages ##############
echo // installing required packages
apt update -y
last_code=$((last_code + $?))
apt install coreutils -y # echo, printf, etc...
last_code=$((last_code + $?))
apt install build-essential -y
last_code=$((last_code + $?))
apt install gcc-multilib g++-multilib -y # needed for 32-bit builds
last_code=$((last_code + $?))
apt install clang -y
last_code=$((last_code + $?))
apt install binutils -y # (optional) contains the tool 'readelf' mainly, and other usefull binary stuff
last_code=$((last_code + $?))
apt install tar -y # we need to extract packages
last_code=$((last_code + $?))
#apt install cmake git wget unzip -y
# exit early if we should install packages only, used by CI mainly
[[ "$INSTALL_PACKAGES_ONLY" -ne 0 ]] && exit $last_code
echo; echo;
[[ -f "$mycmake" ]] || {
echo "[X] Couldn't find cmake" >&2;
exit 1;
}
# use 70%
build_threads="$(( $(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 0) * 70 / 100 ))"
[[ $PARALLEL_THREADS_OVERRIDE -gt 0 ]] && build_threads="$PARALLEL_THREADS_OVERRIDE"
[[ $build_threads -lt 2 ]] && build_threads=2
echo ===========================
echo Tools will be installed in: "$deps_dir"
echo Building with $build_threads threads
echo ===========================
echo // Recreating dir...
rm -r -f "$deps_dir"
sleep 1
mkdir -p "$deps_dir" || {
echo "Couldn't create dir \"$deps_dir\"" >&2;
exit 1;
}
echo; echo
############## copy CMAKE toolchains to the home directory
echo // creating CMAKE toolchains in "$deps_dir"
cat > "$deps_dir/32-bit-toolchain.cmake" << EOL
# cmake -G "xx" ... -DCMAKE_TOOLCHAIN_FILE=/.../64bit.toolchain
# https://github.com/google/boringssl/blob/master/util/32-bit-toolchain.cmake
# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html#toolchain-files
# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html#cross-compiling-for-a-microcontroller
# the name of the target operating system
set(CMAKE_SYSTEM_NAME Linux)
# which compilers to use for C and C++
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_C_FLAGS_INIT "-m32")
set(CMAKE_CXX_FLAGS_INIT "-m32")
EOL
cat > "$deps_dir/64-bit-toolchain.cmake" << EOL
# cmake -G "xx" ... -DCMAKE_TOOLCHAIN_FILE=/.../64bit.toolchain
# https://github.com/google/boringssl/blob/master/util/32-bit-toolchain.cmake
# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html#toolchain-files
# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html#cross-compiling-for-a-microcontroller
# the name of the target operating system
set(CMAKE_SYSTEM_NAME Linux)
# which compilers to use for C and C++
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
EOL
echo; echo;
############## common CMAKE args ##############
# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_FLAGS_CONFIG.html#variable:CMAKE_%3CLANG%3E_FLAGS_%3CCONFIG%3E
cmake_common_args='-G "Unix Makefiles" -S .'
cmake_common_defs="-DCMAKE_BUILD_TYPE=Release -DCMAKE_C_STANDARD_REQUIRED=ON -DCMAKE_CXX_STANDARD_REQUIRED=ON -DCMAKE_C_STANDARD=17 -DCMAKE_CXX_STANDARD=17 -DCMAKE_POSITION_INDEPENDENT_CODE=True -DBUILD_SHARED_LIBS=OFF"
recreate_32="rm -f -r build32/ && rm -f -r install32/ && mkdir build32/ && mkdir install32/"
recreate_64="rm -f -r build64/ && rm -f -r install64/ && mkdir build64/ && mkdir install64/"
cmake_gen32="'$mycmake' $cmake_common_args -B build32 -DCMAKE_TOOLCHAIN_FILE=$deps_dir/32-bit-toolchain.cmake -DCMAKE_INSTALL_PREFIX=install32 $cmake_common_defs"
cmake_gen64="'$mycmake' $cmake_common_args -B build64 -DCMAKE_TOOLCHAIN_FILE=$deps_dir/64-bit-toolchain.cmake -DCMAKE_INSTALL_PREFIX=install64 $cmake_common_defs"
cmake_build32="'$mycmake' --build build32 --config Release --parallel $build_threads $VERBOSITY"
cmake_build64="'$mycmake' --build build64 --config Release --parallel $build_threads $VERBOSITY"
clean_gen32="[[ -d build32 ]] && rm -f -r build32/"
clean_gen64="[[ -d build64 ]] && rm -f -r build64/"
chmod 777 "$mycmake"
# the artificial delays "sleep 3" are here because on Windows WSL the
# explorer or search indexer keeps a handle open and causes an error here
echo // extracting archives
dotglob_state="$( shopt -p dotglob )"
for f in "${deps_archives[@]}"; do
src_arch="$third_party_common_dir/$f"
[[ -f "$src_arch" ]] || {
echo "[X] archive '"$src_arch"' not found";
exit 1;
}
target_dir="$deps_dir/$( dirname "$f" )"
mkdir -p "$target_dir"
echo - extracting archive "'$f'" into "'$target_dir'"
tar -zxf "$src_arch" -C "$target_dir"
sleep 2
echo - flattening dir "'$target_dir'" by moving everything in a subdir outside
shopt -s dotglob
for i in {1..10}; do
mv "$target_dir"/*/** "$target_dir/" && { break; } || { sleep 1; }
done
eval $dotglob_state
sleep 2
chmod -R 777 "$target_dir"
sleep 1
echo;
done
############## build ssq ##############
echo // building ssq lib
pushd "$deps_dir/libssq"
eval $recreate_32
eval $cmake_gen32
last_code=$((last_code + $?))
eval $cmake_build32
last_code=$((last_code + $?))
eval $recreate_64
eval $cmake_gen64
last_code=$((last_code + $?))
eval $cmake_build64
last_code=$((last_code + $?))
popd
echo; echo;
############## build zlib ##############
echo // building zlib lib
pushd "$deps_dir/zlib"
eval $recreate_32
eval $cmake_gen32
last_code=$((last_code + $?))
eval $cmake_build32 --target install
last_code=$((last_code + $?))
eval $clean_gen32
eval $recreate_64
eval $cmake_gen64
last_code=$((last_code + $?))
eval $cmake_build64 --target install
last_code=$((last_code + $?))
eval $clean_gen64
popd
echo; echo;
############## zlib is painful ##############
# lib curl uses the default search paths, even when ZLIB_INCLUDE_DIR and ZLIB_LIBRARY_RELEASE are defined
# check thir CMakeLists.txt line #573
# optional_dependency(ZLIB)
# if(ZLIB_FOUND)
# set(HAVE_LIBZ ON)
# set(USE_ZLIB ON)
#
# # Depend on ZLIB via imported targets if supported by the running
# # version of CMake. This allows our dependents to get our dependencies
# # transitively.
# if(NOT CMAKE_VERSION VERSION_LESS 3.4)
# list(APPEND CURL_LIBS ZLIB::ZLIB) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< evil
# else()
# list(APPEND CURL_LIBS ${ZLIB_LIBRARIES})
# include_directories(${ZLIB_INCLUDE_DIRS})
# endif()
# list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS})
# endif()
# we have to set the ZLIB_ROOT so that it is prepended to the search list
# we have to set ZLIB_LIBRARY NOT ZLIB_LIBRARY_RELEASE in order to override the FindZlib module
# we also should set ZLIB_USE_STATIC_LIBS since we want to force static builds
# https://github.com/Kitware/CMake/blob/a6853135f569f0b040a34374a15a8361bb73901b/Modules/FindZLIB.cmake#L98C4-L98C13
wild_zlib_32=(
"-DZLIB_USE_STATIC_LIBS=ON"
"-DZLIB_ROOT='$deps_dir/zlib/install32'"
"-DZLIB_INCLUDE_DIR='$deps_dir/zlib/install32/include'"
"-DZLIB_LIBRARY='$deps_dir/zlib/install32/lib/libz.a'"
)
wild_zlib_64=(
"-DZLIB_USE_STATIC_LIBS=ON"
"-DZLIB_ROOT='$deps_dir/zlib/install64'"
"-DZLIB_INCLUDE_DIR='$deps_dir/zlib/install64/include'"
"-DZLIB_LIBRARY='$deps_dir/zlib/install64/lib/libz.a'"
)
############## build curl ##############
echo // building curl lib
pushd "$deps_dir/curl"
curl_common_defs="-DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_STATIC_CURL=OFF -DBUILD_STATIC_LIBS=ON -DCURL_USE_OPENSSL=OFF -DCURL_ZLIB=ON"
eval $recreate_32
eval $cmake_gen32 $curl_common_defs "${wild_zlib_32[@]}" -DCMAKE_SHARED_LINKER_FLAGS_INIT="'$deps_dir/zlib/install32/lib/libz.a'" -DCMAKE_MODULE_LINKER_FLAGS_INIT="'$deps_dir/zlib/install32/lib/libz.a'" -DCMAKE_EXE_LINKER_FLAGS_INIT="'$deps_dir/zlib/install32/lib/libz.a'"
last_code=$((last_code + $?))
eval $cmake_build32 --target install
last_code=$((last_code + $?))
eval $clean_gen32
eval $recreate_64
eval $cmake_gen64 $curl_common_defs "${wild_zlib_64[@]}" -DCMAKE_SHARED_LINKER_FLAGS_INIT="'$deps_dir/zlib/install64/lib/libz.a'" -DCMAKE_MODULE_LINKER_FLAGS_INIT="'$deps_dir/zlib/install64/lib/libz.a'" -DCMAKE_EXE_LINKER_FLAGS_INIT="'$deps_dir/zlib/install64/lib/libz.a'"
last_code=$((last_code + $?))
eval $cmake_build64 --target install
last_code=$((last_code + $?))
eval $clean_gen64
popd
echo; echo;
############## build protobuf ##############
echo // building protobuf lib
pushd "$deps_dir/protobuf"
proto_common_defs="-Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF -Dprotobuf_WITH_ZLIB=ON"
eval $recreate_32
eval $cmake_gen32 $proto_common_defs "${wild_zlib_32[@]}" -DCMAKE_SHARED_LINKER_FLAGS_INIT="'$deps_dir/zlib/install32/lib/libz.a'" -DCMAKE_MODULE_LINKER_FLAGS_INIT="'$deps_dir/zlib/install32/lib/libz.a'" -DCMAKE_EXE_LINKER_FLAGS_INIT="'$deps_dir/zlib/install32/lib/libz.a'"
last_code=$((last_code + $?))
eval $cmake_build32 --target install
last_code=$((last_code + $?))
eval $clean_gen32
eval $recreate_64
eval $cmake_gen64 $proto_common_defs "${wild_zlib_64[@]}" -DCMAKE_SHARED_LINKER_FLAGS_INIT="'$deps_dir/zlib/install64/lib/libz.a'" -DCMAKE_MODULE_LINKER_FLAGS_INIT="'$deps_dir/zlib/install64/lib/libz.a'" -DCMAKE_EXE_LINKER_FLAGS_INIT="'$deps_dir/zlib/install64/lib/libz.a'"
last_code=$((last_code + $?))
eval $cmake_build64 --target install
last_code=$((last_code + $?))
eval $clean_gen64
popd
echo; echo;
############## build mbedtls ##############
echo // building mbedtls lib
pushd "$deps_dir/mbedtls"
# AES-NI on mbedtls v3.5.x:
# https://github.com/Mbed-TLS/mbedtls/issues/8400
# https://github.com/Mbed-TLS/mbedtls/issues/8334
# clang/gcc compiler flags ref:
# https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html#index-mmmx
# instruction set details
# https://en.wikipedia.org/wiki/CLMUL_instruction_set
# https://en.wikipedia.org/wiki/AES_instruction_set
# https://en.wikipedia.org/wiki/SSE2
mbedtls_common_defs="-DUSE_STATIC_MBEDTLS_LIBRARY=ON -DUSE_SHARED_MBEDTLS_LIBRARY=OFF -DENABLE_TESTING=OFF -DENABLE_PROGRAMS=OFF -DLINK_WITH_PTHREAD=ON"
eval $recreate_32
CFLAGS='-mpclmul -msse2 -maes' eval $cmake_gen32 $mbedtls_common_defs
last_code=$((last_code + $?))
eval $cmake_build32 --target install
last_code=$((last_code + $?))
eval $clean_gen32
eval $recreate_64
eval $cmake_gen64 $mbedtls_common_defs
last_code=$((last_code + $?))
eval $cmake_build64 --target install
last_code=$((last_code + $?))
eval $clean_gen64
popd
echo; echo;
echo;
if [[ $last_code = 0 ]]; then
echo "[GG] no failures"
else
echo "[XX] general failure" >&2
fi
exit $last_code