CMake не может связать libxml2 в CLion

tl; dr добавить set(CMAKE_CXX_STANDARD_LIBRARIES "-lxml2" ) в CMakeLists.txt (более подробная информация ниже).


Я хочу запустить очень простое приложение в CLion. Это приложение использует libxml2.

Я использую CLion 2018.1.2 на Ubuntu 18.04 LTS, 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 (решение):

вот как создавать проекты с libxml2 в 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")
set(CMAKE_CXX_STANDARD_LIBRARIES "-lxml2" )

add_executable (xmlTest.exe xmlTest.cpp)

Моя проблема заключалась в том, что у меня был неправильный порядок аргументов в моем CMAKE_CXX_FLAGS. эта статья указывает на это. Использование set(CMAKE_CXX_STANDARD_LIBRARIES "-lxml2" ) было ключевым (посмотри это)

Надеюсь, это поможет некоторым будущим путешественникам во времени:

Возможный дубликат Как добавить флаг компилятора "-l" (ell) в CMake

Tsyvarev 15.05.2018 16:54

CFLAGS против LDFLAGS

Joseph D. 15.05.2018 16:55

Спасибо за информацию. Любое конкретное предложение, что я должен добавить к моему CMakeLists.txt как target_link_libraries(<...>), здесь не подходит, потому что я хочу использовать библиотеку, а не собирать ее.

Flatron 15.05.2018 17:10

Технически этот set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -I/usr/include/libxml2 -lxml2 -lz -lm") должен добавить все, что мне нужно.

Flatron 15.05.2018 17:12

Вам не нужно собирать 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.

vre 15.05.2018 17:20

@vre Я добавил ваше предложение, но это не решает проблемы. (см. «Обновление».

Flatron 15.05.2018 17:30

Можете ли вы вывести содержимое ${LibXml2_LIBRARIES} с помощью message(STATUS "libmxl2 ${LibXml2_LIBRARIES}")? А вы удалили файл CMakeCache.txt перед внесением предложенных изменений?

vre 15.05.2018 17:41

Имена переменных имеют неправильный регистр, должны быть LIBXML2_LIBRARIES, LIBXML2_INCLUDE_DIR соответственно. LIBXML2_DEFINITIONS пуст.

Botje 15.05.2018 17:43

Ах вот почему. Я смешал его. Поэтому, пожалуйста, используйте упомянутые имена переменных @Botje и удалите весь вызов target_compile_definitions. Кстати, это LIBXML2_INCLUDE_DIRS. LIBXML2_INCLUDE_DIR используется для поиска пакета libxml2.

vre 15.05.2018 17:44

спасибо за вашу помощь, я нашел решение: set(CMAKE_CXX_STANDARD_LIBRARIES "-lxml2" ). Обновил мой вопрос для будущих путешественников во времени.

Flatron 15.05.2018 17:50
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
10
977
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решение, которое вы придумали, работает, но цель CMake - предоставить средства для выражения независимого от платформы, компилятора и инструмента построения способа описания проектов. Вся магия происходит в модуле FindLibXml2.cmake. И огромное количество модулей поставляется готовыми к использованию с вашей установкой CMake. См. Каталог модулей в /usr/share/cmake-3.10/Modules на Ubuntu 18.04.

Если вы переформулируете 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.04 с GCC 7.3 и Windows 10 с MSVC 15. Вам потребуется еще несколько шагов для сборки в Windows (например, установка и настройка libxml2 и всех его зависимостей). И этот должен работает и с CLion из коробки.

Отлично, это тоже работает, и я использую это решение сейчас. Спасибо, что разъяснили, для чего нужен CMake. Я исхожу из пустых файлов make и просто попадаю в CMake. Спасибо!

Flatron 15.05.2018 21:16

Другие вопросы по теме