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
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; |
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.
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.
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.
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
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
Dann fehlt noch das "-I/home/black/raspberry/simple-libconfig/libs". "-L" und "-l" braucht man nur beim Linken.
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
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
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
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
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.
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
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?
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.
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...
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
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.
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.
Vielleicht mal beim Archlinuxarm-Projekt schauen ob die ein Setup Feuers crosscompiling haben..
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.