Trouble in linking the libIEC61850 library with GTK3+ for C - 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.

Related

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

Why does directly compiling by gcc in the terminal work but not with a make file?

I am trying to compile a GTK+ example using make, but when I run it, the terminal says "make: *** No rule to make target 'all'. Stop."
However, when I compile by typing the following, it compiles successfully.
gcc -g -Wall -o exampleapp main.c exampleapp.c exampleapp.h exampleappwin.c exampleappwin.h -export-dynamic `pkg-config --cflags --libs gtk+-3.0`
Here's what I put in my make file:
NAME=exampleapp
CFLAGS=-g -Wall -o $(NAME)
GTKFLAGS=-export-dynamic `pkg-config --cflags --libs gtk+-3.0`
SRCS= \
main.c \
exampleapp.c exampleapp.h \
exampleappwin.c exampleappwin.h
CC=gcc
all: main
main: $(SRCS)
$(CC) $(CFLAGS) $(SRCS) $(GTKFLAGS)
clean:
/bin/rm -f $(NAME)
Is something wrong with my make file? If so, how can I correct it?
You are missing some tabs in the rule section of your Makefile.
It should look like:
all: main
main: $(SRCS)
$(CC) $(CFLAGS) $(SRCS) $(GTKFLAGS)
clean:
/bin/rm -f $(NAME)
Note that the action lines must be indented with a literal tab character, not with spaces. (Stack Overflow converts the tab to four spaces -- don't just copy and paste!)
there are a few problems with the posted makefile.
Suggest using the following, which has recipe lines properly indented with a <tab> and generates macros using := so they are not re-evaluated every time they are referenced in the makefile.
This sample makefile also corrects the recipes for compiling and linking
NAME=exampleapp
CFLAGS := -g -Wall -Wextra -pedantic -std=gnu11 -c
GTKFLAGS := -export-dynamic `pkg-config --cflags --libs gtk+-3.0`
SRCS := \
main.c \
exampleapp.c \
exampleappwin.c
OBJS := $(SRCS:.c=.o)
HDRS := exampleapp.h examplappwin.h
CC := /usr/bin/gcc
RM := /bin/rm
.PSEUDO: all clean
all: $(NAME)
%.o:%.c $(HDRS)
<tab>$(CC) $(CFLAGS) -o $# $< -I.
$(NAME): $(OBS)
<tab>$(CC) $> $(GTKFLAGS) -o $#
clean:
<tab>$(RM) -f $(NAME) $(OBJS)
Note: the <tab> must be replaced in the actual file with a tab character

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 use pkg-config in Make

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)

In Makefile how do I build seperate executable for each C file

I am using Check for my C unit tests. For each C library file I create there should be one test file which should generate a single executable that is linked from the test and the source code. This executable should then be run to make sure all tests pass.
When there is only 1 test file and 1 source file everything works great. As soon as I add a second source file with the corresponding test file, it tries to link them all into 1 executable.
How do I get the second rule to pull 1 TEST_SRC and the matching SRC and header file into a TEST_OBJ then compile the 2 object files into an executable? Below is my current Makefile
OUT_DIR=bin
BUILD_DIR=build
TEST_BUILD_DIR=test_build
SRC_DIR=src
TEST_SRC_DIR=tests
SRC= $(wildcard $(SRC_DIR)/*.c)
TEST_SRC= $(patsubst $(SRC_DIR)/%.c, $(TEST_SRC_DIR)/%_tests.c, $(SRC))
TEST_OBJ= $(patsubst $(TEST_SRC_DIR)/%.c, $(TEST_BUILD_DIR)/%.o, $(TEST_SRC))
OBJ= $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(SRC))
$(OUT_DIR)/string_calculator_tests: $(TEST_OBJ)
gcc -o $# $^ `pkg-config --cflags --libs check`
$(TEST_OBJ): $(TEST_SRC) $(SRC)
gcc -c -o $# $^ `pkg-config --cflags --libs check`
Any help would be appreciated.
It's a little unclear exactly how you want this makefile to behave, but we can take it in stages.
Look at this rule:
$(TEST_OBJ): $(TEST_SRC) $(SRC)
gcc -c -o $# $^ `pkg-config --cflags --libs check`
Each object is built out of all source files. And you don't seem to have a rule for OBJ. So let's replace this with two static pattern rules:
$(TEST_OBJ): $(TEST_BUILD_DIR)/%.o : $(TEST_SRC_DIR)/%.c
gcc -c -o $# $< `pkg-config --cflags --libs check`
$(OBJ): $(BUILD_DIR)/%.o : $(SRC_DIR)/%.c
gcc -c -o $# $< `pkg-config --cflags --libs check`
Then a rule to build an executable from a pair of object files:
TESTS = $(patsubst $(SRC_DIR)/%.c, $(TEST_BUILD_DIR)/%_test, $(SRC))
$(TESTS): $(TEST_BUILD_DIR)/%_test : $(BUILD_DIR)/%.o $(TEST_BUILD_DIR)/%_tests.o
gcc -o $# $^ `pkg-config --cflags --libs check`
Then a rule to build all tests:
.PHONY: all_tests
all_tests: $(TESTS)
That should be enough to get you started. Once this works, there are many possible improvements, such as targets to run the tests, and tidier ways to write the tests using advanced techniques like vpath. And we haven't even talked about header files and dependency handling...

Resources