c++cmakerapidjson

Unable to include rapidjson in my C++ project


So i have a project directory structure as below

Application
-Utils
 -Transport
  -include
   -Foo.h
  -src
   Foo.cpp
   CMakelists.txt(a)
 -CMakeLists.txt(b)
-third_party
 -argparse
 -rapidjson ( new added)
  -bin
  -include
  ...
  -CMakeLists.txt
 -CMakeLists.txt(c)

CMakelists.txt(a) looks like below

add_library(${PROJECT_NAME}
    Foo.cpp
)

target_include_directories(${PROJECT_NAME}
    PUBLIC
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

target_link_libraries(${PROJECT_NAME}
    PUBLIC
    ...
    CURL::libcurl
    RapidJSON <--newly added
)

CMakelists.txt(b) looks like

project(Transport LANGUAGES CXX)

add_subdirectory("src")

and CMakelists.txt(c) looks like below

add_subdirectory(argparse)
add_subdirectory(rapidjson) <--newly added

Plesae note that my application was compiling before i added rapidjson but since there was a necessity to add rapidjson, i added it and since rapidjson is also a header only library like argparse, i copied it under the third-party folder , added the subdirectory for rapidjson and than added a link dependency on RapidJSON. But when i try to include

#include "rapidjson/document.h"

in Foo.cpp i get the error

fatal error: 'rapidjson/document.h' file not found
    1 | #include "rapidjson/document.h"
      |          ^~~~~~~~~~~~~~~~~~~~~~

Is my understanding correct that since rapidjson is header only library , its CMakelist.txt will create an interface target RapidJSON that i can include in other targets of my project that require rapidjson and since as per https://github.com/Tencent/rapidjson/blob/v1.1.0/CMakeLists.txt#L107 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) than #include "rapidjson/document.h" seems correct to me.

Please note that although i do not think it is necessary but i did tried to include find_package(RapidJSON) in the root CMakelists.txt to see whether that will fix this issue but gives error

CMake Error at cmake-build-debug/third_party/rapidjson/RapidJSONConfig.cmake:3 (include):
  include could not find requested file:

Any pointers on what i am missing here or what assumption are incorrect would be greatly appreciated.

---Update Minimal Reproducible example---

project structure

minimal
-thirdparty
 -argparse ( downloaded files from https://github.com/p-ranav/argparse)
 -rapidjson( downloaded files from https://github.com/Tencent/rapidjson/)
 -CMakelists.txt(a)
-main.cpp
-CMakelists.txt(b)

CMakelists.txt(a)

add_subdirectory(argparse)
add_subdirectory(rapidjson)

CMakelists.txt(b)

cmake_minimum_required(VERSION 3.27)
project(minimal)

add_subdirectory(third_party)

set(CMAKE_CXX_STANDARD 17)

add_executable(minimal main.cpp)

target_link_libraries(minimal
    PUBLIC
    argparse
    RapidJSON
)

main.cpp

#include <iostream>
#include <argparse/argparse.hpp>
#include "rapidjson/document.h"

int main() {
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

error

/Users/foo/CLionProjects/minimal/main.cpp:3:10: fatal error: 'rapidjson/document.h' file not found
    3 | #include "rapidjson/document.h"
      |          ^~~~~~~~~~~~~~~~~~~~~~
1 error generated.

Both argparse and rapidjson are header only libs but seems like for some reason when i include CMakelists.txt from argparse, it is able to find the files but that is not the case for rapidjson.


Solution

  • RapidJSON lists include directories only for install interface. You can add build interface includes yourself as needed:

    add_subdirectory(rapidjson)
    target_include_directories(RapidJSON SYSTEM INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/rapidjson/include>)
    

    Alternatively, as per the documentation you can simply copy the include directory of the library to your project's source tree:

    RapidJSON is a header-only C++ library. Just copy the include/rapidjson folder to system or project's include path.