Command line builds with make
by Kent Reisdorph
In the article “IDE command-line options” I explained the C++Builder IDE’s command-line options and how to use them. In all cases, those options simply control how the IDE starts.
In some cases it is beneficial to be able to build or make a project entirely from the command line (without starting the IDE at all). The make utility that ships with C++Builder allows you to do that. This article will explain how you can use make to build projects from the command line.
Make targets
The file specified as the input file for make is considered the target. One of the nice things about make is that it can be used to build not only projects, but also to build project groups and packages (C++Builder 3 and later). This makes it possible to write scripts (batch files or perl scripts, for example) to automate your build process. At TurboPower, we use make to build our C++Builder packages for a particular product.
The file passed to make must be a makefile. A makefile is a text file that contains a list of the files to compile, rules for how those files will be compiled, the locations of headers or library files that the project requires, instructions for the linker, and so on. Basically, a makefile contains all of the information that the compiler and linker need to build a given project.
Make for C++Builder 1-4
Fortunately, it is not important that you are able to read and fully understand makefiles to be able to use make. You may or may not be aware of this fact, but C++Builder 1-4 projects are actually makefiles. This makes it possible to pass a project file (.MAK for C++Builder 1, or .BPR for C++Builder 3 and 4) directly to make for processing. I’ll explain the makefile command-line options later in the article, but the most important option is the f option. It is used to specify the file that make will operate on. Given that, you can build a project from the command line like this:
c:\Borland\bcb4\bin\make -fproject1.bpr
When make runs, you will see a number of messages on the screen as make calls the compiler and linker. If either the compiler or linker encounters an error, an error message is displayed and make stops building the project.
Not only are project files makefiles, but so are project group files (.BPG) and package source files (.BPK). This means that you can build an entire group of projects with just one call from the command line.
Make for C++Builder 5
The make utility that ships with C++Builder 5 is no different than the make that shipped with previous versions of C++Builder. However, project files in C++Builder 5 are no longer makefiles. Instead, a project file in C++Builder 5 is XML-based. This makes it impossible to pass a C++Builder 5 project file to make as you could with previous versions.
The Borland designers provided a new menu item that exports the project file as a makefile. Choose Proejct | Export Makefile from the C++Builder 5 main menu. When you choose this menu item, the Save As dialog will be displayed. The Save As dialog will have a default name of PROJECT.MAK, where PROJECT is the name of the current project. All you have to do is hit the Enter key to create a makefile for the project. You can then pass this makefile to the make utility. Alternatively, you can use BPR2MAK.EXE (found in the C++Builder 5 BIN directory) to create makefiles for C++Builder 5 projects.
Both project files and package source files are in XML format so you will have to export the makefile for these project types. Project groups, however, still use the old format and can be used directly with make.
It is important to understand that the makefile generated by the IDE is static. If you change the project (by changing project options or adding units to the project, for example) you will have to regenerate the makefile to ensure that it is up to date. If you are building your projects or packages from a batch file, you can simply run BPR2MAK.EXE on the project file before calling make. Doing so will ensure that your makefiles are always up to date.
Make options
The make utility has a number of command-line options. The most often used of those options are listed in Table A. Some of the more esoteric options are not listed in this table. To see a complete list of the command-line options available for make, run make from the command line with the h option:
make -h
This will list all of the make command-line options.
Table A: make command-line options
-B Performs a full build of the target. If this option is not specified, a make of the target is performed rather than a build.
-D Defines a compiler symbol. This can be a simple symbol (-DDEBUG, for example) or can be a symbol with an associated string (as in -DDEBUG=ON).
-I Specifies an include directory where headers are located.
-K Temporary files created by make are preserved when make is finished. When this option is off (the default), temporary files are deleted when make is finished.
-U Undefines a compiler symbol
-f Specifies the target filename (a project file, a makefile, a project group, or a package).
-a Performs auto-dependency checks for included files.
-c Caches auto-dependency information for included files.
-i Ignores errors returned by commands. When this option is off (the default), make will terminate when a compiler or linker error is encountered.
-l Enables use of long command lines (on by default).
-m Displays the date and time stamp of each file compiled.
-n Outputs commands to the console but does not perform them. This can be used to preview a make before actually performing the make.
-p Displays all macro definitions and implicit rules. This is essentially a textual description of the symbols and rules that will be used when the target is built.
-q Returns zero if target is up-to-date and nonzero if it is not (for use in batch files).
-s Silent mode, does not print commands before doing them.
-h Displays the full list of command-line options for make.
-? Same as -h
Using make is fairly simple in most cases. The command-line options you are most likely to use are the f option, and the B option. To perform a complete build of your project, for example, you would use:
make -fmyproject.bpr -B
Make will take the project file and build the project. It’s as simple as that.
Conclusion
In some cases, building from the command line using the make utility will result in faster builds. The primary reason to use make, though, is when using build scripts for complex projects. Complex projects often require a number of steps when built from the IDE (opening several project groups, packages, or projects and building each individually). By using make in a batch file (or other scripting language) you can reduce the number of steps required to build complex projects.