Az időutazás korlátai, avagy hogyan kerüljük el saját korábbi énünket?

 ( NevemTeve | 2016. május 13., péntek - 8:52 )

Na jó, ennyire nem izgalmas a téma, igazából azon gondolkozom, hogy amikor az X program 4.4.3-as verzióját fordítom forrásból, akkor a derék linker (ld(1)) ne a már telepített /usr/local/lib64/libX.so -ra találjon rá, hanem a /usr/local/src/X-4.4.3/bonyolult_path/libX.so-ra.

Természetesen nem állítom, hogy ez önmagában bármilyen hibának az oka, de mindenesetre egy olyan apróság, ami zavar, és szeretném kiszűrni.

Például a gdb-nek van egy ilyen ötlete (Makefile részlet):

SHARED_LIBADD = -Wl,/usr/local/src/gdb-7.10/bfd/.libs/libbfd.so

Ennek egy továbbfejlesztése az lenne, ha leszednénk az elejét:

SHARED_LIBADD = /usr/local/src/gdb-7.10/bfd/.libs/libbfd.so

Haladó esetben a libtool nevű varázseszközt is bevethetjük:

SHARED_LIBADD = /usr/local/src/gdb-7.10/bfd/libbfd.la

Ennek az lenne az előnye, hogy a libtool felírja egy kis fájlba, hogy 'majd az install során ezt majd ügyesen újralinkeljük, de akkor már kicsit más opciókkal'. Ez érdemben ilyesmit jelent:

most:    gcc ... /usr/local/src/gdb-7.10/bfd/.libs/libbfd.libbfd-2.25.51.so
install: gcc ... /usr/local/lib64/libbfd.libbfd-2.25.51.so

(Persze ahhoz, hogy ilyeneket tudjon, részben fekete mágia, részben a *.la fájlokban tárolt információk kellenek.)

Azért ennek a módszernek is van gyenge pontja: vannak termékek, amik nem használnak libtool-t, sőt esetleg valamilyen 'fejlett multiplatformos' eszközt használnak, mint amilyen a 'cmake' vagy a 'waf'. Természetesen ilyenkor szo... szomorú helyetben vagyunk, haxolni és tákolni kell, hogy valami működés-szerű eredményt kapjunk.

**2018.09.01.** No, most perl-lel is előadtam ugyanezt:

gcc -L/usr/local/lib64 -L/usr/local/src/perl-5.28.0 -lperl

Természetesen a korábbi libperl nyer, hiszen annak a könyvtára van előbb...

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

az időutazásnak amúgy sincs jövője..

Az idoutazasnak csak jovoje van.

Nekem sikerült másodpercenként 1 secundumot előre utaznom a jövőbe. :)

hogy amikor az X program 4.4.3-as verzióját fordítom forrásból, akkor a derék linker (ld(1)) ne a már telepített /usr/local/lib64/libX.so -ra találjon rá, hanem a /usr/local/src/X-4.4.3/bonyolult_path/libX.so-ra

export LIBRARY_PATH=/usr/local/src/X-4.4.3/bonyolult_path

Ettől a linkelés sikerülni fog, de a binárisba nem fog belekerülni a teljes út, úgyhogy amikor elindítod a binárist, jó eséllyel fejre fog állni. Azt meg úgy lehet körbehakkolni, hogy a binárist eldugod valamilyen PATH-on nem lévő helyre, írsz köréje egy shell script-et (amit a PATH-ra raksz), olyan tartalommal, hogy:

export LD_LIBRARY_PATH=/usr/local/src/X-4.4.3/bonyolult_path:$LD_LIBRARY_PATH
exec .../executable "$@"

Linkelésnél a .so file-ra lesz szükség a LIBRARY_PATH alatt, futtatásnál pedig a .so.major file-ra, az LD_LIBRARY_PATH alatt.

A kevésbé jó megoldás egy script amivel a programot indítod:

----------------------------------------

#!/bin/bash

LD_LIBRARY_PATH=/usr/local/src/X-4.4.3/bonyolult_path ./program $@

----------------------------------------

A jobb pedig az hogy csinálhatnád így a linkelést:

gcc -L/usr/local/src/X-4.4.3/bonyolult_path -Wl,-rpath=/usr/local/src/X-4.4.3/bonyolult_path,--enable-new-dtags main.o -lX -o program

Lehet hogy ez is elég lesz.

gcc -L/usr/local/src/X-4.4.3/bonyolult_path -Wl,-rpath=/usr/local/src/X-4.4.3/bonyolult_path main.o -lX -o program

Ezután a "program"-ban benne lesz az az információ hogy az indításakor a rendszer honnan szedje a szükséges egyedi lib-eket.

@lacos, @4fonya:

Köszönöm, valószínűleg én nem írtam le elég jól a helyzetet: a gdb/samba/mc/openssl/egyéb bonyolult rendszer fordítás+telepítési folyamatába az egyszeri felhasználónak nem sok beleszólása van (hacsak nem haxol bele kézi erővel a Makefile-okba); vagy összeakad a saját korábbi változatával, vagy nem (és ha összeakad, az vagy okoz gondot, vagy nem).

Azon gondolkodom, van-e generikus megoldás ilyen esetekre. (De sőt például linuxon a shared libek eleve path nélkül kerülnek az executable-pa, tehát a program minden egyes indulása egy-egy kalandjáték: menjél, fiam ld.so, vadásszál shared libeket, valami csak akad.)

Ebben az esetben lehet egy megoldás az LD_LIBRARY_PATH helyes használata: How to correctly use LD_LIBRARY_PATH Érdemes megismerni ennek a hibalehetőségeit is: Why LD_LIBRARY_PATH is bad

Aztán van egy másik módszer is, a binárisban lévő RPATH közvetlen módosítása amit a patchelf segédprogrammal tudsz megoldani. Az oldalon találsz hivatkozást a program forrására is ha a rendszeredre nincs hivatalos csomag.

Persze egy hivatalos tárolóból telepített programot nem egészséges dolog átbuherálni, mert ez megzavarhatja a későbbi frissítést ami miatt ráadásul elvész a módosítás. Ezen felül ha van valamilyen biztonsági programod ami figyeli a rendszerben előállt változásokat akkor hamis riasztást is kaphatsz. Tehát az a minimum hogy a módosítás előtt mentést készítesz az eredeti binárisról.

Off-topik, de azért a perl is jól harcol... Számos sikeres fordulás után most ez jött:

gcc -o miniperl ...
ld: 0711-317 ERROR: Undefined symbol: .PerlProc_pipe_cloexec

Szerk: config.h ezt írja:

/* HAS_PIPE:
 *      This symbol, if defined, indicates that the pipe routine is
 *      available to create an inter-process channel.
 */
/*#define HAS_PIPE              / **/

Szerk: log.configure részlete:

pipe() NOT found.