skip to Main Content

I’m a Java/Go/Python dev trying to get my feet wet with the C++ toolchain and having a hard time forcing CMake to find dependencies. I installed libxml++ on Debian using apt-get install libxml++2.6-dev and it installed it to /usr/include/libxml++2.6/libxml++. This is a problem, because that’s not the right path relative to /usr/include–if I try to #include <libxml++/libxml++.h> it can’t find it obviously, and if I include stuff as e.g. #include <libxml++2.6/libxml++/whatever.h> then whatever.h will be unable to find other header files searching for the libxml++ path, e.g. #include <libxml++/version.h>. There are pkg-config files that come with the library but I couldn’t really figure out what to do with them, and using stuff like find_package(LibXml++) or include_directories(${LibXml++_INCLUDE_DIRS}) didn’t work.

Looking at the CMake docs there appear to be several ways to solve every simple problem, and I feel like this must be a very simple problem with a simple solution if this is related to the way apt-get installs things. Is there something I can add to force CMake to look specifically in /usr/include/[something]/libxml++ and still import it properly with relative paths, or do I need to just move stuff every time I install it with apt?

Apologies if this is a duplicate, but "libxml++" is an incredibly difficult library to Google, both because of the "++" punctuation and the fact that it’s apparently not used anywhere near as much as regular libxml2. I’m happy to read more basic resources but would rather not slog through 30 years of the evolution of C++ to arrive at the answer.

For reference:

CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)
project(sandbox)

set(CMAKE_CXX_STANDARD 17)

find_package(Boost REQUIRED)
find_package(LibXml2 REQUIRED)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ ${LIBXML2_INCLUDE_DIR})
add_executable(sandbox main.cpp)
target_link_libraries(sandbox ${LIBXML2_LIBRARIES})

Source file:

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

int main() {
    std::cout << "hello" << std::endl;
}

Error msg:

[main] Building folder: cpp-sandbox 
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /workspaces/cpp-sandbox/build --config Debug --target all -- -j 6
[build] Scanning dependencies of target sandbox
[build] [ 50%] Building CXX object CMakeFiles/sandbox.dir/main.cpp.o
[build] In file included from /workspaces/cpp-sandbox/main.cpp:2:
[build] /usr/include/libxml++-2.6/libxml++/libxml++.h:50:10: fatal error: libxml++/exceptions/internal_error.h: No such file or directory
[build]  #include <libxml++/exceptions/internal_error.h>
[build]           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[build] compilation terminated.
[build] make[2]: *** [CMakeFiles/sandbox.dir/build.make:63: CMakeFiles/sandbox.dir/main.cpp.o] Error 1
[build] make[1]: *** [CMakeFiles/Makefile2:73: CMakeFiles/sandbox.dir/all] Error 2
[build] make: *** [Makefile:84: all] Error 2
[build] Build finished with exit code 2

3

Answers


  1. You may should add this line to your CMakeLists.txt :

    include_directories("/usr/include/libxml++2.6/")
    

    ( or use any macro to achieve to this result )

    then in your main :

    #include <iostream>
    #include <libxml++/libxml++.h> // <= like this
    
    int main() {
        std::cout << "hello" << std::endl;
    }
    

    Another way to do :

    If it do not fix your problem you can also try to go to the libxml++ page : https://developer.gnome.org/libxml++-tutorial/stable/chapter-introduction.html .

    Here you have a link to download libxml++.

    Then you just have to follow the instruction in the file call INSTALL, and add the include directory with :

    include_directories("<your-path/libxml++2.6>")
    

    and add a new library path for your compilator when it search lib with

    link_directories("<your-other-path>/lib")
    

    Hoping it help you

    Login or Signup to reply.
  2. LibXml2 and LibXml2++ are different libraries, so find_package() for one of them – LibXml2 – won’t help with another.

    CMake isn’t shipped with "Find" script for LibXml2++, but since you have .pc file for the library, using it is quite simple:

    # Search pkg-config utility first
    find_package(PkgConfig REQUIRED)
    # Then use pkg-config for locate specific package
    pkg_check_modules(LIBXMLXX REQUIRED IMPORTED_TARGET libxml++-2.6)
    
    add_executable(sandbox main.cpp)
    
    # Link with the IMPORTED target created by 'pkg_check_modules'
    # That target contains both include directories and actual libraries for link.
    target_link_libraries(sandbox PkgConfig::LIBXMLXX)
    

    Note, that first parameter for pkg_check_modules call (LIBXMLXX) just denotes the name of the IMPORTED target you want to create. You can specify any name, as you wish.

    But the last parameter for pkg_check_modules call (libxml++-2.6) is the name of the package, it should exactly match to the base name of .pc file. Since you have file libxml++-2.6.pc, exactly libxml++-2.6 should be used as the last parameter for pkg_check_modules.

    See that question for more details about using pkg-config with CMake.

    Login or Signup to reply.
  3. I’ve managed to solve the apparently same problem (on Ubuntu 20.04 with g++9) by merging the two answers. Some version change may apply

    cmake_minimum_required (VERSION 3.10)
    project (sandbox)
    find_package (LibXml2 REQUIRED)
    find_package (PkgConfig REQUIRED)
    pkg_check_modules (LIBXMLXX REQUIRED IMPORTED_TARGET libxml++-2.6)
    include_directories (${LIBXML2_INCLUDE_DIR})
    include_directories ("/usr/include/libxml++2.6/")
    add_executable (sandbox main.cpp)
    target_link_libraries (sandbox ${LIBXML2_LIBRARIES} PkgConfig::LIBXMLXX)
    

    And with main.cpp source

    #include <libxml++/libxml++.h>
    int main() { return 0; }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search