How to use pkg-config in Make - c

I want to compile the simplest GTK program.
I can compile it using the command line:
gcc $(pkg-config --cflags --libs gtk+-3.0) main.c -o main.o
However, if I use Make it doesnt work:
CFLAGS=-g -Wall -Wextra $(pkg-config --cflags)
LDFLAGS=$(pkg-config --libs gtk+-3.0)
CC=gcc
SOURCES=$(wildcard *.c)
EXECUTABLES=$(patsubst %.c,%,$(SOURCES))
all: $(EXECUTABLES)
It tells me this:
gcc -g -Wall -Wextra -c -o main.o main.c
main.c:1:21: fatal error: gtk/gtk.h: No such file or directory
#include <gtk/gtk.h>
^
compilation terminated.
<builtin>: recipe for target 'main.o' failed
make: *** [main.o] Error 1
Where do I stick $(pkg-config --cflags --libs gtk+-3.0) in the Makefile to make it compile?
Thanks very much in advance for your kind help.

There are two issues.
First, your CFLAGS line is wrong: you forgot to say gtk+-3.0 in the pkg-config part, so pkg-config will spit out an error instead:
CFLAGS=-g -Wall -Wextra $(pkg-config --cflags gtk+-3.0)
Second, and more important, $(...) is intercepted by make itself for variable substitution. In fact, you've seen this already:
SOURCES=$(wildcard *.c)
EXECUTABLES=$(patsubst %.c,%,$(SOURCES))
all: $(EXECUTABLES)
is all done by make.
There are two things you can do.
First, you can use `...` instead, which does the same thing ($(...) is newer shell syntax).
CFLAGS=-g -Wall -Wextra `pkg-config --cflags gtk+-3.0`
LDFLAGS=`pkg-config --libs gtk+-3.0`
Second, since you seem to be using GNU make, you can use the shell substitution command, which was shown in the answer Basile Starynkevitch linked above:
CFLAGS=-g -Wall -Wextra $(shell pkg-config --cflags gtk+-3.0)
LDFLAGS=$(shell pkg-config --libs gtk+-3.0)

Related

SDL 2 C Compiler Flags

Whenever I run the following, I get undefined references to all the SDL-related functions used in my program:
cc -lSDL2 -lGL *.o
I believe this is caused by the lack of -l linker flags.
GCC arguments are positional, put the link flags after your o files:
gcc *.o -lSDL2 -lGL
Also, if you're on a proper full Linux system I'd recommend using pkg-config to pull compiler/linker flags:
gcc -c main.c `pkg-config sdl2 --cflags`
gcc main.o `pkg-config sdl2 --libs`

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.

Linking SDL in a C program

I have recently become interested in using SDL after having learned some basics of C. I have installed SDL_image and SDL_mixer. They are located in /usr/local/include/SDL2. I realize that you must link against the header files however I am not sure how to do it. I am getting the error that SDL_mixer or SDL_image do not exist (depending on their line order in my source code). I have tried two different compilation commands and neither work here they are:
gcc filename.c -o test -I./include -L./usr/local/include/SDL2 -lSDL2main -lSDL2 -lSDL_mixer -lSDL_image
gcc filename.c -o test -I./usr/local/include/SDL2 -L./lib -lSDL2main -lSDL2 -lSDL_mixer -lSDL_image
If anyone has any ideas I would appreciate it! Thanks in advance!
you do not want that leading period
wrong
gcc filename.c -o test -I./include -L./usr/local/include/SDL2 -lSDL2main -lSDL2 -lSDL_mixer -lSDL_image
closer - not necessarily correct yet
gcc filename.c -o test -L/usr/local/include/SDL2 -lSDL2main -lSDL2 -lSDL_mixer -lSDL_image
any path with a leading period indicates to start from current dir and go relative instead of the intended absolute path
any system has the notion of a default library path which is fine if you are using a standard install ... so no need to do a
-I/include
... sometime a library has helpers to identify and auto populate these ...
sdl and sdl2 do have such a helper ... this will give you those settings
gcc -o test filename.c `pkg-config --cflags --libs sdl2`
notice those backticks ... another syntax style would be
gcc -o test filename.c $(pkg-config --cflags --libs sdl2)
you are free to issue that stand alone just to take a peek
pkg-config --cflags --libs sdl2
... output
-D_REENTRANT -I/usr/include/SDL2 -lSDL2
Now onto your sdl mixer ... well it has a
pkg-config --cflags --libs SDL2_mixer
... output
-D_REENTRANT -I/usr/include/SDL2 -lSDL2_mixer -lSDL2
you probably do not want to mix sdl with sdl2 so replace mention of
-lSDL_mixer -lSDL_image
with
-lSDL2_mixer -lSDL2_image
as per
pkg-config --cflags --libs SDL2_image
... output
-D_REENTRANT -I/usr/include/SDL2 -lSDL2_image -lSDL2
so bundling these together
gcc -o test filename.c -lSDL2main $(pkg-config --cflags --libs sdl2) $(pkg-config --cflags --libs SDL2_mixer) $(pkg-config --cflags --libs SDL2_image)
or more simply combined to
gcc -o test filename.c -lSDL2main $(pkg-config --cflags --libs sdl2 SDL2_mixer SDL2_image )
this can be stripped down to simply the following ... yet above syntax is more robust to changes
gcc -o test filename.c -D_REENTRANT -I/usr/include/SDL2 -lSDL2main -lSDL2 -lSDL2_mixer -lSDL2_image
You can use sdl2-config to supply the appropriate flags to gcc:
gcc filename.c -o test `sdl2-config --cflags --libs`
sdl2-config --cflags produces a list of options that should be passed to the compiler, and sdl2-config --libs produces a list of libraries that should be linked to.

