2013-08-01 26 views
5

Tôi muốn sử dụng jsoncpp để viết mã C++ để phân tích cú pháp tệp JSON. Hãy để tôi giải thích những gì tôi đã làm. Tôi đã tạo một CMakeLists.txt và tôi đã thực hiện FindJsoncpp.cmake cùng với tệp C++ đơn giản để kiểm tra jsoncpp. Khi tôi biên dịch mã nguồn C++ mà không cần dùng cmake, hãy sử dụng -I/usr/include/jsoncpp/ -ljsoncpp nó hoạt động tốt. nhưng khi tôi cố gắng để xây dựng nó bằng cách sử dụng cmake nó không thể tìm thấy tập tin tiêu đề json.h mà tôi đã bao gồm trong mã nguồn C++ của tôi.cách viết mô-đun cmake cho jsoncpp?

ở đây là tôi 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) 

Và đây là FindJsoncpp.cmake mà tôi đã viết:

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

Và cuối cùng là một C đơn giản ++ mã được gọi là jsonparser.cpp để kiểm tra nó:

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

Khi tôi chạy jsonparser.cpp bằng dưới lệnh nó hoạt động tốt.

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

nhưng khi tôi cố gắng để làm cho nó sử dụng cmake tôi nhận được lỗi này:

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

Nó không thể tìm thấy json/json.h tập tin tiêu đề nhưng nó đã thành lập thư viện jsoncpp trong cmake trước. Tôi đã kiểm tra jsoncpp.pc tệp và tìm thấy ti OK. Tôi không biết mình đang làm gì sai! Bất kỳ trợ giúp sẽ được đánh giá cao.

Tôi đang sử dụng ubuntu 13.04 với hỗ trợ đa cấp. Tôi nghe một cái gì đó về vấn đề jsoncpp với trình biên dịch 64bit nhưng không biết nếu đó là trường hợp.

+0

@bennofs lỗi đã thay đổi nhưng vẫn không hoạt động. nó cho lỗi này 'jsonparser.cpp :(. text + 0x29): tham chiếu không xác định đối với Json :: Value :: operator [] (char const *) jsonparser.cpp: (. text + 0x46): undefined reference to Json :: toán tử << (std :: ostream &, Json :: Value const &) j' – sajjadG

+0

thử 'target_link_libraries (json_parser $ (Jsoncpp_LIBRARIES))', điều đó có hoạt động không? (Tôi loại bỏ bình luận trước đó của tôi vì tôi nghĩ rằng nó là ngu ngốc, có vẻ như nó không phải là ngu ngốc) – bennofs

+0

@ bennofs Nó nói: 'Không thể chỉ định thư viện liên kết cho mục tiêu" jsonparser "mà không được xây dựng bởi dự án này.' – sajjadG

Trả lời

7

Ok, tôi có giải pháp biên dịch tốt trên hệ thống của mình. Việc tìm jsoncpp rất phức tạp, vì json-c cài đặt tiêu đề có cùng tên và trên hệ thống của tôi, tiêu đề đó nằm trong /usr/include/json/json.h. Để có được nó làm việc, bạn cần phải thực hiện những thay đổi sau:


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

Tìm kiếm json/features.h thay vì json/json.h tránh việc tìm kiếm tệp json.h của json-c trên hệ thống của tôi, không tương thích.


trong CMakeLists.txt:

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

đây các thư mục tìm thấy được thiết lập, vì vậy CMake thực sự sử dụng chúng.


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

Mã gốc của bạn không biên dịch, vì vậy tôi đã thay thế đoạn mã vi phạm ở trên. Bạn đã quên khai báo biến bài hát chưa?


Tôi cũng đã xóa cuộc gọi getFormattedErrorMessages(), vì tôi chỉ có jsoncpp 0.5.0, trong đó chức năng đó không khả dụng. Điều đó không nên tạo nên sự khác biệt.

Hãy cho tôi biết nếu điều này phù hợp với bạn.

+0

Câu trả lời hay ... +1. Tôi nghĩ nhiều hơn về bình luận của bạn về 2 file json.h khác nhau, và tôi tự hỏi liệu giải pháp mạnh mẽ nhất có phải là 'find_path (... jsoncpp/json/json.h ...)' và sau đó trong nguồn các tệp bạn phải làm '#include" jsoncpp/json/json.h "'. Không có cơ hội vô tình nhặt nhầm json.h rồi. – Fraser

+0

@ Faser Tôi cũng nghĩ về điều đó, nhưng không may, cài đặt mặc định (cài đặt trong mã nguồn) * không * tạo thư mục jsoncpp, nhưng sẽ cài đặt vào/usr/include/json /. Vì vậy, có thể có các hệ thống mà jsoncpp's json.h nằm trong thư mục đó. – bennofs

+0

Ah, phải. Đó là một điều đáng tiếc, vì tôi cho rằng có một cơ hội khá tốt '/ usr/include' sẽ được bao gồm quá thông qua một số phụ thuộc khác? – Fraser

3

jsoncpp bây giờ builds with cmake.

cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -G "Unix Makefiles" ../.. 
  • hỗ trợ pkg-config
  • xây dựng lib tĩnh, lib năng động, hoặc cả hai
  • có thể được đưa vào các dự án khác

Nếu bạn có gợi ý, open an issue at GitHub.

Các vấn đề liên quan