library mit eigenem Program mitkompilieren



  • Hallo

    Bei meinem C Programm unter Linux will ich eine Library "mxml" (mini xml), die als Source mit eigenem Makefile vorliegt, einbinden. Hierbei habe ich Probleme mit der Kompilierung. Als Test habe ich eine .h und eine .c Datei Geschrieben, die Typen aus mxml.h und zwei Funktionen aus mxml.h testweise aufrufen.

    Ziele:
    1. das ganze soll zu einer einzigen test.exe Datei fuehren

    2. ich will mxml mit folgendem in den test.c und test.h ausreichend deklarieren koennen:

    #include <mxml.h>
    

    Das .h File sollte auch im Ordner mxml-2.2.2 gefunden wird und seine Elemente (structs und Funktionen) richtig erkannt werden - ohne explizite Deklaration (ich denke -I als gcc Anweisung sollte das laeisten).

    3. im Makefile will ich zu erste saemtliche Library Unterverzeichnisse durchgehen und dort ein make aufrufen (ausser mxml werden noch ein paar dazu kommen), dann sollen die .c und die entsprechenden .a Dateien kompiliert und gebunden werden.

    4. Als ergebnis soll ein einziges File test.exe stehen.

    Problem:
    Es kompiliert nicht. Die libmxml.a wird zwar erstellt, aber erkennt dann die Elemente in test.c nicht, gibt einen Error und bricht ab. Entferne ich die include mxml.h Anweisung in .h gibt er gleich auf, und sagt, dass ihm die Typennamen in .h komplett unbekannt sind. Wie bringe ich das ganze zum kompilieren? Wie schreibe ich ein Makefile das mir den source einer library mit semparatem Make aufruf mitkompiliert?

    Mir ist klar, dass man Makefiles so oder anders schreiben kann, ich wuerde aber gerne wissen, wo bei DIESEM Makefile der Fehler steckt. 😉

    mein Code liegt so:
    ./test.h
    ./test.c
    ./Makefile
    ./mxml-2.2.2/mxml.h
    ./mxml-2.2.2/Makefile und Rest von mini-xml

    Makefile

    ## Makefile
    SRC=test.c
    OBJ=$(SRC:.c=.o)
    LDLIBS=-L./mxml-2.2.2/libmxml.a
    SUBDIRS=./mxml-2.2.2/
    INCLUDES=-I. -I$(SUBDIRS)
    CFLAGS=-g -Wall -std=c99 -pedantic
    CC=gcc
    
    all: test.exe
    .PHONY: all
    
    clean:
        rm -f $(OBJ) $(OUT) Makefile.bak core
    
    ## link
    test.exe: $(OBJ) $(LDLIBS)
        $(CC) -o $@ $(OBJ) $(LDLIBS) -lm
    
    ## compile
    $(LDLIBS):
        for dir in $(SUBDIRS); do( $(MAKE) -C $$dir ); done
    
    .c.o:
        $(CC) $(INCLUDES) $(CFLAGS) -c $<
    

    test.h

    // test.h
    #ifndef _TEST_H_
    #define _TEST_H_
    
    #include <mxml.h>
    
    //* // structure
    typedef struct mxml_parser_s {
      const mxml_node_t* root;
      const mxml_node_t* node;
    } xml_parser_t;
    typedef xml_parser_t* xml_parser_p;
    //*/
    
    //* // function
    mxml_node_t*
    compose_node( char* name );
    //*/
    
    #endif
    

    test.c

    // test.c
    /*
      test implementation
    //*/
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #include "test.h"
    
    #include <mxml.h>
    
    //*
    #define DEBUG 1
    
    mxml_node_t*
    compose_node( char* name )
    { 
      puts( "compose_node" );
      mxml_node_t* node=NULL;
      node = mxmlNewElement( NULL, "NAME" );
      mxmlNewText( node, 0, name );
    
      return node;
    }
    //*/
    
    int 
    main()
    {
      puts( "Hello World" );
    
      char name[32] = "foobar";
      mxml_node_t* node = NULL;
    
      puts( "compose node ");
      compose_node( name );
    
      puts( "delete node" );
      mxmlDelete( node );
    
      puts( "done" );
      return 0;
    }
    
    gcc -I. -I./mxml-2.2.2/ -g -Wall -std=c99 -pedantic -c test.c 
    for dir in ./mxml-2.2.2/; do( make -C $dir ); done
    make[1]: Entering directory `~/baustelle/minitest/src/mxml-2.2.2'
    gcc -O -Wall   -c mxml-attr.c
    gcc -O -Wall   -c mxml-entity.c
    gcc -O -Wall   -c mxml-file.c
    gcc -O -Wall   -c mxml-index.c
    gcc -O -Wall   -c mxml-node.c
    gcc -O -Wall   -c mxml-search.c
    mxml-search.c: In function ‘mxmlFindElement’:
    mxml-search.c:72: warning: passing argument 1 of ‘mxmlWalkNext’ discards qualifiers from pointer target type
    mxml-search.c:72: warning: passing argument 2 of ‘mxmlWalkNext’ discards qualifiers from pointer target type
    mxml-search.c:93: warning: return discards qualifiers from pointer target type
    mxml-search.c:99: warning: passing argument 1 of ‘mxmlElementGetAttr’ discards qualifiers from pointer target type
    mxml-search.c:106: warning: return discards qualifiers from pointer target type
    mxml-search.c:115: warning: passing argument 1 of ‘mxmlWalkNext’ discards qualifiers from pointer target type
    mxml-search.c:115: warning: passing argument 2 of ‘mxmlWalkNext’ discards qualifiers from pointer target type
    gcc -O -Wall   -c mxml-set.c
    gcc -O -Wall   -c mxml-private.c
    gcc -O -Wall   -c mxml-string.c
    mxml-string.c: In function ‘mxml_strdupf’:
    mxml-string.c:75: warning: implicit declaration of function ‘mxml_vsnprintf’
    /bin/rm -f libmxml.a
    /usr/bin/ar crvs libmxml.a mxml-attr.o mxml-entity.o mxml-file.o mxml-index.o mxml-node.o mxml-search.o mxml-set.o mxml-private.o mxml-string.o
    a - mxml-attr.o
    a - mxml-entity.o
    a - mxml-file.o
    a - mxml-index.o
    a - mxml-node.o
    a - mxml-search.o
    a - mxml-set.o
    a - mxml-private.o
    a - mxml-string.o
    ranlib libmxml.a
    make[1]: Leaving directory `~/baustelle/minitest/src/mxml-2.2.2'
    gcc -o test.exe test.o -L./mxml-2.2.2/libmxml.a -lm
    test.o: In function `compose_node':
    ~/baustelle/minitest/src/test.c:23: undefined reference to `mxmlNewElement'
    ~/baustelle/minitest/src/test.c:24: undefined reference to `mxmlNewText'
    test.o: In function `main':
    ~/baustelle/minitest/src/test.c:45: undefined reference to `mxmlDelete'
    collect2: ld returned 1 exit status
    make: *** [test.exe] Error 1
    


  • Habe folgende Fehler gefunden und es kompiliert:
    Erstens muss es natuerlich in test.c folgendermassen heissen:

    node = compose_node( name );
    

    Zweitens, im Makefile muss es statt

    LDLIBS=-L./mxml-2.2.2/libmxml.a
    

    folgendermassen heissen:

    LDLIBS=-Lmxml-2.2.2 -lmxml
    

    Mir war nicht bewusst, das hier KEIN Pfad zu den .a Dateien direkt gesetzt werden kann/darf, bzw. der Linker das NICHT richtig linkt, wenn man einen Pfad setzt. Das Flag -lmxml stand in der mini-xml Doku.



  • -L gibt den Suchpfad für Libraries an, -l gibt an, zu welchen Libraries gelinkt werden soll.



  • Dieser Thread wurde von Moderator/in nman aus dem Forum Linux/Unix in das Forum Compiler- und IDE-Forum verschoben.

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

    Dieses Posting wurde automatisch erzeugt.



  • nman schrieb:

    -L gibt den Suchpfad für Libraries an, -l gibt an, zu welchen Libraries gelinkt werden soll.

    Nja, schon, aber irgendwo auch nicht (nur). -L, -l und -I nehmen Pfade zu den Verzeichnissen in denen Dateien liegen e.g. libmxml.a oder test.h. Allerdings muessen damit anscheinend auch "Librarynamen" referenziert werden koennen.

    Bspw. im obigen Beispiel kompiliert nichts ohne:

    LDLIBS = -Lmxml-2.2.2 -lmxml
    

    Wenn man nun aber zB von einer Verzeichnisebene hoeher das Makefile aufbaut, fehlt noch zusaetzlich eine Verzeichnisangabe unter -L, wobei die aber so schon angegebenen -L und -l Parameter OHNE Anpassung uebernommen werden muessen. (Die mxml ist von mir NICHT in /lib, /usr/lib oder an sonst einer "ofiziellen" Stelle isntalliert!) Die Zeile sieht dann folgendermassen aus, wenn der Code zB in /src/ liegt:

    LDLIBS = -L ./src/mxml-2.2.2/ -Lmxml-2.2.2 -lmxml
    

    "./mxml-2.2.2/" existiert hier nicht, und mxml gibt es sowieso nicht als Ordner. -l und -L gibt also nicht NUR Pfade an, die direkt so existieren.


Log in to reply