I am trying to compile a simple test project to make sure all my tools, such as CMake, Boost, Clang are working.
The source code I am trying to compile is LibLinkTest.cpp:
#include <boost/filesystem.hpp>
#include <fstream>
#include <iostream>
#include <string>
#include <assert.h>
using namespace boost::filesystem;
int main(int argc, char* argv[])
{
std::string str{"test passed"};
std::cout << str << std::endl;
boost::filesystem::path p{argv[1]};
try {
std::cout << p.string() << std::endl;
if (exists(p)) {
if (is_regular_file(p)) {
std::ifstream file{p.c_str()};
std::string line;
if (file.good() && file.is_open()) {
while (file >> line) {
std::cout << line << std::endl;
}
}
file.close();
} else if (is_directory(p)) {
std::cout << p.string() << " is a directory " << std::endl; // path stream inserter
} else
std::cout << p.string() << " exists, but is neither a regular file nor a directory" << std::endl;
}
else {
std::cout << p.string() << " does not exist" << std::endl;
}
}
catch (const filesystem_error& ex) {
std::cout << ex.what() << std::endl;
}
}
Running:
c++ -std=c++11 -I /usr/boost_1_54_0/boost/ LibLinkTest.cpp -o LibTest -L /usr/boost_1_54_0/lib/ -lboost_filesystem -lboost_system
compiles it just fine and the code runs (with a seg fault, but I'll address that separately).
However, I want to use CMake with my other projects. Trying to compile LibLinkTest.cpp with the following CMakeLists.txt causes linking errors.
CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
PROJECT(BoostTest CXX)
SET(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++")
FIND_PACKAGE(Boost 1.54.0 COMPONENTS filesystem system REQUIRED)
INCLUDE_DIRECTORIES(
${Boost_INCLUDE_DIR}
/usr/include/
/usr/include/c++/4.2.1/
)
ADD_EXECUTABLE(
LibTest
LibLinkTest.cpp
)
TARGET_LINK_LIBRARIES(LibTest boost_filesystem boost_system)
The output from running cmake ../ is:
-- The CXX compiler identification is Clang 5.0.0
-- 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
-- Boost version: 1.54.0
-- Found the following Boost libraries:
-- filesystem
-- system
-- Configuring done
-- Generating done
And finally running make gives the error:
Scanning dependencies of target LibTest
[100%] Building CXX object CMakeFiles/LibTest.dir/LibLinkTest.cpp.o
Linking CXX executable LibTest
Undefined symbols for architecture x86_64:
"std::string::c_str() const", referenced from:
boost::system::system_error::what() const in LibLinkTest.cpp.o
boost::filesystem::path::c_str() const in LibLinkTest.cpp.o
"std::string::empty() const", referenced from:
boost::system::system_error::what() const in LibLinkTest.cpp.o
"std::basic_ios<char, std::char_traits<char> >::good() const", referenced from:
_main in LibLinkTest.cpp.o
It seems like a setting in CMake is not correct, perhaps something that points to the std c++ lib. Does anyone know how I can configure CMake correctly?
I have solved this by changing the line:
SET(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++")
to
SET(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libstdc++")
It seems like I had just made a typo in the CMakeLists.txt.
On a side note, does anyone know why I need to set this flag? Is it a C++11 thing? It also seems to have solved my issues with the seg fault that I was getting when compiling from the command line.
You should change the line
TARGET_LINK_LIBRARIES(LibTest boost_filesystem boost_system)
to
TARGET_LINK_LIBRARIES(LibTest ${Boost_LIBRARIES})
The FIND_PACKAGE command sets the Boost_LIBRARIES variable to what you need to link with.
If you see these two lines from the output
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
It tells you that it might not be clang that is used to compile the source. To see if it is, to e.g.
$ c++ --version
to see what compiler it actually is. If it doesn't say clearly you may want to do e.g.
$ ls -l /usr/bin/c++
and if it's a symbolic link then check the link (and so on). On my system (Ubuntu 13.10) the file /usr/bin/c++ is a symbolic link to /etc/alternatives/c++ which is a symbolic link to /usr/bin/g++, meaning that on my system the command c++ is actually the GCC C++ compiler.
To make sure you use clang, then redo the cmake command (from a clean folder, that you haven't run cmake in before) with the environment variable CXX set to clang++, like
$ CXX=clang++ cmake path/to/folder/with/CMakeLists.txt
Pro-tip: Make a separate folder for building, and run cmake from it. Then you can easily clean it up by just removing it if needed.
Related
Here is a piece of code that I'm trying to run and understand. but it has a awkward error in the
setDefault function.
cmake_minimum_required(VERSION 3.19)
project(OpenCL_HPP)
set(CMAKE_CXX_STANDARD 14)
# find OpenCL
find_package(OpenCL REQUIRED)
find_package(Threads REQUIRED)
include_directories(SYSTEM ${OpenCL_INCLUDE_DIRS})
link_directories(${OpenCL_LIBRARIES})
add_executable(OpenCL_HPP main.cpp)
target_link_libraries(${PROJECT_NAME} ${OpenCL_LIBRARIES} Threads::Threads)
Code:
#define CL_HPP_ENABLE_EXCEPTIONS
#define CL_HPP_MINIMUM_OPENCL_VERSION 120
#define CL_HPP_TARGET_OPENCL_VERSION 200
#include <vector>
#include <memory>
#include <algorithm>
#include <iostream>
#ifdef __APPLE__
#include <OpenCL/cl.hpp>
#else
#include <CL/cl2.hpp>
#endif
constexpr int numElements = 32;
int main(void)
{
// Filter for a 2.0 platform and set it as the default
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
cl::Platform plat;
for (auto &p : platforms) {
std::string platver = p.getInfo<CL_PLATFORM_VERSION>();
if (platver.find("OpenCL 2.") != std::string::npos) {
plat = p;
}
}
if (plat() == 0) {
std::cout << "No OpenCL 2.0 platform found.";
return -1;
}
/*
The setDefault chrashes in the call_once function, with error code -1
*/
cl::Platform newP = cl::Platform::setDefault(platforms[0]);
//cl::Platform newP = plat;
if (newP != plat) {
std::cout << "Error setting default platform.";
return -1;
}
return 0;
}
ERROR:
/home/BLA/CLionProjects/OpenCL_HPP/cmake-build-debug/OpenCL_HPP
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
The error comes int the call_once function, as far as I understand this should be part of the pThread libs but all of that interferes with the stdlib. Correct me if I'm wrong.
The machine where I run this is Ubuntu 16.04, the Opencl comes from Intel, and I do not have any other OpenCL driver installed (for the GPU for example). This code is the main bind example in the OpenCL-HPP doxygen.
I'm wondering, is there a way to rectify this. Is OpenCL-HPP using Pthread lib or STD lib, for linking purposes?
After some debuging and reading about OpenCL-HPP I found the problem.
The main issue is that the OpenCL-HPP uses pthreads and if they are not included / linked one gets problems like described above.
Articles that helped:
cmake fails to configure with a pthread error
Cmake error undefined reference to `pthread_create'
Cmake gives me an error (pthread_create not found) while building BornAgain
The main issue is that the Call_once method crashes without any really understandable cause. The project will build though.
One thing that derails everything is the CMake it is not really helping with understanding the linking procedure.
Output from the CMake setup:
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- 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
-- Detecting C compile features
-- Detecting C compile features - 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
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for CL_VERSION_2_0
-- Looking for CL_VERSION_2_0 - found
-- Found OpenCL: /usr/lib/x86_64-linux-gnu/libOpenCL.so (found version "2.0")
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Configuring done
-- Generating done
The main point here is that pthreads are not really found, and that was not clear to me.
find_package(Threads REQUIRED)
target_link_libraries(${PROJECT_NAME} ${OpenCL_LIBRARIES} Threads::Threads)
The code is not really doing anything since the pthreads are not linked correctly. Or it is not recognized that the pthreads should be linked.
Once I added the following code to my CMake, the magic happens and the crashes go magically away.
if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -Werror=return-type")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")
endif()
Here is where the next problem for me arises. Why does all of this does not give some more verbose warnings or error when linking?
The OpenCL-HPP documentation does not really express the need for linking to pthreads. As a consequence then one has a quite painful experience in searching for the problem.
Why does CMake have to have such a setup for the CMAKE_CXX_FLAGS and is not able to link int the target_link_libraries command?
I am using Mac OS and I created a toy CMake project with OpenMP.
main.cpp:
#include <iostream>
#include "omp.h"
using namespace std;
int main() {
cout << "Hello, World!" << endl;
#pragma omp parallel
cout << "Hello OpenMP from thread " << omp_get_thread_num() << endl;
return 0;
}
CMakeList.txt:
cmake_minimum_required(VERSION 3.12)
project(omp_test)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
add_executable(omp_test main.cpp)
When I tried mkdir build && cd build && cmake .. && make -j to build the project, I got clang: error: unsupported option '-fopenmp'. It works well on Ubuntu. How can I change the CMakeList.txt to enable OpenMP support? Or If the problem can be solved using g++, how to do it?
Thanks for your help!
I have solved my problem by changing the default compiler to g++. (Note: I have already installed gcc/g++ and the OpenMP library from Homebrew.)
I did not change main.cpp and CMakeList.txt, but when I built the project, I use
mkdir build && cd build && cmake -DCMAKE_CXX_COMPILER=g++-9 .. && make -j
then the error clang: error: unsupported option '-fopenmp' disappeared. Specifically, I added the option -DCMAKE_CXX_COMPILER=g++-9 to change the default compiler. Maybe the g++ version on your computer is not g++-9, then you can check it under the path /user/local/bin/.
I am porting a project from MSVC to mingw. The project contains C and C++. However, whenever an exception is thrown, instead of being caught, std::terminate gets called and the application crashes. I can't understand why so any advice would be appreciated.
My toolchain is cmake/ninja/mingw32 in a MSYS2 environment installed in Windows.
MCVE:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.6)
project(FailedExceptions)
add_executable(FailedExceptions c_funcs.c main.cpp)
//main.cpp
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
int main() {
try {
boost::property_tree::ptree pt;
std::printf("reading file\n");
boost::property_tree::read_xml("nonexistant-file", pt);
std::printf("provider file read\n");
} catch (...) {
std::printf("Exception caught\n");
}
return 0;
}
// c_funcs.c
int SomeCFunction()
{
return 0;
}
Output
$ cmake .. -GNinja
-- The C compiler identification is GNU 7.2.0
-- The CXX compiler identification is GNU 7.2.0
-- Check for working C compiler: C:/msys64/mingw32/bin/cc.exe -- works
-- Check for working CXX compiler: C:/msys64/mingw32/bin/c++.exe -- works
-- Configuring done
-- Generating done
-- Build files have been written to: C:/msys64/home/sferguson/src/vis/build
$ ninja -v
[1/3] C:\msys64\mingw32\bin\cc.exe -MD -MT c_funcs.c.obj -MF c_funcs.c.obj.d -o c_funcs.c.obj -c ../c_funcs.c
[2/3] C:\msys64\mingw32\bin\c++.exe -MD -MT main.cpp.obj -MF main.cpp.obj.d -o main.cpp.obj -c ../main.cpp
[3/3] C:\msys64\mingw32\bin\c++.exe c_funcs.c.obj main.cpp.obj -o FailedExceptions.exe -Wl,--major-image-version,0,--minor-image-version,0 -lgcc_eh -lgcc_eh -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
$ ./FailedExceptions.exe
reading file
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
$
Trace:
I can get this trace from Dr. Mingw. It really does appear that the crash happens between construction of the exception and the actual throw.
ntdll.dll!_NtTerminateProcess#8
ntdll.dll!_RtlExitUserProcess#4
kernel32.dll!_ExitProcessStub#4
msvcrt.dll!___crtExitProcess
msvcrt.dll!__cinit
msvcrt.dll!__exit
msvcrt.dll!_abort
FailedExceptions.exe!uw_init_context_1
FailedExceptions.exe!boost::property_tree::xml_parser::xml_parser_error::xml_parser_error
FailedExceptions.exe!boost::property_tree::xml_parser::read_xml<boost::property_tree::basic_ptree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >
FailedExceptions.exe!main
FailedExceptions.exe!__tmainCRTStartup [D:/develop/scripts/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c # 334]
kernel32.dll!#BaseThreadInitThunk#12
ntdll.dll!___RtlUserThreadStart#8
ntdll.dll!__RtlUserThreadStart#8
Troubleshooting:
I found some posts from 5-10 years ago suggesting that this could be a conflict between mingw's dw2 and sjlj libraries, but I only have the libgcc_s_dw2-1.dll binaries installed which come with the mingw-w64-i686-gcc-libs package in the msys pacman repository.
I tried changing my CMakeLists.txt file to compile everything with C++ with project(FailedExceptions LANGUAGES CXX). This prevents cmake from building my C files. So it does work for the MCVE, but my full project is missing all C content.
I've added set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -fexceptions) but it seems to have no effect. I've confirmed with ninja -v that this flag is added to the C-file compilation command.
As soon as I remove the C file from the build, everything works. But even though I'm not using the C-file in this MCVE, I still use it in my big project.
I've found another smaller example here. I can reproduce that problem IFF I also compile a C file in that same project.
It's a feature(bug?) in cmake implicit library detection introduced in cmake 3.1. CMake thinks that in C mode GCC needs to link with gcc_eh, which breaks C++ exception handling.
You can disable implicit library detection by adding this to CMakeLists.txt:
set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "")
(Don't know how to exclude just gcc_eh from the list)
RustyX's answer is the accepted one, but I also found another number of work-arounds that seem to work:
set_source_files_properties(filename.c PROPERTIES LANGUAGE CXX)
set(CMAKE_C_COMPILER /path/to/cpp/compiler)
set(APPEND CMAKE_CXX_SOURCE_FILE_EXTENSIONS c).
But RustyX's is the best answer so far.
Edit: The last one doesn't work. It still builds with the C compiler. I'd also need to remove c from CMAKE_C_SOURCE_FILE_EXTENSIONS.
To add to rustyx answer above (I'm not allowed to comment), this is fixed in cmake 3.10 per this pull-request: https://gitlab.kitware.com/cmake/cmake/merge_requests/1460
I tested with CMake 3.10.2, and it seems like exceptions now work without having to specify the work-around cmake stanza rustyx is mentioning.
I'd like to use the clang static analyzer command line tool scan-build with the convenience of cmake --build.
Most of the resources I found online seem to indicate you need a two-step process:
scan-build cmake .
scan-build make
For example for this small example program with a bug that scan-build catches:
#include <iostream>
int fun() {
int x;
return x; # main.cpp:5:5: warning: Undefined or garbage value returned to caller
}
int main() {
int a = fun();
std::cout << "Hello, World! " << a << std::endl;
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project(test_program)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(test_program ${SOURCE_FILES})
If I run scan-build cmake --build cmake-build-release/ it does not find the bug, even though the binary is built. Is there anyway to get scan-build to work in a one step process with CMake?
If you want to use the Clang Static Analyzer, you should just set CMAKE_EXPORT_COMPILE_COMMANDS=YES. This will create a compilation database that CSA can read. You don't even need to build your project. The file is located at: /path/to/build/compile_commands.json.
scan-build is designed for projects that can't create a compilation database themselves.
Then you can run:
analyze-build --cdb /path/to/build/compile_commands.json \
--use-analyzer /path/to/clang \
--output /path/to/output
It's worth noting that clang-tidy has all of the CSA checks now. You can use this same compilation database technique to run clang-tidy on your codebase.
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.
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.
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.