Reputation: 1385
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:
Upvotes: 2
Views: 1568
Reputation: 6744
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.
Upvotes: 3