C Projekt mit Bibliothek kompilieren



  • Hallo,

    ich möchte gerne ein C-Projekt zum Laufen bringen. Dazu habe ich einmal eine Bibliothek (Bib1) mit ".c" und ".h" Dateien aus der ich eine Funktion "lib_function()" aufrufen möchte, dann habe ich noch eine weitere Bibliothek (Bib2) installiert, die innerhalb der ersten benötigt wird.

    Ich habe jetzt in DevC ein Projekt angelegt und folgendes gemacht:

    1.) main.c Datei erstellt:

    #include <stdio.h>
    #include "lib.h" // Da steckt die lib_function drin
    
    int main(void)
    {
      int r;
    
      r  = lib_function(); // Funktion aus Bib1
      
      return 0;
    }
    

    2.) In DevC habe ich in den Projekt Einstellungen die Pfade zu den Bibliotheken hinzugefügt:

    -I"C:/Program Files/Bib2/include" 
    -I"C:/Users/Me/Downloads/Bib1"
    

    3.) Wenn ich das Projekt kompiliere, dann wird folgendes MakeFile erzeugt:

    # Project: MainTest
    # Makefile created by Dev-C++ 5.11
    
    CPP      = g++.exe
    CC       = gcc.exe
    WINDRES  = windres.exe
    OBJ      = main.o
    LINKOBJ  = main.o
    LIBS     = -L"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib" -L"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib" -static-libgcc
    INCS     = -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -I"C:/Program Files/Bib2/include" -I"C:/Users/Me/Downloads/Bib1"
    CXXINCS  = -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++" -I"C:/Program Files/Bib2/include" -I"C:/Users/Me/Downloads/Bib1"
    BIN      = MainTest.exe
    CXXFLAGS = $(CXXINCS) -std=c11
    CFLAGS   = $(INCS) -std=c11
    RM       = rm.exe -f
    
    .PHONY: all all-before all-after clean clean-custom
    
    all: all-before $(BIN) all-after
    
    clean: clean-custom
    ${RM} $(OBJ) $(BIN)
    
    $(BIN): $(OBJ)
    $(CC) $(LINKOBJ) -o $(BIN) $(LIBS)
    
    main.o: main.c
    $(CC) -c main.c -o main.o $(CFLAGS)
    

    Problem: Mein Problem ist an dieser Stelle, dass beim Kompilieren, mir DevC die Meldung "undefined reference to lib_function" ausgibt. Meine Frage ist hier, wie man das beheben kann. Es scheint irgendwie mit der Zeile 24 und 25 im MakeFile zusammenzuhängen.

    Ich bin etwas ratlos, daher frage ich, wie man nun das Problem beheben kann...


  • Mod

    -I (Include) ist nur für die Übersetzung, damit der Compiler anhand der Header weiß, wie die Funktionen aufzurufen sind. Das eigentliche Programm baut der Linker am Ende zusammen, und der braucht den tatsächlichen Maschinencode der Funktionen. Dazu muss er wissen, wo er den finden kann. Ich weiß nicht, wie genau das bei DevC geht, aber irgendwo wird es sicher etwas geben, wie man die -L (Libraries) Pfade erweitern kann.



  • Hallo,

    danke für deine Antwort. Also wie sehe das denn unabhängig von DevC aus? Also was müsste man genau machen? Ich könnte die IDE auch wechseln, solange das Windows basiert ist...



  • Schau in den Projekt-Optionen unter "Linker": How can I add library files in Dev C++?



  • Dieser Beitrag wurde gelöscht!


  • Dieser Beitrag wurde gelöscht!


  • Also das Hinzufügen, wie es @Th69 vorschlägt, war gut! Aber, wie kann man nun die Abhängigkeiten der ersten Bib1 zur zweiten Bibliothek Bib2 einbauen?

    In der ersten Bibliothek gibt es in einer Datei einen #include <bib2/conf.h> und weitere... Wie kann man die beiden Bibliotheken innerhalb des Programms aneinander "bekannt" machen?!



  • Ich persönlich würde CMake verwenden.
    Diese Art von Problem wird ein ewiger Begleiter sein, zumindest könnte ich siebzehn Lieder davon singen, dass man irgendwelche Include, Lib, etc. Probleme hat in C und C++... da geht gerne genauso viel Zeit flöten, wie für's herkömmliche Debuggen. Vielleicht war ich auch einfach nur unfähig... 32-bit, 64-bit, debug, release, static, shared, hier ein Pfad, usw. usw. ich vermisse es nicht...

    // ./src/main.c
    #include <stdio.h>
    #include <test/test.h>
    
    int main() {
    	printf("2*2 = %d\n", my_square(2));
    }
    
    // ./include/test/test.h
    #ifndef INCLUDE_TEST_H
    #define INCLUDE_TEST_H
    
    int my_square(int x);
    
    #endif // INCLUDE_TEST_H
    
    // ./src/test/test.c
    #include <test/test.h>
    
    int my_square(int x) {
    	return x * x;
    }
    
    # Compile object file from test:
    gcc -c -o ./build/test/test.o -I./include/ ./src/test/test.c
    # Create static library file:
    ar rcs ./lib/test/libtest.a ./build/test/test.o 
    # Compile and link main program with libtest:
    gcc -I./include/ -L./lib/test ./src/main.c -ltest -o ./build/main
    # Run main:
    ./build/main
    2*2 = 4
    
    # Directory structure:
    .
      |-build
      |  |-main
      |  |-test
      |  |  |-test.o
      |-include
      |  |-test
      |  |  |-test.h
      |-lib
      |  |-test
      |  |  |-libtest.a
      |-src
      |  |-main.c
      |  |-test
      |  |  |-test.c
    
    # Adding another lib as dependency to libtest
    mkdir include/magic
    touch include/magic/magic.h
    mkdir src/magic
    touch src/magic/magic.c
    mkdir lib/magic
    mkdir build/magic
    
    // ./include/magic/magic.h
    #ifndef INCLUDE_MAGIC_H
    #define INCLUDE_MAGIC_H
    
    int get_magic();
    
    #endif // INCLUDE_MAGIC_H
    
    // ./src/magic/magic.c
    #include <magic/magic.h>
    
    int get_magic() {
    	return 0xDEADBEEF;
    }
    
    // ./include/test/test.h
    #ifndef INCLUDE_TEST_H
    #define INCLUDE_TEST_H
    
    int my_square(int x);
    int magic_mul(int x);
    
    #endif // INCLUDE_TEST_H
    
    // ./src/test/test.c
    #include <test/test.h>
    #include <magic/magic.h>
    
    int my_square(int x) {
    	return x * x;
    }
    
    int magic_mul(int x) {
    	return x * get_magic();
    }
    
    // ./src/main.c
    #include <stdio.h>
    
    #include <test/test.h>
    
    int main() {
    	printf("2*2 = %d\n", my_square(2));
    	printf("3*'magic' = %d\n", magic_mul(3));
    }
    
    # Create libmagic, libtest, compile main
    gcc -c -o ./build/magic/magic.o -I./include/ ./src/magic/magic.c
    ar rcs ./lib/magic/libmagic.a ./build/magic/magic.o 
    gcc -c -o ./build/test/test.o -I./include/ ./src/test/test.c
    ar rcs ./lib/test/libtest.a ./build/test/test.o
    gcc -I./include/ -L./lib/test -L./lib/magic ./src/main.c -ltest -lmagic -o ./build/main
    ./build/main
    2*2 = 4
    3*'magic' = -1677116211
    
    # Directory structure:
    .
      |-build
      |  |-magic
      |  |  |-magic.o
      |  |-main
      |  |-test
      |  |  |-test.o
      |-include
      |  |-magic
      |  |  |-magic.h
      |  |-test
      |  |  |-test.h
      |-lib
      |  |-magic
      |  |  |-libmagic.a
      |  |-test
      |  |  |-libtest.a
      |  |  |-libtest2.a
      |-src
      |  |-magic
      |  |  |-magic.c
      |  |-main.c
      |  |-test
      |  |  |-test.c
    

    D. h., die Libs müssen nicht untereinander verlinkt werden, sondern das passiert alles zusammen beim Linken des Hauptprogramms.

    Oder in diesem Fall natürlich einfach, eine einzige lib:

    ar rcs ./lib/test/libtest2.a ./build/test/test.o ./build/magic/magic.o
    gcc -I./include/ -L./lib/test ./src/main.c -ltest2 -o ./build/main 
    

    Oder in diesem Fall natürlich noch einfacher, gar keine lib:

    gcc -I./include ./src/main.c ./src/test/test.c ./src/magic/magic.c -o ./build/main
    

Anmelden zum Antworten