how to writing a cmake Module for jsoncpp?

匿名 (未验证) 提交于 2019-12-03 08:46:08

问题:

I want to use jsoncpp for writing a C++ code in order to parse a JSON file. Let me explain what I did. I created a CMakeLists.txt and I made a FindJsoncpp.cmake along with a simple c++ file to test jsoncpp. When I compile the C++ source without cmake using -I/usr/include/jsoncpp/ -ljsoncpp it works fine. but when I try to build it using cmake it cannot find json.h header file that I included in my c++ source code.

here is my CMakeLists.txt:

cmake_minimum_required (VERSION 2.6) project (Parser)  set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")  include(LibFindMacros)  message("----------- trying to find Jsoncpp-------------") find_package(Jsoncpp)  if(Jsoncpp_FOUND)     message("INFO: we found LibJsoncpp on your pc.")     message(Jsoncpp_FOUND = ${Jsoncpp_FOUND})     message(Jsoncpp_INCLUDE_DIR = ${Jsoncpp_INCLUDE_DIR})      message(Jsoncpp_LIBRARY = ${Jsoncpp_LIBRARY}) else(Jsoncpp_FOUND)     message("WARNING: we couldn't find LibJsoncpp on your pc. DLC is disabled.") endif(Jsoncpp_FOUND)  #set(LIBS ${Jsoncpp_LIBRARY})  # Set the include dir variables and the libraries and let libfind_process do the rest. # NOTE: Singular variables for this library, plural for libraries this this lib depends on. set(Jsoncpp_PROCESS_INCLUDES Jsoncpp_INCLUDE_DIR) set(Jsoncpp_PROCESS_LIBS Jsoncpp_LIBRARY)  # add the executable add_executable(jsonparser jsonparser.cpp) 

And this is the FindJsoncpp.cmake that I wrote:

# - Try to find Jsoncpp # Once done, this will define # #  Jsoncpp_FOUND - system has Jsoncpp #  Jsoncpp_INCLUDE_DIRS - the Jsoncpp include directories #  Jsoncpp_LIBRARIES - link these to use Jsoncpp  include(LibFindMacros)  # Use pkg-config to get hints about paths libfind_pkg_check_modules(Jsoncpp_PKGCONF jsoncpp)  # Include dir find_path(Jsoncpp_INCLUDE_DIR   NAMES json/json.h #  PATHS ./jsoncpp/   PATHS ${Jsoncpp_PKGCONF_INCLUDE_DIRS} # /usr/include/jsoncpp/json )  # Finally the library itself find_library(Jsoncpp_LIBRARY   NAMES jsoncpp   PATHS ${Jsoncpp_PKGCONF_LIBRARY_DIRS} #  PATH ./jsoncpp/ )  set(Jsoncpp_PROCESS_INCLUDES Jsoncpp_INCLUDE_DIR) set(Jsoncpp_PROCESS_LIBS Jsoncpp_LIBRARY) libfind_process(Jsoncpp) 

And finally a simple C++ code called jsonparser.cpp to test it:

#include <iostream> #include <fstream> #include <json/json.h> using namespace std;  void printSongInfo(Json::Value song){     std::clog<<"\n-----------printing a song-------------\n";     std::clog<<"Name="<<song["name"];     std::clog<<"Artist="<<song["artist"]; }  int main(){      std::ifstream catalogFile("catalog.json");      Json::Value root;   // will contains the root value after parsing.     Json::Reader reader;     bool parsingSuccessful = reader.parse( catalogFile, root );     if ( !parsingSuccessful ){         // report to the user the failure and their locations in the document.         std::cout  << "Failed to parse configuration\n"                    << reader.getFormattedErrorMessages();         return 1;     }      //parsing songs     const Json::Value songs = root["songs"];     for ( int index = 0; index < songs.size(); ++index ){  // Iterates over the sequence elements.        printSongInfo(songs[index] );     }     return 0; } 

When I run the jsonparser.cpp with below command it works just fine.

g++ -I/usr/include/jsoncpp/ -ljsoncpp jsonparser.cpp 

but when I try to make it using cmake I get this error:

$~/jsoncppTest/build$ cmake .. -- The C compiler identification is GNU 4.7.3 -- The CXX compiler identification is GNU 4.7.3 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done ----------- trying to find Jsoncpp------------- -- Found PkgConfig: /usr/bin/pkg-config (found version "0.26")  -- checking for module 'jsoncpp' --   found jsoncpp, version 0.6.0 -- Found Jsoncpp  INFO: we found LibJsoncpp on your pc. Jsoncpp_FOUND=TRUE Jsoncpp_INCLUDE_DIR=/usr/include/jsoncpp Jsoncpp_LIBRARY=/usr/lib/libjsoncpp.so -- Configuring done -- Generating done -- Build files have been written to: ~/jsoncppTest/build $~/jsoncppTest/build$ make Scanning dependencies of target jsonparser [100%] Building CXX object CMakeFiles/jsonparser.dir/jsonparser.cpp.o ~/jsoncppTest/jsonparser.cpp:3:23: fatal error: json/json.h: No such file or directory compilation terminated. make[2]: *** [CMakeFiles/jsonparser.dir/jsonparser.cpp.o] Error 1 make[1]: *** [CMakeFiles/jsonparser.dir/all] Error 2 make: *** [all] Error 2 

It cannot find json/json.h header file but it has founded the jsoncpp library in cmake before. I checked jsoncpp.pc file and found ti OK. I don't know what I am doing wrong! any help would be appreciated.

I am using ubuntu 13.04 with multiarch support. I heard something about jsoncpp problem with 64bit compiler but don't know if that's the case.

回答1:

Ok, I have a solution that compiles fine on my system. Finding jsoncpp is tricky, because json-c installs a header with the same name, and on my system, that header is located under /usr/include/json/json.h. To get it work, you have to make the following changes:


in FindJsoncpp.cmake:

# Include dir find_path(Jsoncpp_INCLUDE_DIR   NAMES json/features.h   PATH_SUFFIXES jsoncpp   PATHS ${Jsoncpp_PKGCONF_INCLUDE_DIRS} # /usr/include/jsoncpp/json ) 

Searching for json/features.h instead of json/json.h avoids finding the json.h file of json-c on my system, which is not compatible.


in CMakeLists.txt :

include_directories(${Jsoncpp_INCLUDE_DIR}) add_executable(jsonparser jsonparser.cpp) target_link_libraries(jsonparser ${Jsoncpp_LIBRARY}) 

Here the found directories are set up, so CMake actually uses them.


in jsonparser.cpp:

const Json::Value songs = root["songs"]; for ( int index = 0; index < songs.size(); ++index ){  // Iterates over the sequence elements.    std::clog<<"Name="<<songs[index]["name"];    std::clog<<"Artist="<<songs[index]["artist"]; } 

Your orginal code didn't compile, so I replaced the offending piece with the code above. Have you forgot to declare the song variable?


I also removed the getFormattedErrorMessages() call, because I have only jsoncpp 0.5.0, in which that function is not available. That shouldn't make a difference though.

Let me know if this works for you.



回答2:

jsoncpp now builds with cmake.

cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -G "Unix Makefiles" ../.. 
  • supports pkg-config
  • builds static lib, dynamic lib, or both
  • can be included into other projects

If you have suggestions, open an issue at GitHub.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!