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

使用此CMakeLists.txt,它不会在CLion中编译:
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)

我希望这对将来的旅行者有所帮助:

最佳答案

您想出的解决方案是可行的,但是CMake的目的是提供表示平台,编译器和构建工具的独立项目描述方式。所有的魔术都发生在FindLibXml2.cmake模块中。交付了许多模块,可与CMake安装一起使用。请参阅/usr/share/cmake-3.10/ModulesUbuntu 18.04下的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.3上对Windows 10MSVC 15进行了测试。您需要执行更多步骤才能在Windows上进行构建(即,安装和设置libxml2及其所有依赖项)。而且这个应该也可以与CLion一起使用。

关于c++ - CMake无法在CLion中链接libxml2,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50353167/

10-13 08:09