PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RPM unter LFS 5.1.1



7.e.Q
17.01.06, 09:45
Hi Leute,

ich bin im Begriff, auf unserem LFS 5.1.1 einen RPM zu installieren. Hat das schonmal einer gemacht hier? Eventuell irgendwelche Tips? Stolpersteine? Klippen, die es zu umschiffen gilt (eine Klippe umschiffen ist immer noch leichter, als eine Schiffer umklappen:D)? Eventuell sogar irgendwo eine Installationsanleitung?

Der nächste Schritt ist, daß ich einige Komponenten unseres LFS hier in ein RPM packen will, um sie auch auf anderen Systemen schnell und komfortabel installieren zu können. Auch da könnte ich einige Tips und eventuell Links zu Anleitungen, Tutorials o.ä. gebrauchen.

Wäre sehr dankbar für jede Art der Unterstützung

Gruß,
Hendrik

traffic
17.01.06, 12:03
RPMs kann man auf jedem System erstellen, auf dem das Programm "rpmbuild" installiert ist. Mehr Infos dazu gibt es in der Dokumentation:

http://www.redhat.com/docs/books/max-rpm/

Mit dem Installieren bestehender RPMs ist es schon etwas schwieriger, weil RPMs es nicht wirklich mögen, wenn nicht das ganze System von Grund auf aus RPMs besteht. Das hat technische Gründe.

Unmöglich ist es nicht, allerdings muss man dann viele Pakete mit "--nodeps" installieren und kann das automatische Abhängigkeitsmanagement nicht benutzen. Einfacher geht es wahrscheinlich mit dem Programm "rpm2cpio", damit kann man RPMs entpacken und die Dateien selber dorthin kopieren, wo man sie haben will.

7.e.Q
17.01.06, 12:12
Danke für den Link. Installiert ist RPM nun in unserem LFS.

Es geht im Prinzip halt darum, gewisse Bestandteile des LFS (proprietäre, selbstentwickelte Software) in RPMs zu packen, um sie auf "Standard"-Linux-Distros installieren zu können. Das klappt jetzt auch schon ganz gut, nur gibt es noch ein paar Punkte, die ich noch begreifen muss. Zum Beispiel das Einbinden verschiedener Config-Files und Scripte in die Binary-RPMs, das Erstellen benötigter Verzeichnisse auf dem Zielrechner (bspw.: /var/ists/fs, /usr/ists u.a.). Soetwas muss nachher alles die Installation des RPMs können. Desweiteren müssen in das Binary-RPM noch einige Binaries mit hinein, von denen keine Sourcen mehr existieren...

Das sind so die Punkte, die ich noch lernen muss. Wäre dankbar, wenn mir jemand erklären könnte, wie das geht. Nochmal zusammengefasst:

- einbinden von diversen Config- und Script-Files in das Binary-RPM
- einbinden von Binaries ohne vorhandene Sourcen in das Binary-RPM
- erstellen verschiedener Verzeichnisse auf dem Ziel-System


Danke

Gruß,
Hendrik

traffic
17.01.06, 17:41
Steht alles im Buch "Maximum RPM" von Red Hat...

Sorry, ich weiß, dass das Buch umfangreich ist, aber wenn ich es jetzt zusammenfassen würde, wäre ich vielleicht in ein paar Stunden fertig, hätte dann aber das Buch nacherzählt.

Lies es mal und schau auch Source-RPMs anderer Leute an (Hinweis: "Source"-RPMs können auch Binaries enthalten). Insbesondere folgende Punkte wären interessant:

- %pre/%post-Skripte
- der Filesystem Hierarchy Standard
- NoSource-Tags
- ...

hp_tux
17.01.06, 22:09
Hallo,

