Ich verwende nix
im "Einzelbenutzermodus" in einem System, in dem ich nicht der Root bin (siehe unten für eine Beschreibung meines Nix-Setups).
Ich wollte schnell eine meiner Binärdateien ausführen, die dynamisch mit einer Bibliothek verknüpft ist, die im System nicht vorhanden ist.
Also habe ich die Bibliothek installiert mit nix
:
$ nix-env -qa 'gmp'
gmp-4.3.2
gmp-5.1.3
$ nix-env -i gmp-5.1.3
Aber die Bibliothek wird vom Linker immer noch nicht gefunden:
$ ldd -r ../valencies
../valencies: /lib64/libc.so.6: version `GLIBC_2.15' not found (required by ../valencies)
../valencies: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ../valencies)
linux-vdso.so.1 => (0x00007fffbbf28000)
/usr/local/lib/libsnoopy.so (0x00007f4dcfbdc000)
libgmp.so.10 => not found
libffi.so.5 => /usr/lib64/libffi.so.5 (0x00007f4dcf9cc000)
libm.so.6 => /lib64/libm.so.6 (0x00007f4dcf748000)
librt.so.1 => /lib64/librt.so.1 (0x00007f4dcf540000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f4dcf33c000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f4dcf11f000)
libc.so.6 => /lib64/libc.so.6 (0x00007f4dced8b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4dcfde7000)
undefined symbol: __gmpz_gcd (../valencies)
undefined symbol: __gmpn_cmp (../valencies)
undefined symbol: __gmpz_mul (../valencies)
undefined symbol: __gmpz_fdiv_r (../valencies)
undefined symbol: __gmpz_fdiv_q_2exp (../valencies)
undefined symbol: __gmpz_com (../valencies)
undefined symbol: __gmpn_gcd_1 (../valencies)
undefined symbol: __gmpz_sub (../valencies)
symbol memcpy, version GLIBC_2.14 not defined in file libc.so.6 with link time reference (../valencies)
undefined symbol: __gmpz_fdiv_q (../valencies)
undefined symbol: __gmpz_fdiv_qr (../valencies)
undefined symbol: __gmpz_add (../valencies)
undefined symbol: __gmpz_init (../valencies)
undefined symbol: __gmpz_ior (../valencies)
undefined symbol: __gmpz_mul_2exp (../valencies)
undefined symbol: __gmpz_xor (../valencies)
undefined symbol: __gmpz_and (../valencies)
symbol __fdelt_chk, version GLIBC_2.15 not defined in file libc.so.6 with link time reference (../valencies)
undefined symbol: __gmpz_tdiv_qr (../valencies)
undefined symbol: __gmp_set_memory_functions (../valencies)
undefined symbol: __gmpz_tdiv_q (../valencies)
undefined symbol: __gmpz_divexact (../valencies)
undefined symbol: __gmpz_tdiv_r (../valencies)
$
Schauen Sie, es ist im Dateisystem vorhanden:
$ find / -name 'libgmp.so.10' 2>/dev/null
/nix/store/mnmzq0qbrvw6dv1k2vj3cwz9ffdh05zr-user-environment/lib/libgmp.so.10
/nix/store/fnww2w81hv5v3dl9gsb7p4llb7z7krzd-gmp-5.1.3/lib/libgmp.so.10
$
Was mache ich, damit die von installierten Bibliotheken nix
"sichtbar" sind?
Wahrscheinlich, das Standard - Benutzerinstallationsskript von nix
ändert .bash_profile
seine hinzufügen bin/
in PATH
, aber nicht etwas Analoges für Bibliotheken tun.
Mein Nix-Setup:
Das einzige, was ich vom Root verlangt habe, war: mkdir -m 0755 /nix && chown ivan /nix
Ansonsten habe ich das einfache Standard-Nix-Installationsverfahren befolgt. Jetzt kann ich benutzerdefinierte Programme aus nix-Paketen verwenden. Ich konnte dies ohne die Hilfe der Wurzel überhaupt nicht gut machen, dh ohne /nix/
, weil /nix/
es für mich nicht verfügbar war; Ich könnte natürlich ein anderes Verzeichnis verwenden, aber dann wären die vorgefertigten Binärpakete nicht gültig und alle Pakete müssten gemäß der Nix-Dokumentation neu erstellt werden. In meinem Fall war es einfacher, /nix/
nach mir zu fragen .
Eine andere Sache, die ich getan habe, ist das Hinzufügen zu ~/.bash_profile
:
export NIX_CONF_DIR=/nix/etc/nix
damit ich bearbeiten kann nix.conf
. (Es sollte sonst in der Root-Steuerung sein /etc/
. Ich habe es getan, weil ich wollte build-max-jobs
und build-cores
Einstellungen darin.)
quelle
nix-env
, ganz zu schweigen davonnix.conf
. Welches Betriebssystem ist das? Was bedeuten wiederholte Referenzennix
? Ich habe nur gehört, dass es als Abkürzung für verwendet wirdUnix
, aber es scheint, dass Sie es in einem spezifischeren Kontext verwenden.nix
ist ein moderner Paketmanager , und nixOS ist eine Distribution, und Hydra ist ein System zum ständigen Neuerstellen von nix-Paketen. nixOps ist ein Tool zum deklarativen Verwalten einer Infrastruktur (eines Netzwerks aus mehreren Hosts) und disNix zum deklarativen Verwalten einer Reihe von Diensten (auf einer Infrastruktur).guix
ist ein GNU-Nachkomme vonnix
, mit einer Distribution (gefördert als 100% libre IICguix
.Antworten:
TL; DR
Die funktionierende Lösung verwendet
patchelf
(wenn Sie sich mit nicht übereinstimmenden glibc-Versionen befassen müssen: im Host-System und mit dem, mit dem nix libs verknüpft wurden), siehe die zweite Hälfte meiner Geschichte.Den üblichen Ansatz versuchen
Versuch, LD_LIBRARY_PATH zu verwenden
Nun, ich habe eine Umgebungsvariable dafür eingerichtet in
~/.bash_profile
:aber das ist nicht alles!
Jetzt gibt es Probleme beim Verknüpfen mit verschiedenen Versionen von
libc
:2 Versionen von glibc aussortieren
Der überraschendste Fehler hier ist:
denn
nix
muss installiert haben, welche versionglibc
von seiner verwendet wirdlibgmp
!Und tatsächlich ist das
glibc
vonnix
da:Wahrscheinlich
glibc
war es für den Benutzer nicht verfügbar. Als ich meine Binärdatei ausführte, wurde das Systemglibc
zuerst geladen. Beweis:Ok, wir können versuchen, dies
glibc
auch für den Benutzer sichtbar zu machen :Dann ist alles schlecht:
Es scheint also keine leichte Aufgabe zu sein, wenn Sie Bibliotheken laden möchten, wenn Sie
nix
Ihre eigenen Binärdateien ausführen ...Im Moment kommentiere ich aus
und in der Shell-Sitzung tun:
Ich muss mehr nachdenken. (Lesen Sie mehr über __vdso_time: Ungültiger Modus für dlopen () : Es wird erwartet, dass ein anderer
glibc
inLD_LIBRARY_PATH
abstürzt, da Ihrld-linux-x86-64.so.2
nicht mit Ihrem übereinstimmtlibc.so.6
. Es ist möglich, mehrere Versionen von glibc auf einem einzigen System zu haben, aber etwas schwierig, wie in dieser Antwort erläutert.)Die benötigte Lösung: Patchelf
Der Pfad zum dynamischen Linker ist also in der Binärdatei fest codiert. Der verwendete dynamische Linker stammt vom System (vom Host glibc) und nicht von nix. Und weil der dynamische Linker nicht mit dem Glibc übereinstimmt, den wir verwenden möchten und müssen, funktioniert er nicht.
Eine einfache und funktionierende Lösung ist Patchelf .
Danach funktioniert es. Sie müssen jedoch immer noch damit herumspielen
LD_LIBRARY_PATH
.Wenn - wie in meinem Fall unvollkommen - einige der Bibliotheken von nichts genommen werden, aber einige werden von dem Host - System entnommen (weil ich nicht installiert habe sie mit
nix-env -i
), Sie müssen sowohl den Pfad zu dem nichts Libs angeben, und zu Ihrem Hostsystem libs inLD_LIBRARY_PATH
(es überschreibt den Standardsuchpfad vollständig).zusätzlicher Schritt: Patchelf für den Bibliothekssuchpfad
(von der
patchelf
Seite)Ebenso können Sie
RPATH
den Linker-Suchpfad ändern , der in ausführbare Dateien und dynamische Bibliotheken eingebettet ist:Dadurch sucht der dynamische Linker in
/opt/my-libs/lib
und/foo/lib
nach den vom Programm benötigten gemeinsam genutzten Bibliotheken. Natürlich können Sie auch die Umgebungsvariable festlegenLD_LIBRARY_PATH
, dies ist jedoch häufig unpraktisch, da zum Einrichten der Umgebung ein Wrapper-Skript erforderlich ist.quelle
Zusätzlich zum „Einzelbenutzermodus“ von Nix gebe ich eine Antwort für NixOS- Benutzer. Normalerweise können Sie unter NixOS keine Binärdateien ausführen.
Wenn Sie Pakete lokal mit installieren
nix-env -i
, werden alle Ihre.so
Dateien in gespeichert~/.nix-profile/lib/
.Wenn Sie Pakete global installieren, indem Sie sie in angeben
/etc/nixos/configuration.nix
, finden Sie die entsprechenden.so
Dateien in/nix/var/nix/profiles/system/sw/lib/
. Richtiger ist,/nix/store/
dass sich in diesem Verzeichnis nur Symlinks zu entsprechenden Dateien befinden.Wenn Sie also Pakete global installieren, lautet die Lösung von Ivan Zakharyaschev :
Damit der erste Befehl funktioniert, müssen Sie ihn
glibc
global installieren . Sie können den zweiten Befehl auch ändern, wenn Sie Pakete sowohl global als auch pro Benutzer installiert haben:Es kann sein, dass die benötigte
.so
Datei einfach nicht im System installiert ist, sodass folgende Fehler auftreten:Ich bin nicht sicher, wie ich ein entsprechendes Paket für eine fehlende Datei im Allgemeinen finden kann, aber Sie können den Namen der
.so
Datei googeln, das entsprechende Paket installieren und versuchen, Ihre ausführbare Datei erneut mit einer benutzerdefinierten Datei auszuführenLD_LIBRARY_PATH
.quelle