Unable to link NLohmann json library using cmake - cmake

I am trying to link the NLohmann json library to my json interpreter via cmake.
I keep getting the error :
fatal error: 'nlohmann/json.hpp' file not found #include <nlohmann/json.hpp>
From the file :
#include <nlohmann/json.hpp>
#include <fstream>
#include "InterpretJson.h"
#include "game.h"
using namespace std;
using json = nlohmann::json;
InterpretJson(string path){
this->path = path;
ifstream f(path);
json jData = json::parse(f);
f.close();
this->data = jData;
}
Game interpret(Game& game){}
The CMakeLists.txt in the directory which contains src/interpretJson.cpp and include/interpretJson.h.:
find_package(nlohmann_json 3.2.0 REQUIRED)
add_library(interpreter
src/interpretJson.cpp
)
target_include_directories(interpreter
PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
${nlohmann_json_INCLUDE_DIR}
)
target_link_libraries(interpreter
PRIVATE
${nlohmann_json_LIBRARIES}
)
set_target_properties(interpreter
PROPERTIES
LINKER_LANGUAGE CXX
CXX_STANDARD 17
)
install(TARGETS interpreter
ARCHIVE DESTINATION lib
)
How do I fix this?
Edit: This is issue is only happening on arm64 Mac M1 but it is working fine on a linux ubuntu VM. However, the vm is slow and I would still like to know how to make it work on Mac

Related

