How To - Using make with GNAT


The following make file can be used to automate the build process of mixed-language projects. It is designed for use with the Cygwin tools.
# Makefile for mixed-language compile and link -- C main with ada units
#
# Author: David C. Hoos
#         david.c.hoos.sr@ada95.com
#         http://ada95.com
#         ftp://ftp.ada95.com
#
# Assumptions:
#
#  1.  All Ada source files -- i.e., files with names having .ads and .adb
#      extensions -- are used in the build.
#
#  2.  All C source files -- i.e., files with names having .c extensions
#      are used in the build.
#
# The following make macro is used to point to any Ada Library Information
# files in other directories on which the Ada Library Information in this
# directory depend,  
ADAINCLUDES =

# The following make macro defines the debug switch to be used.  if no debugging
# information is desired in the excecutable, it can be left blank.  Or, for
# certain platforms, one might want to use -gstabs here
DEBUG       = -g

# The following make macro defines arguments to be passed to the linker -- e.g
# for extra libraries, such as -L/usr/local/lib or -lm
LDARGS     =

# The following make macro defines argeuemnts given to the C compiler
CCARGS      = -c $(DEBUG)

# The following make macro defines argeuemnts given to gnatbind
BARGS       = -n $(DEBUG) $(ADAINCLUDES)

# The following make macro defines argeuemnts given to the ada compiler
CARGS       = -c -O3 -Wuninitialized

# The following make macro defines the suffix appended to executable filenames
e           = b


# The following make macro defines the suffix appended to object filenames 
o           = .o

# The following make macro defines the location of tcsh.
# NOTE: This Makefile contains certain commands which depend on C-Shell syntax
SHELL       = C:/USR/BIN/tcsh 

# The following make macro defines the name of the executable program 
MAIN        = fact

# The following make macros define the full pathnames for the non-gnat-specific
# executable programs invoked when doing this build.  This is done to guard
# against any subversion of the make process by the user -- e.g., having "rm"
# aliased such that user confirmation of the removal is required for each file.
BIN        = c:/cygnus/cygwin-b20/H-i586-cygwin32/bin
EGREP      = $(BIN)/egrep
GREP       = $(BIN)/grep
LS         = $(BIN)/ls
RM         = $(BIN)/rm
SED        = $(BIN)/sed
SORT       = $(BIN)/sort

GNAT_BIN   = C:/USR/bin
GCC        = $(GNAT_BIN)/gcc
GNATMAKE   = $(GNAT_BIN)/gnatmake
GNATBIND   = $(GNAT_BIN)/gnatbind

# The following make macro defines the names of the Ada Library Information
# files which will exist in the current directory when all Ada units have been
# compiled successfully.
ADA_LIBRARY_INFORMATION = \
    $(shell $(LS) *.ad[bs] | $(SED) 's/\.ad[bs]$\/.ali/g' | $(SORT) -u)

# The following make macro defines the names of the Ada object files which will
# exist in the current directory when all Ada units have been compiled
# successfully.
ADA_OBJECTS = \
    $(shell $(LS) *.ad[bs] | $(SED) 's/\.ad[bs]$\/.o/g' | $(SORT) -u)

# The following make macro defines the base name of the file to be generated
# by the gnat binder. 
BIND_NAME   = ada_binding


# The following make macro lists all of the object files which will be in the
# current directory when all of the C source files have been successfully
# compiled. 
C_OBJECTS   = \
    $(shell $(LS) *.c | $(SED) 's/\.c$\/$(o)/g' | $(SORT) -u)

# Know about no filename suffixes other than our own
.SUFFIXES :

# Our filename suffixes
.SUFFIXES : .ads .adb .ali $(o) .c

# This target, being the first, is the default target
all : $(MAIN)$(e) 

# This "target" is used to delete all products of previous compile, bind,
# and/or link command(s).
clean:
 -$(RM) $(C_OBJECTS) $(ADA_OBJECTS) $(ADA_LIBRARY_INFORMATION) \
 b_$(BIND_NAME).c b_$(BIND_NAME).o $(MAIN)$(e)

# This rule produces the Ada binding source file, and compiles it.
b_$(BIND_NAME)$(o) b_$(BIND_NAME).c: $(ADA_LIBRARY_INFORMATION)
 $(GNATBIND) -o b_$(BIND_NAME).c $(BARGS) $(ADA_LIBRARY_INFORMATION)
 $(GCC) $(CARGS) b_$(BIND_NAME).c

# This is the default rule used for m\compiling C source files
.c$(o):
 $(GCC) $(CCARGS) $<

# This is the default rule for producing Ada Library Information for an Ada
# specification source file -- i.e., one having an extension of ".ads"
.ads.ali:
 @ \
 set f=$<; \
 if (-e $$f:r.adb) set f=$$f:r.adb; \
 $(GNATMAKE) $(CARGS) $$f

# This is the default rule for producing Ada Library Information for an Ada
# body source file -- i.e., one having an extension of ".adb"
.adb.ali:
 @$(GNATMAKE) $(CARGS) $<

# This is the rule for producing the executable program.
$(MAIN)$(e): \
    $(C_OBJECTS) \
    b_$(BIND_NAME).c \
    b_$(BIND_NAME).o \
    ;
 $(GCC) $(DEBUG) $(LDARGS) -o $(MAIN)$(e) \
 $(C_OBJECTS) \
 `$(SED) -n -e '/BEGIN/,/END/p' < b_$(BIND_NAME).c \
 | $(EGREP) -v 'BEGIN|END'`

Contributed by: David C. Hoos, Sr.
Contributed on: January 10, 1999
License: Public Domain