【问题标题】:C++/CMake can't find libxml++C++/CMake 找不到 libxml++
【发布时间】:2020-12-24 04:38:21
【问题描述】:

我是一名 Java/Go/Python 开发人员,我试图用 C++ 工具链弄湿我的脚,并且很难强迫 CMake 找到依赖项。我使用apt-get install libxml++2.6-dev 在Debian 上安装了libxml++,并将它安装到/usr/include/libxml++2.6/libxml++。这是一个问题,因为这不是相对于/usr/include 的正确路径——如果我尝试#include <libxml++/libxml++.h> 它显然无法找到它,并且如果我包含诸如#include <libxml++2.6/libxml++/whatever.h> 然后whatever.h 将无法找到搜索libxml++ 路径的其他头文件,例如#include <libxml++/version.h>。库附带了 pkg-config 文件,但我真的不知道如何处理它们,并且使用 find_package(LibXml++)include_directories(${LibXml++_INCLUDE_DIRS}) 之类的东西不起作用。

查看 CMake 文档,似乎有几种方法可以解决每个简单的问题,如果这与 apt-get 安装东西的方式有关,我觉得这一定是一个非常简单的问题,有一个简单的解决方案。有什么我可以添加的东西来强制 CMake 在 /usr/include/[something]/libxml++ 中特别查看并仍然使用相对路径正确导入它,还是我每次使用 apt 安装时都需要移动东西?

抱歉,如果这是重复的,但是“libxml++”对 Google 来说是一个非常困难的库,因为“++”标点符号以及它显然没有像常规 libxml2 那样使用任何地方。我很高兴阅读更多基本资源,但不想通过 30 年的 C++ 演变来得出答案。

供参考:

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})

源文件:

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

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

错误信息:

[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

【问题讨论】:

  • 不确定您使用的是哪个确切版本的 CMake,但您是否尝试过简单地链接到 LibXml2::LibXml2 导入的 CMake 目标(请参阅 here)?

标签: c++ cmake libxml2


【解决方案1】:

LibXml2 和 LibXml2++ 是不同的库,因此其中一个的find_package() - LibXml2 - 对另一个没有帮助。

CMake 不附带 LibXml2++ 的“查找”脚本,但由于您有库的 .pc 文件,因此使用它非常简单:

# 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)

注意,pkg_check_modules 调用 (LIBXMLXX) 的第一个参数仅表示您要创建的 IMPORTED 目标的名称。您可以根据需要指定任何名称。

但是pkg_check_modules 调用的最后一个参数(libxml++-2.6)是包的名称,它应该与.pc 文件的基本名称完全匹配。由于you have 文件libxml++-2.6.pc,所以libxml++-2.6 应该用作pkg_check_modules 的最后一个参数。

有关在 CMake 中使用 pkg-config 的更多详细信息,请参阅 that question

【讨论】:

    【解决方案2】:

    您可能应该将此行添加到您的 CMakeLists.txt 中:

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

    (或使用任何宏来达到这个结果)

    然后在你的主要:

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

    另一种方法:

    如果它不能解决您的问题,您也可以尝试转到 libxml++ 页面:https://developer.gnome.org/libxml++-tutorial/stable/chapter-introduction.html

    这里有一个下载 libxml++ 的链接。

    然后您只需按照文件调用 INSTALL 中的说明,并添加包含目录:

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

    并在编译器搜索 lib 时为您的编译器添加一个新的库路径

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

    希望对你有帮助

    【讨论】:

      【解决方案3】:

      通过合并两个答案,我设法解决了明显相同的问题(在带有 g++9 的 Ubuntu 20.04 上)。可能会应用一些版本更改

      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)
      

      main.cpp 来源

      #include <libxml++/libxml++.h>
      int main() { return 0; }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-03
        • 2012-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-15
        相关资源
        最近更新 更多