Writing Make Files

From VrlWiki
Jump to navigation Jump to search

The VRL has a custom system of support code for writing cross-platform, multi-compiler-version Makefiles. This helps tame the otherwise brutal strength of the GNU Make, in which it's really easy to write unmaintainable code and shoot oneself in the foot. A Makefile that uses the G Build system will build a single directory containing one library and/or one or more programs. Projects can consist of a directory tree with a Make File in each directory.

Once you've written a Makefile in your directory, you call the command make to build your program. The make program runs other commands (like invoking the compiler or linker) in order, according to the instructions implicit in the Makefile.

Below is a fairly exhaustive listing of all the Make variables that you can put in your custom Makefile in order to control your build. But first you should check out the sample Makefiles for a simple program and library.

Just working from the examples, it's straightforward to get started building your program so long as it is located in a standard sandbox directory. See the software development documentation for more details. However, if you are new to Make, you may find it useful to familiarize yourself with it. Make is a fairly user hostile language. The semantics are difficult to learn and error messages tend to be uninformative. However, Make is a language that is hard to avoid so most programmers become familiar with it. The G Build system uses Gnu make as it has consistent behavior over many platforms. So when please take the time to read the official documentation or find a good tutorial.


Make File Contents

  • Make Variable Settings
G_COMPILER   = <Compiler Version>        Designate a compiler and version.
PROJECT      = <Project Name>            Required project name.
PROJECT_HOME = <Root Directory>          Subdirectories reference the project root.
LIBRARY   = <Library Name>               Use when the directory contains a library.
CXXSRC    = <C++ Source>.cpp ...         List C++ source files for a library.
CSRC      = <C Source>.c     ...         List C source files for a library.
INCLUDE_H = <C/C++ Header>   ...         List public library headers to install.
PROGRAM      = <Program Name>   ...      List each program in the directory.
CXX<Program> = <C++ Source>.cpp ...      List C++ source files for a program.
C<Program>   = <C Source>.c     ...      List C source files for a program.
G_USE         = <Package Name>  ...      Predefined settings for packages.
LDLIB_VER     = <Library Name>  ...      Link a program with a library.
LDLIB_PROJECT = <Project Name>  ...      Add a project library to the search path.      
  • Variable Settings For Experts
BIN_SCRIPT      += <Script Files>       ...   Install files in the bin directory.
SHARE_FILE      += <Shared Files>       ...   Install files in the share directory.
LDLIB           += <Linker Setting>     ...   Pass libraries directly to the linker.
CXXFLAGS        += <C++ Compiler Flag>  ...   Pass flags directly to the C++ compiler.
CFLAGS          += <C Compiler Flag>    ...   Pass flags directly to the C compiler.
CXXINC          += <Include Directory>  ...   Pass includes directly to the C++ compiler. 
CINC            += <Include Directory>  ...   Pass includes directly to the C compiler.


Always add this include statement to bring in the G Build make files.

 include  $(G)/common/build/make/directory.make


Optionally add this include statement to build using all available compilers. Note that when including this make file additional targets are declared for:

install all allclean
 include  $(G)/common/build/make/build.multiple.make


  • Directory Access variables

These variables can be used to access directories to avoid using hard coded paths. Do not set these variables.

G_IMPORT        Location where third party software is installed.
G_INSTALL       Location where files are installed with "make install".

Projects With Multiple Directories

Projects can contain a directory tree that can be organized any way the developers chooses. Make files using the Build system each build a single directory in the tree. By convention the default Make target ("make" with no operand) will build the current directory for a single compiler. By convention an "all" target will build the current directory and all of it's subdirectories.

Usually Makefiles in a directory above several subdirectories will use Gnu Make commands to build the subdirectories. In this case you won't need to include the directory.make file. Here are some typical Gnu Make commands you might want to use:


# Require that the all targets always be used.
#
default:
    @echo  "Use:  make all"

clean:
    @echo  "Use:  make allclean"

test:
    @echo  "Use:  make alltest"


#  Create a target to clean all the subdirectories.
#
allclean:
    $(MAKE)  -C  utility       allclean
    $(MAKE)  -C  library       allclean
    $(MAKE)  -C  program       allclean


# Create a target to build one subdirectory.
#
.PHONY:  utility
utility:
    $(MAKE)  -C  utility    all


Only a small subset of Unix Utilities is included in the G Build system. Limiting the use of Unix commands in rules makes it easier to get a project developed on Unix to work on native Windows. Complex commands can invoke scripts. Python is recommended as you can use it to easily write platform independent scripts with good error reporting.