hmm, normalerweise sollte man eine rpm-Datei auf dem gleichen Systeem erstellen, für das es gedacht ist, also ein rpm-Paket für SuSE 10.0 auf einem SuSE-10.0-System, ein Paket für Mandriva 2006 auf einem Mandriva-2006-System, usw. Es kommt natürlich auch darauf an, von welchen Paketen diese rpm-Datei so alles abhängt.

Gruß

hp_tux

7.e.Q
18.01.06, 04:14
@hp_tux: Das Problem ist, daß sie für verschiedenste Systeme vorgesehen ist, also universell einsetzbar sein soll. Voraussetzungen für die Installation lassen sich ja einbringen. Also sagen wir, um das Programm installieren zu können, bedarf es eines Linux Basissystems mit RPM und einem 2.6er Kernel.

Interessant wäre es noch, ob es eine Möglichkeit gibt, Boot-Scripte gleich automatisch an der richtigen Stelle zu platzieren, je nach System. Gibt's da was?

Susu
18.01.06, 08:51
Warum nicht alles in ein Tarball stopfen und ein kleines Script dazu, welche beim Ausführen die entsprechenden Teile wo auch immer hinkopiert? Wäre auch kompatibler zu Non-RPM-Distris...


Susu

7.e.Q
18.01.06, 09:06
Da ist wiederum das Problem, daß die Software sich in jedes System wie vorgesehen integrieren und auch wieder deinstallieren lassen soll. Also als vollwertiges Software Paket. Darum wollen wir einen Paket-Manager nutzen (RPM halt), der dafür sorgt, daß alle Abhängigkeiten etc. gelöst sind, bevor das Programm installiert wird. Das soll auch vom Kunden problemlos installiert werden können. Und wenn da nachher im tar Script irgendwas nicht geht, dann ruft der Kunde bei uns an und verlangt die Behebung des Fehlers. Bei RPM können wir davon ausgehen, daß ein Fehler bei der Installation am System des Kunden liegt, nicht an dem gepackten RPM. Bei TAR ist das nicht so sicher.

Susu
18.01.06, 10:43
Und wenn der Kunde gar kein RPM-System benutzt?

7.e.Q
18.01.06, 11:14
Das ist dann Grundvoraussetzung zum Zwecke der Kompatibilität. Unser Produkt ist glücklicherweise keines für den Massenmarkt. Wir haben noch die Möglichkeit, die wenigen Kunden die wir haben zu "formen". Und das Projekt, welches jetzt in einem RPM verpackt werden soll, ist auch nur ein zwar ganz kleiner, aber dennoch essenzieller Bestandteil unseres gesamten Produkts.

Fakt ist, wir wollen RPM benutzen. Das Für und Wider ist dabei hinfällig. Es geht jetzt nur noch darum, wie...

Ich habe noch eine weitere Frage zum Thema RPM. Dazu muss ich etwas weiter ausholen:

Das Projekt, das wir in RPM verpacken wollen, ist eine Art Loader für ein Pseudo-Embedded System (nachher auch auf Standard-Hardware, das ist der Sinn dahinter). Der Loader lädt und startet Software, die wir ihm von anderen Systemen quasi eintrichtern. Diese Software, die dort hineingeladen wird, benötigt eine Reihe Bibliotheken, die nicht unbedingt auf dem Basis-System installiert sein müssten. Es geht jetzt darum, das RPM so zu verpacken, daß eventuelle Links auf vorhandene Bibliotheken angelegt werden, bzw. die von der Ladesoftware benötigten Libs aus dem RPM mit installiert werden.

Beispiel: die Ladesoftware dummy.pr6 benötigt die Bibliothekendatei libssl.so.0. Vorhanden auf dem System ist libssl.so.0.9.7f. Ich würde jetzt von Hand einen SymLink auf libssl.so.0.9.7f anlegen, der da libssl.so.0 heißt. Dies soll aber von dem RPM Install-Script übernommen werden können. Das Problem dabei ist, daß RPM scheinbar nicht weiß, welche libssl.so.0.x.x.x installiert ist. Wie findet RPM heraus, auf welche libssl.so.0.x.x.x er die libssl.so.0 verlinken muss?

