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

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 "$<""

Related

Build c program for release and build

The original makefile comes for Release build.
Original
APP:= deepstream-app
TARGET_DEVICE = $(shell gcc -dumpmachine | cut -f1 -d -)
NVDS_VERSION:=5.0
LIB_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/lib/
APP_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/bin/
ifeq ($(TARGET_DEVICE),aarch64)
CFLAGS:= -DPLATFORM_TEGRA
endif
SRCS:= $(wildcard *.c)
SRCS+= $(wildcard ../../apps-common/src/*.c)
INCS:= $(wildcard *.h)
PKGS:= gstreamer-1.0 gstreamer-video-1.0 x11
OBJS:= $(SRCS:.c=.o)
CFLAGS+= -I../../apps-common/includes -I../../../includes -DDS_VERSION_MINOR=0 -DDS_VERSION_MAJOR=5
LIBS+= -L$(LIB_INSTALL_DIR) -lnvdsgst_meta -lnvds_meta -lnvdsgst_helper -lnvdsgst_smartrecord -lnvds_utils -lm \
-lgstrtspserver-1.0 -ldl -Wl,-rpath,$(LIB_INSTALL_DIR)
CFLAGS+= `pkg-config --cflags $(PKGS)`
LIBS+= `pkg-config --libs $(PKGS)`
all: $(APP)
%.o: %.c $(INCS) Makefile
$(CC) -c -o $# $(CFLAGS) $<
$(APP): $(OBJS) Makefile
$(CC) -o $(APP) $(OBJS) $(LIBS)
install: $(APP)
cp -rv $(APP) $(APP_INSTALL_DIR)
clean:
rm -rf $(OBJS) $(APP)
Modified for both Release and Debug
APP:= deepstream-app
DEBUGAPP:= deepstream-app-debug
TARGET_DEVICE = $(shell gcc -dumpmachine | cut -f1 -d -)
NVDS_VERSION:=5.0
LIB_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/lib/
APP_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/bin/
ifeq ($(TARGET_DEVICE),aarch64)
CFLAGS:= -DPLATFORM_TEGRA
endif
SRCS:= $(wildcard *.c)
SRCS+= $(wildcard ../../apps-common/src/*.c)
INCS:= $(wildcard *.h)
PKGS:= gstreamer-1.0 gstreamer-video-1.0 x11
OBJS:= $(SRCS:.c=.o)
CFLAGS+= -I../../apps-common/includes -I../../../includes -DDS_VERSION_MINOR=0 -DDS_VERSION_MAJOR=5
LIBS+= -L$(LIB_INSTALL_DIR) -lnvdsgst_meta -lnvds_meta -lnvdsgst_helper -lnvdsgst_smartrecord -lnvds_utils -lm \
-lgstrtspserver-1.0 -ldl -Wl,-rpath,$(LIB_INSTALL_DIR)
CFLAGS+= `pkg-config --cflags $(PKGS)`
LIBS+= `pkg-config --libs $(PKGS)`
all: $(APP)
%.o: %.c $(INCS) Makefile
$(CC) -c -o $# $(CFLAGS) $<
%.o: %.c $(INCS) Makefile
$(CC) -g3 -c -o $# $(CFLAGS) $<
$(APP): $(OBJS) Makefile
$(CC) -o $(APP) $(OBJS) $(LIBS)
$(DEBUGAPP): $(OBJS) Makefile
$(CC) -g3 -o $(DEBUGAPP) $(OBJS) $(LIBS)
install: $(APP)
cp -rv $(APP) $(DEBUGAPP) $(APP_INSTALL_DIR)
clean:
rm -rf $(OBJS) $(APP) $(DEBUGAPP)
But it doesn't produce deepstream-app-debug. What should I change for both release and debug?
You can add the DEBUGAPP to the target all:
# This belongs in the makefile:
all: $(APP) $(DEBUGAPP)
This will build both APP and DEBUGAPP, if you call make like you used to do it most probably.
However, you can give make any target as an argument without further changing the makefile:
# This is a command in your shell:
make deepstream-app-debug

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.]

makefile not updating .o file with respectively with .h file

I have following make file :-
VER = Debug
CC = gcc
objectfiles = Getstr.o ui.o ustreqsol.o main.o
pkg = `pkg-config --cflags --libs gtk+-3.0`
obj = $(addprefix objs/,$(objectfiles))
../$(VER)/Calculator: $(obj)
$(CC) -o $# $(obj) $(pkg)
./objs/ui.o:ui.c
$(CC) -c -o $# $< $(pkg)
./objs/main.o:main.c
$(CC) -c -o $# $< $(pkg)
./objs/%.o: %.c %.h
$(CC) -c -o $# $<
clean:
-rm ../$(VER)/Calculator
-rm /objs/*
and follwing files in my src dir:-
$ ls
Getstr.c main.c Makefile objs ui.c ui.h ustreqsol.c ustreqsol.h
objs is directory. Whenver I change ustreqsol.h file it compiles ustreqsol.c file but not in case for ui.h file
$ touch ustreqsol.h
$ make
gcc -c -o objs/ustreqsol.o ustreqsol.c
gcc -o ../Debug/Calculator objs/Getstr.o objs/ui.o objs/ustreqsol.o objs/main.o `pkg-config --cflags --libs gtk+-3.0`
$ make
make: '../Debug/Calculator' is up to date.
$ touch ui.h
$ make
make: '../Debug/Calculator' is up to date.
As a noob in makefiles i have no idea why is this happening
The reason ui.c is not being rebuilt is because you explictly said ui.h is not a dependency:
./objs/ui.o:ui.c
$(CC) -c -o $# $< $(pkg)
For the general dependency you have set up:
./objs/%.o: %.c %.h
$(CC) -c -o $# $<
The dependency list only takes effect for files that you didn't explicitly set them for, such as ustreqsol.c.
You need to add targets for each object file specifying the dependencies for each one. The targets can be blank, as the %.o target will fill in what to do.
For example:
./objs/ustreqsol.o: ustreqsol.c ustreqsol.h ui.h
./objs/ui.o: ui.c ui.h
./objs/main.o: main.c ui.h ustreqsol.h
./objs/Getstr.o: Getstr.c
./objs/%.o: %.c %.h
$(CC) -c -o $# $<

Compile GTK with GPLC

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

How to write generic commands in makefile? [duplicate]

This question already has answers here:
Wildcard targets in a Makefile
(3 answers)
Closed 9 years ago.
This is what my current version looks like:
CC = gcc
CFLAGS = `sdl-config --cflags`
LIBS = `sdl-config --libs` -lSDL_ttf
program: uprising
uprising: main.o init.o display.o move.o global.o control.o battle.o
$(CC) main.o init.o display.o move.o global.o control.o battle.o -o uprising $(CFLAGS) $(LIBS)
global.o: global.c
$(CC) -c global.c -o global.o $(CFLAGS)
battle.o: battle.c
$(CC) -c battle.c -o battle.o $(CFLAGS)
main.o: main.c
$(CC) -c main.c -o main.o $(CFLAGS)
init.o: init.c
$(CC) -c init.c -o init.o $(CFLAGS)
display.o: display.c
$(CC) -c display.c -o display.o $(CFLAGS)
move.o: move.c
$(CC) -c move.c -o move.o $(CFLAGS)
control.o: control.c
$(CC) -c control.c -o control.o $(CFLAGS)
clean:
rm -f *~ *# uprising init.o main.o display.o move.o global.o control.o
You see, every module gets compiled in the same manner. I've been tired of editing this makefile when adding a new module to my project. Is there any way to type a module's name for just once (as if it was a argument), and let makefile build each module in the same way?
If you change LIBS to LDLIBS, you can write the entire makefile in just this:
CC = gcc
CFLAGS = `sdl-config --cflags`
LDLIBS = `sdl-config --libs` -lSDL_ttf
program: uprising
uprising: main.o init.o display.o move.o global.o control.o battle.o
$(CC) $^ -o $# $(CFLAGS) $(LDLIBS)
clean:
rm -f *~ *# uprising *.o

Resources