Automatic make file generator

Version of 21 July, 2008.

Overview

Make files are used to control the compiling and linking of programs. In particular they detect which files have been changed and so need to be recompiled.

They are used typically by people who don't have access to an IDE (interactive development environment), don't like IDEs or are using an IDE which requires the use of a make file.

Make files are awkward to generate: you need to remember what depends on what and what files you need for your program; sometimes you need to enter quite a bit of information. If you use several different compilers then each will require a slightly different format.

The aim of the program described here is to generate make files automatically.

You tell genmake the name of the .cpp file containing the main function; it scans this file for #includes of .h files. These .h files need to have the .cpp files they need listed in comment statements in the format described below. The .h files are scanned for these .cpp files and more .h files and so on until all .h and .cpp files required are identified. Then genmake can generate the appropriate make file.

For example, the command

   genmake -g tmt > tmt_gnu.mak

will work out what files are required to build tmt and generate the make file for compiling under the Gnu g++ compiler. In this case tmt.cpp contains the main program. To actually compile and link tmt you would use

   make -f tmt_gnu.mak

where you might need gmake rather than make on some operating systems.

If you are using an extension other than .cpp for the bodies of your C++ files the program will still run provided the extension begins with .c. However you will also need to edit the compile rule in the preamble file.

Naturally some conventions are required to make all this work.

Lots of people have written make file generator programs, several of them with the name genmake. Automake is another name. Search on google for examples.

I use genmake to generate the make files I use for testing my programs and for the programs I write to carry out my analyses. I have all the c++ files I need for a project in a single directory. When I write a new c++ main file to carry out a new analysis I add its name to my target file (see section on the command line) and use genmake to make a new make file. All my work is with console mode compiles. I don't know whether there would be problems with GUI mode compiles. You would need to change some of the options in the preamble files.

The details

The command line

Load the genmake and sdiff executables and the preamble files into the directory containing the C++ source files.

You run genmake from a console window. The command has the form

   genmake -options files > file_name

where options is a sequence of option characters and files is a list of target names. file_name is the name of the make file to be generated. By target I mean the name of the executable file (without the .exe extension). This must also be the name of the source file containing the main program. It must include the extension of the source file if this is not .cpp.

The files list can also include names like @targets.txt. In this case targets.txt must be a file containing a list of target names with one name per line.

Library generation

The list of files can also include names of the form library.lfl where library is the name of a library to be generated. In this case library.lfl contains a list of names of .h files, one name per line. Then the make file will generate a library consisting of the compiled versions of the .cpp files required by those .h files and this library will be used for generating the executable files. At present this facility is available only for some compilers.

If an .lfl file is present, but all the .cpp files required to generate the corresponding library are missing you will get error messages but you will get a make file that assumes that the library is present and up-to-date.

Options

The options show the compiler for which the make file is being generated.

Compiler Option Preamble file Libraries OK
Borland 3.1 -b31 pre_b31.txt no
Borland 5.0 -b0 pre_b0.txt no
Borland 5.0, 16 bit -b0d pre_b0d.txt no
Borland 5.5 -b5 pre_b5.txt yes
Borland 5.6 -b6 pre_b6.txt yes
Borland 5.8 -b8 pre_b8.txt yes
CC -c pre_c.txt yes
Gnu g++ -g pre_g.txt yes
Gnu g++, dynamic library -gd pre_g.txt yes
Intel 5, 6, 7 for Linux -il5 pre_il5.txt yes
Intel 5, 6, 7 for Linux, dynamic library -ild5 pre_il5.txt yes
Intel 5, 6, 7 for windows -i5 pre_i5.txt yes
Intel 8,9,10 for Linux -il8 pre_il8.txt yes
Intel 8,9,10 for Linux, dynamic library -ild8 pre_il8.txt yes
Intel 8,9 for windows -i8 pre_i8.txt yes
Intel 10 for windows -i10 pre_i10.txt yes
Visual C++ 5 -m5 pre_m5.txt yes
Visual C++ 6, 7, 7.1 -m6 pre_m6.txt yes
Visual C++ 8 -m8 pre_m8.txt yes
Open Watcom -ow pre_ow.txt yes
Watcom 10A -w0 pre_w0.txt no
Watcom 10A, 16 bit -w0d pre_w0d.txt no

The preamble file is inserted at the beginning of the make file. This includes the options for the compiler. I have chosen a reasonable set of options, nevertheless you may want to edit these. You may also need to edit the paths given in some of these files.

The last column in the table shows whether I have included the code for building and linking to a library file.

Test option

