mikrocontroller.net

Forum: Compiler & IDEs Cross-Compiling Raspberry-Pi mit libconfig


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Roland H. (blacksmoke)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

Ich versuche gerade für den Raspberry-Pi ein Programm in C zu 
kompilieren. Dazu möchte ich einen Cross-Compiler verwenden. Ebenso 
möchte ich eine lib (libconfig) zum einlesen einer Config-Datei 
verwenden. Dazu habe ich die Bibliothek auf dem Raspberry(Raspbian 
stretch) installiert und mir per rsync die wichtigsten header, libs, ... 
geholt. Dieses habe ich versucht dem Compiler mit --sysroot mitzugeben. 
Die noch benötigten Header habe ich mit -I extra noch angegeben. Ebenso 
die Bibliothek (-L... -lconfig)

nur leider findet er eine bestimmte Objekt-Datei nicht, die ebenfalls im 
sysroot liegt (cannot find crt1.o). Ich habe es schon mit vpath 
versucht. Ohne Erfolg.

Ich bin leider weder Makefile noch gcc-profi. Deshalb hoffe ich hier auf 
ein wenig Licht im dunkel.

Habe ich dabei etwas vergessen/ nicht bedacht ? was gibt es dabei zu 
beachten ?

Ich hätte am Ende einfach gerne ein Set aus compiler/sysroot(muss 
natürlich jedes mal wenn sich was ändert aktualisiert werden) und 
beispielprogramm.

Eine zweite Möglichkeit wäre, die benötigte lib direkt ins programm zu 
kompilieren und zu linken, aber das scheint mir wenig Sinnvoll

