Compile GTK with GPLC - c

Trying to compile a C GTK gui + Prolog file using GPLC. I read that I can pass multiple flags to the gcc compiler from GPLC by using-C 'gcc flags here'
Ok so I can comiple my GUI alone with
gcc foo.c `pkg-config --cflags --libs gtk+-2.0` -o $(NAME)
However this will not work in GPLC because I would have
'`pkg-config --cflags --libs gtk+-2.0`'
This means I won't get the response from pkg-config as I am seeking because it is inside a "string". How can I fix that?
Lastly if I do something ugly like:
gplc -c foo1.c -C '-I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/libpng12 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng12 -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/freetype2 -lgtk-x11-2.0 -lgdk-x11-2.0 -lpangocairo-1.0 -latk-1.0 -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lpangoft2-1.0 -lpango-1.0 -lgobject-2.0 -lglib-2.0 -lfontconfig -lfreetype'
gplc -c foo2.pl
gplc foo1.o foo2.o -o gyges
I get compilation failure during linking due to all references to GTK functions being undefined. why?

Use shell in a Makefile:
GTK_FLAGS = $(shell pkg-config --cflags --libs gtk+-2.0)
gplc -c foo1.c -C $(GTK_FLAGS)
EDIT:
CC = gplc
GTK_CFLAGS = $(shell pkg-config --cflags gtk+-2.0)
GTK_LIBS = $(shell pkg-config --libs gtk+-2.0)
OBJECTS = foo1.o foo2.o
all: gyges
foo1.o: foo1.c
$(CC) -c foo1.c -o foo1.o $(GTK_CFLAGS)
foo2.o: foo2.pl
$(CC) -c foo2.pl -o foo2.o
gyges: $(OBJECTS)
$(CC) $(OBJECTS) -o gyges $(GTK_LIBS)

Answer
To solve the first problem I just needed to use shell inside a Makefile as Alter Mann pointed out.
The second problem was occurring because GPLC was not seeing the gtk libs during linking. This is because I was using the -C flag to pass args to the gcc compiler during compilation AND linking, this is incorrect, the -L flag is the flag that must be used to pass args to gcc during linking according to the gplc man.
So my final working MAKE looks likes this:
CC = gplc
GTK_CFLAGS = $(shell pkg-config --cflags gtk+-2.0)
GTK_LIBS = $(shell pkg-config --libs gtk+-2.0)
OBJECTS = foo1.o foo2.o
all: name
foo1.o:
$(CC) -c foo1.c -o foo1.o -C '$(GTK_CFLAGS)'
foo2.o:
$(CC) -c foo2.pl -o foo2.o
name: $(OBJECTS)
$(CC) $(OBJECTS) -o name -L '$(GTK_LIBS)'
rm *.o

Related

Trouble in linking the libIEC61850 library with GTK3+ for C

I'm having trouble combining compilations and linkages for two separate libraries. Following is a makefile for one of the libraries (libIEC61850):
LIBIEC_HOME=../../iec61850/libiec61850-1.4.0/
#Add this somehow:
#cc `pkg-config --cflags gtk+-3.0` main.c -o a.out `pkg-config --libs gtk+-3.0`
PROJECT_BINARY_NAME = a.out
PROJECT_SOURCES += main.c
INCLUDES += -I.
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS)
clean:
rm -f $(PROJECT_BINARY_NAME)
I would like to add the gtk-3.0 library in the compilation of main.c. To execute a typical gtk3 function, I simply write:
$ cc `pkg-config --cflags gtk+-3.0` main.c -o a.out `pkg-config --libs gtk+-3.0`
and the executable is generated without problem. How can I combine these two?
Fixed. Following is a Makefile to combine the libIEC61850 and GTK+ 3.0 libraries:
# Makefile to combine the libIEC61850 and GTK+-3.0 Libraries
# path to libIEC61850:
LIBIEC_HOME=../../iec61850/libiec61850-1.4.0/
#Add this somehow:
#cc `pkg-config --cflags gtk+-3.0` main.c -o a.out `pkg-config --libs gtk+-3.0`
PROJECT_BINARY_NAME = a.out
PROJECT_SOURCES += main.c
include $(LIBIEC_HOME)/make/target_system.mk
include $(LIBIEC_HOME)/make/stack_includes.mk
all: $(PROJECT_BINARY_NAME)
include $(LIBIEC_HOME)/make/common_targets.mk
$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME)
$(CC) $(CFLAGS) $(shell pkg-config --cflags gtk+-3.0) $(LDFLAGS) \
-o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) \
$(LIB_NAME) $(LDLIBS) $(shell pkg-config --libs gtk+-3.0)
clean:
rm -f $(PROJECT_BINARY_NAME)
I would add pkg-config --cflags gtk+-3.0 to CFLAGS and pkg-config --libs gtk+-3.0 to LDLIBS:
CFLAGS += $(shell pkg-config --cflags gtk+-3.0)
LDLIBS += $(shell pkg-config --libs gtk+-3.0)
They'll be sucked into the build commands the way you want, assuming all recipes follow conventional variable naming.
Use target specific variables if passing the flags to everything isn't to your liking.

