Abstract

If you’re building or fixing Informix ESQL-C applications then you’re almost guaranteed to come across the UNIX ‘make’ utility. This article describes a very simple Makefile for ESQL-C that can be adapted for many small projects.

Content

The example ‘Makefile’ in this article was used for a very small development project, specifically a TPC-C benchmark application originally adapted for Informix by Eric Vercelletto. The application comprises two executable programs: a benchmark runner and a client terminal program.

The original ‘Makefile’ was written to build a C-based PostgreSQL application which was more complex than the equivalent Informix program and contained many more components. The adapted ‘Makefile’ documented in this article demonstrates the relative power and simplicity of Informix ESQL-C and also highlights some of the pitfalls of using a Makefile from another more complex project.

Like any simple Makefile, this example has 3 main sections:

  1. Definition of ‘make’ variables and “pattern rules”
  2. Definition of explicit build rules
  3. Definition of clean-up commands and other common tasks associated with the project
Copy to Clipboard

At the beginning of many Makefile examples you often see something called a “pattern rule”. In this example we see the following:

Copy to Clipboard

Most of the more obvious pattern rules are predefined and this type of rule isn’t particularly relevant for a very small project like this, but a version of it was included in the original so we’ve kept it in there. This essentially acts as a generic rule for any input ESQL-C source file that is presented as an argument to the make utility or not included as a dependency in an explicit rule.Note that -c is not a valid ESQL-C compiler option but a C compiler option. The cc -c or gcc -c option will create an object *.o file from any input source *.c file. The linker isn’t invoked by esql when the –c flag is set which means no executable is created.In order to generate an executable from this object file we would usually call esql again using the generated object file and any dependent object files as input. Note that it is possible to use the native C compiler utility to invoke the linker, but the linker command would look something like the following:

Copy to Clipboard

‘lifsql’ is one of a number of common static library files used by esql programs. You would need to include all such files in the linker command for the linker process to complete successfully. It is actually possible to generate a complete list of static library files referenced by esql using the following command: `esql –libs`. Note that, using esql, there is no requirement to explicitly reference the library paths as these are specified in the environment variable $LD_LIBRARY_PATH.In the original Makefile there were two additional variables that were set, $(LIBS) and $(DEBUG). These have been removed or unset in the new version. This demonstrates a hazard when adapting another project’s Makefile.

Copy to Clipboard

In the original Makefile, $(LIBS) was only included as part of an esql call and –lm is included by default as part of the esql static library list. This means that the reference to $(LIBS) was redundant for the Informix version so we removed any reference to it.In the original Makefile, the variable $(DEBUG) was set to –g. By default this generated a debug version of the target object file and executable. This wasn’t required for our benchmark test so we unset this variable.Informix ESQL-C requires that the Informix environment is set correctly. An explanation of those environment variables that are used by ESQL-C can be found at:

http://www-01.ibm.com/support/knowledgecenter/SSGU8G_11.70.0/com.ibm.esqlc.doc/ids_esqlc_0862.htm

The syntax for the esql command can be found at:

http://www-01.ibm.com/support/knowledgecenter/SSGU8G_11.70.0/com.ibm.esqlc.doc/ids_esqlc_0070.htm
Copy to Clipboard

As you might expect, the ordering of the rules in a Makefile is significant. Specifically, the first rule is referred to as the ‘default goal’. This is the rule that is run by the make command when no arguments are provided. The convention is to use the label ‘all’ to refer to the default goal.

Copy to Clipboard

In this example, the purpose of this rule is to copy all of the executable files and configuration files to the execution directory specified by $(EXECDIR) which is already defined earlier in the Makefile. If this variable weren’t defined or the directory did not exist then the copy command would fail as the target would not be a valid directory. No error checking, validation or conditional processing is included in this Makefile, but it might look something like:

Copy to Clipboard

The original Makefile used the following rule:

Copy to Clipboard

This is worthy of special note because it highlights one of the biggest flaws in adapting an existing Makefile for a new project. The symbols ‘$@’ and ‘$?’ are examples of automatic variables and they have specific meaning to the ‘make’ command. They are interpreted only when the ‘make’ command is invoked. In this case ‘$@’ refers to the name of the target file, clien, and ‘$?’ refers to all of the dependencies that are NEWER than the target. This might have been appropriate in the original ‘C’-based application, but it may cause problems here as explained below.The command we want to be executed is:

Copy to Clipboard

In this example, if we modify ‘client.ec’ but the file ‘extra.o’ has an older timestamp than the target then we could actually see the following command being run instead:

Copy to Clipboard

Unfortunately, this won’t build because the target executable needs the extra.o file at link time and it hasn’t been included in the esql call. If in doubt about how a make command is going to execute then consider doing a dry run by typing ‘make –n’ at the command line.Note that the new Makefile only uses the ‘$@’ automatic variable.
Copy to Clipboard

These labels have no dependencies. These are called phony targets and are usually invoked by being referenced as an argument to the ‘make’ command.There are a couple of things that are worth noting in this example:
  1. All the ‘rm’ commands have the –f (force) flag set. The reason for this is that any error in the command will cause ‘make’ processing to stop and that isn’t necessarily the desired result in this case.
  2. This is subjective, but we’ve chosen to use no wildcards in the ‘rm’ commands. The variables (all defined in section 1) state exactly which files are included and, therefore, removed in each command.

Conclusion

The UNIX ‘make’ command is a very powerful developer productivity tool allowing the software developer to automate and control all aspects of the software build process. By default, the input to the ‘make’ utility is a rule definition file called ‘Makefile’. Unfortunately, for many projects it’s often easier to take a pre-written Makefile and adapt it rather than write one from scratch. This means that quite often ‘make’ can produce some unintended results as hopefully demonstrated in this article.

Disclaimer

Suggestions above are provided “as is” without warranty of any kind, either express or implied, including without limitation any implied warranties of condition, uninterrupted use, merchantability, fitness for a particular purpose, or non-infringement.