Suppose ! is also included in the option list. Then the make file includes the instructions to run each of the programs and send the results to a file with a name of the form target.txx. This is compared with file target.txt and the list of differences output.

The difference program used is a very simple line by line compare program called sdiff. You can edit the preamble file to use a more advanced difference program. (However your difference program must not cause your make program to exit when it finds a difference).

When I am compiling a program with a make file generated with this option, I run it once, delete the *.txx files and run again piping the output through more or less so I can see the results.

Alternatively you can use a make file generated without the ! with the instruction

   make -f something.mak target.txx

to get the comparison.

Compiling the program

You need the files from my string library, the version of May 2005 or later. Copy the files for genmake and sdiff into the same directory. Use one of the make files for Gnu g++, Sun C++, Borland 5.5 or Microsoft Visual C++ 6 or 7 which are included in this package. Use the command appropriate to your system - for example

Gnu g++ (you may need gmake rather than make on some computers):

   make -f gm_gnu.mak

Sun CC:

   make -f gm_cc.mak

Borland 5.5 (you may need to edit the first line of gm_b55.mak):

   make -f gm_b55.mak

Microsoft Visual C++ 6 or 7 (but see the notes below about Microsoft Visual C++ 6 and 7):

   nmake -f gm_m6.mak

The make files themselves were generated with genmake. For example, I generated the Gnu version with the command

   genmake -g @gm_targ.txt > gm_gnu.mak

Once you have managed to compile it once on some compiler you can use a command of the form

   genmake -xxx @gm_targ.txt > gm_xxx.mak

to generate a make file where xxx denotes the option appropriate for your compiler.

The program uses the GString set of classes and so will not compile with older compilers such as the Watcom 10 compilers.

Testing

Run the following pairs of lines

   genmake -g @gm_targ.txt > gm_gnu.txx
   sdiff gm_gnu.mak gm_gnu.txx

   genmake -c @gm_targ.txt > gm_cc.txx
   sdiff gm_cc.mak gm_cc.txx

   genmake -b5 @gm_targ.txt > gm_b55.txx
   sdiff gm_b55.mak gm_b55.txx
   genmake -m6 @gm_targ.txt > gm_m6.txx
   sdiff gm_m6.mak gm_m6.txx

In Unix systems you made need to begin each line with ./

There shouldn't be any mismatches.

Remove the .txx files when you are finished.

Running a make file

Most make files use the command syntax

   make -f makefile target

where makefile is the name of your make file and target is the name of the file you want to generate. If you wanted to generate all the targets listed in the everything line in one of my make files omit the target. For example, if you had generated the make file for Borland Builder 5 with

   genmake -b5 @gm_targ.txt > gm_b55.mak

but wish to generate only sdiff.exe you would use the command

   make -f gm_b55.mak sdiff.exe

On the other hand, if you wished to generate both genmake.exe and sdiff.exe you would use

   make -f gm_b55.mak

Notes on the compilers

Here are some notes on the compilers.

Borland 3.1

This is an elderly Borland compiler. Some people still seem to use it, so I have included the make file generator for it. You cannot compile genmake with it. I am no longer testing this version.

Borland 5.0

This is for version 5.02 that came with Builder 4. You may need to edit the preamble file. If I am running in batch mode I use the following batch file, b0make.bat to run make

   SETLOCAL
   path C:\bc5\bin;%path%
   c:\bc5\bin\make %1 %2 %3 %4
and the command
   b0make -f b0.mak

where b0.mak is the make file generated by genmake, to make sure I get the Borland include and library files.

I cannot compile genmake with 16 bit version of this compiler.

I am no longer testing this version.

Borland 5.5

This is the compiler that is free from Borland's web site and is the main compiler in Builder 5. You may need to edit the preamble file. My tests have been with the Builder 5 compiler. I am no longer testing this version.

Borland 5.6

This is the compiler that comes with Builder 6. You may need to edit the preamble file. My tests have been with Builder 6 personal edition.

Borland 5.8

This is the compiler that comes with the 2006 version of the Borland compiler. You may need to edit the preamble file. The make file is the same as the 5.6 version except for where the Borland files are stored.

CC compiler

My tests are on a compiler on a Sun. The preamble file might need editing for some compilers. I assume the C++ files have extension .cpp, but the compiler wants files with extension .cxx. So I make a link to the .cpp file with extension .cxx before calling the compiler. You can delete the linking commands if your compiler accepts .cpp extensions. I precede executable names with ./. This prevents my program sdiff getting mixed up with a different program on the Sun and is required by some Unix shells.

Gnu compiler