Andersherum wird es problematisch, wenn schon eine libssl.so.0 existiert. Diese darf dann selbstverständlich nicht überschrieben werden, um die Systemstabilität nicht zu gefährden.

Wie löst man solch ein Dilemma (mit RPM)?

traffic
18.01.06, 22:57
Eigentlich gar nicht. Dafür ist RPM nicht gedacht. Eigentlich ist Linux als Ganzes nicht dafür gedacht. Wenn Bibliotheken auf verschiedenen Systemen unterschiedliche Namen oder Versionsnummern haben, dann hat das i.d.R. einen Grund, nämlich den, dass sie nicht binärkompatibel sind. Versionsnummern gibt es nicht zum Spaß, um Leute mit Kompatibilitätsproblemen zu ärgern, sondern damit mehrere inkompatible Versionen gleichzeitig installiert werden können.

Lösung 1 (sauber): Liefer die Bibliothek mit. Aber lass sie keinesfalls vom RPM nach /usr/lib installieren, das gibt nur Konflikte mit garantiert vorher installierten Versionen. Leg irgendwo ein eigenes Verzeichnis für Dein Programm an, installier alle mitgelieferten Bibliotheken da rein und nutz LD_LIBRARY_PATH oder DT_RUNPATH.

Lösung 2 (nicht sauber): Nutz das Feature von RPM, vor und nach der Installation und vor und nach der Deinstallation beliebige Skripte auszuführen (%pre, %post, %preun, %postun - siehe "Maximum RPM", Appendix E.3). Das ist eigentlich keine RPM-Angelegenheit mehr, sondern dafür muss man nur gut mit der Shell umgehen können.

Diese Lösung ist nicht so gut, weil man RPM damit eigentlich missbraucht, es kann aber trotzdem manchmal sinnvoll sein. Als Beispiel könntest Du anschauen, was das acroread-RPM macht. Das sind eigentlich ganz ähnliche Sachen wie Deine:

$ rpm -q AdobeReader_deu --scripts
Das Ergebnis kürze ich mal, weil es zu groß ist:

#
# Check a given file in $PATH
#
check_file_in_path()
{
OLD_IFS=$IFS
IFS=":"

if [ -n "$PATH" ] ; then
for i in $PATH; do
if [ -d "$i" ] ; then
check_file_in_named_path "$1" "$i"
if [ $? -eq 1 ]; then
IFS=$OLD_IFS
echo "$i/$1"
return 1
fi
fi
done
fi

IFS=$OLD_IFS
return 0
}

