How to include jsoncpp library into project on unix? - c++

The library I am trying to include is jsoncpp. I am having serious trouble with this. I used the home-brew install for this library, which is brew install jsoncpp (brew install is unix version of linux sudo-apt get). Normally homebrew installs stuff to my path, so I can just use it. I am going off of this example here.
#include <json/json.h>
Returns an error of 10: fatal error: 'json/value.h' file not found.
I am using cmake because CLion automatically sets it up. Right now it is very basic:
#CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(Read_JSON)
set(CMAKE_CXX_STANDARD 17)
add_executable(Read_JSON main.cpp)
However, for some reason jsoncpp cannot be found. How can I include this library in my project?

You can use in CMake FetchContent capability.
Jsoncpp is available via git repository on GitHub
Here is example how I made with googletest:
https://github.com/adamvm/hello/blob/master/CMakeLists.txt
You need just substitute proper addresses and names

On mac install with command.
brew install osrf/simulation/ignition-fuel-tools2

In Ubuntu (since 18.04) you need to install libjsoncpp-dev[1] package:
sudo apt install libjsoncpp-dev
[1] https://packages.ubuntu.com/search?keywords=libjsoncpp-dev

Related

cmake in Ubuntu 22.04 cannot find Boost

I need to build a C++ program with CMake but it cannot find Boost.
I'm getting the following error no matter what solutions I've found online for other people with this problem...
-- Compiling with C++ standard: 17
CMake Error at /usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
Could NOT find Boost (missing: Boost_INCLUDE_DIR) (Required is at least
version "1.68.0")
Call Stack (most recent call first):
/usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
/usr/share/cmake-3.22/Modules/FindBoost.cmake:2360 (find_package_handle_standard_args)
CMakeLists.txt:49 (find_package)
This is the part of my CMakeLists.txt looking for Boost
if(NUMCPP_NO_USE_BOOST)
target_compile_definitions(${ALL_INTERFACE_TARGET} INTERFACE -DNUMCPP_NO_USE_BOOST)
else()
find_package(Boost 1.68.0 REQUIRED)
target_link_libraries(${ALL_INTERFACE_TARGET} INTERFACE Boost::boost)
endif()
I have installed boost with sudo apt-get install libboost-all-dev and a few other apt-get options. I always see 0 upgraded, 0 newly installed, 0 to remove after running.
$ whereis boost
boost: /usr/include/boost
Do I need to specify it in the cmake .. line in the terminal somehow?
Assuming that you've successfully installed boost in the default directory, and CMake has access to those directories, probably the problem (as #drescherjm mentioned) is in the version of the Boost you've installed (sometimes the packages provided by apt-get are relatively old).
On the other hand it can also be that CMake doesn't have the installation directory in its search path.
The following steps might be a good place to start:
Check the version of the Boost installed: How to determine the Boost version on a system? and here
If the version installed by apt-get satisfies the project requirement, it seems for some reason CMake didn't include a directory of installation to its searching path. If that's the case, skip to the step 3.
If it's lower than your project requires, build it from source (right now 1.80 is available) to your preferred directory. If you need the libraries which need to be built, check this tutorial.
Tell CMake where to search for built Boost. See here: Cmake doesn't find Boost
I hope this reply is not too off-topic. I suggest you consider using a package manager such as conan or vcpkg.
An example of using conan to use external dependencies.
1. Create conanfile.txt
It should have the following content:
[requires]
boost/1.80
[generators]
CMakeDeps
CMakeToolchain
2. Download your dependencies
mkdir build && cd build
conan install .. --build=missing
conan build ..
The last command is optional and can be changed with:
cmake -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake ..
Benefits:
You don't need to "mess" your system with different libraries
Transitional dependencies are handled automatically
The build process is reproducible

How to install a Library for C++ like Eigen and sharkML at vs code?

I am trying to install libraries like eigen, sharkMl, xtensor, and others in VSCode for C++.
Please if anyone can help me to know the right way to do that.
All of these libraries use CMake for their build system so what I do is use CMake as my build system. My favorite way to do this is to use the libraries build systems to install them and then inlcude them with cmakes find_package function. This you can do by cloning the git repository for the library then build it and install it with cmake. On linux you do this by:
git clone https://gitlab.com/libeigen/eigen.git
cd eigen
mkdir build
cd build
cmake ..
sudo make install
VSCode has good integration for cmake so if you have the C/C++ Extension pack you will be able to build with cmake. In your project folder make a CMakeLists.txt file and add the packages you want:
add_executable(main main.cpp)
find_package(Eigen3 3.4 NO_MODULE)
target_link_libraries(main Eigen3::Eigen)
(This example assumes the main cpp file is main.cpp and creates an executable called main) Then when you press ctr+shift+p and perform CMake: Configure you can select your compiler and build the executable.

