Using Borland's Command Line Tools |
|||||||||||||||
|
|||||||||||||||
| On this page: | |||||||||||||||
| Bang ('!') Directives | Command Line | Dot ('.') Directives | |||||||||||||
| Environment Variables | Macros | Operators | |||||||||||||
| Predefined Macros | Rules | Special Characters | |||||||||||||
| Temporary Files | |||||||||||||||
| Macros | |||||||||||||||
|
Macros are case-sensitive symbols defined in this way: MACRONAME=Something To use a macro in the file encase it in $() as in SOURCEFILES=abc.cpp def.c bcc32 -WCR $(SOURCEFILES) Macros do not need to be given a value. This also defines a macro. OTHERNAME= Macros defined on the command line will be known in the make file. This command: make -D_DEBUG;VER="7.0" -DX=3 -f buildit.mak causes make.exe to process buildit.mak with the macro _DEBUG defined and the macros X and VER defined with the values 3 and "7.0" respectively. Environment variables are also known macros! So if you use $(COMSPEC) in your make file it will resolve to the string associated with the environment symbol COMSPEC. If you give the command SET from the command line the environment variables that are defined on your machine will be written to the screen. Predefined Macros Make defines some macros by default. MAKEDIR the path to where make.exe is located. __MAKE__ the version number of make.exe MAKEFLAGS the options found on the command line. |
|||||||||||||||
| Dot Directives ('.' Directives) | |||||||||||||||
|
Directives which begin with a period are: .autodepend .noautodepend Tells Make to handle header file dependencies for C/C++ files. You do not need to list header files included by C/C++ source files as dependencies in rules. This is what makes implicit rules usable for building an object file from a C/C++ or assembly (compiled with TASM/TASM32) source file. .noautodepend turns this off. Note that the autodepend directive works because the object file contains compiler notes called comment records which specify the header files used by the source file. A compiled resource file (a *.RES file) contains no comment records so the autodepend function does not free you from the need to supply all the dependent file names for a *.RC file (such as *.RH, *.ICO and *.BMP file names). .ignore .noignore Ignore or do not ignore the return value or errorlevel from a command. The default is .noignore and if a command's returns value is not zero, the make is stopped. For example, when the compiler finds an error in the code it is compiling it gives a non-zero return value. .silent .nosilent Controls if a command that will be executed is written to the screen. The default is .nosilent .precious : Do not delete a file when the command to build it returned non-zero. As in: .precious : filename.exe otherfile.obj .suffixes : Implicit rules work on the suffix of a file name. This tells the order in which make will search for files with the given suffixes or extensions. For example: Assume there are two implicit rules, one to build a *.obj from a *.cpp and another for how to build a *.obj from a *.c The the result of this line .suffixes : .cpp .c is that when make needs to build a filename.obj it will look for filename.cpp Only if filename.cpp is not found will it then look for filename.c Note that there is a space before the period in each suffix. .path.ext = 'ext' is an actual file extension such as cpp. For example: .path.cpp = c:\projects\cppsrc Tells make.exe to look for files with the extension .cpp in the c:\projects\cppsrc directory. |
|||||||||||||||
| Bang Directives ('!' Directives) | |||||||||||||||
|
These directives work about as C's '#' preprocessor directives
except for !message which writes a message to the screen,
!error which does the same but also ends the make and
!include where encasing the included file name in brackets,
<>, or quotes, "", is optional. |
|||||||||||||||
|
|||||||||||||||
Make also has $d() and !$d() which test if something is or
is not defined.
!if $d(SOMENAME) is equivalent to !ifdef SOMENAME !if !$d(SOMENAME) is equivalent to !ifndef SOMENAMEThe !if and !elif statements are followed by an expression that evaluates to zero or not-zero. The expressions used by those statements can use the following operators: unary (leading) - + - * / % & && || > < >= <= == != ~ ! >> << ?: (as in expression ? true_result : false_result)The << and >> operators also work on strings. Decimal, octal or hexidecimal constants such as are in C/C++ can be used. The result type of an expression depends upon the operation. It will be one of a signed 4-byte number or a string. |
|||||||||||||||
| Make Command Line | |||||||||||||||
|
Command line options are case-sensitive and begin with '-' or
'/'. If you remember nothing else, remember that make -? or make /? will display a command summary help screen. Make uses a text file that we call a make file. When it is run without any arguments to tell what make file to use it will look for the files 'makefile' and 'makefile.mak' If the file name it was told to has no extension then if it is not found it will look for a file with that same name but with the extension .mak Some command line options: -a turns on .autodepend -i -i- .ignore and .noignore -B Build all. -m Show time stamp for each file processed. -s Silent. Do not write to the screen. -n Noexecute. Show but do not execute commands. -K Keep any temporary files created by make.exe -p Show all macros and their values. -f name name is the make file name. The space after the -f is optional. If name is not found and it has no file extension then it will look for name.mak and if found it will use that file. -e Environment macros are favored. If an environment variable has the same name as a macro defined in the make file, then use the value of the environment variable. (Has anyone found this to be of use?) -D Define one or more macros. If more than one macro is defined, each is separated from the next by a semicolon (a ';'). If a value is given it is with an equals sign and if the value is a string, it should be encased in quotes ("). Several -D options can be on one command line. For example: -DMACRO1;MACRO2="AbC.Def";MACRO3=4 -D_DEBUG -r Ignore any rules that are in the file builtins.mak (a configuration file that make.exe loads). -Umacroname Undefine (delete) the macro. Note: Using the command line set of options -B -n -K -p is of great help both in debugging make files and in seeing what an IDE-generated make file actually does. | |||||||||||||||
| Rules | |||||||||||||||
|
A rule is an expression which tells of a target, a file to create
or update and of its dependencies, other files which are needed to create
it. The time and date stamps of the other files are checked.
If any of the dependencies are newer than the target or if the
target does not exist, then the target needs to be built. An explicit rule consists of the target name starting in column 1 (the left column) followed by a colon (a ':') after which are listed the dependencies. If a a target has no dependencies, the colon is still required. Following a rule are lines which are indented, which have spaces in column 1. Those are the command lines to build the target. The following is a rule and command line to build hello.exe from the file hello.obj hello.exe : hello.cpp bcc32 -WCR hello.obj The first rule in the file is the one whose target is the task of the make file. Rules for any of the dependencies that follow in the file will be checked and the dependency built or rebuilt as needed. If you must use one make file to require several targets to be handled do it by writing a dummy rule that depends upon each of the several targets. For example, the following is a dummy rule that causes two targets to be rebuilt (assuming that rules and commands exist further on in the file to build them). Done : target1.exe target2.exe An implicit rule gives two file extensions or suffixes, the first (leftmost) of which is that of a dependency and the second of which is that of the target. No explicit file names are given as dependencies but a colon is still used. You might think of it as saying "how to make a right_suffix_file from a left_suffix_file". For example: .cpp.obj : bcc32 -WCR $< # (the $< above is the left-suffix file name.) |
|||||||||||||||
| Special Characters and Character Sequences | |||||||||||||||
|
'#' Starts a comment. Anything following (to
the right) is a comment. Blank Lines These are ignored. '-' A dash or minus sign as the first (leftmost) character in a command means that if the command fails, ends with a result or errorlevel of non-zero, the file it created is not to be deleted. This does the same thing for that one command that the dot directive .precious does for all commands. '@' An 'at' symbol as the first (leftmost) character in a command says that the command is to not be echoed to the screen. '$<' This is used in the commands which follow a rule. It stands for the file name with path and extension. In an implicit rule the file name is the one from the dependencies list. In an explicit rule it is the target name. '$*' Same as $< but without the extension. '$.' Same as $< but without the path. '$:' Same as $< but only the path. '$&' Same as $< but no path and no extension. '$@' Target name with path and extension. '$**' File name with path and extension.   In an implicit rule it is one file name. In an explicit rule it is the list of all dependent files separated by spaces. '$?' In an implicit rule same as $<. In an explicit rule it is the old dependent file names without path. If you cannot get what you want from what is above, you can also modify the '$' macros by encasing what follows the '$' in '()' and adding one of the letters D, F, B or R. For example: $(<D) Only drive and directory $(<F) File name with extension $(<B) Base file name (no extension) $(@R) Path and file name but no extension. |
|||||||||||||||
| Temporary Files | |||||||||||||||
|
Make can create temporary files that are used in commands. The
sequence is '&&' a character and the end of the line.
That is used to start the definition of of such a file.
Everything from there on until the next occurance of that character
is placed into the temporary file and the name of the file is inserted on
the command line at the location of the &&.
If you had this in a make file: # ----------- .silent done : type &&| This text came from the temporary file | # -----------The text shown will be written to the screen. If you ran make with the command line option -K to keep the temporary file then after the make the file MAKE0000.@@@ would be on the drive and its contents would be the text between the '|' characters. This is useful when a command line is very long. Most of the Borland tools accept response files. When the program sees an at-symbol (an '@') as the first character of a file name it takes the rest of its command line from that file. There are no command line length limitations on the contents of that file. There is an example of this on another of these pages: [Link to Example] You have control over what file name is used for the file, but the file is not temporary unless you let make.exe create the name. If a space and then a file name follows the ending character (the '|' above), then that name is what make will use for the file it creates. This allows you to create files that are used in the make according to what options are specified. For example you might create a string to be used as the window title which when built in debug mode says "Debug version". # ------------- !ifdef _DEBUG copy &&| char window_title[] = "Ed's Great Program - Debug Version" | caption.cpp !else copy &&| char window_title[] = "Ed's Great Program" | caption.cpp !endif # ------------- |
|||||||||||||||
| [Next Page: Create and Use a DLL] | |||||||||||||||