Version of 21 July, 2008.
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.
// body file: liststr.cpp // body file: gstring.cppwhich show which body files are required by that header (copy the spacing shown here).
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.
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.
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.
The options show the compiler for which the make file is being generated.
|Borland 5.0, 16 bit
|Gnu g++, dynamic library
|Intel 5, 6, 7 for Linux
|Intel 5, 6, 7 for Linux, dynamic library
|Intel 5, 6, 7 for windows
|Intel 8,9,10 for Linux
|Intel 8,9,10 for Linux, dynamic library
|Intel 8,9 for windows
|Intel 10 for windows
|Visual C++ 5
|Visual C++ 6, 7, 7.1
|Visual C++ 8
|Watcom 10A, 16 bit
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.
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.
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
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.
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.
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
Here are some notes on the compilers.
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.
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 %4and 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.
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.
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.
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.
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.
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++.
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 %4The Linux make file is just a simple modification of the Gnu version.
In my (64 bit) Red Hat system, I have added the line
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.
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 %4You 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
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.
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
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.
|Style sheet for genmake.htm
|Body file for genmake
|Body file for sdiff
|preamble for Borland 3.1
|preamble for Borland 5.0
|preamble for Borland 5.0 - 16 bit version
|preamble for Borland 5.5
|preamble for Borland 5.6
|preamble for Borland 5.8
|preamble for CC compiler
|preamble for Gnu g++ compiler
|preamble for Intel 5.0 for Linux
|preamble for Intel 5.0 compiler for Windows
|preamble for Intel 8.1,9 for Linux
|preamble for Intel 8.1,9 compiler for Windows
|preamble for VC++ 5
|preamble for VC++ 6, 7, 7.1
|preamble for VC++ 8
|preamble for Open Watcom
|preamble for Watcom 10.0
|preamble for Watcom 10.0 - 16 bit version
|list of programs and libraries to be compiled
|make file for Gnu G++
|make file for Borland 5.5
|make file for Borland 5.6
|make file for Borland 5.8
|make file for Intel compiler 8, 9 for Windows
|make file for Intel compiler 10 for Windows
|make file for Intel compiler 8, 9, 10 for Linux
|make file for VC++ 6 and 7
|make file for VC++ 8
|make file for CC compiler
|make file for Open Watcom