IBM/Rational Purify macro for Autoconf


IBM/Rational Purify® is an analysis software to help developers write reliable code. Purify works at two stages of a program generation: linking and running. At the linking stage it adds aditional instrumentation code into the executable by analysing the object code and also its library dependencies. At the running stage it will report all the errors it discovers in the program. It is very useful for memory related errors.

Integrating IBM/Rational Purify® into an autotools project is quite simple actualy. The simplest thing to do is to replace the default linker command (e.g. g++) with the purify linker command (e.g. purify g++).

I found this autoconf macro online and improved it a bit but I can't seem to find the original source.


        dnl Name: support-purify.m4
        dnl Description: Definition of SUPPORT_PURIFY m4 macro.

        AC_MSG_CHECKING(whether purify linker is enabled)
        AC_ARG_ENABLE(    purify-linker,
                        [Augment the linker with purify.])],

        if test "x$enable_purify_linker" = xyes ; then

            AC_DEFINE([USE_PURIFY_LINKER],[],[Link-time support for Purify.])

            dnl ====================================================
            dnl Specify location of PURIFY

            AC_MSG_CHECKING(for purify binary)
                        [AS_HELP_STRING([--with-purify=PATH Specify the path to the purify binary])],
                        [test "x$with_purify_path" = "xyes" && with_purify_path="purify"],

            dnl test if program exists in path
            /usr/bin/which $with_purify_path >& /dev/null

            if test $HAVE_PURIFY -ne 0; then
                AC_MSG_RESULT([NOT FOUND])
                AC_MSG_ERROR([*** cannot find purify binary at \"$with_purify_path\", use --with-purify-path=path_to_purify])


            dnl ====================================================
            dnl Specify options for Purify
            dnl #PURIFY_OPTIONS="-follow-child-processes=yes -windows=yes -cache-dir=/tmp/purecache -always-use-cache-dir=yes -view-file=${HOME}/tmp/%v-%p.pv -messages=batch -handle-calls-to-java")

            AC_MSG_CHECKING(for purify options)
                        [AS_HELP_STRING([--with-purify-options=ARG manually set PURIFY options to ARG])],
                        [with_purify_options="-follow-child-processes=yes -windows=yes -cache-dir=/tmp/purecache -always-use-cache-dir=yes -handle-calls-to-java -force-rebuild"])


            dnl ====================================================
            dnl Augment linker

            AUX_LINKER="${with_purify_path} ${with_purify_options}"

            AC_SUBST(AUX_LINKER, ["${with_purify_path} ${with_purify_options}"])

            AC_SUBST(CXXLD, ["$AUX_LINKER $CXX"])
            AC_SUBST(CCLD, ["$AUX_LINKER $CC"])

            AC_SUBST(CXXLD, ["$CXX"])
            AC_SUBST(CCLD, ["$CC"])


        dnl ====================================================
        dnl Debug the variables if needed
        dnl echo "AUX_LINKER = $AUX_LINKER"
        dnl echo "In macro SUPPORT PURIFY: CXX = $CXX"
        dnl echo "In macro SUPPORT PURIFY: CXXLD = $CXXLD"

        dnl ====================================================
        dnl End of Purify macro definition


To use the macro, save it to a text file (e.g. support_purify.m4) inside the macros directory on your project root. Then add these two lines to and recreate configure.


After generating configure you will be able to enable purify on your project by running configure with the options:

$ ./configure --enable-purify-linker [--purify-path=/path/to/rational/purify] [--purify-options=-handle-calls-to-java]

This is the output of configure in one of my projects:

$ ./configure --enable-purify-linker --with-purify-path=/opt/rational/releases/purify.i386_linux2.
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking how to create a pax tar archive... gnutar
checking for g++... g++
checking for C++ compiler default output file name... a.out
checking whether the C++ compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking for style of include used by make... GNU
checking dependency style of g++... gcc3
checking whether make sets $(MAKE)... (cached) yes
checking whether purify linker is enabled... yes
checking for purify binary... /opt/rational/releases/purify.i386_linux2.
checking for purify options... -follow-child-processes=yes -windows=yes -cache-dir=/tmp/purecache -always-use-cache-dir=yes -handle-calls-to-java -force-rebuild

checking for gcc... gcc
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking dependency style of gcc... gcc3
checking how to run the C preprocessor... gcc -E
checking for egrep... grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for stdlib.h... (cached) yes
checking for stdbool.h that conforms to C99... yes
checking for _Bool... yes
checking for an ANSI C-conforming const... yes
checking whether time.h and sys/time.h may both be included... yes
checking return type of signal handlers... void
checking for gettimeofday... yes
checking for memset... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: config.h is unchanged
config.status: executing depfiles commands


Published on Tuesday 2012/09/11, last modified on Tuesday 2015/01/13