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


von Roland H. (blacksmoke)


Angehängte Dateien:

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

von Nop (Gast)


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:
1
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:
1
volatile int doQuit;

von Niklas G. (erlkoenig) Benutzerseite


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.

von Roland H. (blacksmoke)


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.
von Niklas G. (erlkoenig) Benutzerseite


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.

von Roland H. (blacksmoke)


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

von Roland H. (blacksmoke)


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
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

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

von Roland H. (blacksmoke)


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

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Oh, falsch gelesen. Wo ist denn der Header?

von Roland H. (blacksmoke)


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
von Niklas G. (erlkoenig) Benutzerseite


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
von Roland H. (blacksmoke)


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
von Niklas G. (erlkoenig) Benutzerseite


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.

von Roland H. (blacksmoke)


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
von Niklas G. (erlkoenig) Benutzerseite


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?

von DPA (Gast)


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.

von Niklas G. (erlkoenig) Benutzerseite


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...

von Roland H. (blacksmoke)


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

von Roland H. (blacksmoke)


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.

von Niklas G. (erlkoenig) Benutzerseite


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.

von Blubb (Gast)


Lesenswert?

Vielleicht mal beim Archlinuxarm-Projekt schauen ob die ein Setup Feuers 
crosscompiling haben..

von DPA (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.