The Ciao lpmake scripting facility

Author(s): Manuel Hermenegildo, The CLIP Group.

Note: lpmake and the make library are still under development, and they may change in future releases.

lpmake is a Ciao application which uses the Ciao make library to implement a dependency-driven scripts in a similar way to the Unix make facility.

The original purpose of the Unix make utility is to determine automatically which pieces of a large program needed to be recompiled, and issue the commands to recompile them. In practice, make is often used for many other purposes: it can be used to describe any task where some files must be updated automatically from others whenever these change. lpmake can be used for the same types of applications as make, and also for some new ones, and, while being simpler, it offers a number of advantages over make. The first one is portability. When compiled to a bytecode executable lpmake runs on any platform where a Ciao engine is available. Also, the fact that typically many of the operations are programmed in Prolog within the makefile, not needing external applications, improves portability further. The second advantage of lpmake is improved programming capabilities. While lpmake is simpler than make, lpmake allows using the Ciao Prolog language within the scripts. This allows establising more complex dependencies and programming powerful operations within the make file, and without resorting to external packages (e.g., operating system commands), which also helps portability. A final advantage of lpmake is that it supports a form of autodocumentation: comments associated to targets can be included in the configuration files. Calling lpmake in a directory which has such a configuration file explains what commands the configuration file support and what these commands will do.

General operation

To prepare to use lpmake, and in a similar way to make, you must write a configuration file: a module (typically called Makefile.pl) that describes the relationships among files in your program or application, and states the commands for updating each file. In the case of compiling a program, typically the executable file is obtained from object files, which are in turn obtained by compiling source files. Another example is running latex and dvips on a set of source .tex files to generate a document in dvi and postscript formats.

Once a suitable make file exists, each time you change some source files, simply typing lpmake suffices to perform all necessary operations (recompilations, processing text files, etc.). The lpmake program uses the dependency rules in the makefile and the last modification times of the files to decide which of the files need to be updated. For each of those files, it issues the commands recorded in the makefile. For example, in the latex/dvips case one rule states that the .dvi file whould be updated from the .tex files whenever one of them changes and another rule states that the .ps file needs to be updated from a .dvi file every time it changes. The rules also describe the commands to be issued to update the files.

So, the general process is as follows: lpmake executes commands in the configuration file to update one or more target names, where name is often a program, but can also be a file to be generated or even a “virtual” target. lpmake updates a target if it depends on prerequisite files that have been modified since the target was last modified, or if the target does not exist. You can provide command line arguments to lpmake to control which files should be regenerated, or how.

Format of the Configuration File

lpmake uses as default configuration file the file Makefile.pl, if it is present in the current directory. This can be overridden and another file used by means of the -m option. The configuration file must be a module and this module must make use of the make package. This package provides syntax for defining the dependency rules and functionality for correctly interpreting these rules.

The configuration file can contain such rules and also arbitrary Ciao Prolog predicates, and can also import other Ciao modules, packages, or make file. This is useful to implement inherintance across diferent configuration files, i.e., the values declared in a configuration file can be easily made to override those defined in another, using the standard Ciao rules for module overriding, reexport, etc. The syntax of the rules is described in The Ciao Make Package, together with some examples.

lpmake usage


Supported command line options:

lpmake [--trace-deps] [-d Name1=Value1] ... [-d Namen=Valuen] \
	<command1> ... <commandn>

  Process commands <command1> ... <commandn>, using file 'Makefile.pl'
  or directory 'installer' in the current directory as configuration
  file. The configuration file must be a module.

  The optional argument '--trace-deps' produces verbose output,
  reporting on the processing of the dependency rules.  Very useful
  for debugging makefiles.

  The argument '-d' indicates that a variable definition Name=Value
  follows.  The effect of this is adding the fact 'name_value(Name, Value).'
  (i.e., 'name_value(Name) := Value.'), defined in the module 
  library(make/make_rt).

lpmake [--trace-deps] [-d Name1=Value1] ... [-d Namen=Valuen] \
	[[-m|-l] <.../Configfile1.pl>] [[-m|-l] <.../Configfilen.pl>] \
        <command1> ... <commandn>

  Same as above, but using files <.../Configfilex.pl> as configuration
  file. One or more configuration files can be used. When using more
  than one configuration file, the additional configuration files are
  loaded dynamically into the first one with the predicate
  register_config_file/1.  Using -l instead of -m indicates that this
  configuration file is a library module (i.e., it will be looked for
  in the libraries).

lpmake -h     [ [-m|-l] <.../Configfile.pl> ]
lpmake -help  [ [-m|-l] <.../Configfile.pl> ]
lpmake --help [ [-m|-l] <.../Configfile.pl> ]

  Print this help message. If a configuration file is available in the
  current directory or is given as an option, and the commands in it
  are commented, then information on these commands is also printed.



Acknowledgments

Some parts of the documentation are taken from the documentation of GNU's gmake.