Thread: 'undefined reference to' with libxml2

  1. #1
    Registered User
    Join Date
    Sep 2012
    Posts
    28

    'undefined reference to' with libxml2

    I am trying to use libxml2 to create a library file, I am on Ubuntu so libxml2 is preinstalled. I am trying to use xmlwriter.h to create the file, if I use the example testwriter program I can successfully compile it, but for some reason my program will not compile. I just can't figure out what I'm doing wrong, it acts like the functions from xmlwriter.h are not defined, but I successfully included the header file. Also, this only happens with xmlwriter.h, I can use the other header files from libxml2 and they work fine, but everything from xmlwriter.h act like they are not defined.

    Here is the function in my program:
    Code:
    #include <libxml/xmlwriter.h>
    #include "library.h"
    #include "globalvars.h"
    
    void load_library() {
        xmlDocPtr doc;
        if(stat("library.xml", &STAT) < 0) {
            // Create library
            xmlTextWriterPtr writer = xmlNewTextWriterFilename("library.xml", 0);
            xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL);
            xmlTextWriterStartElement(writer, "Library");
            xmlTextWriterStartElement(writer, "Comics");
            xmlTextWriterFullEndElement(writer);
            xmlTexWriterEndElement(writer);
            xmlTextWriterEndDocument(writer);
            xmlFreeTextWriter(writer);
        }
    }
    Here's the output:
    Code:
    library.o: In function `load_library':
    library.c:(.text+0x2d): undefined reference to `xmlNewTextWriterFilename'
    library.c:(.text+0x4c): undefined reference to `xmlTextWriterStartDocument'
    library.c:(.text+0x5d): undefined reference to `xmlTextWriterStartElement'
    library.c:(.text+0x6e): undefined reference to `xmlTextWriterStartElement'
    library.c:(.text+0x7a): undefined reference to `xmlTextWriterFullEndElement'
    library.c:(.text+0x8b): undefined reference to `xmlTexWriterEndElement'
    library.c:(.text+0x97): undefined reference to `xmlTextWriterEndDocument'
    library.c:(.text+0xa3): undefined reference to `xmlFreeTextWriter'
    library.c:(.text+0xaf): undefined reference to `xmlParseFile'
    collect2: ld returned 1 exit status
    make: *** [eComics] Error 1

  2. #2
    Registered User
    Join Date
    Sep 2012
    Posts
    28
    I should also note the STAT is in my globalvars.h file, incase anyone noticed that

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > #include <libxml/xmlwriter.h>
    Is this in /usr/include/libxml/xmlwriter.h ?

    Somewhere beneath /lib or /usr/lib, do you have say libxml2.a

    The three key flags for compiling with 3rd party libraries which are not installed in the default location are
    -I
    -L
    -l

    -I tells the compiler where to find .h files
    -L tells the linker where to find .a files
    -l tells the linker what .a files to link with

    So if the library is in /path/to/lib/libfoobar.a, then you would write
    gcc -L/path/to/lib prog.c -lfoobar
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    stat may return -1 for reasons other than the file not existing (and thus you needing to create it). To be extra sure, you should check the value of errno and make sure you're not dealing with some other error. Read the man page for details (link).

    Also, read the documentation for libxml2 more thoroughly. You should be checking for errors. If xmlNewTextWriteFilename can't open the file for any reason, you have potential seg faults, or simply code that appears to do nothing and provides no output to inform you why.

    Lastly, a couple style notes: global variables are generally not the best solution to a problem, so declare them where appropriate and pass them around as needed. More info here: Global Variables Are Bad. And usually, identifiers in all uppercase (like STAT) are reserved for constants.

  5. #5
    Registered User
    Join Date
    Sep 2012
    Posts
    28
    Quote Originally Posted by Salem View Post
    > #include <libxml/xmlwriter.h>
    Is this in /usr/include/libxml/xmlwriter.h ?

    Somewhere beneath /lib or /usr/lib, do you have say libxml2.a

    The three key flags for compiling with 3rd party libraries which are not installed in the default location are
    -I
    -L
    -l

    -I tells the compiler where to find .h files
    -L tells the linker where to find .a files
    -l tells the linker what .a files to link with

    So if the library is in /path/to/lib/libfoobar.a, then you would write
    gcc -L/path/to/lib prog.c -lfoobar
    I forgot to include this part in my post, but I already have the compiling argument for libxml2, it's `xml2-config --cflags --libs`, the section in my makefile is:
    Code:
    library.o: library.c library.h globalvars.h
        gcc `xml2-config --cflags --libs` -c library.c -Wall
    xmlwriter.h is located in /usr/include/libxml2/libxml/, and like I already stated the other header files from libxml2 don't have any problems.

  6. #6
    Registered User
    Join Date
    Sep 2012
    Posts
    28
    Quote Originally Posted by anduril462 View Post
    stat may return -1 for reasons other than the file not existing (and thus you needing to create it). To be extra sure, you should check the value of errno and make sure you're not dealing with some other error. Read the man page for details (link).

    Also, read the documentation for libxml2 more thoroughly. You should be checking for errors. If xmlNewTextWriteFilename can't open the file for any reason, you have potential seg faults, or simply code that appears to do nothing and provides no output to inform you why.

    Lastly, a couple style notes: global variables are generally not the best solution to a problem, so declare them where appropriate and pass them around as needed. More info here: Global Variables Are Bad. And usually, identifiers in all uppercase (like STAT) are reserved for constants.
    I already understand that about stat, the way I'm using it now is temporary, right now I'm just trying to get xmlwriter to work, and the problem is not in stat. Also I have read the documentation for xmlwriter.h pretty thoroughly, it's not throwing an error saying it can't create the file, that's not an error that would happen at compile time, it would happen at run time, the error I'm having is a compile error saying that the references are not defined, when they are defined in xmlwriter.h.

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Note that the error messages in your original post are linker errors, which gives you some clue as to where in the build process the problems are happening. If you're not sure about the difference between "compilation proper" and "linking", a quick Google should turn up some easy, fast reads on this.

    That make file rule only does "compilation proper", not linking. It only produces a .o file, so you only need `xml2-config --cflags` for that part, i.e. the -I part of Salem's post above.

    Presumably somewhere you have a rule that makes an executable from the .o files, i.e. the "linking" phase of the build. That is where you need to use `xml2-config --libs`. That's the -L and -l parts of Salem's post.

    I had to google xml2-config to find out exactly what it does and how it works. One of the first sites that came up is the FAQ for libxml2 (link), which has some suggestions for using xml2-config in a makefile.
    Last edited by anduril462; 10-16-2012 at 04:54 PM.

  8. #8
    Registered User
    Join Date
    Sep 2012
    Posts
    28
    Quote Originally Posted by anduril462 View Post
    Note that the error messages in your original post are linker errors, which gives you some clue as to where in the build process the problems are happening. If you're not sure about the difference between "compilation proper" and "linking", a quick Google should turn up some easy, fast reads on this.

    That make file rule only does "compilation proper", not linking. It only produces a .o file, so you only need `xml2-config --cflags` for that part, i.e. the -I part of Salem's post above.

    Presumably somewhere you have a rule that makes an executable from the .o files, i.e. the "linking" phase of the build. That is where you need to use `xml2-config --libs`. That's the -L and -l parts of Salem's post.

    I had to google xml2-config to find out exactly what it does and how it works. One of the first sites that came up is the FAQ for libxml2 (link), which has some suggestions for using xml2-config in a makefile.
    Thank you, you helped me figure out my problem, here's the relavant lines of my makefile now:
    Code:
    myapp: main.o config.o gui.o library.o
        gcc main.o config.o gui.o library.o -o ../myapp `xml2-config --libs` `pkg-config --libs gtk+-3.0`
        
    library.o: library.c library.h globalvars.h
        gcc -c `xml2-config --cflags` library.c -Wall
    I didn't realize all the --libs need to be in the compilation of all the .o files into the executable, and the --cflags need to be in the initial creation of the .o files.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Undefined reference to...
    By legendus in forum C Programming
    Replies: 19
    Last Post: 10-25-2009, 06:18 AM
  2. undefined reference to
    By shaun84 in forum C Programming
    Replies: 12
    Last Post: 10-15-2006, 02:32 AM
  3. undefined reference
    By B_Love in forum C++ Programming
    Replies: 6
    Last Post: 09-26-2005, 08:13 AM
  4. undefined reference
    By Axel in forum C Programming
    Replies: 16
    Last Post: 09-11-2005, 09:42 PM
  5. undefined reference
    By siubo in forum C Programming
    Replies: 1
    Last Post: 04-11-2003, 05:34 AM

Tags for this Thread