Issue with CMake when using glib library - cmake

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.

Related

Unable to link NLohmann json library using 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

Undefined references in Apache user-written module

I have some undefined reference errors in an Apache module. I've cut the source code down to a minimum that reproduced the error. Below is the source for "mod_test.c" ...
#include "httpd.h"
#include "http_config.h"
#include "http_request.h"
#include "http_protocol.h"
#include "http_core.h"
#include "http_main.h"
#include "http_log.h"
#include "ap_mpm.h"
#include "apr_strings.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
module AP_MODULE_DECLARE_DATA test_module;
static int test_handler(request_rec *r);
static int test_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s);
/* Structure containing state information for the module */
typedef struct {
} ns_mod_config;
static int ns_typematch(request_rec *r) {
ns_mod_config *ns_scfg = ap_get_module_config(r->server->module_config,
&test_module);
core_request_config *creq_cfg;
creq_cfg = ap_get_core_module_config(r->request_config);
return 0;
}
module AP_MODULE_DECLARE_DATA test_module = {
STANDARD20_MODULE_STUFF,NULL,NULL,NULL,NULL,NULL,NULL};
I am using a more-or-less standard Makefile for compiling the module (note that the install option has been removed as this is a test to demonstrate the problem.)
APXS=/usr/local/apache2/bin/apxs
APXS_OPTS=-Wc, -Wc,-DDST_CLASS=3
SRC=src/mod_test.c
OBJ=src/.libs/mod_test.so
$(OBJ): $(SRC)
#echo
$(APXS) $(APXS_OPTS) -c $(SRC)
#echo
#echo write '"make install"' to install module
#echo
clean:
rm -f src/.libs/*
rm -f src/*.o
rm -f src/*.lo
rm -f src/*.la
rm -f src/*.slo
rmdir src/.libs
The compile fails as follows:
/usr/local/apache2/bin/apxs -Wc, -Wc,-DDST_CLASS=3 -c src/mod_test.c
/usr/local/apache2/build/libtool --silent --mode=compile gcc -prefer-pic -DLINUX -D_REENTRANT -D_GNU_SOURCE -D_LARGEFILE64_SOURCE -g -O2 -pthread -I/usr/local/apache2/include -I/usr/local/apache2/include -I/usr/local/apache2/include -DDST_CLASS=3 -c -o src/mod_test.lo src/mod_test.c && touch src/mod_test.slo
src/mod_test.c: In function âns_typematchâ:
src/mod_test.c:34:3: error: unknown type name âcore_request_configâ
core_request_config *creq_cfg;
^~~~~~~~~~~~~~~~~~~
src/mod_test.c:35:14: warning: implicit declaration of function âap_get_core_module_configâ [-Wimplicit-function-declaration]
creq_cfg = ap_get_core_module_config(r->request_config);
^~~~~~~~~~~~~~~~~~~~~~~~~
src/mod_test.c:35:12: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
creq_cfg = ap_get_core_module_config(r->request_config);
^
apxs:Error: Command failed with rc=65536
.
Makefile:23: recipe for target 'src/.libs/mod_test.so' failed
make: *** [src/.libs/mod_test.so] Error 1
I am not sure how this can occur. http_core.h is present in /usr/local/apache2/include and it does include the definitions that are claimed missing by the compile. Six other modules on the same system compile without errors, though none of them use this specific reference to the core data structures.
Help will be gratefully received.
After posting to the Apache modules mailing list, it develops that the problem is in two parts.
Defining CORE_PRIVATE is required under Apache 2.2 to have access to the core data structures.
ap_get_core_module_config is an Apache 2.4 construct.

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)

Unable to link a static C library in an Obj-C project (Xcode 4.6.3)

I'm trying to build a basic FTP client using libftp. I've compiled and archived it as libftp.a and placed it in /usr/local/lib. All the necessary headers I've placed in /usr/local/include/ftp.
Under Build Settings, I've set "Header Search Paths" to /usr/local/include, and I've set "Library Search Paths" to /usr/local/lib. For "Other Linker Flags", I've added -lftp.
Here is the shell of my C++ class:
Connector.h:
#include <stdlib.h>
#include <ftp/ftp.h>
#include <stdio.h>
class Connector{
private:
FtpConnection *connection;
public:
Connector();
~Connector();
bool connect(const char *hostname, const char *port);
};
Connector.cc:
#include "Connector.h"
Connector::Connector(){
}
Connector::~Connector(){
}
bool Connector::connect(const char *hostname, const char *port){
ftpGetAddresses(hostname, port);
printf("Connected!\n");
return true;
}
Upon compiling, this is the error I get:
Undefined symbols for architecture x86_64: "ftpGetAddresses(char
const*, char const*)", referenced from:
Connector::connect(char const*, char const*) in Connector.o ld: symbol(s) not found for architecture x86_64 clang: error: linker
command failed with exit code 1 (use -v to see invocation)
It's probably worth noting that this is part of a Cocoa project, so the Connector class is #included in my AppDelegate, which is of course an Obj-C class. All of my Obj-C source files have the .mm extension.
I am certain that the lib is in working order, as I have no issue compiling a program on the command line with gcc ... -lftp. It's only a problem with Xcode.
Well, it appears I just talked myself through my own problem. As I was typing the last part of my question, I realized that the issue was linking a C library in a C++ source file. gcc would compile just fine on command line, but g++ gave me the same error as Xcode. One google search later I found this link, which solved my problem beautifully. Basically, if you want a C library to be compatible with C++, you need to add
#ifdef __cplusplus
extern "C" {
#endif
at the top of the library header file, and add
#ifdef __cplusplus
}
#endif
at the bottom of the file. I'll leave the question here hoping it will help someone else in the future.

GCC errors out on code that used to work fine

I have a program that has successfully compiled in the past, but now I get a bunch of errors.The source code is just:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
int main()
{
int fd;
fd = creat("datafile.dat", S_IREAD | S_IWRITE);
if (fd == -1)
printf("Error in opening datafile.dat\n");
else
{
printf("datafile.dat opened for read/write access\n");
printf("datafile.dat is currently empty\n");
}
close(fd);
exit (0);
}
Now I get the errors:
cre.C:8:54: error: ‘creat’ was not declared in this scope
cre.C:16:17: error: ‘close’ was not declared in this scope
cre.C:17:16: error: ‘exit’ was not declared in this scope
Sometimes I get an error about gxx_personality_v0 instead, and sometimes I get no error at all! I've tried updating gcc, but the problem remains. What's going wrong?
OS UBUNTU 12.1 on vaio laptop
From your error messages I see that you called your file cre.C. gcc is case-sensitive for file names: try naming it cre.c and compiling it.
$ LANG=C cc -o foo foo.C
foo.C: In function 'int main()':
foo.C:8:54: error: 'creat' was not declared in this scope
foo.C:16:17: error: 'close' was not declared in this scope
foo.C:17:16: error: 'exit' was not declared in this scope
but
$ LANG=C cc -o foo foo.c
foo.c: In function 'main':
foo.c:17:9: warning: incompatible implicit declaration of built-in function 'exit' [enabled by default]
As noted in a comment, a file with .C extension is handled by the C++ compiler, thus you are seeing those errors.
Read the man pages for the creat, close, and exit functions.
On my system, creat() requires:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
close() requires:
#include <unistd.h>
and exit() requires:
#include <stdlib.h>
As for why the code was compiling before, it's hard to tell. Perhaps the compiler was being invoked in a more permissive mode that didn't complain about missing function declarations, or perhaps some of the headers you do include have #include directives for the headers you need.