Probleme mit 'make'



  • Hallo, ich will ein Makefile für mein C Programm erstellen,
    bekomme aber einen Fehler, der mich verwirrt..

    Wenn ich make all, oder make p1/make p2 (so heissen die einzelnen Programme) aufrufe, kommt folgender Fehler (hier das beispiel mit Aufruf 'make p2'):

    gcc -o p2 p2_main.c printfunctions.c
    /tmp/ccvEQ251.o: In function `func1':
    printfunctions.c:(.text+0x0): multiple definition of `func1'
    /tmp/ccWR3YdI.o:p2_main.c:(.text+0x0): first defined here
    /tmp/ccvEQ251.o: In function `func2':
    printfunctions.c:(.text+0x24): multiple definition of `func2'
    
    /tmp/ccWR3YdI.o:p2_main.c:(.text+0x24): first defined here
    /tmp/ccvEQ251.o: In function `func3':
    printfunctions.c:(.text+0x43): multiple definition of `func3'
    /tmp/ccWR3YdI.o:p2_main.c:(.text+0x43): first defined here
    collect2: ld returned 1 exit status
    make: *** [p2] Fehler 1
    

    hier einmal der inhalt dieser "printfunctions.c" datei, damit ihr mit
    dem fehler etwas anfangen könnt:

    #include <stdio.h>
    
    int func1(int a,int b)
    {
       int c = a+b;
       printf("%i\n",c);
    
    }
    
    int func2(int a)
    {
       a--;
       printf("%i\n",a);
    
    }
    
    int func3(int a)
    {
       int temp = 2*a;
       printf("%i\n",temp);
    
    }
    

    und hier der inhalt der "p2_main.c" datei:

    #include <stdio.h>
    #include "printfunctions.c"
    
    int main()
    {
       func3(20);
       return 0;
    }
    

    Ich verstehe nicht so ganz, wieso "multiple function" als Fehler kommt.
    Ich habe die einzelnen Funktionen doch nirgendwo mehrmals deklariert.

    Any ideas? Merci 🙂



  • Das hat mit make überhaupt nichts zu tun. Du definierst die Funktionen tatsächlich doppelt: Einmal in printfunctions.c und einmal in p?_main.c, wo Du printfunctions.c includierst. Grundsätzlich includiert man im Normalfall niemals Codefiles.



  • hi, problem hat sich erledigt.
    Trotzdem danke für die Antwort.

    P.s: die Funktion war nicht doppekt deklariert.
    Sie war in printfunctions deklariert, und in p2_main wurde sie nur aufgerufen.

    Deklaration: int func(...) = (...)
    Aufruf: func(..);

    Es lag daran, dass die Funktionen keinen Rückgabewert hatten (return 0;)
    Das Programm ging komischerweise trotzdem, nur make kann ohne einen Return Wert scheinbar nix damit anfangen.



  • hdi schrieb:

    Es lag daran, dass die Funktionen keinen Rückgabewert hatten (return 0;)
    Das Programm ging komischerweise trotzdem, nur make kann ohne einen Return Wert scheinbar nix damit anfangen.

    Nein daran lag es definitiv nicht.
    Aus deinem geposteten Code ist klar ersichtlicht
    das du printfunktions.c in die main.c inkludierst.
    Also höre auf LordJaxom und unterlasse das.

    Stattdessen schreibst du dir eine printfunktions.h
    und deklarierst die Funktionen dort, diese Datei
    kannst du dann in der main inkludieren.

    Eine Deklaration ist übrigens sowas:
    int func(int);
    
    Eine Definition:
    int func(int name) {
    ...
    }
    
    Und ein Aufruf:
    func(3);
    

    Und make kann in diesem Fall nichts dafür.



  • Also ihr seid hier die Profis, aber ich meine ich habe lediglich
    bei jeder der Funktionen in der printfunctions "return 0" hingeschrieben,
    und alles ging wunderbar !
    Also ich bin jetzt verwirrt...

    @storm.xapek.de
    ja stimmt, ist natürlich eine definition und keine deklaration.
    aber zumindest ist das in p2_main.c sicherlich nur ein aufruf, und keine
    definition! das sieht man eigentlich eindeutig, vielleicht hat sich LordJaxom nur etwas falsch ausgedrückt.

    Achso: Was soll ich denn unterlassen? Ihm zu widersprechen? Also sorry, aber was soll denn das? Wenn er etwas sagt, und das stimmt nicht, dann darf ich dagegen nichts sagen?

    Du definierst die Funktionen tatsächlich doppelt: Einmal in printfunctions.c und einmal in p2_main.c

    Es ist SICHERLICH keine definition sondern nur ein aufruf in p2_main.c
    immerhin fehlt jegliche zuweisung durch ":=" oder "=" oder was auch immer.
    die funktion wird mit bestimmten parametern aufgerufen, nicht definiert 😉



  • hdi schrieb:

    Du definierst die Funktionen tatsächlich doppelt: Einmal in printfunctions.c und einmal in p2_main.c

    Es ist SICHERLICH keine definition sondern nur ein aufruf in p2_main.c

    Schau nochmal genau hin: Oben in p2_main.c steht in diesem Thread #include "printfunctions.c" (muss ich einen Screenshot machen bevor Du es änderst? :p). Der Präprozessor macht reine Textersetzungen, was bedeutet dass die komplette Datei printfunctions.c nochmals in der p2_main.c compiliert wird. Damit sind die betreffenden Funktionen definitiv doppelt vorhanden - einmal in printfunctions.c und einmal in der p2_main.c, welche die printfunctions.c includiert.



  • hm..

    aber wenn ich das inkludieren weglasse, und p2_main aufrufen will,
    sagt er mir dass er die funktion "func3" nicht finden kann.

    und wenn ich den aufruf "func3(..)" in der main-methode weglasse,
    dann macht ja mein komplettes programm nix 😉

    also...wie sollte das denn anders überhaupt gehen?
    mfg



  • Also irgendwie komm ich mit diesen Makefiles gar nicht klar 😞

    Ich habe wieder ein Programm, wo make irgendwie Faxen macht
    (also weil ihr immer sagt es liegt an make: schon klar dass es am Programm liegt
    wahrscheinlich aber das Programm an sich funktioniert und tut, was es soll).

    und zwar kommt bei make all oder make prog der Fehler:

    gcc -g -Wall -o prog P-1-2.c
    P-1-2.c: In function ‘main’:
    P-1-2.c:9: warning: statement with no effect
    

    Ich weiss nicht so, wie ich das werten soll. Soll die 9 da die neunte
    Zeile andeuten? Da steht nur die for-Bedingung...Keine Ahnung, hier mein Programm:

    //Das Programm bekommt verschiedene Parameter übergeben und druckt diese wieder //aus. Die Anzahl der übergebene Parameter steht erst zur Laufzeit fest.
    
    # include <stdio.h>
    
    int main(int argc, char *argv[])
    {
    	if (argv[1] == NULL)
    	{printf("Bitte übergeben Sie mindestens ein Argument.\n");}
    
    	int c = argc-1;
    	for (c;c >= 0;c--)
    	{
    	if (c != 0)
    	{
    	int changeOrder = argc - c;
    	printf("Parameter %i: ",changeOrder);
    	printf(argv[changeOrder]);
    	printf("\n");
    	}
    	}
    return 0;
    }
    


  • Also irgendwie komm ich mit diesen Makefiles gar nicht klar 😞

    Das hat doch absolut nichts mit den Makefiles zu tun. Das ist der Compiler, der dich warnt. Lies dir durch was er sagt und schau dir die Zeile an, die er bemängelt. (Und ja, die Zahle hinter dem Dateinamen deutet die Zeile an).

    Tipp: Schau dir mal die Anfangsbedingung in der for-Schleife an und überleg dir, was dieses Statement macht (und beachte was der Compiler sagt)...



  • hdi schrieb:

    hm..

    aber wenn ich das inkludieren weglasse, und p2_main aufrufen will,
    sagt er mir dass er die funktion "func3" nicht finden kann.

    und wenn ich den aufruf "func3(..)" in der main-methode weglasse,
    dann macht ja mein komplettes programm nix 😉

    also...wie sollte das denn anders überhaupt gehen?
    mfg

    Deklarier die Funktion. 🙄



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum Linux/Unix in das Forum ANSI C verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • @rüdiger:

    das lustige is ja irgendwie, dass die Programme alle einwandfrei funktionieren.

    Aber nur beim erstellen bzw. aufrufen von Makefiles kommen Fehler.
    Das ist der Grund, warum ich sage, ich komme nicht mit den Makefiles zurecht,
    weil das Programm prima funktioniert.

    Aber zum Problem:

    Also erstens mal habe ich gesehen, dass meine if-Abfrage völliger Schmarrn ist.
    Stattdessen habe ich aus dem ">=" bei for ein ">" gemacht 😉

    Aber trotzdem...ich verstehe nicht, was du meinst.
    Wieso kein Effekt? Die Zeile macht doch etwas oder nicht? Sie dekrementiert
    'c' und sie überprüft etwas..

    Tut mir leid, ich verstehe ja dass man selber was tun muss und nicht das forum für jeden Dreck missbrauchen soll, aber ich verstehe es wirklich nicht 😞

    Wieso regt sich make über die Zeile auf, der Compiler aber nicht und das Programm funktioniert?

    danke 😞



  • hdi schrieb:

    Aber nur beim erstellen bzw. aufrufen von Makefiles kommen Fehler.
    Das ist der Grund, warum ich sage, ich komme nicht mit den Makefiles zurecht,
    weil das Programm prima funktioniert.

    Das möchte ich sehen, dass die Meldung nicht kommt, wenn Du den Compiler manuell anwirfst 😉

    hdi schrieb:

    Aber trotzdem...ich verstehe nicht, was du meinst.
    Wieso kein Effekt? Die Zeile macht doch etwas oder nicht? Sie dekrementiert
    'c' und sie überprüft etwas..

    Die Initialisierung im Kopf der for-Schleife: Dort steht bei Dir "c;" - dieses Statement macht garnix, hat also keinen Effekt. Daher die Meldung. Effekt hätte z.B. "c=1;" oder "c++;" aber nicht "c;". Davon abgesehen ist die Meldung nur eine Warnung, was auch der Grund dafür ist dass das Programm trotzdem funktioniert. Der Compiler möchte Dir halt nur sagen "schau mal, da ist was von dem ich glaube dass Du was anderes gemeint haben könntest".

    hdi schrieb:

    Wieso regt sich make über die Zeile auf, der Compiler aber nicht und das Programm funktioniert?

    Der Compiler regt sich aus o.g. Gründen auf. Make nicht. Wie kommst Du überhaupt darauf die Fehlermeldungen könnten von make stammen?



  • Also genau das mit der Initialisierung in der for-Anweisung hatte ich mir gedacht.

    In meinem Programm steht ja:

    int c = argc-1;
    for(c;c >0;c++)
    

    wenn ich allerdings die erste Zeile weglasse und statt dessen schreibe:

    for(int c = argc-1;c>0;c++)
    

    dann kommt eine fehlermeldung beim compilen:

    P-1-2.c: In function ‘main’:
    P-1-2.c:8: error: ‘for’ loop initial declaration used outside C99 mode
    

    Und noch einmal, ich schwöre es ist wirklich so:
    Wenn ich das Programm compile mit gcc dann kommt NICHTS.
    keine warnmeldung.

    jedoch wenn ich make aufrufe, kommt die meldung.

    d.h. es ist anders herum, wie du sagst. der compiler meckert bei gcc nicht, aber bei make. deswegen dachte ich, dass make damit ein problem hat.

    nun, wie dem auch sei: was soll das mit dem "outside C99 mode"?

    mfg



  • hdi schrieb:

    In meinem Programm steht ja:

    int c = argc-1;
    for(c;c >0;c++)
    

    wenn ich allerdings die erste Zeile weglasse und statt dessen schreibe:

    for(int c = argc-1;c>0;c++)
    

    dann kommt eine fehlermeldung beim compilen:

    P-1-2.c: In function ‘main’:
    P-1-2.c:8: error: ‘for’ loop initial declaration used outside C99 mode
    

    Dann übersetzt Du den Code im C89-Modus (bei gcc glaube ich auch der Standardmodus). Da kannst Du Variablen im Kopf der Schleife nicht definieren. Aber der andere Code war soweit vollkommen in Ordnung. Du hättest lediglich das "Statement without effect" wegnehmen müssen:

    int c = argc-1;
    for( ; c >0; c++)
    

    Und noch einmal, ich schwöre es ist wirklich so:
    Wenn ich das Programm compile mit gcc dann kommt NICHTS.
    keine warnmeldung.

    Hast Du im Makefile evtl. -Wall gesetzt, und manuell nicht?

    nun, wie dem auch sei: was soll das mit dem "outside C99 mode"?

    Wie gesagt, diese Form der Definition im Kopf der Schleife ist erst in C99 (oder C++) möglich, nicht in ANSI C 89. Du kannst aber (entsprechend neue Version vorausgesetzt) auch dem gcc mit dem Parameter --std=c99 C99 beibringen.



  • hdi schrieb:

    wenn ich allerdings die erste Zeile weglasse und statt dessen schreibe:

    for(int c = argc-1;c>0;c++)
    

    Probier mal

    int c;
    for(c = argc-1;c>0;c++)
    

    Kleiner Tip: wenn du mal nicht weiterkommst mit Fehlermeldungen: copy&paste bei google, und meistens bist du sehr schnell etwas schlauer geworden 😉



  • Hast Du im Makefile evtl. -Wall gesetzt, und manuell nicht?

    Jetzt endlich verstehe ich auch, wieso das alles mit make nix zu tun hat!
    Ich wusste nicht, dass gcc standartmässig nicht -Wall aufruft.
    Und weil mir make Meldungen ausgegeben hat, gcc aber nicht, dachte ich eben,
    es liegt am Makefile.

    p.s.: Kann man -Wall irgendwie zum Standard bei gcc machen?
    Ich würde diese Option sehr gerne nutzen, aber ohne jedesmal den Parameter anzugeben.

    p.p.s: Wieso wird denn Standar-t vom Forum zensiert? was ist denn so schlimm am
    Begriff "dar-t" 😕

    mfg, ihr seid echt spitze!



  • hdi schrieb:

    p.p.s: Wieso wird denn Standar-t vom Forum zensiert? was ist denn so schlimm am
    Begriff "dar-t" 😕

    An dem Spiel, wo man mit Pfeilen auf eine Zielscheibe wirft, ist nichts verkehrt - aber der Begriff Stand-art könnte doch eher die Kunst bezeichnen, Messestände kunstvoll zu gestalten. Es ist halt einfach falsch, so wie vor-raus 😉



  • http://www.k-faktor.com/stand art/

    😉

    Blede Zensur, einfach Blank wegnehmen



  • Das meinte ich ja auch!
    Ich dachte mir halt: wenn schon etwas compilen, warum dann nich auch gleich noch n schöner Messestand. 😃


Anmelden zum Antworten