My tests are on Linux and on a Sun and also on Cygwin. On some Unix machines you may need to use gmake rather than make. I precede executable names with ./ as is required by my version of Linux.

If you are compiling on a 64 bit machine add -m64 after every g++ in the make file that is generated if you want a 64 bit compile and -m32 if you want a 32 bit compile. Alternatively add one of these to the first line of pre_g.txt after g++.

Intel compiler

The PC version uses the Microsoft libraries and nmake. I use the following batch file to run nmake. You might need to make some changes to suit your system - particularly to suit the version of Visual C++ you are piggybacking off. This is for version 8 of the Intel compiler and version 7 of Visual C++.

   @echo off
   Rem Intel(R) C++ Compiler Build Environment for 32-bit applications
   echo.
   echo Intel(R) C++ Compiler 8.0 Build Environment for 32-bit applications
   echo Copyright (C) 1985-2003 Intel Corporation. All rights reserved.
   echo.
   SETLOCAL
   @call "C:\Program Files\Microsoft Visual Studio .NET\Vc7\Bin\Vcvars32.bat"
   echo.
   SET INTEL_COMPILER80=C:\Program Files\Intel\CPP\Compiler80
   SET INTEL_SHARED=C:\Program Files\Common Files\Intel\Shared Files
   SET INTEL_LICENSE_FILE=C:\Program Files\Common Files\Intel\Licenses
   SET PATH=%INTEL_COMPILER80%\Ia32\Bin;%INTEL_SHARED%\Ia32\Bin;%PATH%
   SET LIB=%INTEL_COMPILER80%\Ia32\Lib;%INTEL_SHARED%\Ia32\Lib;%LIB%
   SET INCLUDE=%INTEL_COMPILER80%\Ia32\Include;%INCLUDE%

   "C:\program files\Microsoft Visual Studio .NET\Vc7\bin\nmake" %1 %2 %3 %4
The Linux make file is just a simple modification of the Gnu version.

In my (64 bit) Red Hat system, I have added the line

. /opt/intel/cce/10.1.011/bin/iccvars.sh

to the .bashrc file to set up the appropriate links for the Intel 10 compiler.

In both cases you might want to tune the options in the preamble files. In this version, I have deleted the options -Qpc80 (Windows) or -pc80 (Linux). These appear to give more accuracy at the expense of more memory space. If memory space is not a problem you might like to reinstate them.

Microsoft Visual C++

Make with nmake. The preamble for version 5 of Visual C++ turns off optimisation.

I use the m6 version with version 7 (that comes with Visual.net). I use the following batch file to run nmake when I want version 7.

   SETLOCAL

   path C:\program files\Microsoft Visual Studio .NET\Vc7\bin;C:\program files\Microsoft Visual Studio .NET\Common7\Ide;%path%
   set include=C:\program files\Microsoft Visual Studio .NET\Vc7\include;C:\program files\Microsoft Visual Studio .NET\Vc7\PlatformSDK\include;%include%
   set lib=C:\program files\Microsoft Visual Studio .NET\Vc7\lib;C:\program files\Microsoft Visual Studio .NET\Vc7\PlatformSDK\lib;%lib%

   "C:\program files\Microsoft Visual Studio .NET\Vc7\bin\nmake" %1 %2 %3 %4
You will need to put in the correct disk letter. I used to find it necessary to copy the file mspdb70.dll from "C:\Program Files\Microsoft Visual Studio .NET\Common7\IDE\mspdb70.dll" to the current directory, but this seems to be fixed now.

With version 7.1 (that comes with Visual net2003) I use the batch file

   SETLOCAL

   path C:\program files\Microsoft Visual Studio .NET 2003\Vc7\bin;C:\program files\Microsoft Visual Studio .NET 2003\Common7\Ide;%path%
   set include=C:\program files\Microsoft Visual Studio .NET 2003\Vc7\include;C:\program files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include;%include%
   set lib=C:\program files\Microsoft Visual Studio .NET 2003\Vc7\lib;C:\program files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\lib;%lib%

   "C:\program files\Microsoft Visual Studio .NET 2003\Vc7\bin\nmake" %1 %2 %3 %4

With version 8 I use the batch file

@set VCINSTALLDIR=j:\program files\microsoft visual studio 8\VC
@set VSINSTALLDIR=j:\program files\microsoft visual studio 8

@if "%VSINSTALLDIR%"=="" goto error_no_VSINSTALLDIR
@if "%VCINSTALLDIR%"=="" goto error_no_VCINSTALLDIR

@echo Setting environment for using Microsoft Visual Studio 2005 x86 tools.