Include glib library in Makefile

I'm not an expert of Makefile.
In my program I'm using hashtables of glib.h so in my Makefile I wrote this:
exec: bin/test
bin/test
clean:
rm -f build/* bin/*
CFLAGS = -g -Wall -Wpedantic -Wno-padded -O $(shell pkg-config --cflags --libs glib-2.0)
INCLUDES = include/*.h
COMMON_DEPS = $(INCLUDES) Makefile
build/%.o: src/%.c $(COMMON_DEPS)
$(CC) $(CFLAGS) -c $< -o $#
bin/test: /* functions.o*/ $(COMMON_DEPS)
$(CC) -o bin/test /* functions.o*/
But when I execute the Makefile I receive a list of these error messages:
...
functions.c: undefined reference to "g_str_hash"
functions.c: undefined reference to "g_str_equal"
...
I don't understand why
At the end I solved it in this way:
exec: bin/test
bin/test
clean:
rm -f build/* bin/*
CFLAGS = -g -Wall -Wpedantic -Wno-padded -O $(shell pkg-config --cflags glib-2.0)
LFLAGS = $(shell pkg-config --libs glib-2.0)
INCLUDES = include/*.h
COMMON_DEPS = $(INCLUDES) Makefile
build/%.o: src/%.c $(COMMON_DEPS)
$(CC) $(CFLAGS) -c $< -o $#
bin/test: /*functions.o */ $(COMMON_DEPS)
$(CC) -o bin/test /*functions.o */ $(LFLAGS)
The crux of the problem is that you're including the link flags in the compile command rather than the link command itself.
Remove --libs glib-2.0 from CFLAGS and add it to a new variable LFLAGS that can be used on the link line...
exec: bin/test
bin/test
clean:
rm -f build/* bin/*
CFLAGS = -g -Wall -Wpedantic -Wno-padded -O $(shell pkg-config --cflags glib-2.0)
LFLAGS = $(shell pkg-config --libs glib-2.0)
INCLUDES = include/*.h
COMMON_DEPS = $(INCLUDES) Makefile
build/%.o: src/%.c $(COMMON_DEPS)
$(CC) $(CFLAGS) -c $< -o $#
bin/test: /* functions.o*/ $(COMMON_DEPS)
$(CC) $(LFLAGS) -o bin/test /* functions.o*/
[Note: I've left the rest of the makefile untouched but the dependency specification for bin/test does look very odd.]

'gtk/gtk.h' file not found Even with pkg-config

I'm creating a software in C using the SDL library and GTK+3. My first attempt with GTK+3 on a specific main.c and its Makefile works well, but when I try to add my GTK project to the other piece of code using my "real" Makefile, even if I added the same flags for GTK+3, I can't compile and get the gtk/gtk.h file no found error. I visited many threads about this error but I still can't make it work.
Here's my old Makefile, making things work:
CC=clang
CPPFLAGS= `pkg-config --cflags gtk+-3.0`
CFLAGS= -Wall -Wextra -std=c99 -O2
LDFLAGS=
LDLIBS= `pkg-config --libs gtk+-3.0` `pkg-config gmodule-2.0 --libs`
SRC= main.c
OBJ= ${SRC:.c=.o}
all: main
main: ${OBJ} -lm
clean:
rm -f *~ *.o main
And here's the one I use for the project:
CC=clang
CPPFLAGS= `pkg-config --cflags sdl gtk+-3.0`
CFLAGS= -Wall -Wextra -Werror -std=c99 -O2 -pedantic
LDFLAGS=
LDLIBS= `pkg-config --libs sdl` `pkg-config --libs gtk+-3.0` `pkg-config gmodule-2.0 --libs` -lgtk -lgdk -lglib -lX11 -lXext -lSDL -lSDL_image -lm
SRCDIR = src
OBJDIR = obj
BINDIR = bin
TARGET = main
SOURCES := $(wildcard $(SRCDIR)/*.c)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
DEPENDS := $(wildcard $(OBJDIR)/*.d)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm = rm -f
all: makedirs $(BINDIR)/$(TARGET)
$(BINDIR)/$(TARGET): $(OBJECTS)
#$(CC) $(OBJECTS) $(LDLIBS) -o $#
#echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
#$(CC) $(CFLAGS) -c $< -o $#
#echo "[OK] Compiled "$<""
makedirs:
#mkdir -p $(OBJDIR)
#mkdir -p $(BINDIR)
#echo "[OK] Created directories : $(BINDIR) $(OBJDIR)"
[....] etc
And the error:
src/main.c:2:14: fatal error: 'gtk/gtk.h' file not found
#include <gtk/gtk.h>
Tanks for the attention :)
[EDIT]
~
▶ pkg-config --libs gtk+-3.0
-lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0
~
▶ pkg-config --cflags sdl gtk+-3.0
-D_GNU_SOURCE=1 -D_REENTRANT -pthread -I/usr/include/SDL -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng12 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
And the header of main.c:
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include "neural.h"
As Y. Verzun said, I forgot to add the CPPFLAGS rule, but not only to the OBJECTS:
$(BINDIR)/$(TARGET): $(OBJECTS)
#$(CC) $(OBJECTS) $(LDLIBS) $(CPPFLAGS) -o $#
#echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
#$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $#
#echo "[OK] Compiled "$<""
here's the code working, notice both of the $(CPPFLAGS) added.
Thanks a lot !
You simply forgot to add CPPFLAGS to the rule $(OBJECTS)
It should look like:
$(OBJECTS): $(OBJDIR)/%.o :
$(SRCDIR)/%.c#$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $#
#echo "[OK] Compiled "$<""

linking error in gtk2 application in ubuntu 12.04

I've a C GUI application (in GTK+2.0) that I used to link as follows :
gcc -O2 -std=gnu99 -pipe -Wall -lm `pkg-congig gtk+-2.0 `pkg-config --libs gtk+-2.0` -o exec a.o b.o c.o
which eventually converted into :
gcc -O2 -std=gnu99 -pipe -Wall -lm -pthread -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/x86_64 linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangoft2-1.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 -lglib-2.0 -lcairo -lgtk-x11-2.0 -lglib-2.0 -o exec a.o b.o c.o
It was until Ubuntu 12.04.
When I tried to link the files in the same way in Ubuntu 12.04 as well, it showed the following error :
/usr/bin/ld: b.o: undefined reference to symbol 'gdk_color_parse'
/usr/bin/ld: note: 'gdk_color_parse' is defined in DSO /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libgdk-x11-2.0.so so try adding it to the linker command line
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libgdk-x11-2.0.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status
If anyone has any idea about this please share.
With newer versions of GCC/binutils, linker flags have to come last because the linker looks ahead only for undefined symbols. Try
gcc -O2 -std=gnu99 -pipe -Wall a.o b.o c.o -lm `pkg-config --libs gtk+-2.0` -o exec
instead.

Glade and static linking

If I'm statically linking a GTK+ program under FreeBSD 8, gtk_builder_add_from_file() suddenly returns with an error:
Invalid object type `GtkWindow'
How to fix that? With dynamic linking everything works fine.
Update: linking is done by:
cc -o foobar foo.o bar.o main.o -Wall -pedantic -std=c99 D_THREAD_SAFE -DORBIT2=1 -D_REENTRANT -I/usr/local/include/gtk-2.0 -I/usr/local/lib/gtk-2.0/include -I/usr/local/include/atk-1.0 -I/usr/local/include/cairo -I/usr/local/include/pango-1.0 -I/usr/local/include -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/gconf/2 -I/usr/local/include/orbit-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/include/dbus-1.0/include -DGTK_DISABLE_DEPRECATED=1 -DGDK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED -DG_DISABLE_DEPRECATED=1 -DGTK_MULTIHEAD_SAFE=1 -export-dynamic -static -pthread -L/usr/local/lib -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lpangocairo-1.0 -lgio-2.0 -lXinerama -lXi -lXcursor -lXcomposite -lXdamage -lpangoft2-1.0 -lXext -lXfixes -lcairo -lpixman-1 -lpng -lxcb-render-util -lXrender -lxcb-render -lX11 -lxcb -lXau -lXdmcp -lpango-1.0 -lfontconfig -lexpat -lfreetype -lz -lgconf-2 -lORBit-2 -lm -ldbus-1 -lgmodule-2.0 -lgthread-2.0 -lgobject-2.0 -lglib-2.0 -liconv -lintl -lpcre
or in another words, in Makefile I have:
CFLAGS := -Wall -pedantic -std=c99
LDFLAGS := -export-dynamic -static
CFLAGS += $(shell pkg-config --cflags gtk+-2.0 gconf-2.0) \
-DGTK_DISABLE_DEPRECATED=1 -DGDK_DISABLE_DEPRECATED \
-DGDK_PIXBUF_DISABLE_DEPRECATED -DG_DISABLE_DEPRECATED=1 \
-DGTK_MULTIHEAD_SAFE=1
LDFLAGS += $(shell pkg-config --libs --static gtk+-2.0 gconf-2.0) -lintl -lpcre
...
$(NAME): $(OBJ)
cc -o $# $^ $(CFLAGS) $(LDFLAGS)
First of all linking gtk+ against an application statically is not supported. You are likely to run into a lot of hairy problems.
GtkBuilder needs to be able to dlopen your library, you need to make sure that all he symbols from the related libraries are also exported by your binary. On ELF systems you'll have to pass in the -export-dynamic/-Wl,-export-dynamic to the linker/gcc.

Resources