#Make Soft Links To gnome-speech libraries
MakeLibGnomeSpeechLinks()
{
InstallDir="$1/Reader"

TESTSPEECHEXEC=`check_file_in_path "test-speech"`
if [ $? -ne 0 ]
then
check_file_in_path "ldd" >/dev/null
if [ $? -ne 0 ]
then
check_file_in_path "sed" >/dev/null
if [ $? -ne 0 ]
then
rm -f "$InstallDir"/intellinux/lib/libORBit-2.so 2>/dev/null
rm -f "$InstallDir"/intellinux/lib/libbonobo-2.so 2>/dev/null
rm -f "$InstallDir"/intellinux/lib/libbonobo-activation.so 2>/dev/null
rm -f "$InstallDir"/intellinux/lib/libgnomespeech.so 2>/dev/null

TrimCmd="sed -e 's/^[ \t]*\([^ \t]\)\(.*\)\([^ \t]\)[ \t]*$/\1\2\3/g'"
LIB_ORBit2="`ldd $TESTSPEECHEXEC 2>/dev/null | grep -i libORBit-2.* | cut -d '>' -f2 | cut -d '(' -f 1 | sh -c "$TrimCmd" `"
LIB_BONOBO="`ldd $TESTSPEECHEXEC 2>/dev/null | grep -i bonobo-2.* | cut -d '>' -f2 | cut -d '(' -f 1 | sh -c "$TrimCmd" `"
LIB_BONOBOACTIVATION="`ldd $TESTSPEECHEXEC 2>/dev/null | grep -i bonobo-activation.* | cut -d '>' -f2 | cut -d '(' -f 1 | sh -c "$TrimCmd" `"
LIB_GNOMESPEECH="`ldd $TESTSPEECHEXEC 2>/dev/null | grep -i libgnomespeech.* | cut -d '>' -f2 | cut -d '(' -f 1 | sh -c "$TrimCmd" `"
if [ -f "$LIB_ORBit2" -a -f "$LIB_BONOBO" -a -f "$LIB_BONOBOACTIVATION" -a -f "$LIB_GNOMESPEECH" ]
then
ln -s "$LIB_ORBit2" "$InstallDir/intellinux/lib/libORBit-2.so"
ln -s "$LIB_BONOBO" "$InstallDir/intellinux/lib/libbonobo-2.so"
ln -s "$LIB_BONOBOACTIVATION" "$InstallDir/intellinux/lib/libbonobo-activation.so"
ln -s "$LIB_GNOMESPEECH" "$InstallDir/intellinux/lib/libgnomespeech.so"
fi
fi
fi
fi
}
So ein ähnliches Skript müsstest Du halt auch schreiben - dabei aber bitte sehr pingelig sein, Dateien vor dem Überschreiben testen, Symlinks am besten nur im eigenen Verzeichnis und nie in /usr/lib anlegen, Exit-Codes abfangen, etc. pp, Shell-Scripting halt - und als %post-Skript einbinden.

Folgende Tipps fallen mir noch ein:

- beim Mitliefern von Bibliotheken die Lizenzen beachten - LGPL-Bibliotheken wirst Du sicherlich nicht mitliefern wollen

- bei DT_RUNPATH beachten: das muss kein absoluter Pfad sein, mittels $ORIGIN kann man auch relative Pfade benutzen

- bei distributionsübergreifenden RPMs wirklich pingeligst auf die Abhängigkeiten achten, am besten nur LSB-standardisierte Bibliotheken als gegeben voraussetzen

Aber nochmal ganz konkret zu einer der Einzelfragen:

Das Problem dabei ist, daß RPM scheinbar nicht weiß, welche libssl.so.0.x.x.x installiert ist. Wie findet RPM heraus, auf welche libssl.so.0.x.x.x er die libssl.so.0 verlinken muss?
Gar nicht. RPM kann das nicht, weil es für sowas nicht konzipiert wurde. Dafür wirst Du so oder so ein eigenes Skript schreiben müssen, ob nun mit oder ohne RPM. Fummel nie in /usr/lib rum! Leg die Symlinks in ein separates Verzeichnis und sorg mit einer der genannten Methoden dafür, dass das Binary die Bibliotheken dort findet. Und vergiss nicht, dass zu jedem %post-Skript auch ein %postun-Skript gehört, das die Schritte des ersteren wieder rückgängig macht.

7.e.Q
19.01.06, 06:30
Ich bin dann doch eher für die saubere Lösung 1. Aber wie bringe ich dem System bei der Installation bei, daß es permanent zu den Standard-Pfaden auch noch beispielsweise /usr/ists/lib als Bibliotheks-Suchpfad verwendet? Permanent bedeutet hier, daß die Einstellung auch nach einem Neustart noch verfügbar sein soll, ohne das Paket neu installieren zu müssen. Ein einfaches Setzen der Umgebungsvariablen LD_... im %post Script reicht wohl nicht aus, oder?

Achso, und wie finde ich heraus unter welcher Lizenz eine Library vertrieben wurde/wird?