@rem
@rem Root of Visual Studio IDE installed files.
@rem
@set DevEnvDir=%VSINSTALLDIR%\Common7\IDE

@set PATH=%DevEnvDir%;%VCINSTALLDIR%\BIN;%VSINSTALLDIR%\Common7\Tools;%VSINSTALLDIR%\Common7\Tools\bin;%VCINSTALLDIR%\PlatformSDK\bin;%FrameworkSDKDir%\bin;%FrameworkDir%\%FrameworkVersion%;%VCINSTALLDIR%\VCPackages;%PATH%
@set INCLUDE=%VCINSTALLDIR%\ATLMFC\INCLUDE;%VCINSTALLDIR%\INCLUDE;%VCINSTALLDIR%\PlatformSDK\include;%FrameworkSDKDir%\include;%INCLUDE%
@set LIB=%VCINSTALLDIR%\ATLMFC\LIB;%VCINSTALLDIR%\LIB;%VCINSTALLDIR%\PlatformSDK\lib;%FrameworkSDKDir%\lib;%LIB%
@set LIBPATH=%FrameworkDir%\%FrameworkVersion%;%VCINSTALLDIR%\ATLMFC\LIB

"C:\program files\Microsoft Visual Studio 8\VC\bin\nmake" %1 %2 %3 %4

@goto end

:error_no_VSINSTALLDIR
@echo ERROR: VSINSTALLDIR variable is not set. 
@goto end

:error_no_VCINSTALLDIR
@echo ERROR: VCINSTALLDIR variable is not set. 
@goto end

:end
 

Watcom

I had version 10A of Watcom which is now very old. The make file produced by genmake won't work with version 11. I used to use the following batch file to run Watcom's make.

   path C:\WATCOM\bin;C:\WATCOM\binb;C:\WATCOM\binw;%path%
   set include=C:\WATCOM\h;C:\WATCOM\h\win
   set watcom=C:\WATCOM\.
   wmake %1 %2 %3 %4

You cannot compile genmake with Watcom's version 10A. I am no longer testing this version.

Open Watcom

I use the following batch file

   SETLOCAL

   SET PATH=C:\watcom\BINNT;C:\watcom\BINW;%PATH%
   SET WATCOM=C:\watcom
   SET EDPATH=C:\watcom\EDDAT
   SET INCLUDE=C:\watcom\H;C:\watcom\H\NT
   SET FINCLUDE=C:\watcom\SRC\FORTRAN
   wmake %1 %2 %3 %4

Dynamic linking under Linux

See The Linux GCC HOWTO. Add the extra option d to implement dynamic linking under Gnu G++ or the Intel compiler for Linux. You need to insert a link from some directory in your library path to the .so link that is generated in the directory you are compiling in. You can set the major and minor codes by editing the relevant prefix file.

Files

genmake.htm This file
rbd.css Style sheet for genmake.htm
genmake.cpp Body file for genmake
sdiff.cpp Body file for sdiff
pre_b31.txt preamble for Borland 3.1
pre_b0.txt preamble for Borland 5.0
pre_b0d.txt preamble for Borland 5.0 - 16 bit version
pre_b5.txt preamble for Borland 5.5
pre_b6.txt preamble for Borland 5.6
pre_b8.txt preamble for Borland 5.8
pre_c.txt preamble for CC compiler
pre_g.txt preamble for Gnu g++ compiler
pre_il5.txt preamble for Intel 5.0 for Linux
pre_i5.txt preamble for Intel 5.0 compiler for Windows
pre_il8.txt preamble for Intel 8.1,9 for Linux
pre_i8.txt preamble for Intel 8.1,9 compiler for Windows
pre_m5.txt preamble for VC++ 5
pre_m6.txt preamble for VC++ 6, 7, 7.1
pre_m8.txt preamble for VC++ 8
pre_ow.txt preamble for Open Watcom
pre_w0.txt preamble for Watcom 10.0
pre_w0d.txt preamble for Watcom 10.0 - 16 bit version
gm_target.txt list of programs and libraries to be compiled
gm_gnu.mak make file for Gnu G++
gm_b55.mak make file for Borland 5.5
gm_b56.mak make file for Borland 5.6
gm_b58.mak make file for Borland 5.8
gm_i8.mak make file for Intel compiler 8, 9 for Windows
gm_i10.mak make file for Intel compiler 10 for Windows
gm_il8.mak make file for Intel compiler 8, 9, 10 for Linux
gm_m6.mak make file for VC++ 6 and 7
gm_m8.mak make file for VC++ 8
gm_cc.mak make file for CC compiler
gm_ow.mak make file for Open Watcom

 

History