Adventures with C #1: GLib on Windows with MinGW/MSys using autotools

This is the first document in what may become a series of docs on cross-platform development using pure C (not C++) along with commonly available libraries.

A brief aside about my background for newcomers: I’m experienced with Python and C++ (although admittedly rusty in the latter), and I’ve written straight C as well (in college, for work, for GNU Typist). However, I feel my C skills are not as strong as they could be.

Basically, I know how to program and am not interested in reinventing the wheel. My focus is on developing my skills with practical C development, using any open source available libraries which I can along with, if feasible/possible, the MinGW/MSys toolchain.

This first article is a tutorial of how to use GLib with the autotools on Windows via MinGW/MSys.

MinGW/MSys were installed via the automatic installer. Relevant versions of installed programs include gcc 4.5.0, automake 1.11.1, and autoconf 2.67.

The GTK+ bundle in use is gtk+-bundle_2.22.0-20101016_win32.zip. I’m not actually using GTK+ in this project; however, the bundle includes GLib, pkg-config and the needed autoconf macros.

Unzip the GTK+ bundle somewhere on your system. Add the bin folder to your PATH, likely at the beginning to avoid conflicts with other tools.

The m4 macros in the share/aclocal folder of the GTK+ bundle should be copied to the folder identified by aclocal --print-ac-dir. On my system, this is /mingw/share/aclocal via the MSys shell.

Before going further, you should test pkg-config and make sure it works as expected:

pkg-config --cflags --libs glib-2.0

# Output on my machine:
#   -mms-bitfields -Ic:/gtk_bundle/include/glib-2.0 -Ic:/gtk_bundle/lib/glib-2.0/include  -Lc:/gtk_bundle/lib -lglib-2.0 -lintl

If this works, then create the following source file:

glib_test.c:

#include <glib.h>
#include <stdio.h>

int main(int argc, char **argv) {
	printf("GLib version: %d.%d.%d\n",
		GLIB_MAJOR_VERSION,
		GLIB_MINOR_VERSION,
		GLIB_MICRO_VERSION);
	return 0;
}

Run autoscan to create configure.scan. It should look like this initially:

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.67])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([glib_test.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT

We need to make a few changes to configure.scan to make a working configure.ac.

Autoconf will actually work without automake. So, if we want to use automake as well, we need to add a macro for it:

AM_INIT_AUTOMAKE([foreign])

Also, we’re using GLib, which requires special linker and compiler flags provided by the pkg-config tool. When using autoconf, we link these in via some special macros.

The following will check for pkg-config, get the needed flags from pkg-config for GLib, and assign them to two variables usable in automake:

PKG_PROG_PKG_CONFIG([0.23])  # Replace with target pkg-config version (I just used "pkg-config --version")
PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.26.0])  # Replace with target GTK version number
AC_SUBST([GLIB_CFLAGS])
AC_SUBST([GLIB_LIBS])

Finally, we need to specify the makefiles we want to generate via ./configure. For this example, we just need one: Makefile.

AC_CONFIG_FILES([Makefile])

While we’re working on this, go ahead and fill in some values for FULL-PACKAGE-NAME, VERSION and BUG-REPORT-ADDRESS.

Finally, if we merge all the above changes together and save as configure.ac, we should have something like the following:

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.67])
AC_INIT([glibtest], [0.1], [fakeaddress@foo.net])
AM_INIT_AUTOMAKE([foreign])  
AC_CONFIG_SRCDIR([glib_test.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC
PKG_PROG_PKG_CONFIG([0.23])

# Checks for libraries.
PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.26.0])
AC_SUBST([GLIB_CFLAGS])
AC_SUBST([GLIB_LIBS])

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_CONFIG_FILES([Makefile])
AC_OUTPUT

Now that configure.ac is out of the way, we need a Makefile.am. This will use the GLIB_CFLAGS and GLIB_LIBS variables made in the autoconf.ac.

Makefile.am:

bin_PROGRAMS = glib_test

glib_test_SOURCES = glib_test.c
glib_test_CFLAGS = $(GLIB_CFLAGS)
glib_test_LDADD = $(GLIB_LIBS)

The next step is to run autoreconf -i, which run all the necessary autotools and creates a configure file.

Run ./configure followed by make. This should compile the program.

Test the program: glib_test.exe. The MSys shell output should be something like the following:

Vultaire@core /c/code/projects/glibtest
$ glib_test.exe
GLib version: 2.26.0