How to make cmake find pybind11

I am trying to follow the simple example for embedding python within c++ using pybind11 as found on this page. However, when trying to use cmake to build the solution, I keep getting an error that says
By not providing "Findpybind11.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file
provided by "pybind11", but CMake did not find one.
Could not find a package configuration file provided by "pybind11"
with any of the following names:
pybind11Config.cmake
pybind11-config.cmake
I have a folder called pybindtest on my Desktop which includes CMakeLists.txt and main.cpp as described in the link above, as well as a build folder that I created. While in the build folder, I have tried the following lines to no avail (running on Powershell 7):
cmake ..
cmake .. -Dpybind11_DIR=C:/Users/ben.wolfley/Anaconda3/Library/share/cmake/pybind11/pybind11Config.cmake
cmake .. -DCMAKE_MODULE_PATH=C:/Users/ben.wolfley/Anaconda3/Library/share/cmake/pybind11
I installed pybind11 using conda install pybind11, and pybind11Config.cmake is in C:\Users\ben.wolfley\Anaconda3\Library\share\cmake\pybind11
In case someone having the same issue without Anaconda, like directly with pip pybind11 or manual clone installation, both caused problems in my case. Manual installation of pybind11 with git didn't install the cmake config pybind11Config.cmake, although there is a tools/pybind11Config.cmake.in file, that I couldn't turn into a proper pybind11Config.cmake.
Installation pybind11 global with pip solved it for me, and automatically uninstalled the manual git installation:
pip install "pybind11[global]"
which installed both pybind11 and pybind11-global with proper cmake config like Anaconda does.
Thanks to Tsyvarev for pointing me in the right direction. The following command worked:
cmake .. -G "Visual Studio 15 2017" -A x64 `
-Dpybind11_DIR=C:/Users/ben.wolfley/Anaconda3/Library/share/cmake/pybind11/
I was pointing to the .cmake file instead of the file's directory. I also had to specify the compiler in order for the code to work.
Add following to CMakeLists.txt:
```cmake
# set pybind11 dir
set(pybind11_DIR /Users/Caleb/Softwares/pybind11)
find_package(pybind11 REQUIRED)
```

How to avoid users to manually install GDAL dependencies with CMake?

I know how to link GDAL with a C++ application using CMake. The procedure is summarized hereafter in two steps: (1) Installing the dependency on the system and (2) linking it to the C++ application (see here for more details).
Install GDAL (here on Ubuntu 18.04)
Add the PPA to the sources: sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable
Update: sudo apt-get update
Install GDAL and its development files: sudo apt-get install gdal-bin libgdal-dev
Test the installation: gdalinfo --version
Link GDAL with the C++ application using CMake:
# find system installed GDAL package with predefined CMake variable for finding GDAL
find_package(GDAL REQUIRED)
...
# Specify location of GDAL header files
include_directories( include ${GDAL_INCLUDE_DIRS})
...
# Specify GDAL libraries to link your cpp executable target against
target_link_libraries( your_cpp_executable_target_name ${GDAL_LIBRARIES})
What is the most convenient way to avoid the user to perform the manual installation of the dependency? That is, how to ensure that the missing dependency will not stop the configuration, and download/build the dependency if not found on the system?
For managing the Boost dependency, I used the CMake ExternalProject feature with a Superbuild pattern, and I think a similar approach should be relevant for managing GDAL dependency. However, I am very new at modern CMake, and I struggle adapting this CMake project handling the Boost dependency to also manage a GDAL dependency.
Any general or step-by-step directions to help doing (or good reasons not to do so) would be helpful.

How to change version of Eigen

In my ROS package I would like to use a last stable version of Eigen which is 3.3.4.
However when I check my version into package by EIGEN_MAJOR_VERSION, EIGEN_WORLD_VERSION, EIGEN_MINOR_VERSION I have got a 3.3.90.
In my CMakeList:
find_package(Eigen3 REQUIRED)
include_directories(include ${EIGEN3_INCLUDE_DIR}
find_package for specific version does not exists.
So how can I change the version? I downloaded Eigen from official github. I built it bysudo make install I got a log that everything is updated.
Up-to-date: /usr/local/include/eigen3/...
Thanks.
The answer was very very simply, when I clone from githube it was the newest version...
You can find the last stable version on official Eigen web. Then download, and follow the INSTALL instructions. So create build folder, cmake src_directory, sudo make install which will copy all headers into /usr/include/eigen3/.. then you can use version which you compile.
I suppose that as Eigen has only .h files you don't really need compile lib only do find_package(Eigen3 REQUIRED PATH ...) but I didn't test this solution.