【问题标题】:CMake unable to link libxml2 in CLionCMake 无法在 CLion 中链接 libxml2
【发布时间】:2018-10-25 11:06:00
【问题描述】:

tl;dr 将 set(CMAKE_CXX_STANDARD_LIBRARIES "-lxml2" ) 添加到 CMakeLists.txt(更多信息如下)。


我想在 CLion 中运行一个非常简单的应用程序。此应用程序使用 libxml2。

我在 Ubuntu 18.04 LTS 上使用 CLion 2018.1.2,libxml2-dev 已正确安装。

我的项目确实编译:

g++ -I /usr/include/libxml2 xmlTest.cpp -o xmlTest.exe -lxml2

虽然它不能在 CLion 中编译,但使用 CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)
project(xmlTest)

set(CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -I/usr/include/libxml2 -lxml2 -lz -lm")

include_directories( /usr/local/include/libxml2 )

add_executable (xmlTest.exe xmlTest.cpp)

编译器抛出了我:

/home/xxxx/.local/share/JetBrains/Toolbox/apps/CLion/ch-0/181.4668.70/bin/cmake/bin/cmake --build /home/xxxx/src/cmake-build-debug --target xmlTest.exe -- -I /usr/include/libxml2 -lxml2
Scanning dependencies of target xmlTest.exe
[ 50%] Building CXX object CMakeFiles/xmlTest.exe.dir/xmlTest.cpp.o
[100%] Linking CXX executable xmlTest.exe
CMakeFiles/xmlTest.exe.dir/xmlTest.cpp.o: In function `main':
/home/xxxx/src/xmlTest.cpp:10: undefined reference to `xmlReadFile'
/home/xxxx/src/xmlTest.cpp:17: undefined reference to `xmlDocGetRootElement'
/home/xxxx/src/xmlTest.cpp:21: undefined reference to `xmlFreeDoc'
/home/xxxx/src/xmlTest.cpp:25: undefined reference to `xmlStrcmp'
/home/xxxx/src/xmlTest.cpp:27: undefined reference to `xmlFreeDoc'

我的申请 (xmlTest.cpp):

#include <stdlib.h>
#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>

int main(int argc, char const *argv[]) {
  xmlDocPtr doc;
  xmlNodePtr cur;

  doc = xmlReadFile(argv[1], NULL, 0);

  if (doc == NULL ) {
    fprintf(stderr,"Document not parsed successfully. \n");
    return 1;
  }

  cur = xmlDocGetRootElement(doc);

  if (cur == NULL) {
    fprintf(stderr,"empty document\n");
    xmlFreeDoc(doc);
    return 1;
  }

  if (xmlStrcmp(cur->name, (const xmlChar *) "users")) {
    fprintf(stderr,"document of the wrong type, root node != story");
    xmlFreeDoc(doc);
    return 1;
  }

  return 0;
}

在摆弄 libxml2 和 CMake 几个小时而没有成功之后,我愿意知道该怎么做才能告诉 CMake libxml2 确实存在...


更新 #1:

感谢@vre 的建议,我更新了我的CMakeLists.txt 文件:

cmake_minimum_required(VERSION 3.10)
project(xmlTest)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -I/usr/include/libxml2 -lxml2 -lz -lm")
set(CMAKE_CXX "/usr/local/include/libxml2")
find_library(libxml2 libxml2)
link_directories(/usr/local/include/libxml2)
add_compile_options("-I/usr/include/libxml2 -lxml2 -lz -lm")
find_package(LibXml2 REQUIRED)
add_executable (xmlTest.exe xmlTest.cpp)
target_compile_definitions(xmlTest.exe PUBLIC ${LibXml2_DEFINITIONS})
target_include_directories(xmlTest.exe PUBLIC ${LibXml2_INCLUDE_DIRS})
target_link_libraries(xmlTest.exe ${LibXml2_LIBRARIES})

但这并没有改变或解决错误。

更新 #2(解决方案):

这是在 CLion 中使用libxml2 构建项目的方法:

cmake_minimum_required(VERSION 3.10)
project(xmlTest)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -I/usr/include/libxml2")
set(CMAKE_CXX_STANDARD_LIBRARIES "-lxml2" )

add_executable (xmlTest.exe xmlTest.cpp)

我的问题是我在CMAKE_CXX_FLAGS 中的参数顺序错误。 This article 指出了这一点。使用 set(CMAKE_CXX_STANDARD_LIBRARIES "-lxml2" ) 是关键 (see this)

我希望这对未来的时间旅行者有所帮助:

【问题讨论】:

  • CFLAGS 与 LDFLAGS
  • 感谢您提供的信息。任何我应该添加到我的CMakeLists.txttarget_link_libraries(&lt;...&gt;) 的具体建议都不适合这里,因为我想使用一个库而不是构建它。
  • 从技术上讲,set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -I/usr/include/libxml2 -lxml2 -lz -lm") 应该添加我需要的所有内容。
  • 你不需要自己构建libxml2来使用target_link_libaries。我会使用现代 CMake 方式并按顺序将find_package(LibXml2 REQUIRED) add_executable(xmlTest.exe xmlTest.cpp) target_compile_definitions(xmlTest.exe ${LibXml2_DEFINITIONS}) target_include_directories(xmlTest.exe ${LibXml2_INCLUDE_DIRS}) target_link_libraries(xmlTest.exe ${LibXml2_LIBRARIES}) 添加到CMakeLists.txt

标签: c++ cmake libxml2 clion


【解决方案1】:

您提出的解决方案可行,但CMake 的目的是提供一种表示平台、编译器和构建工具独立于描述项目的方式的方法。所有的魔法都发生在FindLibXml2.cmake 模块中。大量模块已交付,可与您的CMake 安装一起使用。在Ubuntu 18.04 上查看/usr/share/cmake-3.10/Modules 下的模块目录。

如果您按照以下方式重新定义您的 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)

project(xmlTest)

set(CMAKE_CXX_STANDARD 11)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
elseif(MSVC)
  # add options for Visual C/C++ Compiler here
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()    

find_package(LibXml2 REQUIRED)

add_executable(xmlTest.exe xmlTest.cpp)

target_compile_definitions(xmlTest.exe PUBLIC ${LIBXML2_DEFINITIONS})
target_include_directories(xmlTest.exe PUBLIC ${LIBXML2_INCLUDE_DIRS})
target_link_libraries(xmlTest.exe ${LIBXML2_LIBRARIES})

您可以在各种平台以及编译器和 IDE 的组合上工作。这是在Ubuntu 18.04GCC 7.3Windows 10MSVC 15 上测试的。您需要更多步骤才能在 Windows 上构建(即安装和设置 libxml2 及其所有依赖项)。而且这个应该也可以与CLion一起使用。

【讨论】:

  • 太好了,这也有效,是我现在使用的解决方案。感谢您阐明 CMake 的用途。 我来自纯 make 文件,刚刚进入 CMake。 谢谢!
猜你喜欢
  • 2021-10-30
  • 2017-04-22
  • 2020-06-17
  • 1970-01-01
  • 1970-01-01
  • 2018-08-18
  • 1970-01-01
  • 2019-09-05
  • 1970-01-01
相关资源
最近更新 更多