If you got this far, excellent. You’re ready to start hacking with GLib.

An aside: why GLib? Because it provides a number of the data structures which would be covered by the STL in C++, or as part of the standard library in many higher level languages. It seems like a good foundation library to use for general development purposes, even if GTK+ is never used in the project.

Update, 2011-Jan-19:

Minor fix: Replaced glib_test_LIBS with glib_test_LDADD. The former was a mistake; the latter is the proper variable for specifying extra libraries which need to be linked.

Also, some documentation references:

http://www.flameeyes.eu/autotools-mythbuster/pkgconfig/pkg_check_modules.html: My original source for the pkg-config macros.
http://people.freedesktop.org/~dbn/pkg-config-guide.html#faq: Documents simple usage of the pkg-config macros with automake.
http://sources.redhat.com/automake/automake.html: Automake manual (confirms that glib_test_LDADD is where we should put pkg-config input.)

6 thoughts on “Adventures with C #1: GLib on Windows with MinGW/MSys using autotools

  • Hi! Could you please post the detailed instructions to setup GLib and MinGW on Windows 7. And followed by an example to run a program(preferably one in the link below).
    I’ve installed MingW(used the installer) and GLib.
    The setup is as follows:
    C:\Program Files (x86)\MinGW
    C:\opt\gtk
    But when trying to execute this program(Hello World program) http://www.ibm.com/developerworks/linux/tutorials/l-glib/section2.html , I run into errors(posted below).
    I am trying to compile the above program using following commands:
    (https://developer.gnome.org/glib/2.36/glib-compiling.html)
    cc hello.c `pkg-config –cflags –libs glib-2.0` -o hello
    gcc hello.c `pkg-config –cflags –libs glib-2.0` -o hello
    Following errors are returned:
    cc: error: `pkg-config: No such file or directory
    cc: error: glib-2.0`: No such file or directory
    cc: error: unrecognized option ‘–cflags’
    cc: error: unrecognized option ‘–libs’
    The O/P of following commands are:
    pkg-config –cflags glib-2.0
    pkg-config –libs glib-2.0
    -mms-bitfields -IC:/opt/gtk/include/glib-2.0 -IC:/opt/gtk/lib/glib-2.0/include
    -LC:/opt/gtk/lib -lglib-2.0 -lintl
    If you were to post the instructions….I would request you to design them around the example in the above link and my installation setup. That way I would be able to set the appropriate flags while compiling it.
    Thank you!

    • 1. Sorry for taking so long to approve this comment; I accidentally overlooked it.
      2. Sorry, but you’re asking me to do way too much here. But I can give you a pointer:
      Based on your error messages: it looks like you are executing this in a regular command shell, rather than MSys. The graves (`) are a feature of the bash shell which means, “run this command, and whatever it prints on stdout, inject into the outer command.” Bash handles this, but cmd.exe does not.
      Try installing MSys (if you haven’t already), and re-run your code via MSys. If you still get an error, reply and I might be able to give another pointer.
      Best of luck,
      – Paul

  • After I originally left a comment I seem to have clicked the -Notify me when new comments are added- checkbox and now
    each time a comment is added I recieve 4 emails wiyh the same comment.
    Perhaps there iis an easy method you are able to rekove me
    from that service? Many thanks!

  • hey paul
    i installed mingw and msys shell i installed libffi ,libconv-1.14 .gettext , glib 2.23 pkg-config and sdl packages , actually i followed this tuto http://www.betaarchive.com/forum/viewtopic.php?t=28834
    and i can successfully configure and compile qemu but when i run it a window error displayed
    Unable to start the program because it lacks libglib-2.0-0.dll on your computer
    i enter pkg-config file and try this command pkg-config –cflags –libs glib-2.0
    but i got
    package glib-2.0 was not found in the pkg-config search path, perhaps you should add the directory containing ‘glib-2.0.pc’ to the PKG_CONFIG_PATH environment variable , no package ‘glib-2.0’found
    any suggestion please

    • Hi,
      This is a rather old blog post and I haven’t worked on this stuff in ages… But the one thing I can suggest is that you try to install the “dev” package for glib. If you just installed the main glib package, you likely don’t have the bits needed for building stuff which depends on it, which would be why pkg-config said it couldn’t find glib-2.0.
      Hope that helps!

Leave a Reply to neo Cancel reply

Your email address will not be published. Required fields are marked *