1

I'm trying to build a simple gtk+ example in Eclipse.

#include <gtk-2.0/gtk/gtk.h>
#include <glib-2.0/glib.h>

int main (int argc, char *argv[])
{
  /*-- Declare the GTK Widgets used in the program --*/
  GtkWidget *window;

  /*--  Initialize GTK --*/
  gtk_init (&argc, &argv);

  /*-- Create the new window --*/
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  /*-- Display the window --*/
  gtk_widget_show(window);

  /*-- Start the GTK event loop --*/
  gtk_main();

  /*-- Return 0 if exit is successful --*/
  return 0;
}

My console output after I build the project is...

make all 
Building file: ../src/gtkTest.c
Invoking: GCC C Compiler
gcc -I/usr/local/include -O0 -g3 -Wall -c -fmessage-length=0   `pkg-config --cflags --libs gtk+-2.0` -MMD -MP -MF"src/gtkTest.d" -MT"src/gtkTest.d" -o "src/gtkTest.o" "../src/gtkTest.c"
Finished building: ../src/gtkTest.c

Building target: testParallel
Invoking: GCC C Linker
gcc  `pkg-config --cflags --libs gtk+-2.0` -o "testParallel"  ./src/gtkTest.o   
./src/gtkTest.o: In function `main':
gtkTest.c:(.text+0x1e): undefined reference to `gtk_init'
gtkTest.c:(.text+0x28): undefined reference to `gtk_window_new'
gtkTest.c:(.text+0x38): undefined reference to `gtk_widget_show'
gtkTest.c:(.text+0x3d): undefined reference to `gtk_main'
collect2: error: ld returned 1 exit status

But if I compile it with following command in the command line, it builds successfully.

gcc -o main ../src/gtkTest.c `pkg-config gtk+-2.0 --cflags --libs`

What is the difference between the 2 commands? And how can I do it in Eclipse?

harsh
  • 905
  • 1
  • 10
  • 21

1 Answers1

1

The difference is that this compile-and-link command:

gcc -o main ../src/gtkTest.c `pkg-config gtk+-2.0 --cflags --libs`

correctly places the required libraries later in the linkage sequence than the object file(s) that require those libraries; while this link command:

gcc  `pkg-config --cflags --libs gtk+-2.0` -o "testParallel"  ./src/gtkTest.o

incorrectly places the libraries before the object file that needs them. Change to:

gcc -o "testParallel"  ./src/gtkTest.o `pkg-config --cflags --libs gtk+-2.0` 

Objects that want symbol definitions must be linked before the objects that provide the definitions. You have the symmetrically opposite problem to this one

Community
  • 1
  • 1
Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
  • So is it better to separate `cflags` and `libs` since we need includes to build the object files? – harsh Oct 27 '15 at 09:31
  • gcc `pkg-config --cflags gtk+-2.0` -o "testParallel" ./src/gtkTest.o `pkg-config --libs gtk+-2.0`. Something like this? – harsh Oct 27 '15 at 09:34
  • Yes, in Eclipse-CDT I think you'd need to discriminate for linkage, e.g. putting `pkg-config --libs-only-L gtk+-2.0` in **Miscellaneous** -> **Linker flags** and put the libraries reported by `pkg-config --libs-only-l gtk+-2.0` in **Libraries**. Anyhow its a matter of being more picky about which `pkg-config ...` invocations you use in which places. `man pkg-config` of course. – Mike Kinghan Oct 27 '15 at 09:56
  • In C++ Build settings --> GCC C Compiler / Linker --> Command line pattern I added ``pkg-config --cflags --libs gtk+-2.0`` at the very end and now I'm able to compile. Thanks! – harsh Oct 27 '15 at 11:01
  • Ah, that's good to know! Thought Eclipse must have an easier way. – Mike Kinghan Oct 27 '15 at 11:02