Setting up a SystemC project with CMake: undefined reference to `sc_core

I'm trying to build a simple hello world in SystemC with CMake.
Here's the SystemC file main.cpp:
#include <systemc.h>
using namespace std;
SC_MODULE (hello_world) {
SC_CTOR (hello_world) {
}
void say_hello() {
cout << "Hello World SystemC" << endl;
}
};
int sc_main(int argc, char* argv[]) {
hello_world hello("HELLO");
hello.say_hello();
return(0);
}
Here is the CMakeLists.txt:
cmake_minimum_required(VERSION 3.1)
project(SystemCExample)
set (CMAKE_PREFIX_PATH /usr/local/systemc-2.3.2)
include_directories(${CMAKE_PREFIX_PATH}/include)
find_library(systemc systemc ${CMAKE_PREFIX_PATH}/lib-linux64)
link_directories(${CMAKE_PREFIX_PATH}/lib-linux64)
set(CMAKE_CXX_STANDARD 11) # C++11...
set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required...
set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(SystemCExample systemc)
I keep getting the error:
/usr/local/systemc-2.3.2/include/sysc/kernel/sc_ver.h:179: error: undefined reference to `sc_core::sc_api_version_2_3_2_cxx201103L<&sc_core::SC_DISABLE_VIRTUAL_BIND_UNDEFINED_>::sc_api_version_2_3_2_cxx201103L(sc_core::sc_writer_policy)'
It points to sc_ver.h to the line:
api_version_check
(
SC_DEFAULT_WRITER_POLICY
);
The error mesage appears also when I replace the main.cpp with another simple example. How can I fix it?
Most likely you've built SystemC with C++98. It is default. Currently it requires that you use same C++ standard during library build and for your application.
Here are steps to build SystemC 2.3.2 with CMake
Download SystemC 2.3.2, unpack, change directory to systemc-2.3.2
cd /path/to/systemc-2.3.2
Create build directory:
mkdir build
Configure SystemC build with C++11 support. I also recommend to build it in Debug mode, this helps while learning. Later you can switch to Release builds to speed-up simulation
cmake ../ -DCMAKE_CXX_STANDARD=11 -DCMAKE_BUILD_TYPE=Debug
Build
cmake --build .
CMake will automatically export SystemC library targets to User Package Registry: https://cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html#user-package-registry
Optionally you can install it somewhere, read CMake manual to learn how.
Now try to create sample SystemC project:
main.cpp
#include <systemc.h>
SC_MODULE (hello_world) {
SC_CTOR (hello_world)
{
SC_THREAD(say_hello);
}
void say_hello()
{
cout << "Hello World SystemC" << endl;
}
};
int sc_main(int argc, char* argv[])
{
hello_world hello("HELLO");
sc_start();
return (0);
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(test_systemc)
find_package(SystemCLanguage CONFIG REQUIRED)
set (CMAKE_CXX_STANDARD ${SystemC_CXX_STANDARD})
add_executable(test_systemc main.cpp)
target_link_libraries(test_systemc SystemC::systemc)
Build, run, expected output:
./test_systemc
SystemC 2.3.2 --- Oct 14 2017 19:38:30
Copyright (c) 1996-2017 by all Contributors,
ALL RIGHTS RESERVED
Hello World SystemC

Issue with CMake when using glib library

I am writing a bluez C program to read battery service. I am using CMake for building the code.
My Cmake File is :
# CMakeLists file for module-bluez project
cmake_minimum_required(VERSION 3.02)
project (bluez-module)
find_package(PkgConfig REQUIRED)
# Adding dbus library
pkg_check_modules(DBUS REQUIRED dbus-1>= 1.6)
include_directories(${DBUS_INCLUDE_DIRS})
link_directories(${DBUS_LIBRARY_DIRS})
#Adding glib library
pkg_check_modules(GLIB REQUIRED glib-2.0>=2.23)
include_directories(${GLIB_INCLUDE_DIRS})
link_directories(${GLIB_LIBRARY_DIRS})
pkg_check_modules (DBUSGLIB REQUIRED dbus-glib-1)
include_directories(${DBUSGLIB_INCLUDE_DIRS})
link_directories(${DBUSGLIB_LIBRARY_DIRS})
# Adding bluetooth using extra libs
list(APPEND EXTRA_LIBS "bluetooth")
# Expose 'gattlib.h' to all sub-directories
include_directories(include)
add_executable(bluez-module scantest.c)
# Linking libraries
message(${DBUSGLIB_LIBRARIES})
target_link_libraries(bluez-module ${EXTRA_LIBS})
#target_link_libraries(bluez-module ${DBUS_LIBRARIES})
target_link_libraries(bluez-module ${DBUSGLIB_LIBRARIES})
target_link_libraries(bluez-module ${GLIB_LIBRARIES})
I have to use g_main_loop in my code. But after building the source file I always get the below error :
[ 50%] Linking C executable bluez-module
CMakeFiles/bluez-module.dir/scantest.c.o: In function `read_battery_service':
scantest.c:(.text+0x5b8): undefined reference to `g_dbus_setup_bus'
collect2: error: ld returned 1 exit status
My read_battery function code is as below :
int read_battery_service(struct hci_state *current_hci_state , char *dev_addr)
{
GError *error = NULL;
GDBusClient *client;
GOptionContext *context;
context = g_option_context_new(NULL);
main_loop = g_main_loop_new(NULL, FALSE);
dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
return 0;
}
Just trying to initialize for to access dbus apis.
I have included these headers in the code
#include <assert.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <stdio.h>
#include <gdbus.h>
#include <glib/gmain.h>
What would be the issue ? Is glib.h contains the function g_main_loop_new ? Where should I find it ? Or Is CMake not linking glib properly ?
Looks like you are missing the gdbus linker flags. Try using
pkg_check_modules (DBUSGLIB REQUIRED dbus-glib-1) and add
target_link_libraries(module-bluez ${DBUS_LIBRARIES} ${DBUSGLIB_LIBRARIES})
and see if it helps.

Linking error for basic Qt5 application using CMake

I am trying to build a simple Qt5 application using CMake
The Qt5 project is the basic project generated when creating a new project with a Widget.
The project builds and runs successfully with QtCreator
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
The CMakeLists file have been written according to the example given in the Qt5 documentation. The path to the Qt5 directory is given in the cache.
http://doc.qt.io/qt-5/cmake-manual.html
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.11)
project(test0)
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
# Find the QtWidgets library
find_package(Qt5Widgets)
# Tell CMake to create the executable
add_executable(test0 WIN32 main.cpp)
# Use the Widgets module from Qt 5.
target_link_libraries(test0 Qt5::Widgets)
The Cmake generation works fine.
I'm getting linking errors (undefined reference to methods belonging to the Widget class) when building the app using the Makfile generated by Cmake.
(here is a capture of the errors)
http://s31.postimg.org/edefl1m6j/Capturetest0.png
Any tips ?
System :
Windows 7
Compiler :
MinGW32
Versions :
QT 5.6.1 (mingw49_32)
CMake 3.6.0
Two mistakes in the CMakeLists
- widget.cpp has to be mentionend in add_executable as explained Tsyvarev
- use autouic in order to create the ui_widget.h associated with the widget.ui and widget.cpp
The working CMakeLists is the following :
cmake_minimum_required(VERSION 2.8.11)
project(test0)
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
# Find the QtWidgets library
find_package(Qt5Widgets)
# Tell CMake to create the executable
add_executable(test0 WIN32 main.cpp widget.cpp widget.ui)
# Use the Widgets module from Qt 5.
target_link_libraries(test0 Qt5::Widgets)

