gcc Compileroptionen bei Makefiles

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Servus ihr C-Freaks,

    Meine Erfahrung bei C ist relativ überschaubar: Ich kann vorhandenen Code einigermaßen lesen/verstehen und auch selber einen 20-Zeiler (oder so) aufziehen. Allerdings stöße ich an meine Grenzen bei #include, vor allem, wenn dann ein Modul nicht gefunden werden kann. Richtig undurchsichtig wird's für mich, wenn fette Makefiles dabei sind, in denen man auf den ersten Blick nicht einmal die gcc-Aufrufe findet. So z.B. wenn man die GNU-Bibliothek libcdio installieren will und dann das erste Beispiel von der GNU-Seite versucht zu kompilieren. Das schlägt natürlich fehl!

    Installation von libcdio auf dem RPi

    Die Installation habe ich weitestgehend nach der Installationsanleitung (README-Dateien) vermutlich erfolgreich(?) vorgenommen

    Code
    $ sudo apt-get install git make autoconf automake libtool m4 texinfo help2man

    Am RPi unter Raspbian Stretch PIXEL:

    * autoconf: 1358kB Archive, 4185kB Plattenplatz entpackt

    * libtool: 704kB Archive, 2177kB Plattenplatz entpackt

    * texinfo: 4199kB Archive, 17,1MB Plattenplatz entpackt

    * help2man: 162kB Archive, 465kB Plattenplatz entpackt

    --> die nicht aufgeführten Pakete sind bereits im aktuellen Raspbian enthalten...

    Code
    $ git clone git://git.savannah.gnu.org/libcdio.git   # Herunterladen des aktuellen Projektes
    $ cd libcdio
    $ sh ./autogen.sh                                    # erstellt "automatisch" das Script configure.ac und führt es aus
    $ make # or remake                                   # --> dauert auf dem RPi2 ca. 5-6 Minuten
    $ make check # or remake check                       # Überprüfungen

    Es sollte eine Ausgabe ohne Fehler erscheinen, war bei mir auch der Fall.

    Code
    $ sudo make install # you may have to do this as root # or "sudo make install" --> Libraries befinden sich in "/usr/local/lib"

    Bei den make-Aufrufen werden u.a. die Beispielcodes in ./libcdio/src und ./libcdio/example erfolgreich kompiliert.

    Wenn ich aber eines der Programme mit gcc eject.c -o eject kompilieren will, erhalte ich vom Compiler bloß folgende Fehlermeldungen:

    Im Makefile finde ich zwar die Definitionen

    Code
    CC = gcc
    CFLAGS = -g -O2  -Wall -Wbad-function-cast -Wcast-align -Wchar-subscripts -Wdeclaration-after-statement -Wdisabled-optimization # und noch etliche andere -W...-Optionen

    Aber auch ein gcc eject.c -o eject -g -O2 führt nicht zum Erfolg.

    Meine Frage:

    Wie kompiliert man diese Programme standalone? Kann ja kein Hexenwerk sein...

    Die bestehenden Programme kann man ja mit make neu erstellen. Aber wie erstelle ich neue Programme unter Nutzung dieser Bibliothek?


    Hat da jemand mehr Erfahrung als ich und kann mir da mal Ratschläge geben, wie man so große C-Projekte (vor allem fremde) richtig versteht und anpackt?

    schlizbäda

    PS:
    Die Datei Makefile.txt heißt bei mir nur Makefile, aber unter diesem Namen darf ich sie im Forum nicht hochladen :wallbash:

  • Meine Frage:

    Wie kompiliert man diese Programme standalone? Kann ja kein Hexenwerk sein...

    Die bestehenden Programme kann man ja mit make neu erstellen. Aber wie erstelle ich neue Programme unter Nutzung dieser Bibliothek?

    Du musst sicher sein, dass die header-Dateien richtig gefunden werden bzw. die libs für build- und run-time gefunden werden, und dann geht das schon. Z. B. so (... btw. nur als Test bei mir; sonst wäre die lib für run-time, in einem anderen Verzeichnis!):

    Code
    $ gcc -v -Wl,-rpath=/home/gm/Downloads/libcdio/lib/driver/.libs -o eject eject.c -L/home/gm/Downloads/libcdio/lib/driver/.libs -lcdio
    Code
    $ ldd ./eject
        linux-gate.so.1 =>  (0xb775a000)
        libcdio.so.18 => /home/gm/Downloads/libcdio/lib/driver/.libs/libcdio.so.18 (0xb772b000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7560000)
        /lib/ld-linux.so.2 (0xb775c000)

    The most popular websites without IPv6 in Germany.  IPv6-Ausreden

    Meine PIs

    PI4B/8GB (border device) OpenBSD 7.4 (64bit): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server

    PI3B+ FreeBSD 14.0-R-p3 (arm64): SSH-Serv., WireGuard-Serv., ircd-hybrid-Serv., stunnel-Proxy, Mumble-Serv., ddclient

    PI4B/4GB Bullseye-lite (64bit; modifiziert): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server, botamusique, ample

    Einmal editiert, zuletzt von rpi444 (31. Dezember 2017 um 10:32)

  • Hallo Tell,

    Gibt es ein Script namens configure im Directory?

    ein solches Script gibt es. Ich glaube es wurde ursprünglich im Rahmen meiner durchgeführten Installation beim Aufruf von sh ./autogen.sh erstellt und auch gleich aufgerufen.

    Ein erneuter manueller Aufruf lief erfolgreich(?) durch.

    Trotzdem funktioniert der Aufruf gcc eject.c -o eject nicht. Fehlermeldung nach wie vor wie in Beitrag 1.

    Das ist ja mein Problem: Ich lade ein C-Projekt herunter und versuche es zu kompilieren, aber es will nicht. Dann ist meist ein Makefile dabei, riesig und damit (für mich) undurchschaubar.

    Ausgaben vom Script configure

    Dort fielen mir folgende Zeilen auf:

    checking minix/config.h usability... no

    checking minix/config.h presence... no

    checking for minix/config.h... no

    weiter unten kommt aber

    config.status: creating config.h

    config.status: config.h is unchanged

    Dass das Programm cdda-player offenbar nicht erstellt wurde, liegt daran, dass das GNU-Paket curses/ncurses nicht installiert ist. Da habe ich ganz ähnliche Probleme. Dies ist aber für's Erste nicht so wichtig

    schlizbäda

  • Dass das Programm cdda-player offenbar nicht erstellt wurde, liegt daran, dass das GNU-Paket curses/ncurses nicht installiert ist.

    BTW: Dann hättest Du das .configure-Script auch mit der Option ausführen können:

    Code
    ./configure --without-cdda-player

    BTW: Vor dem Ausführen des configure-Script ist es immer gut, wenn man sich die Ausgabe von:

    Code
    ./configure --help

    anschaut.

    The most popular websites without IPv6 in Germany.  IPv6-Ausreden

    Meine PIs

    PI4B/8GB (border device) OpenBSD 7.4 (64bit): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server

    PI3B+ FreeBSD 14.0-R-p3 (arm64): SSH-Serv., WireGuard-Serv., ircd-hybrid-Serv., stunnel-Proxy, Mumble-Serv., ddclient

    PI4B/4GB Bullseye-lite (64bit; modifiziert): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server, botamusique, ample

  • Hallo rpi444,

    vielen Dank, das ist die Lösung. Pfad zur Library über -L angeben und der Code wird kompiliert.

    Code
    $ gcc -v -Wl,-rpath=/home/gm/Downloads/libcdio/lib/driver/.libs -o eject eject.c -L/home/gm/Downloads/libcdio/lib/driver/.libs -lcdio

    Ich verstehe jetzt nur nicht, was es mit dem Kommandozeilenparameter -W1,-rpath=<Pfad zur lib> auf sich hat. Den meckert der gcc bei mir an. -W... ist ja meines Wissens nach "nur" eine Einstellung bezüglich Warnings, deshalb ließ ich ihn einfach weg.

    Den Parameter -l<Kurzbezeichnung der lib> kenne ich zwar dunkel und verstehe ich im Übrigen auch nicht, vor allem nicht, wie man letztlich konkret von libcdio auf cdio kommt.

    Ich weiß schon, warum ich seinerzeit zu unserem Praktikanten in der Arbeit bei all seinen Fragen immer sagte "C is the programming language that I hate so much":

    * Einfach und gerade deswegen so schwierig

    * Das Einbinden von Libraries ist (für mich) schwer bis nicht durchschaubar.

    * Man braucht's einfach immer wieder, ob man will oder nicht

    * Der Code wird in ein schnelles und effektives Programm übersetzt

    * Da muss ich noch viel lernen... Gibt's da ein wirklich gutes und aktuelles Buch?

    schlizbäda

    PS:

    Nachdem ich jetzt libcdio-mäßig gerüstet bin, muss ich mal schauen, ob ich mein ursprünglich geplantes python-Projekt raspiblaster nun doch in C umsetzen werde, in der Hoffnung mich nicht komplett zu verfahren. Da brauche ich zusätzlich noch eine GUI-Bibliothek und habe dabei an Qt5 gedacht...

  • > checking minix/config.h usability... no

    > checking minix/config.h presence... no

    > checking for minix/config.h... no

    >

    > weiter unten kommt aber

    >

    > config.status: creating config.h

    > config.status: config.h is unchanged

    Das stimmt so. Das Script checkt welche Header da sind und erzeugt einen neuen fuer das Projekt.

    Der wurde schon mal erzeugt und braucht nicht geaendert zu werden.

    Seltsam dass dann so grundlegende Header wie stdio.h und string.h fehlen. Werden die in

    config.h nicht aufgefuehrt?

    Hmm, da ist zwar noch ein ifdef drauf.


    Was passiert bei cc -DHAVE_CONFIG_H eject.c -o eject

    Wenn's besser wird: die Library-Optionen von rpi444 noch dazugeben.

  • Ich verstehe jetzt nur nicht, was es mit dem Kommandozeilenparameter -W1,-rpath=<Pfad zur lib> auf sich hat. Den meckert der gcc bei mir an. -W... ist ja meines Wissens nach "nur" eine Einstellung bezüglich Warnings, deshalb ließ ich ihn einfach weg.

    Den Parameter -l<Kurzbezeichnung der lib> kenne ich zwar dunkel und verstehe ich im Übrigen auch nicht, vor allem nicht, wie man letztlich konkret von libcdio auf cdio kommt.

    Du musst dort Wl (d. h. kleines L) und nicht W1 (eins) eingeben.

    Damit habe ich ihm den Pfad für die run-time vorgegeben, weil die lib nicht dort ist wo er sie zur run-time sucht. Siehe die Ausgabe von "ldd <dyn.-gelinktes-binary>".

    Betr. "-l" siehe in der manpage für gcc; ist dort ausführlich beschrieben.

    The most popular websites without IPv6 in Germany.  IPv6-Ausreden

    Meine PIs

    PI4B/8GB (border device) OpenBSD 7.4 (64bit): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server

    PI3B+ FreeBSD 14.0-R-p3 (arm64): SSH-Serv., WireGuard-Serv., ircd-hybrid-Serv., stunnel-Proxy, Mumble-Serv., ddclient

    PI4B/4GB Bullseye-lite (64bit; modifiziert): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server, botamusique, ample

  • Wenn's besser wird: die Library-Optionen von rpi444 noch dazugeben.

    Damit konnte ich erste Demoprogramme erfolgreich kompilieren.

    Jetzt muss ich mein raspiblaster-Projekt (Achtung: Unwort!) nur noch in C programmieren, so dass es für ein Kind bedienbar wird... Wenn's denn bei diesem Lösungsansatz bleibt:)

  • Seltsam dass dann so grundlegende Header wie stdio.h und string.h fehlen. Werden die in

    config.h nicht aufgefuehrt?

    Die header-Dateien fehlen nicht. Schau in die source-code-Dateien, dann wirst Du sehen wo sie gesucht werden. Du kannst den Pfad ändern oder sie dort hin kopieren, wo sie lt. den source-code-Dateien gesucht werden. Vorhanden sind diese Dateien ja, auf deinem Gerät. config.h hat damit nichts zu tun.

    The most popular websites without IPv6 in Germany.  IPv6-Ausreden

    Meine PIs

    PI4B/8GB (border device) OpenBSD 7.4 (64bit): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server

    PI3B+ FreeBSD 14.0-R-p3 (arm64): SSH-Serv., WireGuard-Serv., ircd-hybrid-Serv., stunnel-Proxy, Mumble-Serv., ddclient

    PI4B/4GB Bullseye-lite (64bit; modifiziert): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server, botamusique, ample

  • > Die header-Dateien fehlen nicht.

    Und warum kommt dann diese Meldung:

    1. eject.c:55:7: warning: incompatible implicit declaration of built-in function 'printf'

    > Schau in die source-code-Dateien,

    Hab ich gemacht. Da steht:

    ifdef HAVE_CONFIG_H

    #include "config.h"

    #define __CDIO_CONFIG_H__ 1

    #endif

    #ifdef HAVE_STDIO_H

    #include <stdio.h>

    #endif

    #ifdef HAVE_STDLIB_H

    #include <stdlib.h>

    #endif

    #ifdef HAVE_STRING_H

    #include <string.h>

    #endif

  • Das mit den Headerdateien stdio.h etc. war mir schon irgendwie klar:

    Die übergestülpte #ifdef HAVE_..._H-Geschichte ist ein Konzept der Programmierer der libcdio und steht in der Doku. Damit können sie in Teilbereichen des Codes den Zugriff auf bestimmte Headerdateien umbiegen und wieder zurückbiegen (zumindest habe ich es so verstanden), um bei Einbindung der Bibliothek in bestehende Projekte den Ursprungscode weitestgehend unverändert übernehmen zu können.

    Wenn das Ganze nicht richtig anbeißt, weil bei gcc die Kommandozeilenparameter fehlen, kann auch das nicht funktionieren. Da muss ich die Details noch nicht einmal verstehen. Der Quellcode sagt bereits durch geschickte Namensgebung, was gemeint ist und gewollt wird.

  • Hallo Schlizbäda,


    mit welcher Entwicklungsumgebung arbeitest Du denn ?

    Falls Windows für Dich eine Alternative sein kann, gibt es mit "Visual Studio" die Möglichkeit auch große und größte C- und C++-Linux-Projekte für den Raspberry zu entwickeln und vor allem auch auf dem Raspberry komfortabel zu debuggen. Zum Debuggen nutzt VS im Hintergrund den gdb, was man allerdings nicht bemerkt. Die Ausgaben des gdb werden so aufbereitet, dass man keinen Unterschied erkennt, ob man den Code für den PC oder den Raspberry entwickelt.

    Für den Einstieg wird von VS sogar ein einfaches Projekt für den Raspberry mitgeliefert, welches via GPIO eine LED blinken lässt. Das Makefile für Projekte wird durch VS automatisch erstellt. Zum Compilieren werden die Dateien vom PC zum Raspberry übertragen und dort mit g++ bzw. gcc (je nach Einstellung) übersetzt.

    Bei Interesse kann ich die erforderlichen URLs mal rauskramen.

    Ansonsten bietet sich natürlich Eclipse an, da ist der Einstieg allerdings wesentlich komplizierter.

    Gruß

    Prittzl

  • Servus Bäda ... ;)

    die Beispiele übersetzt Du nicht mit

    Trotzdem funktioniert der Aufruf gcc eject.c -o eject nicht. Fehlermeldung nach wie vor wie in Beitrag 1.

    oder so.

    Du machst

    Code
    pi@pi-lcurr:~ $ cd libcdio/
    pi@pi-lcurr:~/libcdio $ cd example/
    pi@pi-lcurr:~/libcdio/example $ make cdio-eject
    make: 'cdio-eject' is up to date.
    pi@pi-lcurr:~/libcdio/example $


    Auf diese Art kannst Du jedes der Programme (neu) erzeugen ...

    //EDT: Das Makefile aus example kannst Du dann als Vorlage für Deine eigenen Programme verwenden.


    cheers,

    -ds-

  • Diese Meldungen kommen nicht wenn er das macht was ich geschrieben habe. Er muss den source code (betr. _projektspezifische_ header-Dateien) anpassen. Z. B. in der eject.c-Datei so (... und btw. mit seinem Pfad):

    C
    /*
    #ifdef HAVE_CONFIG_H
    #include "config.h"
    #define __CDIO_CONFIG_H__ 1
    #endif
    */
    #include "/home/gm/Downloads/libcdio/config.h"

    The most popular websites without IPv6 in Germany.  IPv6-Ausreden

    Meine PIs

    PI4B/8GB (border device) OpenBSD 7.4 (64bit): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server

    PI3B+ FreeBSD 14.0-R-p3 (arm64): SSH-Serv., WireGuard-Serv., ircd-hybrid-Serv., stunnel-Proxy, Mumble-Serv., ddclient

    PI4B/4GB Bullseye-lite (64bit; modifiziert): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server, botamusique, ample

    Einmal editiert, zuletzt von rpi444 (31. Dezember 2017 um 12:50)

  • Hallo Prittzl,


    So sieht dann Debuggen auf dem Raspberry aus:

    danke für diesen Hinweis. Das sollte ich mir mal zu Gemüte führen. :conf:

    Aus Windows bin ich (zumindest privat) weitestgehend heraus, aber Visual Studio ist mir aus der Arbeit durchaus geläufig. Dort verwenden wir zwar wesentlich ältere Versionen (VS2005, VS2008, teilweise VS2010). Dass die neueren Versionen auch den RPi unterstützen, war mir so nicht klar.

    Anscheinend macht Microsoft bisweilen auch gute und brauchbare Programme ;)

    Frage:

    Läuft auf dem RPi bei dieser Anwendung das Win10 IOT Core oder ein Linux-Betriebssystem (Raspbian etc.)?

    Falls Windows für Dich eine Alternative sein kann, gibt es mit "Visual Studio" die Möglichkeit auch große und größte C- und C++-Linux-Projekte für den Raspberry zu entwickeln und vor allem auch auf dem Raspberry komfortabel zu debuggen.

    EDIT: Wer lesen kann, ist im Vorteil!

  • Liebe Forenmitglieder,

    vielen Dank für Eure Hilfe. Damit komme ich zunächst schon mal wesentlich weiter. Insbesondere der Hinweis von rpi444 in Beitrag #3 brachte mich auf die richtige Spur.

    Ich habe den Thread mal als erledigt markiert, bin aber für weitere Hinweise nach wie vor dankbar.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!