Commit 0f1f892
0
plików
+0
dodanych
-0
usuniętych
@@ -116,6 +116,31 @@ if [[ -n "$BUILD_ROOTFS" ]]; then
116
116
done < <(find "$BUILD_ROOTFS/usr/lib" "$BUILD_ROOTFS/lib" -name '*.so*' -type f -print0 2>/dev/null \
117
117
) | sed 's/@.*$//' | sort -u > "$TMP/build.syms"
118
118
msg " symboli w środowisku budowy: $(wc -l < "$TMP/build.syms")"
119
+
120
+ # Mapa „który soname dostarcza dany symbol” (środowisko budowy) + soname'y
121
+ # obecne w systemie docelowym. Pozwala odróżnić DWIE sytuacje, które wcześniej
122
+ # wyglądały identycznie (i dawały fałszywe „ROZJAZD ABI”):
123
+ # * DRIFT ABI – biblioteka o TYM SAMYM soname JEST w targetcie, ale bez
124
+ # potrzebnego symbolu (np. zbudowane pod nowsze Debianowe libxml2/librsvg)
125
+ # → naprawdę zepsuty pakiet,
126
+ # * BRAK ZALEŻNOŚCI – takiej biblioteki nie ma w targetcie WCALE, więc jest
127
+ # to zwykła zależność z repo (np. cmake → librhash.so.1, libuv.so.1,
128
+ # libjsoncpp.so.27). To NIE rozjazd ABI, ale MUSI trafić do `depends:`.
129
+ msg "▸ Buduję mapę dostawców symboli (symbol → soname)…"
130
+ : > "$TMP/build.prov"
131
+ while IFS= read -r -d '' lib; do
132
+ _sn="$(readelf -d "$lib" 2>/dev/null | sed -n 's/.*SONAME.*\[\(.*\)\].*/\1/p' | head -n1)"
133
+ [[ -n "$_sn" ]] || _sn="$(basename "$lib")"
134
+ nm -D --defined-only --format=posix "$lib" 2>/dev/null | awk -v s="$_sn" 'NF{print $1 "\t" s}'
135
+ done < <(find "$BUILD_ROOTFS/usr/lib" "$BUILD_ROOTFS/lib" -name '*.so*' -type f -print0 2>/dev/null) \
136
+ | sed 's/@.*$//' | sort -u > "$TMP/build.prov"
137
+ : > "$TMP/target.sonames"
138
+ while IFS= read -r -d '' lib; do
139
+ _sn="$(readelf -d "$lib" 2>/dev/null | sed -n 's/.*SONAME.*\[\(.*\)\].*/\1/p' | head -n1)"
140
+ [[ -n "$_sn" ]] && printf '%s\n' "$_sn"
141
+ basename "$lib"
142
+ done < <(find "$ROOTFS/usr/lib" "$ROOTFS/lib" -name '*.so*' -type f -print0 2>/dev/null) \
143
+ | sort -u > "$TMP/target.sonames"
119
144
fi
120
145
121
146
# Katalogi wtyczek: te pliki .so są dlopen()owane przez proces-gospodarza
@@ -139,7 +164,9 @@ fi
139
164
# ── 2) Sprawdzenie każdego pakietu ──────────────────────────────────────────
140
165
_broken=0
141
166
_warned=0
167
+_depwarn=0
142
168
_checked=0
169
+: > "$TMP/dep_all.txt"
143
170
for pag in "${PKGS[@]}"; do
144
171
[[ -f "$pag" ]] || { msg " ! pomijam (brak pliku): $pag"; continue; }
145
172
@@ -162,6 +189,9 @@ for pag in "${PKGS[@]}"; do
162
189
163
190
_pkg_missing="$TMP/missing.txt"
164
191
: > "$_pkg_missing"
192
+ # Soname'y bibliotek spoza obrazu (zależności runtime) – liczone od nowa dla
193
+ # każdego pakietu.
194
+ : > "$TMP/dep_sonames.txt"
165
195
166
196
# Każdy plik ELF: nierozwiązane symbole (BEZ słabych – te są opcjonalne)
167
197
while IFS= read -r -d '' f; do
@@ -180,9 +210,25 @@ for pag in "${PKGS[@]}"; do
180
210
# odrzuć: własne symbole pakietu + listę wyjątków
181
211
comm -23 "$TMP/u.syms" <(sort -u "$TMP/pkg.syms" "$TMP/ignore.syms") > "$TMP/u2.syms"
182
212
if [[ -n "$BUILD_ROOTFS" ]]; then
183
- # TRYB ROZJAZDU: interesują nas TYLKO symbole, które środowisko budowy
184
- # MA, a system docelowy NIE MA (czyli „zbudowane pod inne biblioteki”).
185
- comm -12 "$TMP/u2.syms" "$TMP/build.syms" | comm -23 - "$TMP/target.syms" > "$TMP/u3.syms"
213
+ # TRYB ROZJAZDU: kandydaci to symbole, które środowisko budowy MA,
214
+ # a system docelowy NIE MA. Potem rozdzielamy drift od zależności.
215
+ comm -12 "$TMP/u2.syms" "$TMP/build.syms" | comm -23 - "$TMP/target.syms" > "$TMP/cand.syms"
216
+ awk -F'\t' -v tfile="$TMP/target.sonames" '
217
+ BEGIN { while ((getline l < tfile) > 0) inT[l] = 1 }
218
+ NR == FNR { prov[$1] = prov[$1] (prov[$1] ? "," : "") $2; next }
219
+ {
220
+ if (!($1 in prov)) { print $1 "\tDRIFT\t?"; next }
221
+ n = split(prov[$1], a, ","); hit = 0; miss = ""
222
+ for (i = 1; i <= n; i++) {
223
+ if (a[i] in inT) hit = 1
224
+ else miss = miss (miss ? "," : "") a[i]
225
+ }
226
+ if (hit) print $1 "\tDRIFT\t" miss
227
+ else print $1 "\tDEP\t" miss
228
+ }' "$TMP/build.prov" "$TMP/cand.syms" > "$TMP/classified.txt"
229
+ awk -F'\t' '$2 == "DRIFT" { print $1 }' "$TMP/classified.txt" > "$TMP/u3.syms"
230
+ awk -F'\t' '$2 == "DEP" && $3 != "" { n = split($3, a, ","); for (i = 1; i <= n; i++) print a[i] }' \
231
+ "$TMP/classified.txt" >> "$TMP/dep_sonames.txt"
186
232
else
187
233
# TRYB CELU: wszystko, czego nie ma w obrazie (informacyjnie).
188
234
comm -23 "$TMP/u2.syms" "$TMP/target.syms" > "$TMP/u3.syms"
@@ -193,7 +239,10 @@ for pag in "${PKGS[@]}"; do
193
239
done < <(find "$TMP/x/data" -type f -print0 2>/dev/null)
194
240
195
241
_checked=$((_checked + 1))
196
- if [[ -s "$_pkg_missing" ]]; then
242
+ _has_drift=0; [[ -s "$_pkg_missing" ]] && _has_drift=1
243
+ _has_dep=0; [[ -s "$TMP/dep_sonames.txt" ]] && _has_dep=1
244
+
245
+ if [[ $_has_drift -eq 1 ]]; then
197
246
if [[ -n "$BUILD_ROOTFS" ]]; then
198
247
_broken=$((_broken + 1))
199
248
printf '\033[1;31m✗ %s\033[0m – ROZJAZD ABI: %s symboli jest w środowisku budowy, a nie ma w %s:\n' \
@@ -215,14 +264,30 @@ for pag in "${PKGS[@]}"; do
215
264
fi
216
265
fi
217
266
if [[ -n "$BUILD_ROOTFS" ]]; then
218
- printf ' ↳ pakiet powstał w środowisku o innych bibliotekach niż docelowe\n'
267
+ printf ' ↳ symbol jest w środowisku budowy, a brak go w bibliotece o TYM SAMYM\n'
268
+ printf ' sonamie w %s – pakiet zbudowano pod inne biblioteki\n' "$ROOTFS"
219
269
printf ' (np. chroot Debiana na VPS). Przebuduj natywnie:\n'
220
270
printf ' ./build-repo.sh --rootfs %s %s\n' "$BUILD_ROOTFS" \
221
271
"$(basename "$pag" | sed 's/-[0-9][^-]*-[0-9]*\.pag$//')"
222
272
fi
223
- else
273
+ fi
274
+
275
+ # Brakujące zależności runtime: bibliotek, których w obrazie nie ma WCALE.
276
+ # To nie rozjazd ABI (dociągnie je `pag` z repo), ale muszą być w `depends:`
277
+ # receptury – inaczej użytkownik dostanie „error while loading shared
278
+ # libraries”. Tak wyszło przy cmake: brakowało librhash/libuv/libjsoncpp.
279
+ if [[ $_has_dep -eq 1 ]]; then
280
+ _depwarn=$((_depwarn + 1))
281
+ sort -u "$TMP/dep_sonames.txt" >> "$TMP/dep_all.txt"
282
+ printf '\033[1;33m· %s\033[0m – %s bibliotek spoza obrazu (zależności runtime – dopisz do depends:):\n' \
283
+ "$(basename "$pag")" "$(sort -u "$TMP/dep_sonames.txt" | wc -l)"
284
+ printf ' %s\n' "$(sort -u "$TMP/dep_sonames.txt" | tr '\n' ' ')"
285
+ fi
286
+
287
+ if [[ $_has_drift -eq 0 && $_has_dep -eq 0 ]]; then
224
288
msg " ✓ $(basename "$pag") – bez zarzutów"
225
289
fi
290
+
226
291
done
227
292
228
293
echo
@@ -232,6 +297,15 @@ if [[ -n "$BUILD_ROOTFS" && $_broken -gt 0 ]]; then
232
297
exit 1
233
298
fi
234
299
if [[ -n "$BUILD_ROOTFS" ]]; then
300
+ if [[ $_depwarn -gt 0 ]]; then
301
+ printf '\033[1;33m! %d pakiet(ów) używa bibliotek spoza obrazu: %s\033[0m\n' \
302
+ "$_depwarn" "$(sort -u "$TMP/dep_all.txt" 2>/dev/null | tr '\n' ' ')"
303
+ printf ' To normalne dla repo (`pag` dociąga je z repo), ale każda z nich musi być w `depends:` receptury.\n'
304
+ if [[ $STRICT -eq 1 ]]; then
305
+ printf '\033[1;31m✗ --strict: brakujące zależności traktowane jak błąd\033[0m\n'
306
+ exit 1
307
+ fi
308
+ fi
235
309
printf '\033[1;32m✓ %d pakietów sprawdzonych – bez rozjazdu ABI (środowisko budowy == %s)\033[0m\n' \
236
310
"$_checked" "$ROOTFS"
237
311
else