traffic
19.01.06, 09:01
Sei mir bitte nicht böse, aber ich habe gewisse Schwierigkeiten, die Frage ernst zu nehmen. Ich meine, das sind Grundkenntnisse der GNU-Toolchain. Ich habe absolut kein Problem damit, ein wenig zu helfen, aber wenn es um die Vermittlung von Grundkenntnissen an Unternehmen geht, die eine Software verkaufen wollen, habe ich doch ein etwas eigenartiges Gefühl.

Zu den Lizenzen: Sorry, die müsstest Du eigentlich bereits vor der Entwicklung der Software gekannt haben. Andernfalls kannst Du sie eigentlich gar nicht zur Entwicklung eigener Software benutzen. Im Zweifelsfall hilft eine Google-Recherche oder ein kurzer Blick in den Quelltext.

Zum Bibliotheks-Suchpfad: Da gibt es zwei Möglichkeiten. Entweder man kodiert den Suchpfad direkt ins Binary. Dafür gibt es zwei Möglichkeiten:

a) Man verwendet die Linker-Option "-rpath". D.h. der GCC-Befehl zum Linken der Anwendung müsste ungefähr so aussehen:

gcc -o programm source.c -Wl,-rpath,/usr/wasauchimmer
Es geht um diesen "-Wl,-rpath,/usr/wasauchimmer"-Teil.

Wie gesagt, kann man auch relative Pfade nehmen. Wenn die Bibliotheken zum Beispiel in demselben Verzeichnis gesucht werden sollen, in dem das Binary liegt, könnte man es so machen:

gcc -o programm source.c -Wl,-rpath,\$ORIGIN
b) Man setzt während des Linkens die Umgebungsvariable LD_RUN_PATH. Das würde ungefähr so aussehen:

LD_RUN_PATH=/usr/wasauchimmer
export LD_RUN_PATH
gcc -o programm source.c
Achtung: Diese Möglichkeit funktioniert nur, wenn man keine "-Wl,-rpath,/usr/wasauchimmer"-Option in der Befehlszeile drin hat.

Man kann übrigens auch mehrere Pfade kodieren, dazu einfach mehrere "-Wl,-rpath,/usr/wasauchimmer"-Optionen nacheinander benutzen.

Oder man verwendet die Umgebungsvariable LD_LIBRARY_PATH. Das geht am leichtesten mit einem Shell-Wrapper. D.h. man benennt das eigentliche Binary um, z.B. von "programm" in "programm.bin", und erstellt an dessen ursprünglicher Stelle ein Shell-Skript:

#!/bin/sh
LD_LIBRARY_PATH=/usr/wasauchimmer
export LD_LIBRARY_PATH
exec "programm"
Das hat den Vorteil, dass die Kunden den Pfad auch nachträglich noch ändern können.

Kleiner Tipp: Vielleicht findest Du irgendwo jemanden, der das RPM für einen angemessenen Preis für Dich macht. Wenn nicht: Alle Infos stehen in den man-pages zu gcc, ld, rpmbuild, bash und vielleicht noch ein paar weiteren.

7.e.Q
19.01.06, 09:40
Hmm, die Frage kannst du schon ernst nehmen. Du hast bestimmt schonmal was von dem Begriff Bildungslücke gehört, oder?! Man kann halt nicht alles wissen. Und was man nicht weiß, das erfragt man sich, bzw. liest es sich an. Unter Zeitdruck ist erfragen allerdings einfacher, weil man dann nebenbei noch was anderes machen kann. Liest man es sich an, ist man selber mit lesen beschäftigt, kann keine anderen Aufgaben wahrnehmen. Soviel dazu.

Inzwischen habe ich dennoch selbst herausbekommen, wie das alles mit RPM und ldconfig zu bewerkstelligen ist.

Danke trotzdem!

Was die Lizenzen angeht... ich werde mich da mal schlau machen. Aber um die Entwicklung mit lizenzpflichtiger Software und den damit zusammenhängenden Problemen muss sich mein Chef kümmern. Ich entwickle nur.