Autor: Nop (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei Deiner Frage kann ich Dir zwar leider auch nicht helfen, das ist ein 
Problem mit den Pfaden für die verwendete libc, aber in Deinem C-File 
kann es bei der Ausführung ein Problem geben:
int doQuit = 0;

Die Initialisierung mit 0 ist überflüssig, das wird bei globalen 
Variablen automatisch gemacht, aber sie muß in dieser Verwendung 
volatile sein, sonst darf der Compiler Dir die Schleifenterminierung 
wegoptimieren. Also so:
volatile int doQuit;

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Roland H. schrieb:
> Dazu möchte ich einen Cross-Compiler verwenden.

Welche Linux-Distro nutzt du? Unter Debian/Ubuntu kannst du auch 
"gcc-arm-linux-gnueabihf" über apt installieren. Da wird dann auch die 
C-Library mit installiert, d.h. inkl der crt*.o Dateien.
--sysroot dürfte hier verkehrt sein, weil es dann die bereits 
installierte C-Library nicht mehr findet. Kopiere die libconfig doch 
nach "/usr/arm-linux-gnueabihf/lib", dann ist alles an einem Platz, und 
lasse --sysroot weg.

Autor: Roland H. (blacksmoke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich benutze Archlinux. Dafür gibt es natürlich auch einen 
Cross-Compiler.

Ich habe eben nur bedenken wegen der libconfig. Diese kann ich nicht auf 
meine Host-libconfig verlinken.

Wie wird das denn richtig gemacht (wenn nicht mit sysroot) ?

Ich muss ja in irgend einer weiße ein sysroot als referenz angeben, 
damit der Compiler weiß welche libs, header, ... auf dem device 
vorhanden sind.

Ich habe so ähnliche sachen schon auf anderen Platformen gemacht, aber 
nie sowas selbst aufgesetzt (Makefile, sysroot erstellen, richtiger 
compiler, ...)

Beitrag #5691027 wurde vom Autor gelöscht.
Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Roland H. schrieb:
> Ich muss ja in irgend einer weiße ein sysroot als referenz angeben,
> damit der Compiler weiß welche libs, header, ... auf dem device
> vorhanden sind.

Der Compiler bzw. dessen Distribution sollte eigentlich eine eigene 
C(++)-Library mitliefern; da musst du nix konfigurieren. Die konkrete 
libconfig musst du da nur noch mit reinwerfen; im Verzeichnis des 
Compilers sollte es irgendwo einen "lib" Ordner geben, in welchen du 
deine libconfig.a/so kopieren kannst - da sollten auch die libc.so und 
die diversen crt*.o drin sein. Ansonsten kannst du den Pfad zur 
libconfig auch einfach per -L und -I angeben. --sysroot würde ich wie 
gesagt nicht benutzen.

Autor: Roland H. (blacksmoke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Niklas G. schrieb:
> Roland H. schrieb:
>> Ich muss ja in irgend einer weiße ein sysroot als referenz angeben,
>> damit der Compiler weiß welche libs, header, ... auf dem device
>> vorhanden sind.
>
> Der Compiler bzw. dessen Distribution sollte eigentlich eine eigene
> C(++)-Library mitliefern; da musst du nix konfigurieren. Die konkrete
> libconfig musst du da nur noch mit reinwerfen; im Verzeichnis des
> Compilers sollte es irgendwo einen "lib" Ordner geben, in welchen du
> deine libconfig.a/so kopieren kannst - da sollten auch die libc.so und
> die diversen crt*.o drin sein. Ansonsten kannst du den Pfad zur
> libconfig auch einfach per -L und -I angeben. --sysroot würde ich wie
> gesagt nicht benutzen.


Die Richtung klingt für mich sinnvoller. Den standard-cross-compiler zu 
verwenden inkl. standard-bibliotheken und dann nur noch die zusätzlich 
installierten libs wie libconfig vom device vielleicht ins Projekt 
kopieren libconfig.a und mit -L -l angeben. wenn ich das jetzt richtig 
verstanden habe.

Dazu werde ich erst mal den Cross-Compiler installieren (aktuell 
verwende ich einen fertigen irgendwo von github) anschließend werde ich 
das testen

Autor: Roland H. (blacksmoke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt den entsprechenden Compiler installiert

dafür findet er halt jetzt die header zur lib nicht

arm-linux-gnueabihf-gcc -L/home/black/raspberry/simple-libconfig/libs 
-lconfig -c main.c -o build/main.o
main.c:6:10: fatal error: libconfig.h: No such file or directory
 #include <libconfig.h>
          ^~~~~~~~~~~~~
compilation terminated.


die libconfig.a, libconfig.so hab ich unter 
"/home/black/raspberry/simple-libconfig/libs" abgelegt

: Bearbeitet durch User
Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann fehlt noch das "-I/home/black/raspberry/simple-libconfig/libs". 
"-L" und "-l" braucht man nur beim Linken.

Autor: Roland H. (blacksmoke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Niklas G. schrieb:
> Dann fehlt noch das "-I/home/black/raspberry/simple-libconfig/libs".
> "-L" und "-l" braucht man nur beim Linken.

im libs verzeichniss liegen halt keine header sondern nur oben genannte 
dateien

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, falsch gelesen. Wo ist denn der Header?

Autor: Roland H. (blacksmoke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das was ich benutze ist eine lib, die man sich im raspbian über apt-get 
installieren kann (libconfig) dafür will ich cross-compilieren. Ich 
hätte die header nur da, weil ich mir die vom device per rsync auf 
meinen host gezogen hab. wenn ich diese aber mit

"-I/home/black/raspberry/sysroot/usr/include/"

einbinde, kommen noch mehr volgefehlern von weiteren headern die er 
nicht findet. Das Problem muss also meiner ansicht nach wo anders zu 
suchen sein.

theoretisch müsste man die ja auch mit

"vpath %.h /home/black/raspberry/sysroot/usr/include/"

suchen lassen, falls nicht gefunden. Das funktioniert aber ebenfalls 
nicht

: Bearbeitet durch User
Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Roland H. schrieb:
> Ich
> hätte die header nur da, weil ich mir die vom device per rsync auf
> meinen host gezogen hab.

Ja, das ist richtig. Du musst sowohl Header als auch die eigentliche 
Bibliotheksdatei (.a, .so) kopieren.

Roland H. schrieb:
> einbinde, kommen noch mehr volgefehlern von weiteren headern die er
> nicht findet.

Dann fehlen möglicherweise noch mehr Libraries, von denen libconfig 
abhängig ist.

vpath ist doch nur für make relevant, das beeinflusst den Compiler 
nicht.

: Bearbeitet durch User
Autor: Roland H. (blacksmoke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
falls ich das libconfig.h problem gelöst habe kommt eine schier 
unüberschaubere Anzahl Fehler wie diese:

/home/black/raspberry/sysroot/usr/include/unistd.h:1114:12: error: 
storage class specified for parameter 'fdatasync'
 extern int fdatasync (int __fildes);
            ^~~~~~~~~
In file included from main.c:4:
/home/black/raspberry/sysroot/usr/include/signal.h:32:10: fatal error: 
bits/sigset.h: No such file or directory
 #include <bits/sigset.h>  /* __sigset_t, __sig_atomic_t.  */
          ^~~~~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:25:



sigset z.B. ist aber durchaus im sysrot-ordner vorhanden:

/usr/include/arm-linux-gnueabihf/bits/sigset.h

: Bearbeitet durch User
Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast die Standard-Header unistd.h und signal.h kopiert?! Kopiere 
nur die Header von libconfig selbst und kopiere sie entweder in das 
include-Verzeichnis des Compilers oder in ein eigenes Verzeichnis, 
welches du per -I angibst. Benutze nicht --sysroot.

Autor: Roland H. (blacksmoke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du hast recht. ich hätte nur die kopieren dürfen, die ich zusätzlich 
brauche. ich habe mir jetzt in meinem projekt ein ordner namens 
"sysroot" erstellt mit den unterordnern libs und includes. Dort habe ich 
nun einmal die libconfig.h und die libconfig.a und libconfig.so.* 
hinterlegt.

nun sieht es besser aus. ein objdump zeigt nun, dass gegen die richtige 
gelinkt wird und nicht mehr gegen die libconfig.so.11 von meinem host

Dynamic Section:
  NEEDED               libconfig.so.9
  NEEDED               libc.so.6
  NEEDED               ld-linux-armhf.so.3


test auf dem raspberry verlief nun ebenfalls erfolgreich.

Ihr wart mir dabei eine sehr große Hilfe. Ich danke euch

: Bearbeitet durch User
Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Roland H. schrieb:
> und nicht mehr gegen die libconfig.so.11 von meinem host

Nicht mehr? Das heißt du konntest du Library vom Host mit linken? Wie 
hast du das geschafft, ist der Host auch ARM?

Autor: DPA (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falls du von einem Linux aus cross compilierst, würde ich dafür ein 
chroot oder ein Container nehmen, das ist am einfachsten. Entweder ein 
neues Rootfs dafür besorgen (bootstrappen (debootstrap in debianoiden), 
image, etc.), oder alle Files kopieren (mit benutzern und allem. (cp -a, 
rsync -a --progress, etc.)). Wenn du alle Dateien lokal in einem Ordner 
hast, installiere ein statisch gelinktes qemu user mode binary für die 
architektur, und richte binfmt-misc ein. (Unter debain/devuan reicht ein 
`apt-get install qemu-user-static`. Enthält den emulator für extrem 
viele architekturen.). Je nachdem, wie binfmt-misc eingerichtet wurde, 
muss qemu-<die_ziel_architektur>-static noch ins Zielsystem kopiert 
werden `cp {,./my_root_fs/}"$(which 
qemu-<die_ziel_architektur>-static)"`. (Bei debian/devuan ist das nötig. 
Die qemu binaries sind dort unter /usr/bin/qemu-*-static). Danach kannst 
du in zukunft einfach mit `chroot ./my_root_fs/` oder `chroot 
./my_root_fs/ /bin/sh` in dein Crosskompilierenvironment wechseln, ond 
dort ganz normal mit gcc und co. arbeiten. Eventuell vorher noch einen 
Bind mount machen, um z.B. dein Home im chroot verfügbar zu machen. Das 
ganze könnte man vermutlich auch mit (libvirt-lxc oder LXC) Containern 
machen, muss das aber noch ausprobieren.

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
DPA schrieb:
> Falls du von einem Linux aus cross compilierst, würde ich dafür ein
> chroot oder ein Container nehmen, das ist am einfachsten.

Klingt irgendwie komplizierter als 3 Dateien zu kopieren und -I und -L 
anzugeben...

Autor: Roland H. (blacksmoke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
DPA schrieb:
> Falls du von einem Linux aus cross compilierst, würde ich dafür ein
> chroot oder ein Container nehmen, das ist am einfachsten. Entweder ein
> neues Rootfs dafür besorgen (bootstrappen (debootstrap in debianoiden),
> image, etc.), oder alle Files kopieren (mit benutzern und allem. (cp -a,
> rsync -a --progress, etc.)). Wenn du alle Dateien lokal in einem Ordner
> hast, installiere ein statisch gelinktes qemu user mode binary für die
> architektur, und richte binfmt-misc ein. (Unter debain/devuan reicht ein
> `apt-get install qemu-user-static`. Enthält den emulator für extrem
> viele architekturen.). Je nachdem, wie binfmt-misc eingerichtet wurde,
> muss qemu-<die_ziel_architektur>-static noch ins Zielsystem kopiert
> werden `cp {,./my_root_fs/}"$(which
> qemu-<die_ziel_architektur>-static)"`. (Bei debian/devuan ist das nötig.
> Die qemu binaries sind dort unter /usr/bin/qemu-*-static). Danach kannst
> du in zukunft einfach mit `chroot ./my_root_fs/` oder `chroot
> ./my_root_fs/ /bin/sh` in dein Crosskompilierenvironment wechseln, ond
> dort ganz normal mit gcc und co. arbeiten. Eventuell vorher noch einen
> Bind mount machen, um z.B. dein Home im chroot verfügbar zu machen. Das
> ganze könnte man vermutlich auch mit (libvirt-lxc oder LXC) Containern
> machen, muss das aber noch ausprobieren.

klingt interessant. mit containern arbeite ich beruflich hin und wieder, 
denn die meisten umgebungen sind nur für ubuntu, ... gemacht. deshalb 
ist es manchmal einfacher einfach einen docker-container zu nehmen.

Deine Variante klingt n bisschen aufwändiger, aber evtl schon 
interessant

Autor: Roland H. (blacksmoke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Niklas G. schrieb:
> Roland H. schrieb:
>> und nicht mehr gegen die libconfig.so.11 von meinem host
>
> Nicht mehr? Das heißt du konntest du Library vom Host mit linken? Wie
> hast du das geschafft, ist der Host auch ARM?

ich habe das programm vorher direkt auf meinem host laufen lassen (also 
nur mit gcc kompiliert) in meinem host ist eine neuere libconfig 
installiert (libconfig.so.11).

ich habe mir dann von beiden den objdump ausgegen um zu überprüfen, dass 
nun auch wirklich richtig gelinkt wird

Das Programm war aber eigentlich von anfang an für den Raspberry 
gedacht.

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Roland H. schrieb:
> ich habe das programm vorher direkt auf meinem host laufen lassen (also
> nur mit gcc kompiliert)

Achso. Ich fragte, weil es nicht möglich sein sollte, in ein 
ARM-Programm eine x86-Bibliothek einzulinken; der Linker sollte sich 
beschweren.

Autor: Blubb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht mal beim Archlinuxarm-Projekt schauen ob die ein Setup Feuers 
crosscompiling haben..

Autor: DPA (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
DPA schrieb:
> Das ganze könnte man vermutlich auch mit (libvirt-lxc oder LXC) Containern
> machen, muss das aber noch ausprobieren.

Hab das jetzt mal ausprobiert. Bei sysvinit von devuan hängt sich 
startpar von sysvinit beim start auf. openrc funktioniert aber 
einwandfrei. ifupdown geht auch, nur ein paar Warnungen. ethtool geht 
nicht, braucht man aber auch nicht mehr unbedingt. Programme, die 
seccomp verwenden, können Probleme machen. Bei ssh muss man die sandbox 
in der sshd config ausschalten. Alles andere funktioniert einwandfrei. 
Ausprobiert hab ich das mit einem arm64 devuan als libvirt-lxc container 
auf einem x64 devuan host. Die qemu-aarch64-static hab ich mit einem 
readonly bind mount durch libvirt automatisch einbinden lassen, das wird 
aber bald überflüssig werden. Ich weiss nicht, ob es in debian Testing 
oder Unstable ist, aber ich glaube in einem von beiden wurde das F flag 
zum entsprechenden binfmt-misc Eintrag hinzugefügt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.