2

I am writing a C++ app for Windows using Code Blocks IDE. I am interested in using the following XML++ library: http://libxmlplusplus.sourceforge.net/

It requires libxml2 and glibmm-2.4 libraries. I downloaded the source for each of these libraries and included all of the headers into my project by right clicking on "Build Options" ==> "Search Directories" tab ==> "Compiler" tab. I specified the header include files there. I modified the main.cpp file using the source code from "examples/dom_parser" from the xml++/examples directory.

Now, I am having trouble with the following error message. I have never "linked" or used *.lib, *.dll files before... but I am now getting the following "undefined reference" error messages. Please let me know what I'd need to do in order to build this. Is there a particular file that I need to "link" and if so, where are these files located? I can't seem to find them in the source files that I extracted. Could you help with specific instructions on which files to include and which folders they might be located in? I am using the CodeBlocks IDE.

Could someone replicate the project on your Windows 64 bit PC and see if it is able to run correctly?

Thank you.

UPDATE

C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:44: undefined reference to `xmlpp::ContentNode::is_white_space() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:47: undefined reference to `xmlpp::Node::get_name() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:49: undefined reference to `Glib::ustring::empty() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:53: undefined reference to `xmlpp::Node::get_namespace_prefix() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:54: undefined reference to `Glib::ustring::empty() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:55: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:57: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:57: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:57: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:69: undefined reference to `xmlpp::ContentNode::get_content() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:69: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:69: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:74: undefined reference to `xmlpp::ContentNode::get_content() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:74: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:74: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:79: undefined reference to `xmlpp::ContentNode::get_content() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:79: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:79: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:87: undefined reference to `xmlpp::Node::get_line() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:90: undefined reference to `xmlpp::Element::get_attributes() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:96: undefined reference to `xmlpp::Node::get_namespace_prefix() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:97: undefined reference to `Glib::ustring::empty() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:98: undefined reference to `xmlpp::Attribute::get_value() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:98: undefined reference to `xmlpp::Attribute::get_name() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:98: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:98: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:98: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:98: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `xmlpp::Attribute::get_value() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `xmlpp::Attribute::get_name() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:100: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:101: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:103: undefined reference to `Glib::ustring::ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:103: undefined reference to `Glib::ustring::ustring(char const*)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:103: undefined reference to `xmlpp::Element::get_attribute(Glib::ustring const&, Glib::ustring const&) const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:103: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:103: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:106: undefined reference to `xmlpp::Attribute::get_value() const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:106: undefined reference to `Glib::operator<<(std::ostream&, Glib::ustring const&)'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:106: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:113: undefined reference to `Glib::ustring::ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:113: undefined reference to `xmlpp::Node::get_children(Glib::ustring const&) const'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:113: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:118: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:57: undefined reference to `Glib::ustring::~ustring()'
C:/Users/blah/Desktop/workspace/xmlpp/main.cpp:69: undefined reference to `Glib::ustring::~ustring()'

**UPDATED 02/11/2014 - at 10:45am **

Hi. Thanks for your suggestion. I ended up downloading the following ( http://ftp.gnome.org/pub/gnome/binaries/win32/gtkmm/2.22/ ) the entire gtkmm-win32-devel-2.22.0-2.exe and installed it onto my Windows PC in C:\gtkmm. Then, I modified my project by including the header files, library files, and bin files. Here are the screen shots:

enter image description here

enter image description here

enter image description here

enter image description here

After building, I am now seeing 0 errors and 0 warning messages. However, it appears to CRASH. I have no idea why. It seems that the gtk installation uses libxml++ version 2.6. This is fine. I downloaded the libxml++ 2.6 from the website to see the examples that they provided. I used the following source code in my main.cc. Do you know what is the problem?

// -*- C++ -*-

/* main.cc
 *
 * Copyright (C) 2002 The libxml++ development team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <libxml++/libxml++.h>

#include <iostream>

void print_indentation(unsigned int indentation)
{
  for(unsigned int i = 0; i < indentation; ++i)
    std::cout << " ";
}

void print_node(const xmlpp::Node* node, unsigned int indentation = 0)
{
  std::cout << std::endl; //Separate nodes by an empty line.

  const xmlpp::ContentNode* nodeContent = dynamic_cast<const xmlpp::ContentNode*>(node);
  const xmlpp::TextNode* nodeText = dynamic_cast<const xmlpp::TextNode*>(node);
  const xmlpp::CommentNode* nodeComment = dynamic_cast<const xmlpp::CommentNode*>(node);

  if(nodeText && nodeText->is_white_space()) //Let's ignore the indenting - you don't always want to do this.
    return;

  Glib::ustring nodename = node->get_name();

  if(!nodeText && !nodeComment && !nodename.empty()) //Let's not say "name: text".
  {
    print_indentation(indentation);
    std::cout << "Node name = " << node->get_name() << std::endl;
    std::cout << "Node name = " << nodename << std::endl;
  }
  else if(nodeText) //Let's say when it's text. - e.g. let's say what that white space is.
  {
    print_indentation(indentation);
    std::cout << "Text Node" << std::endl;
  }

  //Treat the various node types differently:
  if(nodeText)
  {
    print_indentation(indentation);
    std::cout << "text = \"" << nodeText->get_content() << "\"" << std::endl;
  }
  else if(nodeComment)
  {
    print_indentation(indentation);
    std::cout << "comment = " << nodeComment->get_content() << std::endl;
  }
  else if(nodeContent)
  {
    print_indentation(indentation);
    std::cout << "content = " << nodeContent->get_content() << std::endl;
  }
  else if(const xmlpp::Element* nodeElement = dynamic_cast<const xmlpp::Element*>(node))
  {
    //A normal Element node:

    //line() works only for ElementNodes.
    print_indentation(indentation);
    std::cout << "     line = " << node->get_line() << std::endl;

    //Print attributes:
    const xmlpp::Element::AttributeList& attributes = nodeElement->get_attributes();
    for(xmlpp::Element::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
    {
      const xmlpp::Attribute* attribute = *iter;
      print_indentation(indentation);
      std::cout << "  Attribute " << attribute->get_name() << " = " << attribute->get_value() << std::endl;
    }

    const xmlpp::Attribute* attribute = nodeElement->get_attribute("title");
    if(attribute)
    {
      std::cout << "title found: =" << attribute->get_value() << std::endl;

    }
  }

  if(!nodeContent)
  {
    //Recurse through child nodes:
    xmlpp::Node::NodeList list = node->get_children();
    for(xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
    {
      print_node(*iter, indentation + 2); //recursive
    }
  }
}

int main(int argc, char* argv[])
{
  Glib::ustring filepath;
  if(argc > 1 )
    filepath = argv[1]; //Allow the user to specify a different XML file to parse.
  else
    filepath = "example.xml";

  try
  {
    xmlpp::DomParser parser;
    parser.set_validate();
    parser.set_substitute_entities(); //We just want the text to be resolved/unescaped automatically.
    parser.parse_file(filepath);
    if(parser)
    {
      //Walk the tree:
      const xmlpp::Node* pNode = parser.get_document()->get_root_node(); //deleted by DomParser.
      print_node(pNode);
    }
  }
  catch(const std::exception& ex)
  {
    std::cout << "Exception caught: " << ex.what() << std::endl;
  }

  return 0;
}
code
  • 5,294
  • 16
  • 62
  • 113
  • Make sure you have installed and are linking to all required dependencies (libxml2, glibmm-2.4). – Aleph Feb 08 '14 at 12:37
  • I added each of the include/header files for (libxml++,libxml2, and glibmm-2.4) but i am now seeing "undefined reference" error messages. I cant seem to find the "library" / "linker" files for these libraries. Do you know the names of these files and the directories that they reside in? I updated my original post with the error messages – code Feb 10 '14 at 07:54

1 Answers1

2

Are libxml2 and glibmm-2.4 built?

You can find prebuilt windows binaries for libxml2 here. I can't find prebuilt windows binaries for glibmm, so you'll either have to download the entire gtkmm installer, or build it yourself.

After this process is done, you should have files such as

libxml2.lib
libxml2.a
libxml2.dll

Depending on you compiler (GCC or MSVC), and the desired linking method (static or dynamic), you should choose the required library files.

In Code::Blocks you do the linking via the "Linker settings" tab, accessible through Project -> Build options... -> Linker settings. Click add and select the previously compiled library files (libxml2, glibmm-2.4 and libxml++) using the folder browser.

Update: I am able to successfully run the project on my Windows 8 64-bit PC.

I have a MinGW-64 installation from MinGW-builds (GCC 4.8.1). The only other thing I had to download was the gtkmm-win64 installer. I chose the "full installation".

The search directories in the project build settings were:

C:\gtkmm64\include
C:\gtkmm64\include\libxml++-2.6
C:\gtkmm64\include\glibmm-2.4
C:\gtkmm64\include\glib-2.0
C:\gtkmm64\lib\glibmm-2.4\include
C:\gtkmm64\lib\glib-2.0\include
C:\gtkmm64\lib\libxml++-2.6\include

The import libraries to link to were:

C:\gtkmm64\lib\libxml++-2.6.dll.a
C:\gtkmm64\lib\libglibmm-2.4.dll.a
C:\gtkmm64\lib\libglibmm_generate_extra_defs-2.4.dll.a

And the DLL's copied to the executable's location from the gtkmm64\bin folder were:

libglib-2.0-0.dll
libglibmm-2.4-1.dll
libglibmm_generate_extra_defs-2.4-1.dll
libxml++-2.6-2.dll
libxml2-2.dll

The executable ran successfully (excluding the fact that the program terminated due to some parsing exception).

Avidan Borisov
  • 3,235
  • 4
  • 24
  • 27
  • Thanks for your suggestion. Please see my UPDATED post above. I added screen shots and my code. I downloaded the entire gtkmm installer and installed it onto my windows pc. It is now able to build with 0 errors and 0 warnings but I am now seeing it crash. Do you know what may be the problem? Are you able to replicate this? – code Feb 11 '14 at 18:53
  • It seems that it can't even execute the first line now: "Glib::ustring filepath;" – code Feb 11 '14 at 19:00
  • As far as I'm aware of, `.dll.a` files are *import libraries*, not *static libraries*. They don't contain the actual functions, just stubs which call the dynamic library's functions. Try to link to `libglibmm-2.4.a` and `libxml++-2.6.a` instead. – Avidan Borisov Feb 11 '14 at 19:19
  • Hi - the only files that appear in the gtkmm/lib/ directory appear to have the extension ".dll.a" I can't seem to find the "*.a" versions of them. Do you know where they reside or where I can get them? – code Feb 11 '14 at 19:22
  • I am using the latest version here (2.22.0-2.exe): http://ftp.gnome.org/pub/gnome/binaries/win32/gtkmm/2.22/ – code Feb 11 '14 at 19:24
  • Can you find it using some sort of a search tool? Can you find `.dll` files? If not, [I'll suggest you build the library yourself](https://github.com/GNOME/glibmm/blob/master/README.win32). You will want to remove the `--disable-static` part from the `./configure` command though. – Avidan Borisov Feb 11 '14 at 19:30
  • The .dll files are located in gtkmm/bin . There is libglib-2.0-0.dll, libglibmm-2.4-1.dll, libxml++-2.6-2.dll, libxml2-2.dll, etc in there. I put this path under Search Directories ==> Linker "C:\gtkmm\bin" as seen in the screenshot. But should these ".dll" be added to the "Link Libraries" ? In "Link Libraries", when adding, it only allows us to add *.a, *.so, *.lib, and *.dyl file types – code Feb 11 '14 at 19:34
  • I did a search for "libxml++-2.6.a" and "libglibmm-2.4.a" and they do not exist :( – code Feb 11 '14 at 19:39
  • If you do have the `.dll` files, try to copy them to the location of the executable and link against the import libraries (the `.dll.a` files) – Avidan Borisov Feb 11 '14 at 19:48
  • Hmm.. I copied over libglib-2.0-0.dll, libglibmm-2.4-1.dll, libxml++-2.6-2.dll, libxml2-2.dll into the project directory xmlpp\bin\Debug, where the "xmlpp.exe" resides. The "Link Libraries" from the screenshot in my post has "libglibmm-2.4.dll.a", "libxml++-2.6.dll.a", "libxml2.dll.a", "libxml2.lib", "libglib-2.0.dll.a" and "glib-2.0.lib". Hm, it is still crashing :( – code Feb 11 '14 at 20:21
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/47261/discussion-between-user1456962-and-avidanborisov) – code Feb 11 '14 at 20:21
  • Hi avi thank you so much for your help. I am still having issues whether using 32 bit gtkmm or 64 bit gtkmm. I have included all of the libs, dlls, and included header files. It is able to build and compile, but it seems to crash every time it is executed. I've placed all the dll's listed from DependencyWalker into the executable's directory and it is still unable to run. By any chance, could you try to replicate the project using CodeBlocks on a 64bit Windows machine with the source code I used in the post and the gtkmm library? I am stumped by this. – code Feb 11 '14 at 23:52
  • Ah I replicated the same settings exactly and the same order using Windows 7 64 bit and gtkmm 64 bit. I am really confused why it doesn't work. Anyway, thank you for your help avi. – code Feb 12 '14 at 19:10
  • @user1456962 were you able to finally get this to work..I am also stuck with the same problem and unable to get this to work!! – markiv May 06 '14 at 15:29
  • @user1456962 The compilation goes through fine but I get the `[myapp.exe] has stopped working` popup message and the exe crashes. – markiv May 06 '14 at 16:14