Repository navigation
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·619 lines (524 loc) · 27.7 KB
/
Copy pathsetup.sh
File metadata and controls
executable file
·619 lines (524 loc) · 27.7 KB
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
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
#!/bin/bash
# ==============================================================================
# V2X QoS Full Environment Setup & Compilation Orchestrator
# ==============================================================================
# This script automates dependency verification, smart package installation,
# python virtualenv creation, requirements sync, and CMake-based compilation
# for the Vanetza protocol library and training environment.
#
# Supported Systems: Ubuntu / Debian
# Naming Standards: PEP8/Google Style for Bash variables and functions
# ==============================================================================
# Exit immediately if any command fails, undefined variables are referenced,
# or any command in a pipeline fails.
set -euo pipefail
# ------------------------------------------------------------------------------
# Decoupled ANSI Color Escape Sequences (Consistent with run_experiments.sh)
# ------------------------------------------------------------------------------
readonly ANSI_RESET="\033[0m"
readonly ANSI_BOLD="\033[1m"
readonly ANSI_CYAN="\033[1;36m"
readonly ANSI_GREEN="\033[1;32m"
readonly ANSI_YELLOW="\033[1;33m"
readonly ANSI_RED="\033[1;31m"
readonly ANSI_BLUE="\033[1;34m"
# ------------------------------------------------------------------------------
# Semantic Color Mapping
# ------------------------------------------------------------------------------
readonly COLOR_RESET="${ANSI_RESET}"
readonly COLOR_BOLD="${ANSI_BOLD}"
readonly COLOR_INFO="${ANSI_CYAN}"
readonly COLOR_SUCCESS="${ANSI_GREEN}"
readonly COLOR_WARNING="${ANSI_YELLOW}"
readonly COLOR_DANGER="${ANSI_RED}"
readonly COLOR_PRIMARY="${ANSI_BLUE}"
# ------------------------------------------------------------------------------
# Logging Utilities
# ------------------------------------------------------------------------------
log_success() {
echo -e "${COLOR_SUCCESS}[SUCCESS] $1${COLOR_RESET}"
}
log_warning() {
echo -e "${COLOR_WARNING}[WARNING] $1${COLOR_RESET}"
}
log_error() {
echo -e "${COLOR_DANGER}[ERROR] $1${COLOR_RESET}" >&2
}
# ------------------------------------------------------------------------------
# Version Comparison Helper
# ------------------------------------------------------------------------------
# Compare two semantic versions ($1 >= $2)
# Returns 0 (true) if version $1 is greater than or equal to $2, otherwise 1 (false).
version_ge() {
local ver1="$1"
local ver2="$2"
[ "$(printf '%s\n%s' "$ver2" "$ver1" | sort -V | head -n1)" = "$ver2" ]
}
# ------------------------------------------------------------------------------
# Dependency Version Resolution Functions
# ------------------------------------------------------------------------------
# Get installed C++ compiler version (GCC or Clang)
get_compiler_version() {
if command -v g++ >/dev/null 2>&1; then
g++ -dumpfullversion -dumpversion 2>/dev/null || g++ -dumpversion 2>/dev/null || echo "0"
elif command -v clang++ >/dev/null 2>&1; then
clang++ --version | head -n1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "0"
else
echo "0"
fi
}
# Get installed CMake version
get_cmake_version() {
if command -v cmake >/dev/null 2>&1; then
cmake --version | head -n1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "0"
else
echo "0"
fi
}
# Get installed Boost version (parses headers or queries dpkg)
get_boost_version() {
if [ -f "/usr/include/boost/version.hpp" ]; then
local version_str
version_str=$(grep -E '#define BOOST_LIB_VERSION' /usr/include/boost/version.hpp | grep -oE '[0-9]+_[0-9]+(_[0-9]+)?' | tr '_' '.' || true)
if [ -n "$version_str" ]; then
echo "$version_str"
return
fi
fi
local dpkg_ver
dpkg_ver=$(dpkg-query -W -f='${Version}' libboost-dev 2>/dev/null | grep -oE '^[0-9]+\.[0-9]+\.[0-9]+' || true)
if [ -n "$dpkg_ver" ]; then
echo "$dpkg_ver"
else
echo "0"
fi
}
# Get installed GeographicLib version
get_geographic_version() {
if pkg-config --exists geographiclib 2>/dev/null; then
pkg-config --modversion geographiclib 2>/dev/null
elif [ -f "/usr/include/GeographicLib/Config.h" ]; then
grep -E '#define GEOGRAPHICLIB_VERSION_STRING' /usr/include/GeographicLib/Config.h | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' || echo "0"
else
local dpkg_ver
dpkg_ver=$(dpkg-query -W -f='${Version}' libgeographic-dev 2>/dev/null | grep -oE '^[0-9]+\.[0-9]+(\.[0-9]+)?' || true)
if [ -n "$dpkg_ver" ]; then
echo "$dpkg_ver"
else
echo "0"
fi
fi
}
# Get installed Crypto++ version
get_cryptopp_version() {
if pkg-config --exists libcrypto++ 2>/dev/null; then
pkg-config --modversion libcrypto++ 2>/dev/null
elif [ -f "/usr/include/cryptopp/config.h" ]; then
local raw_ver
raw_ver=$(grep -E '#define CRYPTOPP_VERSION' /usr/include/cryptopp/config.h | grep -oE '[0-9]+' || true)
if [ -n "$raw_ver" ]; then
local major=${raw_ver:0:1}
local minor=${raw_ver:1:1}
local patch=${raw_ver:2:1}
patch=${patch:-0}
echo "${major}.${minor}.${patch}"
return
fi
fi
local dpkg_ver
dpkg_ver=$(dpkg-query -W -f='${Version}' libcrypto++-dev 2>/dev/null | grep -oE '^[0-9]+\.[0-9]+\.[0-9]+' || true)
if [ -n "$dpkg_ver" ]; then
echo "$dpkg_ver"
else
echo "0"
fi
}
# Get installed OpenSSL version
get_openssl_version() {
if command -v openssl >/dev/null 2>&1; then
openssl version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+[a-z]?' | head -n1 || echo "0"
else
echo "0"
fi
}
# ------------------------------------------------------------------------------
# Main Orchestration Logic
# ------------------------------------------------------------------------------
# Define minimum version requirements
readonly REQ_COMPILER_GCC="4.8.0"
readonly REQ_CMAKE="3.12.0"
readonly REQ_BOOST="1.58.0"
readonly REQ_GEOGRAPHIC="1.37.0"
readonly REQ_CRYPTOPP="5.6.1"
# List to aggregate missing APT packages
missing_packages=()
print_usage() {
echo -e "${COLOR_INFO}Usage:${COLOR_RESET} $0 ${COLOR_SUCCESS}[patch|unpatch|all|python|freeze]${COLOR_RESET}"
echo -e ""
echo -e "${COLOR_BOLD}Modes:${COLOR_RESET}"
echo -e " ${COLOR_SUCCESS}patch${COLOR_RESET} Validate dependencies, configure Python environment, and compile the patched library."
echo -e " ${COLOR_SUCCESS}unpatch${COLOR_RESET} Validate dependencies, configure Python environment, and compile the unpatched library."
echo -e " ${COLOR_SUCCESS}all${COLOR_RESET} Validate dependencies, configure Python environment, and build both workspaces sequentially."
echo -e " ${COLOR_SUCCESS}python${COLOR_RESET} Only configure the Python virtual environment and install dependencies."
echo -e " ${COLOR_SUCCESS}freeze${COLOR_RESET} Freeze the current Python virtual environment packages into requirements.txt."
}
# Help is informational and must not trigger dependency checks or installation.
if [ $# -eq 1 ] && { [ "$1" = "-h" ] || [ "$1" = "--help" ]; }; then
print_usage
exit 0
fi
# Ensure command line arguments are present and valid
if [ $# -ne 1 ]; then
log_error "Invalid number of arguments."
print_usage
exit 1
fi
readonly MODE="$1"
if [ "$MODE" != "patch" ] && [ "$MODE" != "unpatch" ] && [ "$MODE" != "all" ] && [ "$MODE" != "freeze" ] && [ "$MODE" != "--freeze" ] && [ "$MODE" != "python" ] && [ "$MODE" != "venv" ]; then
log_error "Unknown mode: '${MODE}'"
print_usage
exit 1
fi
# Get the script directory as the root path (define it early)
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# ------------------------------------------------------------------------------
# Action Helper Functions
# ------------------------------------------------------------------------------
freeze_python_venv() {
local venv_dir="${SCRIPT_DIR}/tools/rl_bridge/venv"
local req_file="${SCRIPT_DIR}/tools/rl_bridge/requirements.txt"
echo -e "${COLOR_INFO}[*] Freezing Python virtual environment packages...${COLOR_RESET}"
if [ ! -d "$venv_dir" ]; then
log_error "Python virtual environment does not exist at ${venv_dir}. Run setup first."
exit 1
fi
if [ ! -f "$venv_dir/bin/pip" ]; then
log_error "pip executable not found in virtual environment at ${venv_dir}."
exit 1
fi
"$venv_dir/bin/pip" freeze > "$req_file"
log_success "Updated requirements file at ${req_file} successfully."
}
setup_python_venv() {
local venv_dir="${SCRIPT_DIR}/tools/rl_bridge/venv"
local req_file="${SCRIPT_DIR}/tools/rl_bridge/requirements.txt"
# Warn the user and require explicit confirmation to avoid accidental global python pollution
if [ -t 0 ]; then
echo -e "${COLOR_WARNING}[WARNING] This step will verify/install Python dependencies inside the virtual environment under tools/rl_bridge/venv.${COLOR_RESET}"
read -p "Do you want to proceed with virtual environment package synchronization? (Y/N): " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo -e "${COLOR_WARNING}[WARNING] Python virtual environment synchronization bypassed by user.${COLOR_RESET}"
return 0
fi
fi
echo -e "${COLOR_INFO}[*] Setting up Python virtual environment...${COLOR_RESET}"
# Verify python3 is installed
if ! command -v python3 >/dev/null 2>&1; then
log_error "Python 3 is required but not found in PATH."
exit 1
fi
# Create virtual environment if it doesn't exist
if [ ! -d "$venv_dir" ]; then
echo -e "${COLOR_INFO}[*] Creating new virtual environment at ${venv_dir}...${COLOR_RESET}"
if ! python3 -m venv "$venv_dir" 2>/dev/null; then
# Attempt to install python3-venv if missing (Ubuntu/Debian)
log_warning "python3-venv module may be missing. Requesting installation..."
sudo apt-get install -y python3-venv
python3 -m venv "$venv_dir"
fi
log_success "Virtual environment created."
else
echo -e "${COLOR_SUCCESS}[SUCCESS] Python virtual environment already exists at ${venv_dir}.${COLOR_RESET}"
fi
# Apply requirements
local req_rpi="${SCRIPT_DIR}/tools/rl_bridge/requirements-rpi.txt"
local active_req="$req_file"
local dpkg_arch
dpkg_arch=$(dpkg --print-architecture 2>/dev/null || uname -m)
if [ -f "$req_rpi" ] && { [ "$dpkg_arch" = "armhf" ] || [ "$dpkg_arch" = "arm64" ] || [ "$(uname -m)" != "x86_64" ]; }; then
echo -e "${COLOR_INFO}[*] Detected ARM / Raspberry Pi environment (${dpkg_arch}). Using ${req_rpi}...${COLOR_RESET}"
active_req="$req_rpi"
fi
if [ -f "$active_req" ]; then
echo -e "${COLOR_INFO}[*] Applying Python requirements from ${active_req}...${COLOR_RESET}"
"$venv_dir/bin/pip" install --upgrade pip
"$venv_dir/bin/pip" install -r "$active_req"
if [ "$dpkg_arch" = "armhf" ] || [ "$(uname -m)" = "armv7l" ]; then
echo -e "${COLOR_INFO}[*] Installing 32-bit ARM prebuilt onnxruntime wheel for Raspberry Pi Bullseye...${COLOR_RESET}"
"$venv_dir/bin/pip" install https://github.com/nknytk/built-onnxruntime-for-raspberrypi-linux/raw/master/wheels/bullseye/onnxruntime-1.16.0-cp39-cp39-linux_armv7l.whl || true
fi
log_success "Python requirements successfully applied."
else
log_warning "Requirements file not found at ${active_req}. Skipping package installation."
fi
}
# If the user requested freeze, exit early after doing so
if [ "$MODE" == "freeze" ] || [ "$MODE" == "--freeze" ]; then
freeze_python_venv
exit 0
fi
if [ "$MODE" == "python" ] || [ "$MODE" == "venv" ]; then
setup_python_venv
exit 0
fi
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}[*] Step 1: Starting Smart Prerequisites Check...${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
# 1. Check C++11 Compiler (GCC / Clang)
compiler_ver=$(get_compiler_version)
if [ "$compiler_ver" != "0" ] && version_ge "$compiler_ver" "$REQ_COMPILER_GCC"; then
echo -e "${COLOR_SUCCESS}[SUCCESS]${COLOR_RESET} Compiler found: version ${COLOR_SUCCESS}${compiler_ver}${COLOR_RESET} (supports C++11)"
else
echo -e "${COLOR_WARNING}[WARNING]${COLOR_RESET} C++11 compatible compiler not found or insufficient version (${COLOR_WARNING}${compiler_ver}${COLOR_RESET} < ${COLOR_INFO}${REQ_COMPILER_GCC}${COLOR_RESET})."
missing_packages+=("build-essential" "g++")
fi
# 2. Check CMake
cmake_ver=$(get_cmake_version)
if [ "$cmake_ver" != "0" ] && version_ge "$cmake_ver" "$REQ_CMAKE"; then
echo -e "${COLOR_SUCCESS}[SUCCESS]${COLOR_RESET} CMake found: version ${COLOR_SUCCESS}${cmake_ver}${COLOR_RESET} (>= ${COLOR_INFO}${REQ_CMAKE}${COLOR_RESET})"
else
echo -e "${COLOR_WARNING}[WARNING]${COLOR_RESET} CMake not found or insufficient version (${COLOR_WARNING}${cmake_ver}${COLOR_RESET} < ${COLOR_INFO}${REQ_CMAKE}${COLOR_RESET})."
missing_packages+=("cmake")
fi
# 3. Check Boost
boost_ver=$(get_boost_version)
if [ "$boost_ver" != "0" ] && version_ge "$boost_ver" "$REQ_BOOST"; then
echo -e "${COLOR_SUCCESS}[SUCCESS]${COLOR_RESET} Boost found: version ${COLOR_SUCCESS}${boost_ver}${COLOR_RESET} (>= ${COLOR_INFO}${REQ_BOOST}${COLOR_RESET})"
else
echo -e "${COLOR_WARNING}[WARNING]${COLOR_RESET} Boost not found or insufficient version (${COLOR_WARNING}${boost_ver}${COLOR_RESET} < ${COLOR_INFO}${REQ_BOOST}${COLOR_RESET})."
missing_packages+=("libboost-dev" "libboost-all-dev")
fi
# 4. Check GeographicLib
geo_ver=$(get_geographic_version)
if [ "$geo_ver" != "0" ] && version_ge "$geo_ver" "$REQ_GEOGRAPHIC"; then
echo -e "${COLOR_SUCCESS}[SUCCESS]${COLOR_RESET} GeographicLib found: version ${COLOR_SUCCESS}${geo_ver}${COLOR_RESET} (>= ${COLOR_INFO}${REQ_GEOGRAPHIC}${COLOR_RESET})"
else
echo -e "${COLOR_WARNING}[WARNING]${COLOR_RESET} GeographicLib not found or insufficient version (${COLOR_WARNING}${geo_ver}${COLOR_RESET} < ${COLOR_INFO}${REQ_GEOGRAPHIC}${COLOR_RESET})."
missing_packages+=("libgeographic-dev")
fi
# 5. Check Crypto++
crypto_ver=$(get_cryptopp_version)
if [ "$crypto_ver" != "0" ] && version_ge "$crypto_ver" "$REQ_CRYPTOPP"; then
echo -e "${COLOR_SUCCESS}[SUCCESS]${COLOR_RESET} Crypto++ found: version ${COLOR_SUCCESS}${crypto_ver}${COLOR_RESET} (>= ${COLOR_INFO}${REQ_CRYPTOPP}${COLOR_RESET})"
else
echo -e "${COLOR_WARNING}[WARNING]${COLOR_RESET} Crypto++ not found or insufficient version (${COLOR_WARNING}${crypto_ver}${COLOR_RESET} < ${COLOR_INFO}${REQ_CRYPTOPP}${COLOR_RESET})."
missing_packages+=("libcrypto++-dev")
fi
# 6. Check OpenSSL (Optional backend)
openssl_ver=$(get_openssl_version)
if [ "$openssl_ver" != "0" ]; then
echo -e "${COLOR_SUCCESS}[SUCCESS]${COLOR_RESET} OpenSSL found: version ${COLOR_SUCCESS}${openssl_ver}${COLOR_RESET}"
else
echo -e "${COLOR_WARNING}[WARNING]${COLOR_RESET} OpenSSL not found. Marking optional package ${COLOR_INFO}'libssl-dev'${COLOR_RESET} for installation."
missing_packages+=("libssl-dev" "openssl")
fi
# ------------------------------------------------------------------------------
# Install Missing Dependencies
# ------------------------------------------------------------------------------
if [ ${#missing_packages[@]} -gt 0 ]; then
echo -e "${COLOR_WARNING}[WARNING] The following required dependencies are missing or outdated:${COLOR_RESET} ${COLOR_INFO}${missing_packages[*]}${COLOR_RESET}"
echo -e "${COLOR_INFO}[*] Requesting root privileges to install missing packages...${COLOR_RESET}"
# Check if apt-get is available
if ! command -v apt-get >/dev/null 2>&1; then
echo -e "${COLOR_DANGER}[ERROR] apt-get package manager not found. Please install the dependencies manually.${COLOR_RESET}" >&2
exit 1
fi
sudo apt-get update
sudo apt-get install -y "${missing_packages[@]}"
echo -e "${COLOR_SUCCESS}[SUCCESS] Prerequisites successfully installed via package manager.${COLOR_RESET}"
else
echo -e "${COLOR_SUCCESS}[SUCCESS] All prerequisites are satisfied. Skipping dependency installation.${COLOR_RESET}"
fi
# ------------------------------------------------------------------------------
# Action Helper Functions
# ------------------------------------------------------------------------------
apply_patches() {
local target_dir="$1"
echo -e "${COLOR_INFO}[*] Preparing workspace at ${target_dir}...${COLOR_RESET}"
# ==========================================
# TODO / PLACEHOLDER: Insert patch commands
# ==========================================
# Add your custom patch applications here.
# E.g., patch -p1 < custom_mitigation.patch
# ==========================================
echo -e "${COLOR_WARNING}[WARNING] TODO: Insert custom patch application commands in this block.${COLOR_RESET}"
# ==========================================
echo -e "${COLOR_SUCCESS}[SUCCESS] Patch configuration successfully applied.${COLOR_RESET}"
}
revert_patches() {
local target_dir="$1"
echo -e "${COLOR_INFO}[*] Preparing workspace at ${target_dir}...${COLOR_RESET}"
# ==========================================
# TODO / PLACEHOLDER: Insert unpatch commands
# ==========================================
# Add your commands to revert/remove patches.
# E.g., patch -R -p1 < custom_mitigation.patch
# ==========================================
echo -e "${COLOR_WARNING}[WARNING] TODO: Insert custom patch reversion commands in this block.${COLOR_RESET}"
# ==========================================
echo -e "${COLOR_SUCCESS}[SUCCESS] Patch configuration successfully reverted.${COLOR_RESET}"
}
compile_library() {
local target_dir="$1"
local mode_name="$2"
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}[*] Compiling Vanetza Library at ${target_dir}...${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
if [ ! -d "$target_dir" ]; then
echo -e "${COLOR_DANGER}[ERROR] Target directory does not exist: ${target_dir}${COLOR_RESET}" >&2
exit 1
fi
local build_dir="${target_dir}/build"
rm -rf "$build_dir/CMakeCache.txt" "$build_dir/CMakeFiles"
mkdir -p "$build_dir"
cd "$build_dir"
echo -e "${COLOR_INFO}[CMAKE] Running CMake configuration...${COLOR_RESET}"
cmake ..
local cores=$(nproc)
local dpkg_arch
dpkg_arch=$(dpkg --print-architecture 2>/dev/null || uname -m)
if [ "$dpkg_arch" = "armhf" ] || [ "$dpkg_arch" = "arm64" ] || [ "$(uname -m)" != "x86_64" ]; then
echo -e "${COLOR_INFO}[MAKE] Detected ARM / Raspberry Pi. Limiting build concurrency to 2 jobs to prevent RAM OOM...${COLOR_RESET}"
cores=2
fi
echo -e "${COLOR_INFO}[MAKE] Starting compilation on ${COLOR_SUCCESS}${cores}${COLOR_RESET} ${COLOR_INFO}CPU cores...${COLOR_RESET}"
make -j"${cores}"
echo -e "${COLOR_SUCCESS}[SUCCESS] Vanetza library compilation complete in ${COLOR_WARNING}${mode_name}${COLOR_RESET} mode."
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
}
setup_onnxruntime() {
local target_dir="${SCRIPT_DIR}/third_party/onnxruntime"
local dpkg_arch
dpkg_arch=$(dpkg --print-architecture 2>/dev/null || uname -m)
local onnx_arch="x64"
if [ "$dpkg_arch" = "arm64" ] || [ "$(uname -m)" = "aarch64" ]; then
onnx_arch="aarch64"
fi
# Check if target_dir exists and holds compatible binaries
if [ -d "$target_dir/lib" ]; then
local lib_file="${target_dir}/lib/libonnxruntime.so"
if [ -f "$lib_file" ] && command -v file >/dev/null 2>&1; then
local file_info
file_info=$(file "$lib_file")
if [[ "$onnx_arch" == "aarch64" && "$file_info" == *"ARM aarch64"* ]]; then
echo -e "${COLOR_SUCCESS}[SUCCESS] Native ARM64 ONNX Runtime C++ library configured at ${target_dir}.${COLOR_RESET}"
return 0
elif [[ "$onnx_arch" == "x64" && "$file_info" == *"x86-64"* ]]; then
echo -e "${COLOR_SUCCESS}[SUCCESS] Native x86_64 ONNX Runtime C++ library configured at ${target_dir}.${COLOR_RESET}"
return 0
else
echo -e "${COLOR_WARNING}[WARNING] Existing ONNX Runtime architecture mismatched system architecture (${onnx_arch}). Updating library...${COLOR_RESET}"
rm -f "${target_dir}/lib/libonnxruntime.so"*
fi
fi
fi
if [ "$dpkg_arch" = "armhf" ] || [ "$(uname -m)" = "armv7l" ]; then
echo -e "${COLOR_INFO}[*] Detected 32-bit ARM (armhf) architecture.${COLOR_RESET}"
if [ -f "${target_dir}/lib/libonnxruntime.so" ] && [ -f "${target_dir}/include/onnxruntime_cxx_api.h" ]; then
echo -e "${COLOR_SUCCESS}[SUCCESS] Native 32-bit ARM C++ ONNX Runtime library configured at ${target_dir}.${COLOR_RESET}"
return 0
fi
echo -e "${COLOR_INFO}[*] Downloading 32-bit C++ ONNX Runtime library from GitHub Releases (20MB)...${COLOR_RESET}"
mkdir -p "${target_dir}/lib" "${target_dir}/include"
local arm32_url1="https://github.com/csukuangfj/onnxruntime-libs/releases/download/v1.17.1/onnxruntime-linux-arm-1.17.1.zip"
local arm32_url2="https://github.com/csukuangfj/onnxruntime-libs/releases/download/v1.16.0/onnxruntime-linux-arm-1.16.0.zip"
local zipfile="/tmp/onnx_arm32.zip"
rm -f "$zipfile"
if command -v curl >/dev/null 2>&1; then
curl -L -# "$arm32_url1" -o "$zipfile" || curl -L -# "$arm32_url2" -o "$zipfile"
elif command -v wget >/dev/null 2>&1; then
wget --no-check-certificate --show-progress "$arm32_url1" -O "$zipfile" || wget --no-check-certificate --show-progress "$arm32_url2" -O "$zipfile"
fi
if [ -f "$zipfile" ] && [ -s "$zipfile" ]; then
echo -e "${COLOR_INFO}[*] Unpacking 32-bit ARM ONNX C++ library and headers...${COLOR_RESET}"
unzip -q "$zipfile" -d /tmp/ 2>/dev/null || true
local extracted_dir
extracted_dir=$(find /tmp -maxdepth 1 -name "onnxruntime-linux-arm*" -type d 2>/dev/null | head -n 1)
if [ -n "$extracted_dir" ] && [ -d "$extracted_dir" ]; then
cp -r ${extracted_dir}/lib/* "${target_dir}/lib/" 2>/dev/null || true
cp -r ${extracted_dir}/include/* "${target_dir}/include/" 2>/dev/null || true
cd "${target_dir}/lib"
local lib_so
lib_so=$(find . -maxdepth 1 -name "libonnxruntime.so.*" 2>/dev/null | head -n 1)
if [ -n "$lib_so" ]; then
ln -sf "$lib_so" libonnxruntime.so 2>/dev/null || true
fi
cd "${SCRIPT_DIR}"
rm -rf "$zipfile" "$extracted_dir"
echo -e "${COLOR_SUCCESS}[SUCCESS] Native 32-bit ARM C++ ONNX Runtime library configured at ${target_dir}.${COLOR_RESET}"
return 0
fi
fi
echo -e "${COLOR_DANGER}[ERROR] Download of 32-bit C++ ONNX Runtime library failed.${COLOR_RESET}" >&2
return 1
fi
echo -e "${COLOR_INFO}[*] Downloading ONNX Runtime C++ prebuilt binaries (${onnx_arch})...${COLOR_RESET}"
mkdir -p "${SCRIPT_DIR}/third_party"
local version="1.16.3"
local tarball="onnxruntime-linux-${onnx_arch}-${version}.tgz"
local url="https://github.com/microsoft/onnxruntime/releases/download/v${version}/${tarball}"
if command -v wget >/dev/null 2>&1; then
wget -q --show-progress "$url" -O "/tmp/${tarball}"
elif command -v curl >/dev/null 2>&1; then
curl -L -# "$url" -o "/tmp/${tarball}"
else
echo -e "${COLOR_DANGER}[ERROR] Neither wget nor curl found. Please install one of them to proceed.${COLOR_RESET}" >&2
exit 1
fi
tar -xzf "/tmp/${tarball}" -C "/tmp"
mv "/tmp/onnxruntime-linux-${onnx_arch}-${version}" "$target_dir"
rm "/tmp/${tarball}"
echo -e "${COLOR_SUCCESS}[SUCCESS] ONNX Runtime C++ library configured successfully at ${target_dir}.${COLOR_RESET}"
}
# ------------------------------------------------------------------------------
# Run Requested Actions
# ------------------------------------------------------------------------------
# Configure Python virtual environment and install requirements
setup_python_venv
# Download and extract ONNX Runtime dependency
setup_onnxruntime
if [ "$MODE" == "patch" ]; then
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}[*] Step 2: Processing Patch Configuration...${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
apply_patches "${SCRIPT_DIR}/vanetza_patched"
compile_library "${SCRIPT_DIR}/vanetza_patched" "patch"
elif [ "$MODE" == "unpatch" ]; then
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}[*] Step 2: Processing Patch Configuration...${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
revert_patches "${SCRIPT_DIR}/vanetza_unpatched"
compile_library "${SCRIPT_DIR}/vanetza_unpatched" "unpatch"
elif [ "$MODE" == "all" ]; then
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}[*] Step 2: Processing Patch Configuration for 'unpatch'...${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
revert_patches "${SCRIPT_DIR}/vanetza_unpatched"
compile_library "${SCRIPT_DIR}/vanetza_unpatched" "unpatch"
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}[*] Step 3: Processing Patch Configuration for 'patch'...${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
apply_patches "${SCRIPT_DIR}/vanetza_patched"
compile_library "${SCRIPT_DIR}/vanetza_patched" "patch"
fi
run_self_check() {
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}[*] Step 4: Running System Self-Check & Diagnostic Verification...${COLOR_RESET}"
echo -e "${COLOR_PRIMARY}======================================================================${COLOR_RESET}"
local onnx_lib="${SCRIPT_DIR}/third_party/onnxruntime/lib/libonnxruntime.so"
local onnx_hdr="${SCRIPT_DIR}/third_party/onnxruntime/include/onnxruntime_cxx_api.h"
local binary="${SCRIPT_DIR}/vanetza_unpatched/build/tools/qos-harness/qos-harness"
if [ -f "$onnx_lib" ] && [ -f "$onnx_hdr" ]; then
echo -e "${COLOR_SUCCESS}[SELF-CHECK] 32-bit ARM ONNX C++ library & headers: INSTALLED${COLOR_RESET}"
else
echo -e "${COLOR_DANGER}[SELF-CHECK FAILED] ONNX C++ library missing in third_party/onnxruntime!${COLOR_RESET}"
fi
if [ -f "$binary" ]; then
if strings "$binary" 2>/dev/null | grep -q "Native C++ ONNX Runtime Engine ACTIVE"; then
echo -e "${COLOR_SUCCESS}[SELF-CHECK PASSED] Native C++ ONNX Engine is 100% ACTIVE (USE_ONNX=1)${COLOR_RESET}"
else
echo -e "${COLOR_WARNING}[SELF-CHECK WARNING] Binary built in fallback mode (USE_ONNX=0). Re-run ./setup.sh unpatch.${COLOR_RESET}"
fi
fi
}
run_self_check