Showing posts with label autotools. Show all posts
Showing posts with label autotools. Show all posts

Sunday, June 9, 2019

Building Gtk Applications with the GNU Build System


Brief

In training (Qs-GnuBuildEnvironment) we discussed the rationale and means of using the Gnu Build System in application development and deployment. This training extends on that training to include instructions on how to utilize this build environment in the development of Gtk applications.

Introduction

The GNU Build System (also known as autotools) is a suite of tools authored by Gnu used to make portable software products. The build system includes two significant programs: automake and autoconf. The automake utility is used in the generation of makefiles from a Makefile.am template. The autoconf utility provides a set of utilities that help to generate the configure script. Together, these utilities provide the means of interrogating the target system and generating a target-specific makefile to be used to compile the application.

Before beginning, it is assumed that your system has the following packages installed:
  1. autoconf
  2. automake
  3. gcc
  4. g++
  5. pkg-config
  6. libgtk2.0-dev

Discussion

We will begin with the a simple non-Gtk application, examining the Gnu Build System configure.ac and Makefile.am inputs. Next, we will extend these files to support compiling and linking in the required Gtk includes and libraries.

Non-Gtk Application

We'll begin with a similar example to that outlined in training Qs-GnuBuildEnvironment. The example is similar but simplified to use a single source file. Without discussion we will identify the contents of the input files and abbreviated procedure for setting up the build environment.

configure.ac

AC_PREREQ(2.59)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AM_INIT_AUTOMAKE(someApp,2.1)
AC_CONFIG_HEADER([config.h])
AC_PROG_CC
AC_OUTPUT(Makefile)

Makefile.am

bin_PROGRAMS=someApp
someApp_SOURCES=myMain.c

myMain.c

#include <stdio.h>
#include <stdlib.h>

int main()
{
printf("(%s:%d) main process initializing\n",__FILE__,__LINE__);
printf("(%s:%d) main process terminating\n",__FILE__,__LINE__);
return EXIT_SUCCESS;
}

Brief Build System Setup

Given the configure.ac, Makefile.am, and myMain.c files stepping through the following procedure will result in building the someApp application.
$ aclocal
$ autoconf
$ autoheader
$ touch NEWS README AUTHORS ChangeLog
$ automake -a
$ ./configure
$ make


Gtk Application Extension

If our application is critically dependent on Gtk extending the autoconf package requirements to include Gtk will be our first step. Our configure.ac file changes to include the Gtk dependency:

configure.ac

AC_PREREQ(2.59)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AM_INIT_AUTOMAKE(someApp,2.1)
AC_CONFIG_HEADER([config.h])
AC_PROG_CC
GTK_REQUIRED_VERSION=2.0.0
PKG_CHECK_MODULES([GTK], gtk+-2.0 >= $GTK_REQUIRED_VERSION)
AC_OUTPUT(Makefile)

After making the above changes to the configure.ac file you must repeat the procedure for re-establishing the build environment.
$ aclocal
$ autoheader
$ automake –add-missing –copy
$ autoconf

Running ./configure will now execute the Gtk test rule, giving the following output:
checking for GTK... yes
If you examine the compiler outputs you will fail to find the inclusion of Gtk include path, nor Gtk library path. The Gtk include and library paths must be passed to make to accomplish our intentions.

The Makefile.am file must be extended to pass the Gtk flags and libraries on to the compiler. This is done by updating the Makefile.am as follows:

Note: if you get a “syntax error near unexpected token 'GTK,gtk+-2.0'” you'll need to install the pkg-config package.

Makefile.am

bin_PROGRAMS=someApp
someApp_SOURCES=myMain.c
myApp_LDADD=
myApp_CPPFLAGS = @GTK_CFLAGS@
myApp_LDADD += @GTK_LIBS@

Variables surrounded by @'s are automatically propagated without change to Makefile.in, the configure script makes the necessary substitutions by expanding them as appropriate.

Repeat the previous procedure since we've made modifications to the autotools input files:
$ aclocal
$ autoheader
$ automake –add-missing –copy
$ autoconf

Now, building the application will result in the GTK_CFLAGS and GTK_LIBS arguments being passed to the compiler. Inclusion of Gtk headers and references to Gtk objects can now be resolved during compilation.

Conclusion

In closing, authoring a Gnu Build Environment compliant product offers flexibility to the user by incorporating a standardized means for examining the target system and ensuring the required product dependencies are met and offers a well defined configuration and build environment when distributing your product by source. Incorporation of Gtk libraries into a simple example can be daunting when referencing man pages or elaborate examples, but can be relatively straight-forward with a simplified example.

References

  1. Introduction to the GNU Build System; FSK Consulting








Sunday, June 2, 2019

GNU Build System – Conditional Features


Brief

