3

I cannot find a way to link jsoncpp with my executable. I have tried many things but none succeeded:

  • linking jsoncpp_lib
  • also what is written here:
find_package(PkgConfig REQUIRED)
pkg_check_modules(JSONCPP jsoncpp)
link_libraries(${JSONCPP_LIBRARIES})
add_executable(myprogram myprogram.cpp)
target_link_libraries(myprogram ${JSONCPP_LIBRARIES})

I want to use the jsoncpp library that comes with ubuntu. Has anyone managed to do this?

$ ls /usr/lib/x86_64-linux-gnu/libjsoncpp.*

/usr/lib/x86_64-linux-gnu/libjsoncpp.a   /usr/lib/x86_64-linux-gnu/libjsoncpp.so.1
/usr/lib/x86_64-linux-gnu/libjsoncpp.so  /usr/lib/x86_64-linux-gnu/libjsoncpp.so.1.7.4

CMakeLists.txt

cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)

project(jsoncpp_example)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -stdlib=libc++ -Wall -Werror")
set(CMAKE_EXE_LINKER_FLAGS "-lstdc++ -lpthread")

add_executable(parse main.cpp)
target_include_directories(parse PRIVATE include)
target_link_libraries(parse jsoncpp)

Parser.h

#ifndef MY_PARSER_H
#define MY_PARSER_H

#include <vector>
#include <fstream>
#include <jsoncpp/json/json.h>

class MyParser {
public:
    MyParser() = default;
    ~MyParser() = default;
    
    inline static 
    Json::Value parse(const char* inputFile) {
        Json::Value val;
        std::ifstream ifs(inputFile);
        Json::Reader reader;
        reader.parse(ifs, val);
        return val;
    }

};

#endif /* MY_PARSER_H */

main.cpp

#include <iostream>
#include "Parser.h"

int main(){
    Json::Value val = MyParser::parse("input.json");
    std::cout << val["name"] << std::endl;
}

Ubuntu 18.04, compiling with clan-8.0

CXX=clang-8 cmake ..
make -j

The error I get

Scanning dependencies of target parse
[ 50%] Building CXX object CMakeFiles/parse.dir/main.cpp.o
[100%] Linking CXX executable parse
CMakeFiles/parse.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x3e): undefined reference to `Json::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Json::Value const&)'
CMakeFiles/parse.dir/main.cpp.o: In function `MyParser::parse(char const*)':
main.cpp:(.text._ZN8MyParser5parseEPKc[_ZN8MyParser5parseEPKc]+0x349): undefined reference to `Json::Reader::parse(std::__1::basic_istream<char, std::__1::char_traits<char> >&, Json::Value&, bool)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
CMakeFiles/parse.dir/build.make:94: recipe for target 'parse' failed
make[2]: *** [parse] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/parse.dir/all' failed
make[1]: *** [CMakeFiles/parse.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225
afvmil
  • 362
  • 3
  • 11

4 Answers4

1

The wiki mentions

get_target_property(JSON_INC_PATH jsoncpp_lib INTERFACE_INCLUDE_DIRECTORIES)
include_directories(${JSON_INC_PATH})

target_link_libraries(${PROJECT_NAME} jsoncpp_lib)

but I couldn't get that to work myself. If you have the jsoncpp .cmake files installed in a place searched automatically, this could be an option:

cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)

project(jsoncpp_example)

find_package(PkgConfig REQUIRED)
pkg_check_modules(JSONCPP jsoncpp)

set(CMAKE_THREAD_PREFER_PTHREAD TRUE) # these are to use the prefered -pthread flag
set(THREADS_PREFER_PTHREAD_FLAG TRUE) # over the -lpthread option
find_package(Threads REQUIRED)

add_executable(parse main.cpp)
set_property(TARGET parse PROPERTY CXX_STANDARD 17)
target_compile_options(parse PRIVATE -Wall -Werror)

target_link_libraries(parse PRIVATE Threads::Threads ${JSONCPP_LIBRARIES})
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • This gives me `/usr/bin/ld: CMakeFiles/parse.dir/main.cpp.o: undefined reference to symbol '_ZSt9terminatev@@GLIBCXX_3.4' //usr/lib/x86_64-linux-gnu/libstdc++.so.6: error adding symbols: DSO missing from command line` I guess I still need `set(CMAKE_EXE_LINKER_FLAGS "-lstdc++")`? – afvmil Jun 02 '21 at 23:02
  • With the liker flag it worked, thank you! – afvmil Jun 02 '21 at 23:02
  • @afvmil You're welcome. It seems the OS X delvelopment toolchain is setup in a slightly differnet way than I'm used to. I found this explanation why: https://developer.apple.com/forums/thread/655588?answerId=665804022#665804022 – Ted Lyngmo Jun 03 '21 at 05:55
1

For those who came to this topic, like me, who are looking for a way to include the jsoncpp library in a C++ project with cmake. I solved this problem by cloning the vcpkg repository into an external folder and installing the jsoncpp package through vcpkg, as the official jsoncpp repository suggests. I've better described the solution to this problem in this topic here since it was more generic in search terms.

Maykon Meneghel
  • 335
  • 6
  • 8
1

With cmake 3.22 i got it to work:

find_package(jsoncpp REQUIRED)
...
target_link_libraries({app_name} ... jsoncpp_lib)
edwinc
  • 1,658
  • 1
  • 14
  • 14
0

On Linux this worked for me

  1. install the dev libs.

    sudo apt-get install libjsoncpp-dev

  2. in cmakelists.

pkg_search_module(JSONCPP jsoncpp)

add to...

TARGET_LINK_LIBRARIES(${JSONCPP_LIBRARIES})

  1. cmake .
  2. make