Friday, October 14, 2011

Compiling GTK 3.0 programs in CodeBlocks

I spent some free time installing Ubuntu 11.10 in a VirtualBox session hosted by OS X. The trials involved with getting that to work may be the subject of another post. The punchline? VirtualBox and Unity 3d don't get along. Install the host drivers, update, then log in with Unity 2d selected. Doing those first two steps is tricky when the desktop windows don't redraw unless you go to the desktop switcher. Wowie. This was true in 11.04 and 11.10 beta 2.

My motivation for moving to 11.10 from 10.10 was so that I could get a handle on GTK 3.0. A few weekends ago I really beat myself into a pulp trying to make a basic "hello world" sort of program using Cairo in GTK and failed. A lot of the issues I had were with the basic initialization and packing a Cairo window into a GTK container. I also couldn't hash out the relationship between Cairo and GTK pixbuffs. That functionality seems to have changed a lot in GTK 3.0 and I want to try again.

I use CodeBlocks out of habit. Eclipse has a weird project organization that rubbed me the wrong way, and Anjuta was just plain hard to use. I don't know of any other popular IDEs in Linux (emacs and vim worry me).

Installing CodeBlocks and Synaptic Package Manager (to get the GTK 3.0 development files) was easy enough through the Ubuntu Software Center. No problems there, although I was very surprised that Synaptic wasn't pre-installed like in 10.10.

Expecting the default GTK program (the code that is generated when you start a new GTK project) to compile the first time was naive of me (well... it worked for GTK 2.0). The errors were about not being able to find the header files. I went error to error and added the paths to the headers in the compiler search options (Project->Build Options->Search directories->Compiler tab). Once all the missing files errors went away I got a bunch of new errors about how all the functions weren't defined. This basically means the libraries it needed to link against couldn't be found. Hooray.

I sat and thought about it and realized that if I were to compile this in the terminal I'd use pkg-config. pkg-config is a tool that looks at some different file (.pc files?) for all the compiler flags you'd need to use a certain package, like GTK.

If I type into the terminal: pkg-config --cflags gtk+-3.0

I get this out:

-pthread -DGSEAL_ENABLE -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/gtk-3.0

Similarly, if I type in: pkg-config --cflags gtk+-3.0

I get this:

-pthread -lgtk-3 -lgdk-3 -latk-1.0 -lcairo-gobject -lgio-2.0 -lpangoft2-1.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lglib-2.0 

GCC has this neat feature (or maybe it's a Linux thing?) where you can embed commands with text output into the GCC options when you run it if you surround the command with these: ''

So the compile command would look like this:

gcc program.c -o program`pkg-config --cflags --libs gtk+-2.0`

And you'd get all of those extra instructions into the gcc command. Pretty neat, right?

Ok, so I got real excited and found precedent for using pkg-config in CodeBlocks via StackOverflow in a question very similar to my own:

http://stackoverflow.com/questions/5921460/how-to-setup-gtk-to-develop-with-codeblocks-on-ubuntu-linux

However, when I did this (add the pkg-config lines to the compiler/linker "Other options") the error message I got said there was no input file. It's the same error you get if you just run gcc in the terminal.

As a last resort I simply copied the output of "pkg-config --cflags gtk+-2.0" into the compiler "Other options" and the output of "pkg-config --libs gtk+-2.0" into the linker "Other options" and now everything works just fine. This seems like a bit of a hack but I can't argue with the results.

I'm glad I finally have a functional development environment, but this raises a lot of questions. Why did it automagically work with GTK 2.0 in Ubuntu 10.10? Why did implementing the solution in the StackOverflow thread not work? Is this how everyone else has to do it?

This is a pretty strong argument in favor of avoiding IDEs for everything but editing. I should either learn Make or create a shell script that runs gcc with the pkg-config lines that takes in the .c file as an argument.

1 comment:

  1. The problem is in C::B's Gtk+2.0 project script. You need to update the path variables in that script for Gtk+3.0 paths.

    ReplyDelete