gcc glib symbol lookup error

I am currently programming a little C-programm that uses GLib-2.0 for its data structures.
I am compiling with the following command:
gcc -g -O3 -std=gnu99 -fPIC -shared -I/usr/local/java/jdk1.8.0_20/include \
-I/usr/local/java/jdk1.8.0_20/include/linux \
`pkg-config --cflags glib-2.0` `pkg-config --libs glib-2.0` \
-o runtimesamplingagent.so runtimesamplingagent.c
This works without problems.
However, when I run the program, I get following error:
symbol lookup error: ./runtimesamplingagent.so: undefined symbol: g_node_new
What's the cause of this?
I am pretty new to C but I would guess it's some kind of linking issue.
Any hints what could be the cause of it?
I am working on a Ubuntu 14.04 LTS 64bit machine with libglib-2.0-dev installed.
You have already included the linking option in the build command; the problem is that it is in the wrong place.
Your command looks like this:
gcc -g -O3 -std=gnu99 -fPIC -shared \
-I/usr/local/java/jdk1.8.0_20/include \
-I/usr/local/java/jdk1.8.0_20/include/linux \
`pkg-config --cflags glib-2.0` \
`pkg-config --libs glib-2.0` \ <<<
-o runtimesamplingagent.so \
runtimesamplingagent.c
In that line marked with <<<, you have already specified the options needed to link GLib. The only problem is that it is in the wrong place. You should put this at the very end, after the .c file.
So your command should look like this instead:
gcc -g -O3 -std=gnu99 -fPIC -shared \
-I/usr/local/java/jdk1.8.0_20/include \
-I/usr/local/java/jdk1.8.0_20/include/linux \
`pkg-config --cflags glib-2.0` \
-o runtimesamplingagent.so \
runtimesamplingagent.c \
`pkg-config --libs glib-2.0`
appending
-lglib-2.0
to the end of the build command, fixed it.

Undefined reference to `g_ascii_strcasecmp'

I can compile with this line:
#include <glib.h>
But when I add this line:
GTree* t = g_tree_new((GCompareFunc)g_ascii_strcasecmp);
I'm getting this error:
gcc cli.c -g -Wall -O0 -o httpget `pkg-config --cflags glib-2.0`
/s/cli.c:215: undefined reference to `g_ascii_strcasecmp'
/s/cli.c:215: undefined reference to `g_tree_new'
What do I do wrong?
You're forgetting to link with glib:
gcc `pkg-config --cflags glib-2.0` -g -Wall -O0 -o httpget cli.c `pkg-config --libs glib-2.0`
Or better, separate compilation and linking:
gcc `pkg-config --cflags glib-2.0` -g -Wall -O0 -c cli.c
gcc -o httpget cli.o `pkg-config --libs glib-2.0`

Resources