In training (Qs-GnuBuildEnvironment) we discussed the rationale and means of using the Gnu Build System in application development and deployment. This training extends on that training to include instructions on how to utilize this build environment in the development of more sophisticated applications where autoconf will examine the system and tailor the application dependent on the existence of module dependencies.

Introduction

The GNU Build System (also known as autotools) is a suite of tools authored by Gnu used to make portable software products. The build system includes two significant programs: automake and autoconf. The automake utility is used in the generation of makefiles from a Makefile.am template. The autoconf utility provides a set of utilities that help to generate the configure script. Together, these utilities provide the means of interrogating the target system and generating a target-specific makefile to be used to compile the application.

Before beginning, it is assumed that your system has the following packages installed:
  1. autoconf
  2. automake
  3. gcc
  4. g++
  5. pkg-config
  6. libgtk2.0-dev

Discussion


We begin with a similar example to that outlined in training Qs-GnuBuildEnvironment. The example is similar but simplified to use a single source file. Without discussion we will identify the contents of the input files and abbreviated procedure for setting up the build environment.

Base Example

configure.ac

AC_PREREQ(2.59)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AM_INIT_AUTOMAKE(someApp,2.1)
AC_CONFIG_HEADER([config.h])
AC_PROG_CC
AC_OUTPUT(Makefile)

Makefile.am

bin_PROGRAMS=someApp
someApp_SOURCES=myMain.c

myMain.c

#include <stdio.h>
#include <stdlib.h>

int main()
{
printf("(%s:%d) main process initializing\n",__FILE__,__LINE__);
printf("(%s:%d) main process terminating\n",__FILE__,__LINE__);
return EXIT_SUCCESS;
}

Brief Build System Setup

Given the configure.ac, Makefile.am, and myMain.c files stepping through the following procedure will result in building the someApp application.
$ aclocal
$ autoconf
$ autoheader
$ touch NEWS README AUTHORS ChangeLog
$ automake -a
$ ./configure
$ make


Example Extension

The autoconf utility allows examining the target system for features. A common action for applications is to allow autoconf to define C preprocessor symbols based on the result of such feature tests.

configure.ac

AC_PREREQ(2.59)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AM_INIT_AUTOMAKE(someApp,2.1)
AC_CONFIG_HEADER([config.h])
AC_PROG_CC
AC_CHECK_HEADER([popt.h],
[AC_DEFINE([HAVE_POPT_H], [1],
[Define to 1 if you have <popt.h>.])],
[AC_MSG_ERROR([Sorry, can't do anything for you])])
AC_OUTPUT(Makefile)

After making the above changes to the configure.ac file you must repeat the procedure for re-establishing the build environment.
$ aclocal
$ autoheader
$ automake –add-missing –copy
$ autoconf

Running ./configure will now execute the AC_CHECK_HEADER feature test, giving the following output:
checking for popt.h... no
configure: error: Sorry, can't do anything for you
or
checking for popt.h... yes
If the feature test for popt.h fails configure outputs an error and aborts the script. If the feature test for popt.h succeeds AC_DEFINE will define the HAVE_POPT_H precompiler symbol as 1, defined in config.h. This test effectively defines a critical dependency on popt.h, which isn't exactly what we intended. What we intended is the definition of a precompiler symbol based on the autoconf examination of the system. If we update the configure.ac file as follows we will get the desired result.

configure.ac

AC_PREREQ(2.59)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AM_INIT_AUTOMAKE(someApp,2.1)
AC_CONFIG_HEADER([config.h])
AC_PROG_CC
AC_CHECK_HEADER([popt.h],
[AC_DEFINE([HAVE_POPT_H], [1],
[Define to 1 if you have <popt.h>.])])
AC_OUTPUT(Makefile)

Next, by placing precompiler commands we can test for the definition of the HAVE_POPT_H symbol. This allows us to place conditional code in our application. In the absence of popt libraries we could substitute our own command line parsing routine.

myMain.c

#include <stdio.h>
#include <stdlib.h>

int main()
{
printf("(%s:%d) main process initializing\n",__FILE__,__LINE__);
#ifdef HAVE_POPT_H
printf("(%s:%d) whee...we have popt.h\n",__FILE__,__LINE__);
#else
printf("(%s:%d) rats...we don't have popt.h\n",__FILE__,__LINE__);
#endif
printf("(%s:%d) main process terminating\n",__FILE__,__LINE__);
return EXIT_SUCCESS;
}


Conclusion

In closing, authoring a Gnu Build Environment compliant product offers flexibility to the user by incorporating a standardized means for examining the target system and ensuring the required product dependencies are met and offers a well defined configuration and build environment when distributing your product by source. Incorporation of autoconf feature examination allows the conditional definition of precompiler symbols. These symbols can be used to place conditional code in our application, giving us alternatives to continue in the absence of optional features.

References

  1. Introduction to the GNU Build System; FSK Consulting