tl;dr add set(CMAKE_CXX_STANDARD_LIBRARIES "-lxml2" )
to CMakeLists.txt
(more infos below).
I want to run a very simple application within CLion. This application uses libxml2.
I use CLion 2018.1.2 on Ubuntu 18.04 LTS, libxml2-dev
is properly installed.
My project does compile with:
g++ -I /usr/include/libxml2 xmlTest.cpp -o xmlTest.exe -lxml2
it does not compile in CLion though, using this 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)
the compiler throws me:
/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'
my application (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;
}
after fiddling with libxml2 and CMake for hours now without success, I am open to any idea what to do to tell CMake libxml2
actually exists...
Update #1:
thanks to @vre's suggestion I updated my CMakeLists.txt
file:
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})
This did not change or resolve the error though.
Update #2 (solution):
this is how to build projects with libxml2
in 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)
My issue was that I had the wrong order of arguments in my CMAKE_CXX_FLAGS
. This article points this out. Using set(CMAKE_CXX_STANDARD_LIBRARIES "-lxml2" )
was the key (see this)
I hope this helps some future timetravelers:
The solution you came up with works but the intention of CMake
is to provide means to express a platform, compiler, and build tool independent way of describing projects. All the magic happens in the FindLibXml2.cmake
module. And a huge number of modules are delivered ready to use with your CMake
installation. See the modules directory under /usr/share/cmake-3.10/Modules
on Ubuntu 18.04
.
If you reformulate your CMakeLists.txt
the following way:
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})
you are able to work on a wide range of platforms and combinations of compilers and IDEs. This was tested on Ubuntu 18.04
with GCC 7.3
and Windows 10
with MSVC 15
. You need some more steps to build on Windows (i.e. installing and setup libxml2 and all of its dependencies). And this should work with CLion
too out of the box.