Undeclared GTK_OBJECT during g++ compilation - g++

I get errors during compilation of a GTK+ application saying I have undeclared functions/definitions (I believe GTK_OBJECT might be a definition in a header file). This is my code (main.c):
#include <gtk/gtk.h>
static gint delete_event_cb(GtkWidget* w, GdkEventAny* e, gpointer data);
int main(int argc, char *argv[]) {
//Create widgets
GtkWidget *window;
gtk_init(&argc, &argv);
//Initialize widgets
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
//Configure widgets
gtk_window_set_title(GTK_WINDOW(window), "Hello World");
//Display widgets
gtk_widget_show(window);
//Set up signals
gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(delete_event_cb), NULL);
gtk_main();
return 0;
}
static gint delete_event_cb(GtkWidget* w, GdkEventAny* e, gpointer data) {
gtk_main_quit();
turn FALSE;
}
I am using the following command in bash:
g++ `pkg-config --libs --cflags gtk+-3.0` main.c -o binary
I do have the developer version of gtk+ 3.0 installed. Any help is greatly appreciated.
Edit: This is the error message I get:
main.c: In function ‘int main(int, char**)’:
main.c:21:41: error: ‘GTK_OBJECT’ was not declared in this scope
gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(delete_event_cb), NULL);
^
main.c:21:91: error: ‘GTK_SIGNAL_FUNC’ was not declared in this scope
gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(delete_event_cb), NULL);
^
main.c:21:98: error: ‘gtk_signal_connect’ was not declared in this scope
gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(delete_event_cb), NULL);
^
In file included from /usr/lib/x86_64-linux-gnu/glib-2.0/include/glibconfig.h:9:0,
from /usr/include/glib-2.0/glib/gtypes.h:32,
from /usr/include/glib-2.0/glib/galloca.h:32,
from /usr/include/glib-2.0/glib.h:30,
from /usr/include/gtk-3.0/gdk/gdkconfig.h:13,
from /usr/include/gtk-3.0/gdk/gdk.h:30,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from main.c:1:
main.c: In function ‘gint delete_event_cb(GtkWidget*, GdkEventAny*, gpointer)’:
/usr/include/glib-2.0/glib/gmacros.h:229:17: error: ‘turn’ was not declared in this scope
#define FALSE (0)
^
main.c:29:10: note: in expansion of macro ‘FALSE’
turn FALSE;
^

I solved it by myself, but it was difficult to find out how. I gave the wrong order of arguments to g++ and missed an argument as well. This is the bash command that worked for me:
g++ `pkg-config --libs --cflags gtk+-3.0` main.c -o binary `pkg-config --libs gtk+-3.0`

Related

Linker error in boost serialization of custom archive

I've tried to implement an own archive type for boost serialization following official boost example to write archives.
#include <iostream>
#include <vector>
#include <boost/serialization/nvp.hpp>
#include "boost/serialization/vector.hpp"
#include <boost/archive/detail/common_oarchive.hpp>
#include <boost/archive/detail/register_archive.hpp>
#include <boost/archive/detail/archive_serializer_map.hpp>
class complete_oarchive : public boost::archive::detail::common_oarchive<complete_oarchive>
{
friend class boost::archive::save_access;
template<class T>
void save(T & t){
std::cout << "saved data\n";
}
public:
void save_binary(void *address, std::size_t count){
}
};
template class boost::archive::detail::archive_serializer_map<complete_oarchive>;
template class boost::archive::detail::common_oarchive<complete_oarchive>;
BOOST_SERIALIZATION_REGISTER_ARCHIVE(complete_oarchive)
int main(int argc, char *argv[])
{
std::vector<double> testVector = {1, 2, 3, 4};
complete_oarchive oa;
std::vector<double>* pVec = &testVector;
oa << BOOST_SERIALIZATION_NVP(testVector);
oa << BOOST_SERIALIZATION_NVP(pVec);
return 0;
}
Compiling this example with
g++ -c -g -std=c++11 -MMD -MP -MF "build/Debug/GNU-Linux/demo.o.d" -o build/Debug/GNU-Linux/demo.o demo.cpp
g++ -o dist/Debug/GNU-Linux/serializationdemo build/Debug/GNU-Linux/demo.o -lboost_serialization
leads to the following linker error
build/Debug/GNU-Linux/demo.o: In function `boost::archive::detail::pointer_oserializer<complete_oarchive, std::vector<double, std::allocator<double> > >::pointer_oserializer()':
/opt/tools/boost/boostRdk-1.66.0/include/boost/archive/detail/oserializer.hpp:222: undefined reference to `boost::archive::detail::archive_serializer_map<complete_oarchive>::insert(boost::archive::detail::basic_serializer const*)'
build/Debug/GNU-Linux/demo.o: In function `boost::archive::detail::pointer_oserializer<complete_oarchive, std::vector<double, std::allocator<double> > >::~pointer_oserializer()':
/opt/tools/boost/boostRdk-1.66.0/include/boost/archive/detail/oserializer.hpp:227: undefined reference to `boost::archive::detail::archive_serializer_map<complete_oarchive>::erase(boost::archive::detail::basic_serializer const*)'
collect2: error: ld returned 1 exit status
It seems that serializing a pointer in
oa << BOOST_SERIALIZATION_NVP(pVec);
leads to this error. After deletion of this line everything works fine and the result is as expected.
Does anybody have experience in writting own serialization archives?
A simimal Problem was solved here
https://groups.google.com/forum/#!topic/boost-list/CMoDosGZUo8
but I wasn't able to solve this by forward declarations.
I solved the issue by replacing
#include <boost/archive/detail/archive_serializer_map.hpp>
by
#include <boost/archive/impl/archive_serializer_map.ipp>

