1

I want to add RapidXML to my CMake Project, so i can use it. My Project Structure looks like this:

Root
|
|_inc (for my own Headers)
|    |_main.h
|    |_CMakeList.txt
|_src (for my own Sources)
|    |_main.cpp
|    |_CMakeList.txt
|_libs (for third party libs)
|     |_rapidxml
|     |_CMakeList.txt
|_CMakeList.txt

Can someone help me? Thanks in advance!

arrowd
  • 33,231
  • 8
  • 79
  • 110
Limatuz
  • 666
  • 2
  • 6
  • 12

2 Answers2

1

RapidXML is actually a header-only library, so you don't need to add it to CMake - just #include <rapidxml/rapidxml.hpp>. However, you can do it "properly" and in a portable way using CMake's find_package() function. It's not easier though!

Firstly, create a cmake folder in your project directory somewhere - this can be used for other libraries that don't have built-in CMake modules, too. Add it to your module path by putting this line somewhere near the top of your CMakeLists.txt:

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")

Within that folder, create a file called FindRapidXML.cmake and give it the following contents:

#
# Search and find the RapidXML library
#

# Search for the include path
find_path(
  RapidXML_INCLUDE_DIR
  NAMES
    rapidxml.hpp
    rapidxml_utils.hpp
    rapidxml_iterators.hpp
    rapidxml_print.hpp
  HINTS "${RapidXML_ROOT_DIR}"
  PATH_SUFFIXES include rapidxml
)

# If we find the library, add it as a target
if (RapidXML_INCLUDE_DIR)
  set(RapidXML_FOUND TRUE)

  # Pull the version number out of the header
  message(DEBUG "Pulling version from ${RapidXML_INCLUDE_DIR}/rapidxml.hpp")
  file(STRINGS "${RapidXML_INCLUDE_DIR}/rapidxml.hpp"
    RapidXML_VERSION REGEX "^//[ ]*Version[ ]+[0-9]+\.[0-9]+[ ]*$")
  string(REGEX REPLACE "^//[ ]*Version[ ]+([0-9]+)\.([0-9]+)[ ]*$" "\\1\.\\2" RapidXML_VERSION "${RapidXML_VERSION}")
  
  # Print a message that we found it
  if (NOT RapidXML_FIND_QUIETLY)
    message(STATUS "Found RapidXML (found version \"${RapidXML_VERSION}\")")
  endif (NOT RapidXML_FIND_QUIETLY)

  # Create a target for it, if there isn't one already created
  if (NOT TARGET RapidXML::RapidXML)
    add_library(RapidXML::RapidXML INTERFACE IMPORTED)
    set_target_properties(RapidXML::RapidXML PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${RapidXML_INCLUDE_DIR}")
  endif (NOT TARGET RapidXML::RapidXML)
else ()
  # If we don't find the library, fail as appropriate
  if (RapidXML_FIND_REQUIRED)  
    message(FATAL_ERROR "RapidXML was NOT found")
  elseif (NOT RapidXML_FIND_QUIETLY)
    message(STATUS "RapidXML was NOT found")
  endif (RapidXML_FIND_REQUIRED)
endif (RapidXML_INCLUDE_DIR)

# Hide the variables that we set
mark_as_advanced(RapidXML_INCLUDE_DIR)

Then, you can import RapidXML into your project with one simple line:

find_package(RapidXML REQUIRED)

And you can include it in a target like so:

target_link_libraries(<target> PRIVATE RapidXML::RapidXML)

The beauty of this is that you can use the options from find_package() to have it required or not, so you get an earlier failure if it's not found. The FindRapidXML.cmake file is also reusable in other projects, the loic to find it is kept out of your main cmake file, and if it's installed into non-standard locations you can hint to where it is using HINTS <path> as you would with any other package.

Ed R
  • 91
  • 1
  • 6
0

I found a Solution myself. :) In the /Root/libs/CMakeList.txt I added the following lines:

add_subdirectory(rapidxml)
add_library(rapidxml INTERFACE)
target_include_directories(rapidxml INTERFACE rapidxml/ )

if there is a better solution I am happy to hear!

Limatuz
  • 666
  • 2
  • 6
  • 12