Mehrere C Datei kombinieren



  • Hi hab folgendes Testprogramm geschrieben:

    #ifndef _CUSTOMHEADER_H_
    #define _CUSTOMHEADER_H_
    
    void printOutput( void );
    
    #endif
    
    #include "CustomHeader.h"
    #include <stdio.h>
    
    void printOutput( void ) {
      printf("CustomHeader\n");
    }
    

    und schließlich Test.c:

    #include "CustomHeader.h"
    #include <stdio.h>
    
    main() {
    
      printf("Hello World!\n");
      printOutput();
    
    }
    

    Mein Makefile sieht so aus:

    CC = gcc
    CFLAGS = 
    
    all:Test
    	rm -f Test.o CustomHeader.o
    
    Test.o: Test.c CustomHeader.o
    	$(CC) $(CFLAGS) -c Test.c -o Test CustomHeader.o
    
    CustomHeader.o: CustomHeader.c
    	$(CC) $(CFLAGS) -c CustomHeader.c
    
    clean:
    	rm -f Test Test.o
    

    Leider erhalte ich folgenden Fehler:

    make
    gcc Test.o -o Test
    Undefined symbols:
    "_printOutput", referenced from:
    _main in Test.o
    ld: symbol(s) not found
    collect2: ld returned 1 exit status
    make: *** [Test] Error 1

    Wie kompiliert man das richtig?



  • HändyÄndy schrieb:

    und schließlich Test.c:

    #include "CustomHeader.h"
    #include <stdio.h>
    
    int main(void) {
    ...
    }
    

    Deine definition von main war falsch, ich habs mal korrigiert.

    HändyÄndy schrieb:

    Mein Makefile sieht so aus:

    CC = gcc
    CFLAGS = 
    
    all:Test
    	rm -f Test.o CustomHeader.o
    
    Test.o: Test.c CustomHeader.o
    	$(CC) $(CFLAGS) -c Test.c -o Test CustomHeader.o
    
    CustomHeader.o: CustomHeader.c
    	$(CC) $(CFLAGS) -c CustomHeader.c
    
    clean:
    	rm -f Test Test.o
    

    Leider erhalte ich folgenden Fehler:

    make
    gcc Test.o -o Test
    Undefined symbols:
    "_printOutput", referenced from:
    _main in Test.o
    ld: symbol(s) not found
    collect2: ld returned 1 exit status
    make: *** [Test] Error 1

    Wie kompiliert man das richtig?

    Der Linker-Step fehlt in der Makefile. Bisher wandelst du die Source-Dateien nur in Objekt-Dateien um. Am Ende werden diese Objekt-Dateien alle zusammen zu einer Applikation gelinkt.



  • Ah, danke. Welchen Linker muss ich denn nehmen, bzw. wie sähe der Befehl dafür aus (benutze Mac OS X)?



  • Linken macht auch der gcc. Allerdings musst du ihn anders aufrufen. Das was du jetzt machst ist die C-Dateien in Objekt-Dateien zu compilieren. Der Linkeraufruf sähe so aus:

    Test: Test.o CustomHeader.o
        gcc -o test Test.o CustomHeader.o
    

    Das liefert dir eine ausführbare Datei mit dem Namen Test.

    Du kannst übrigends das -c und das -o in deine CFLAGS reinziehen. Zu dem ist sie ja da. Sieht dann so aus:

    CC=gcc
    LD=gcc
    CFLAGS=-c -g -Wall -o
    LDFLAGS=-o
    
    Test: Test.o CustomHeader.o
        $(LD) $(LDFLAGS) Test Test.o CustomHeader.o
    
    Test.o: Test.c
        $(CC) $(CFLAGS) Test.o Test.c
    
    CustomHeader.o: CustomHeader.c
        $(CC) $(CFLAGS) CustomHeader.o CustomHeader.c
    
    clean:
        rm -f Test Test.o CustomHeader.o
    

    Wenn du noch mehrere C-Files bekommen solltest, dann kannst auch über ein Pattern arbeiten. Sieht so aus:

    CC=gcc
    LD=gcc
    CFLAGS=-c -g -Wall -o
    LDFLAGS=-o
    
    TARGET=Test
    OBJ=Test.o CustomHeader.o
    
    %.o: %.c
        $(CC) $(CFLAGS) $@ $<
    
    $(TARGET): $(OBJ)
        $(LD) $(LDFLAGS) $(TARGET) $(OBJ)
    
    clean:
        rm -rf $(OBJ)
        rm -rf $(TARGET)
    

    Das ist dann schon ein ziemlich generisches Makefile. Damit kannst immer arbeiten. Du musst nur bei den $(OBJ) deine .o-Files eintragen und dann compiliert er dir alle Files und linkt sie auch gleich. in $(TARGET) sthet der Name der ausführbaren Datei. Wichtig ist nur, dass du, wenn du den Code oben jetzt in eine Datei kopierst, dass du in Zeile 10, 13, 16 und 17 die Leerzeichen durch ein TAB ersetzt.



  • Jo, geht jetzt. Besten Dank!


Log in to reply