PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Umgebungsvariable LD_LIBRARY_PATH in C-Programm setzen?



SeeksTheMoon
10-02-2005, 01:45
Ich habe Programme, die bestimmte Umgebungsvariablen gesetzt haben müssen, damit sie laufen.
Damit der Anwender das nicht machen muss, habe ich in C++ ein Startprogramm geschrieben dass das mit der C-Funktion setenv() macht.

Jetzt wird allerdings noch eine Bibliothek nicht gefunden, die zu meinem Anwendungsbundle gehört und ich habe mir gedacht, dass ich den Pfad dorthin mit der Umgebungsvariable LD_LIBRARY_PATH setze, aber leider gibts folgende Probleme:
o wird diese Variable gesetzt, bricht die Programmausführung ab, weil z.B. die C-Bibliothek des Systems nicht mehr gefunden wird.
o Ich habe keine Ahnung wie man Umgebungsvariablen auf diese Weise verkettet, das sollte möglichst auch OS- unabhängig sein.

Gibt es keinen schöneren Weg, einer Anwendung zu sagen wo ihre Bibliotheken liegen?

locus vivendi
10-02-2005, 15:34
Ich habe keine Ahnung wie man Umgebungsvariablen auf diese Weise verkettet, das sollte möglichst auch OS- unabhängig sein.
OS unabhängig kann ich dir nicht sagen, ich glaube nicht das es sowas gibt. Aber die Umgebungsvariable verketten kannst du so (auf der shell):
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:[neuer Pfad 1]:[neuer Pfad 2]:[...]


Gibt es keinen schöneren Weg, einer Anwendung zu sagen wo ihre Bibliotheken liegen?
Schöner weiss ich nicht. Es gibt noch "festverdrahtete" Pfade in binaries, wenn du z.B. den gcc (oder genauer gesagt ld) benutzt. Wenn verfügbar, schau doch mal ins ld-Manual oder die Texinfo-Pages nach der Option "-rpath". (und ins gcc-Manual wie man Optionen an den Linker weitergibt, falls nicht geläufig)

Ansonsten könnte libtool vielleicht noch weiterhelfen, aber das benutze ich eigentlich nicht, deshalb kann ich dazu nicht mehr sagen.

anda_skoa
10-02-2005, 16:58
Wenn ein Programm bestimmte Umgebungsvariablen braucht ist es normaleweise wesentlich sinnvoller das über ein Script zu machen.

Dort einfach das benötigte Environment herstellen und das eigentliche Executable starten.

Ciao,
_

SeeksTheMoon
11-02-2005, 10:28
Das Script ist dann aber an die Shell gebunden und unter Windows läuft das dann nicht (immer unter der Annahme, der User sei ein DAU).
Das C-Programm kann ich wenigstens für Windows kompilieren.

-rpath und -rpath-link habe ich auch schon gesehen, mir ist jetzt klarer wofür man das braucht. Das dürfte besser sein als die Umgebungsvariablen.

anda_skoa
11-02-2005, 12:16
Wir haben hier in der Firma 4 verschiedene Plattformen und machen das immer mit sh-Scripts unter Unix und BATCH Scripts unter Windows

Speziell für den Windows User ist der Unterschied ohnehin nicht merkbar, der klick in 99,99999% der Fällen nur auf das Programmicon.

Ciao,
_

panzi
12-02-2005, 21:13
Der Code sollte zwar unter jeden OS funktionieren, aber nur unter den Unixoiden werden die Pfade mit : getrennt, unter windows werden sie mit ; getrennt. Also dafür hat ein #ifdef welches das OS abfragt. Aber die Variable LD_LIBRARY_PATH ist wohl unter Windows nicht verwendet. Hab keine Ahnung ob die überhaupt unter allen Unixoiden verwendet wird, oder ob das nur Linux so macht. Ich _glaub_ unter Windows wird dafür einfach "Path" verwendet. (Ja "Path", nicht "PATH". Aber ich denk unter Windows ist das nicht case sensitiv.)


#include <stdlib.h>
#include <errno.h>
#include <string.h>

int addtoenv( const char * name, const char * path ) {
int ret = 0;
const char * envvar = getenv( name );

if( envvar ) {
char * newpath = malloc( strlen(path) + strlen(envvar) + 1 );

if( newpath ) {
sprintf( newpath, "%s:%s", envvar, path );
ret = setenv( name, newpath, 1 );
free( newpath );
}
else {
/* errno kann eigentlich nur ENOMEM sein */
ret = errno;
}
}
else {
ret = setenv( name, path, 1 );
}

return ret;
}

SeeksTheMoon
21-02-2005, 14:39
ok, nach zähem Ringen habe ich rausgefunden wie das mit -rpath funktioniert:
Man linkt mit -rpath=<Pfad in dem die Binary suchen soll>
Der Pfad kann auch relativ sein.
Damit wäre man nicht mehr auf LD_LIBRARY_PATH angewiesen.

Jetzt bleibt ein Restproblem:
ich habe die Binaries in
out/bin und die Libs in /out/lib.
-rpath ist entsprechend auf ../lib gesetzt, das klappt auch.
LEIDER: Diese Angabe "../lib" wird auf den aktuellen Pfad angewendet in dem ich mich befinde...:
Jetzt muss der User noch in das bin-Verzeichnis wechseln, anstatt das Programm von überall ausführen zu können.
Was ich brauche, das ist eine relative Pfadangabe, die aber auf die Binaries angewendet wird und nicht auf den aktuellen Pfad des Users.

Ist da jemandem was bekannt?

panzi
21-02-2005, 15:44
Ist da jemandem was bekannt?
Leider nicht, zumal es unter Linux/Unix keinen wirclich zuverlässigen Weg gibt, den Ort des Binaries rauszufinden (man muss argv[0] und PATH durchsuchen, aber das kann alles gefaked sein).