2013-08-01 4 views
5

Я хочу использовать jsoncpp для написания кода на C++ для анализа файла JSON. Позвольте мне объяснить, что я сделал. Я создал CMakeLists.txt, и я сделал FindJsoncpp.cmake, а также простой файл C++ для тестирования jsoncpp. Когда я компилирую исходный код C++ без cmake, используя -I/usr/include/jsoncpp/ -ljsoncpp, он отлично работает. но когда я пытаюсь построить его с помощью cmake, он не может найти заголовочный файл json.h, который я включил в свой исходный код на C++.Как написать модуль cmake для jsoncpp?

вот мой 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) 

И это FindJsoncpp.cmake, что я писал:

# - 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) 

И, наконец, простой C++ код называется jsonparser.cpp, чтобы проверить это:

#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; 
} 

Когда я запускаю jsonparser.cpp с ниже команда работает отлично.

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

, но когда я пытаюсь сделать это с помощью cmake я получаю эту ошибку:

$~/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 

Он не может найти json/json.h заголовочный файл, но он основал библиотеку jsoncpp в CMake раньше. Я проверил файл jsoncpp.pc и нашел ti OK. Я не знаю, что я делаю неправильно! любая помощь будет оценена по достоинству.

Я использую ubuntu 13.04 с поддержкой multiarch. Я услышал что-то о проблеме jsoncpp с 64-битным компилятором, но не знаю, так ли это.

+0

@bennofs ошибка изменилась, но все еще не работает. он дает эту ошибку 'jsonparser.cpp :(. text + 0x29): неопределенная ссылка на Json :: Value :: operator [] (char const *) jsonparser.cpp :(. text + 0x46): неопределенная ссылка на Json :: оператор << (std :: ostream &, Json :: Value const &) j' – sajjadG

+0

try 'target_link_libraries (json_parser $ (Jsoncpp_LIBRARIES))', это работает? (Я удалил свой предыдущий комментарий, потому что я думал, что это глупо, кажется, что это было не так глупо) – bennofs

+0

@bennofs В нем говорится: 'Невозможно указать библиотеки ссылок для целевого« jsonparser », который не построен этим проектом.' – sajjadG

ответ

7

Хорошо, у меня есть решение, которое отлично компилируется в моей системе. Найти jsoncpp сложно, потому что json-c устанавливает заголовок с тем же именем, а в моей системе этот заголовок находится под /usr/include/json/json.h. Для того, чтобы получить его работу, вы должны сделать следующие изменения:


в 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 
) 

Поиск JSON/features.h вместо JSON/json.h избегает нахождения json.h файл json-c в моей системе, который несовместим.


в CMakeLists.txt:

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

Здесь найдены каталоги устанавливаются, так CMake на самом деле использует их.


in jsonparser.каст:

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"]; 
} 

Ваш код оригинал не обобщать, поэтому я заменил оскорбительную часть с выше кодом. Вы забыли объявить переменную песни?


Я также удалил getFormattedErrorMessages() вызов, потому что у меня есть только jsoncpp 0.5.0, в котором эта функция не доступна. Однако это не должно меняться.

Дайте мне знать, если это сработает для вас.

+0

Хороший ответ ... +1. Я больше думал о вашем комментарии относительно двух разных файлов json.h, и мне интересно, будет ли наиболее надежное решение состоять в том, чтобы сделать 'find_path (... jsoncpp/json/json.h ...)', а затем в источнике файлы, которые вам нужно будет выполнить '#include" jsoncpp/json/json.h ". Нет шансов случайно набрать неправильный json.h. – Fraser

+0

@Fraser Я тоже подумал об этом, но, к сожалению, по умолчанию установить (сделать установку в исходном коде) * не создавать каталог jsoncpp, а устанавливать в/usr/include/json /. Таким образом, могут существовать системы, в которых json.h jsoncpp находится в этом каталоге. – bennofs

+0

А, правильно. Жаль, так как я полагаю, что есть неплохая вероятность, что '/ usr/include' будет включен также через какую-то другую зависимость? – Fraser

3

jsoncpp сейчас builds with cmake.

cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -G "Unix Makefiles" ../.. 
  • поддерживает pkg-config
  • создает статическую LIB, динамический ОМТ или оба
  • могут быть включены в другие проекты

Если у вас есть предложения, open an issue at GitHub.