Issue
I want to compile which includes libraries for both gtk2 and linux canbus (PICAN 1.2) compilation
problem is these two compilations occur in a different way
canbus applications are compiled where make command is used:
gcc -c hello.c
gcc -o hello lib.o hello.o
here is a weird lib.o file used, in a hello.c is a #include"lib.h"
and #include"terminal.h"
, when I try:
$ gcc -Ihome/foo/linux-can-utils hello.c -o hello
Several outputs come up:
undefined reference to `fprint_canframe'
undefined reference to `fprint_long_canframe'
gtk2 applications are compiled:
gcc `pkg-config --cflags --libs gtk+-2.0` hello.c -o hello
where pkg-config
is used as a helping tool
$ pkg-config --cflags gtk+-2.0 -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/X11R6/include -I/usr/include/freetype2 -I/usr/include/atk-1.0
$ pkg-config --libs gtk+-2.0 -L/usr/lib -L/usr/X11R6/lib -lgtk-x11-2.0 -lgdk-x11-2.0 -lXi -lgdk_pixbuf-2.0 -lm -lpangox -lpangoxft -lXft -lXrender -lXext -lX11 -lfreetype -lpango -latk -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0
Solution
First, you should understand the basic of what you're trying to do, and what -I
, -L
, and -l
gcc options are used for. Then, as you're mixing several things here, leave the GTK+ aspect out, and just try to generate the candump binary.
This can be done using:
gcc candump.c lib.c -o candump
Or to split things:
gcc -c candump.c # compiles candump.c into candump.o
gcc -c lib.c # compiles lib.c into lib.o
gcc candump.o lib.o -o candump # links candump.o and lib.o into the candump binary
The undefined reference
errors you get are because you can't link into a binary as candump.c
uses functions declared in lib.c
. So when the linker tries to resolve all the symbols, it sees some code in candump.o
that wants to call fprint_canframe
, and the linker can't find that function anywhere in the file you've given to it. I had to grep fprint_canframe *
to find where that function was defined, see it was in lib.c
, and then tell it to gcc.
Now getting the arguments by hand for one single binary made of 2 .c
files is the simple case. Things like GTK+ are made of multiple libraries and getting the right arguments can be complicated. This is where pkg-config
enters. Some projects like GTK+ provide a .pc
file for pkg-config
to use. It declares the different options, paths, and dependencies it uses. So by calling pkg-config --libs gtk+-2.0
and you'll see the -l
options to provide to the linker so it knows wich library to link with to use the GTK+ 2 library. pkg-config --cflags --libs gtk+-2.0
will give the CFLAGS
, the C compiler flags, like the -I
flags that tell where to find the include files. This way when you do:
#include <gtk/gtk.h>
The compiler will know that that gtk
directory may be found in (for example) /usr/include
, and it will be able to copy its content into your .c
file when resolving the #include
.
Now if you want a binary that uses GTK+, you just have to give all the dependencies: the GTK+ ones, and yours. To know how to build GTK+ 2 applications, read Compiling GTK+ applications section of the documentation.
By the way, GTK+ 2 is really old, and will soon be unmaintained. You should switch to GTK+ 3 if you plan to learn GTK+.
Answered By - liberforce