User:Jeholm/Cons (program)

Cons is a computer program for build automation, designed as an alternative to Make. Cons is written in Perl and also uses Perl for the build description files.

Cons was originally developed by Bob Sidebotham, while employed at FORE Systems. Version 1.1 was published on CPAN in november 1996. In 2000 Cons was released under the GPL license and the copyright was transferred  from FORE Systems to the Free Software Foundation. Development of Cons stopped in 2001. Cons was the main inspiration for the SCons program written in Python.

Features

 * portable, since Cons is written in Perl
 * build files are Perl scripts, so the full power of a script language can be used
 * cryptographic checksums (MD5) are used to decide when a file needs to be rebuilt
 * #include file dependencies in C/C++ are automatically detected
 * changes in command lines causes rebuild
 * handles multi-directory builds using one global dependency tree (no "recursive make" problems)

Missing features:
 * can not build in parallel

Construct file syntax
Cons reads a build description file named Construct. This file contains Perl code telling Cons what to build, and corresponds to the Makefile used by Make. An example file building a C program consisting of two modules can look like: This file roughly corresponds to the following Makefile:

Running Cons
To build the program hello-world described above the following command can be issued: $ cons hello-world cc -Wall -g -c hello.c -o hello.o cc -Wall -g -c world.c -o world.o cc -g -o hello-world hello.o world.o If a file is changed, Cons will detect that and rebuild the affected files: $ edit world.c       # some change to source code $ cons hello-world cc -Wall -g -c world.c -o world.o cc -g -o hello-world hello.o world.o In some situations the behavior of Cons may seem non-intuitive to users of Make: $ rm world.o $ cons hello-world cc -Wall -g -c world.c -o world.o cons: "hello-world" is up-to-date. Since the file world.o was built the same way as before, the executable file hello-world is still considered up-to-date. This is a consequence of the the way Cons uses cryptographic checksums to decide if a file need to be updated.

Checksum calculation
Cons uses the cryptographic hash function MD5 to calculate "build signatures" for the files it builds. When this build signature is calculated, everything the file depends on is included: When the build signature differs from the previous time a file was built, it means that some aspect of the way the file is built has changed. This is what triggers a rebuilt of the file.
 * the command line used to produce the file
 * the signatures for the input file(s) used by the command
 * the signatures for the files found via #include (when compiling C/C++ files)

Cons is unable (by design) to tell directly what caused a change in signature for a file.

To see how Cons calculates the build signatures the option -S md5::debug can be given on the command line. Then Cons will produce a verbose log of its signature calculations: $ cons -S md5::debug hello-world sig::md5::srcsig(hello.c)	=> |87521dc6ff0839944b5f105ff1a12e39| sig::md5::srcsig(world.h)	=> |33072d54bdb336a75c303e1f9a7320b6| sig::md5::collect(33072d54bdb336a75c303e1f9a7320b6,                 87521dc6ff0839944b5f105ff1a12e39) => |57d6db512f6559ba08616ae88acf2503| sig::md5::collect(87521dc6ff0839944b5f105ff1a12e39,                 57d6db512f6559ba08616ae88acf2503,                  cc -Wall -g  -c %< -o %>) => |628c9bc22d672564b5717ef34f977ded| sig::md5::current(|e6e448c8931640acab2bdbbbc6682632|             <-- changed signature               eq |628c9bc22d672564b5717ef34f977ded|) cc -Wall -g -c hello.c -o hello.o sig::md5::srcsig(world.c)	=> |da0ce95af8e59804c23db0f484289d26| sig::md5::collect(da0ce95af8e59804c23db0f484289d26) => |9dace762171368c4e765c796b70a0f85| sig::md5::collect(da0ce95af8e59804c23db0f484289d26,                 9dace762171368c4e765c796b70a0f85,                  cc -Wall -g  -c %< -o %>) => |2e609c44279cd78f1839311e1a6ce940| sig::md5::current(|2e609c44279cd78f1839311e1a6ce940|              eq |2e609c44279cd78f1839311e1a6ce940|) sig::md5::collect => |d41d8cd98f00b204e9800998ecf8427e| sig::md5::collect(628c9bc22d672564b5717ef34f977ded,                 2e609c44279cd78f1839311e1a6ce940,                  d41d8cd98f00b204e9800998ecf8427e,                  cc -g -o %> %<  ) => |ec93c9a68d2ca4e981b426a661ac042a| sig::md5::current(|003f220a81bc578f2ae94e4fd047dd3b|             <-- changed signature               eq |ec93c9a68d2ca4e981b426a661ac042a|) cc -g -o hello-world hello.o world.o

The exact way Cons does the signature calculations has changed several times during the life of Cons. The behavior described above should be accurate for revision 1.147 of <tt>cons.pl</tt> from 2001-03-21.