Tensorflow XLA AOT: Eigen related Error Building Project

I'm currently trying to work through the tensorflow XLA ahead of time compilation work flow for the first time, and I've hit a problem while trying to build the final executable binary which includes the AOT compiled object.
I've used the tutorial here to generate the test_graph_tfgather.pb and test_graph_tfgather.config.pbtxt files. Then I've used the tfcompile tool directly to produce MyClass.o and MyClass.h. So far so good.
I'm now building a simple makefile project which includes this compiled model, but I'm getting some errors related to Eigen. Could this be due to a different version of eigen3 being installed on my computer? I've also had to comment out the Eigen::ThreadPool lines due to eigen errors too so some version miss match may be the problem. Has anyone seen this problem before or does anyone have any ideas how to get this working?
Thanks.
The build errors:
g++ -c -std=c++11 -I . -I /usr/include/eigen3 -I /home/user/tensorflow_xla/tensorflow -I /usr/include main.cpp
In file included from /home/user/tensorflow_xla/tensorflow/tensorflow/compiler/xla/types.h:22:0,
from /home/user/tensorflow_xla/tensorflow/tensorflow/compiler/xla/executable_run_options.h:20,
from /home/user/tensorflow_xla/tensorflow/tensorflow/compiler/tf2xla/xla_compiled_cpu_function.h:22,
from MyClass.h:14,
from main.cpp:6:
/home/user/tensorflow_xla/tensorflow/tensorflow/core/framework/numeric_types.h: In static member function ‘static tensorflow::bfloat16 Eigen::NumTraits<tensorflow::bfloat16>::infinity()’:
/home/user/tensorflow_xla/tensorflow/tensorflow/core/framework/numeric_types.h:79:28: error: ‘infinity’ is not a member of ‘Eigen::NumTraits<float>’
return FloatToBFloat16(NumTraits<float>::infinity());
^
/home/user/tensorflow_xla/tensorflow/tensorflow/core/framework/numeric_types.h: In static member function ‘static tensorflow::bfloat16 Eigen::NumTraits<tensorflow::bfloat16>::quiet_NaN()’:
/home/user/tensorflow_xla/tensorflow/tensorflow/core/framework/numeric_types.h:83:28: error: ‘quiet_NaN’ is not a member of ‘Eigen::NumTraits<float>’
return FloatToBFloat16(NumTraits<float>::quiet_NaN());
^
/home/user/tensorflow_xla/tensorflow/tensorflow/core/framework/numeric_types.h: At global scope:
/home/user/tensorflow_xla/tensorflow/tensorflow/core/framework/numeric_types.h:95:34: error: ‘log’ is not a template function
const tensorflow::bfloat16& x) {
^
/home/user/tensorflow_xla/tensorflow/tensorflow/core/framework/numeric_types.h:101:34: error: ‘exp’ is not a template function
const tensorflow::bfloat16& x) {
^
/home/user/tensorflow_xla/tensorflow/tensorflow/core/framework/numeric_types.h:107:34: error: ‘abs’ is not a template function
const tensorflow::bfloat16& x) {
^
Makefile:10: recipe for target 'main.o' failed
main.cpp source:
#define EIGEN_USE_THREADS
#define EIGEN_USE_CUSTOM_THREAD_POOL
#include <iostream>
#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
#include "MyClass.h" // generated
int main(int argc, char** argv) {
//Eigen::ThreadPool tp(2); // Size the thread pool as appropriate.
//Eigen::ThreadPoolDevice device(&tp, tp.NumThreads());
MyClass matmul;
//matmul.set_thread_pool(&device);
// Set up args and run the computation.
const float args[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
std::copy(args + 0, args + 6, matmul.arg0_data());
std::copy(args + 6, args + 12, matmul.arg1_data());
matmul.Run();
// Check result
if (matmul.result0(0, 0) == 58) {
std::cout << "Success" << std::endl;
} else {
std::cout << "Failed. Expected value 58 at 0,0. Got:"
<< matmul.result0(0, 0) << std::endl;
}
return 0;
}
Makefile
EIGEN_INC=-I /usr/include/eigen3
TF_INC=-I /home/user/tensorflow_xla/tensorflow
CPPFLAGS=-c -std=c++11
xla_hw: main.o MyClass.o
g++ -o xla_hw main.o MyClass.o
main.o: main.cpp
g++ $(CPPFLAGS) -I . $(TF_INC) $(EIGEN_INC) -I /usr/include main.cpp
I've solved this problem now, it turns out there is a specific version of eigen3 included with tensorflow and you need to use this version for it to work. When tensorflow has been built the correct version of eigen3 is located at <tensorflow path>bazel-tensorflow/external/eigen_archive
Below is the working makefile which includes the correct Eigen path as well as the libraries needed to link the project.
TF_INC=-I /home/user/tensorflow_xla/tensorflow/bazel-tensorflow/external/eigen_archive -I /home/user/tensorflow_xla/tensorflow
TF_LIBS=-L/home/user/tensorflow_xla/tensorflow/bazel-bin/tensorflow/compiler/tf2xla/ -lxla_compiled_cpu_function -L/home/user/tensorflow_xla/tensorflow/bazel-bin/tensorflow/compiler/aot -lruntime
CPPFLAGS=-c -std=c++11
xla_hw: main.o MyClass.o
g++ -o xla_hw main.o MyClass.o $(TF_LIBS)
main.o: main.cpp
g++ $(CPPFLAGS) -I . $(TF_INC) -I /usr/include main.cpp

Why do delegating method for file access in LD_PRELOAD override cause permission errors?

I'm working on a successor of auto-apt, a script which records open, access and stat requests for files (e.g. during run of configure scripts) and compares them with a list of installed files and files available in Contents.gz indices. This recoding has been done in the original which is undocumented and unmaintained for years (and the author unreachable) with a shared library used in LD_PRELOAD overriding open, access, stat, open64, stat64, etc.
I'm started learning how to use LD_PRELOAD with https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/. I do not understand the original.
While for some programs, like gnome-calculator, there're no issues, I'm experiencing permission denied errors at the beginning of configure of GCC 7.2 and bison 3.0.4, e.g.
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking whether ln works... yes
checking whether ln -s works... yes
checking for a sed that does not truncate output... /bin/sed
checking for gawk... gawk
checking for libatomic support... yes
checking for libcilkrts support... yes
checking for libitm support... yes
checking for libsanitizer support... yes
checking for libvtv support... yes
checking for libmpx support... yes
checking for libhsail-rt support... yes
checking for gcc... gcc
./configure: line 4297: conftest.err: Permission denied
./configure: line 4297: conftest.err: Permission denied
./configure: line 4297: conftest.err: Permission denied
cat: confdefs.h: Permission denied
checking for C compiler default output file name...
sed: can't read conftest.c: Permission denied
configure: error: in `/home/richter/sources/gcc-7.2.0':
configure: error: C compiler cannot create executables
See `config.log' for more details.
cat: confdefs.h: Permission denied
(I'm aware that one has to download prerequisistes with a script in contrib, but that shouldn't influce the issue here and GCC seems a good example for reproduction).
Following the referenced blog post I created
/*
* Experiments with LD_PRELOAD following
* https://web.archive.org/web/20171226024326/https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/
*/
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
typedef int (*orig_open_f_type)(const char *filename, int flags);
typedef int (*orig_stat_f_type)(int ver, const char *filename, struct stat *buf);
typedef int (*orig_stat64_f_type)(int ver, const char *filename, struct stat64 *buf);
int open(const char *filename, int flags, ...)
{
orig_open_f_type orig_open;
orig_open = (orig_open_f_type)dlsym(RTLD_NEXT,"open");
return orig_open(filename, flags);
}
int __libc_open(const char *filename, int flags, ...)
{
orig_open_f_type orig_open;
orig_open = (orig_open_f_type)dlsym(RTLD_NEXT,"__libc_open");
return orig_open(filename, flags);
}
int open64(const char *filename, int flags, ...)
{
orig_open_f_type orig_open;
orig_open = (orig_open_f_type)dlsym(RTLD_NEXT,"open64");
return orig_open(filename, flags);
}
int __libc_open64(const char *filename, int flags, ...)
{
orig_open_f_type orig_open;
orig_open = (orig_open_f_type)dlsym(RTLD_NEXT,"__libc_open64");
return orig_open(filename, flags);
}
int access(const char *filename, int type)
{
orig_open_f_type orig_open;
orig_open = (orig_open_f_type)dlsym(RTLD_NEXT,"access");
return orig_open(filename, type);
}
int euidaccess(const char *filename, int type)
{
orig_open_f_type orig_open;
orig_open = (orig_open_f_type)dlsym(RTLD_NEXT,"euidaccess");
return orig_open(filename, type);
}
int __xstat(int ver, const char *filename, struct stat *buf)
{
orig_stat_f_type orig_stat;
orig_stat = (orig_stat_f_type)dlsym(RTLD_NEXT,"__xstat");
return orig_stat(ver, filename, buf);
}
int __xstat64(int ver, const char *filename, struct stat64 *buf)
{
orig_stat64_f_type orig_stat64;
orig_stat64 = (orig_stat64_f_type)dlsym(RTLD_NEXT,"__xstat64");
return orig_stat64(ver, filename, buf);
}
int __lxstat(int ver, const char *filename, struct stat *buf)
{
orig_stat_f_type orig_stat;
orig_stat = (orig_stat_f_type)dlsym(RTLD_NEXT,"__lxstat");
return orig_stat(ver, filename, buf);
}
int __lxstat64(int ver, const char *filename, struct stat64 *buf)
{
orig_stat64_f_type orig_stat64;
orig_stat64 = (orig_stat64_f_type)dlsym(RTLD_NEXT,"__lxstat64");
return orig_stat64(ver, filename, buf);
}
which creates the above output when running env LD_PRELOAD=/path/to/ldpreload.so dash ./configure. config.log doesn't seem to help:
configure:3309: checking for libhsail-rt support
configure:3321: result: yes
configure:4038: checking for gcc
configure:4054: found /usr/bin/gcc
configure:4065: result: gcc
configure:4294: checking for C compiler version
configure:4303: gcc --version >&5
gcc (Ubuntu 7.2.0-8ubuntu3) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
configure:4314: $? = 0
configure:4303: gcc -v >&5
configure:4314: $? = 1
configure:4303: gcc -V >&5
configure:4314: $? = 1
configure:4303: gcc -qversion >&5
configure:4314: $? = 1
configure:4334: checking for C compiler default output file name
configure:4356: gcc conftest.c >&5
cc1: fatal error: conftest.c: Permission denied
compilation terminated.
configure:4360: $? = 1
configure:4397: result:
configure: failed program was:
configure:4403: error: in `/home/richter/sources/gcc-7.2.0':
configure:4407: error: C compiler cannot create executables
See `config.log' for more details.
A MCVE can be found at https://gitlab.com/krichter/ld-preload-demo.

Googlemock - multiple actions in WillOnce cause build error

I am already using gtest for some time but recently wanted to try out gmock. I am trying to mock class with method that returns value but also returns something in output parameter through reference. Here is my small code.
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using namespace ::testing;
class AReal
{
public:
virtual bool foo(std::vector<int>& v) const = 0;
};
class AMock : public AReal
{
public:
MOCK_CONST_METHOD1(foo, bool(std::vector<int>&));
};
class B
{
public:
B(AReal* _a) : a(_a) {}
bool foo(std::vector<int>& v) const { return a->foo(v); }
private:
AReal* a;
};
class FooTest : public Test {};
TEST_F(FooTest,
DummyTestVector) {
AMock a;
B b(&a);
std::vector<int> exp = { 1, 2, 3 };
EXPECT_CALL(a, foo(_))
.Times(1)
.WillOnce(AllOf(SetArgReferee<0>(exp), Return(true)));
std::vector<int> load;
EXPECT_TRUE(a.foo(load));
EXPECT_EQ(exp, load);
}
int main(int argc, char** argv) {
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
However, this code gives me this error.
$ g++ -Wall -Wextra -std=c++14 -I. -o test test.cpp gmock-gtest-all.cc -lpthread
test.cpp: In member function ‘virtual void FooTest_DummyTestVector_Test::TestBody()’:
test.cpp:40:61: error: no matching function for call to ‘testing::internal::TypedExpectation<bool(std::vector<int>&)>::WillOnce(testing::internal::AllOfResult2<testing::SetArgRefereeActionP<0, std::vector<int> >, testing::internal::ReturnAction<bool> >::type)’
.WillOnce(AllOf(SetArgReferee<0>(exp), Return(true)));
^
In file included from test.cpp:2:0:
gmock/gmock.h:10172:21: note: candidate: testing::internal::TypedExpectation<F>& testing::internal::TypedExpectation<F>::WillOnce(const testing::Action<F>&) [with F = bool(std::vector<int>&)]
TypedExpectation& WillOnce(const Action<F>& action) {
^
gmock/gmock.h:10172:21: note: no known conversion for argument 1 from ‘testing::internal::AllOfResult2<testing::SetArgRefereeActionP<0, std::vector<int> >, testing::internal::ReturnAction<bool> >::type {aka testing::internal::BothOfMatcher<testing::SetArgRefereeActionP<0, std::vector<int> >, testing::internal::ReturnAction<bool> >}’ to ‘const testing::Action<bool(std::vector<int>&)>&’
If I don't use AllOf but rather specify just one action, either SetArgReferee or Return, everything works just fine. The use of AllOf causes this kind of error. I have found about AllOf here gmock multiple in-out parameters SetArgReferee and basically my code is same as the answer.
After one whole afternoon of trying everything I found out it was just my stupidity. All the time I somehow thought that AllOf == DoAll. Realized it just now.

Use dlsym on a static binary

Is there any hope of running dlopen(NULL, ...) and getting symbols for a statically compiled binary?
For example, with the following code I can get symbols if the program is compiled dynamically and I use -rdynamic.
$ gcc -o foo foo.c -ldl -rdynamic
$ ./foo bar
In bar!
But with -static I get a cryptic error message:
$ gcc -static -o foo foo.c -ldl -rdynamic
/tmp/cc5LSrI5.o: In function `main':
foo.c:(.text+0x3a): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$ ./foo bar
/lib/x86_64-linux-gnu/: cannot read file data: Is a directory
The source for foo.c follows:
#include <dlfcn.h>
#include <stdio.h>
int foo() { printf("In foo!\n"); }
int bar() { printf("In bar!\n"); }
int main(int argc, char**argv)
{
void *handle;
handle = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL);
if (handle == NULL) {
fprintf(stderr, "%s\n", dlerror());
return 1;
}
typedef void (*function)();
function f = (function) dlsym(handle, argv[1]);
if (f == NULL) {
fprintf(stderr, "%s\n", dlerror());
return 2;
}
f();
return 0;
}
Is there any hope of running dlopen(NULL, ...) and getting symbols for a statically compiled binary?
No.
On most UNIXes you can't even link with -static and -ldl at the same time. Using glibc you can, but the utility of doing so is very limited. Basically, this ability is present only to support /etc/nsswitch.conf, and nothing else.
There is also no point in doing the dynamic lookup you did.
If you are trying to allow one of foo, bar or baz be called depending on command line arguments, just put a table in, e.g.
struct { const char *fname, void (*fn)(void) } table[] =
{ {"foo", &foo}, {"bar", &bar}, ...};
for (int i = 0; i < ...; ++i)
if (strcmp(argv[1], table[i].fname) == 0)
// found the entry, call it
(*table[i].fn)();
If you are trying to "maybe" call foo if it is linked in, and do nothing otherwise, then use weak references:
extern void foo(void) __attribute((weak));
if (&foo != 0) {
// foo was linked in, call it
foo();
}