← PaganLinux

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