Cmake test program cannot find -lgcc_s

I'm using cmake with custom GCC(with shared libraries) and during cmake compiler test I get following error:
The C compiler "/path/to/gcc/bin/gcc" is not able to compile a simple test program.
...
/path/to/gcc/x86_64-unknown-linux-gnu/bin/ld:
cannot find -lgcc_s
Here's a simple "testme.cpp" file:
#include <iostream>
int main( int argc, char * argv[] ) {
std::cout << "Hello world" << std::endl;
return 0;
}
and here's a CMakeLists.txt:
cmake_minimum_required(VERSION 2.6.2)
project(testme)
file( GLOB srcs "testme.cpp" )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -Wall -std=c++11")
set(CMAKE_LDFLAGS "${CMAKE_LDFLAGS} -L/path/to/gcc/lib/gcc/x86_64-unknown-linux-gnu/lib64")
add_executable(testme ${srcs})
to build with my custom GCC I'm exporting CXX and CC:
export CXX=/path/to/gcc/bin/g++
export CC=/path/to/gcc/bin/gcc
and then hit:
cmake .
make
and the result is that it can't find libgcc_s.so which is located in the "lib/gcc/x86_64-unknown-linux-gnu/lib64" folder.
However, when I invoke gcc like this:
/path/to/gcc/bin/g++ testme.cpp -L/path/to/gcc/lib/gcc/x86_64-unknown-linux-gnu/lib64
it compiles successfully. I've tried to add it to LD_LIBRARY_PATH but that doesn't seem to help.
So, is there a way to pass library path to CMake compiler check?
Chrono Kitsune was sort of right ... /path/to/gcc/x86_64-unknown-linux-gnu/bin/ld was build with "--enable-shared" and libraries where not in systems search path.

cmake: linking software to boost::mpi (with mpich2)

For this simple code (taken from the boost-mpi documentation):
#include <boost/serialization/string.hpp>
#include <iostream>
#include <string>
#include <boost/mpi.hpp>
namespace mpi = boost::mpi;
int main(int argc, char *argv[])
{
mpi::environment env(argc, argv);
mpi::communicator world;
if (world.rank() == 0) {
world.send(1, 0, std::string("Hello"));
std::string msg;
world.recv(1, 1, msg);
std::cout << msg << "!" << std::endl;
} else if (world.rank() == 1) {
std::string msg;
world.recv(0, 0, msg);
std::cout << msg << ", ";
std::cout.flush();
world.send(0, 1, std::string("world"));
};
return 0;
};
And for such CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(mpi-tests CXX)
FIND_PACKAGE(Boost 1.4 COMPONENTS mpi serialization REQUIRED)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(test ${Boost_LIBRARIES})
It cannot find boost_mpi:
CMake Error at /usr/share/cmake/Modules/FindBoost.cmake:1135 (message):
Unable to find the requested Boost libraries.
Boost version: 1.47.0
Boost include path: /usr/include
The following Boost libraries could not be found:
boost_mpi
But! I have installed next packages:
boost-graph-mpich2
boost-mpich2
boost-mpich2-devel
boost-mpich2-python
mpich2
mpich2-devel
Why it can't find? There are a plenty examples over Internet where people use FIND_PACKAGE(Boost 1.4 COMPONENTS mpi REQUIRED).
Boost might not be installed in a location that the module FindBoost searches. You can specify the prefix where Boost was installed by setting the variable BOOST_ROOT to your Boost installation prefix.
To your code I would add:
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(mpi-tests CXX)
set( BOOST_ROOT "/path/to/boost/install/prefix" )
FIND_PACKAGE(Boost 1.4 COMPONENTS mpi serialization REQUIRED)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(test ${Boost_LIBRARIES})