PROJECTNAME = logical_expression_parser
VERSION = 0.01
# Installation prefix
PREFIX = /usr
LIBRARY_NAME = logical_expression_parser_library
# Any other files you want to distribute when the tarball is created with
# "make dist"
EXTRA_DIST_FILES = README
# The extensions for C++ code, C code, YACC grammars, and LEX scanners
CCFILEEXT = cc
CFILEEXT = c
FFILEEXT = f
YACCFILEEXT = y
LEXFILEEXT = lex
SCRIPTFILEEXT = sh
# Typical flags for GNU compilers: -g (debugging information), -p (profiling),
# -O2 (optimization), -Idir (extra include directory), -DDEBUG,
# -Wall (all warnings)
CFLAGS = -Wall -pedantic -O3
FFLAGS = -g -C
# Linker flags. Use -lg2c if you're calling Fortran from C/C++
LDFLAGS =
# Appear on the end of the link line
LIB_FLAGS :=
# You should really leave this as GNUmakefile since this makefile uses GNU
# extensions
MAKEFILE_NAME := GNUmakefile
# -----------------------------------------------------------------------------
# Programs
LN = '/sw/bin/ln'
CP = '/sw/bin/cp'
RM = '/bin/rm'
MV = '/sw/bin/mv'
BASH = bash
FIND = '/sw/bin/find'
GREP = '/usr/bin/grep'
CHMOD = '/sw/bin/chmod'
CC = gcc
CXX = '/usr/bin/g++'
FC = g77
LD = '/usr/bin/g++'
AR = '/usr/bin/ar'
LEX = flex
UNIX2DOS = unix2dos
YACC = yacc
MKDIR = '/sw/bin/mkdir'
TAR = tar
GZIP = gzip
ZIP = zip
DIFF = diff
MKDIRHIER = $(PERL) $(UTILSDIR)/mkdirhier.pl
DATE = '/bin/date'
PERL = '/usr/bin/perl'
MAKEDEPEND = $(PERL) $(UTILSDIR)/makedependgcc
COLORS = $(PERL) $(UTILSDIR)/colors
BASEDIR = $(PERL) $(UTILSDIR)/basedir
DIRNAME = '/usr/bin/dirname'
EXPR = '/bin/expr'
# -----------------------------------------------------------------------------
# Set to "true" to disable colors
DISABLE_COLORS = true
# Color preferences
DEFAULT_FOREGROUND = white
DEFAULT_BACKGROUND = black
MAIN_STEP_FOREGROUND = green
MAIN_STEP_BACKGROUND = black
SUB_STEP_FOREGROUND = cyan
SUB_STEP_BACKGROUND = black
WARNING_FOREGROUND = red
WARNING_BACKGROUND = black
ERROR_FOREGROUND = black
ERROR_BACKGROUND = red
# -----------------------------------------------------------------------------
# Set to true to store files in another location and create symbolic links to
# the current directory. This is useful for systems with slow NFS performance,
# or systems with limited user disk space. (i.e. we can store things in /tmp
# as specified by the STORAGE_DIRECTORY variable.)
STORE_FILES_ELSEWHERE = false
# NOTE: This directory will be created if necessary. It will NOT be deleted
# during make clean.
STORAGE_DIRECTORY = /tmp/$(USER)/$(PROJECTNAME)
###############################################################################
default : progs
# Custom dependencies, if any, go here
############################# END OF CONFIGURATION ############################
###############################################################################
# Directories
SRCDIR = src
TESTDIR = tests
PROGDIR = progs
BUILDDIR = build
LIBDIR = lib
ETCDIR = etc
UTILSDIR = util
DOCUMENTDIR = doc
# Add $(BUILDDIR) because there may be generated .h files from yacc.
CFLAGS := -I$(SRCDIR) -I$(BUILDDIR) $(CFLAGS)
LDFLAGS := -L$(LIBDIR) $(LDFLAGS)
# -----------------------------------------------------------------------------
PROGRAMS = $(CP) $(RM) $(MV) $(FIND) $(GREP) $(CXX) $(LD) $(FC) \
$(AR) $(LEX) $(UNIX2DOS) $(YACC) $(MKDIR) $(TAR) $(GZIP) \
$(ZIP) $(DIFF) $(MKDIRHIER) $(DATE) $(PERL) $(MAKEDEPEND) \
$(CHMOD) $(BASH) $(LN) $(DIRNAME) $(BASEDIR) $(EXPR)
# -----------------------------------------------------------------------------
# We use a simple assignment to prevent re-evaluation of the shell command
# (resulting in different PIDs and random numbers)
TEMPDIR := $(shell $(DATE) +tempdir-%H-%M-%S-$$$$-$$RANDOM)
DISTFILE = $(shell $(DATE) +$(PROJECTNAME)-$(VERSION)-%Y-%m-%d)
# -----------------------------------------------------------------------------
# Libraries
LIB_FLAGS := -l$(LIBRARY_NAME) $(LIB_FLAGS)
EMPTY =
SPACE = $(EMPTY) $(EMPTY)
COMMA = ,
make_pattern = \($(subst $(SPACE),\|,$(1))\)
SRC_FILE_EXTS = \
$(CFILEEXT) $(CCFILEEXT) $(FFILEEXT) $(LEXFILEEXT) $(YACCFILEEXT)
GENERATED_SRC_FILE_EXTS = $(LEXFILEEXT) $(YACCFILEEXT)
# A couple patterns for easier searching commands
SRC_FILE_EXTS_PATTERN = \
$(call make_pattern,$(SRC_FILE_EXTS))
GENERATED_SRC_FILE_EXTS_PATTERN = \
$(call make_pattern,$(GENERATED_SRC_FILE_EXTS))
SRC_DIRS_PATTERN = $(call make_pattern,$(call compute_subdirs_with_sources))
# Some subroutines to find source files and compute their corresponding object
# files
find_source_files = \
$(shell $(FIND) $(SRCDIR) -regex '$(SRCDIR)/$(1)/.*\.$(SRC_FILE_EXTS_PATTERN)')
find_shell_scripts = \
$(shell $(FIND) $(SRCDIR) -regex '$(SRCDIR)/$(1)/.*\.$(SCRIPTFILEEXT)')
# In case we need this later
#find_nonsource_files = \
# $(filter-out \
# $(shell $(FIND) $(SRCDIR) -regex '$(SRCDIR)/$(1)/.*\.$(SRC_FILE_EXTS_PATTERN)'), \
# $(shell $(FIND) $(SRCDIR) -regex '$(SRCDIR)/$(1)/.*'))
find_gen_source_files = \
$(shell $(FIND) $(SRCDIR) -regex '$(SRCDIR)/$(1)/.*\.$(GENERATED_SRC_FILE_EXTS_PATTERN)')
compute_subdirs_with_sources = $(filter-out progs tests progs/% tests/%, \
$(sort $(subst $(SRCDIR)/,, \
$(patsubst %/,%,$(dir $(call find_source_files,*))))))
compute_ofiles = $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%.o, \
$(basename $(call find_source_files,$1)))
compute_ofile = $(patsubst $(firstword \
$(subst /,$(SPACE),$(1)))/%,$(BUILDDIR)/%.o,$(basename $(1)))
# Source files generated from lex or yacc
GENERATED_SRC_FILES = $(patsubst $(SRCDIR)/%, \
$(BUILDDIR)/%.$(CCFILEEXT), \
$(basename $(call find_gen_source_files,$(SRC_DIRS_PATTERN))))
# Object files. Just used for dependency analysis
OBJFILES = $(call compute_ofiles,$(SRC_DIRS_PATTERN)) \
$(call compute_ofiles,tests) $(call compute_ofiles,progs)
# Test cases and test binaries
COMPILED_TESTS = $(patsubst $(SRCDIR)/tests/%,$(TESTDIR)/%, \
$(basename $(call find_source_files,tests)))
NONCOMPILED_TESTS = $(patsubst $(SRCDIR)/tests/%,$(TESTDIR)/%, \
$(call find_shell_scripts,tests))
TESTS = $(COMPILED_TESTS) $(NONCOMPILED_TESTS)
# Programs
PROGS = $(patsubst $(SRCDIR)/progs/%,$(PROGDIR)/%, \
$(basename $(call find_source_files,progs)))
.SUFFIXES : $(patsubst %,.%,$(SRC_FILE_EXTS)) .o .a .t .$(YACCFILEEXT) .$(LEXFILEEXT)
# To prevent gnu make from deleting the intermediate parser-related
# implementation files
.SECONDARY :
.PHONY: progs lib tests
################################# MAIN TARGETS ################################
###############################################################################
install : install_progs install_lib
install_progs : progs
install $(PROGS) $(PREFIX)/bin
install_lib: lib
install $(LIBDIR)/lib$(LIBRARY_NAME).a ${PREFIX}/lib
lib : lib_message $(LIBDIR)/lib$(LIBRARY_NAME).a
# Check build environment
check : check_message check_programs check_colors
# Run tests
test : compiled_tests noncompiled_tests
@$(call main_step_msg,Tests completed)
@echo ' Compiled' tests: `cat $(TESTDIR)/COMPILED_TESTS_PASS` passed, `cat $(TESTDIR)/COMPILED_TESTS_FAIL` failed
@echo Noncompiled tests: `cat $(TESTDIR)/NONCOMPILED_TESTS_PASS` passed, `cat $(TESTDIR)/NONCOMPILED_TESTS_FAIL` failed
@$(RM) $(TESTDIR)/COMPILED_TESTS_PASS $(TESTDIR)/COMPILED_TESTS_FAIL \
$(TESTDIR)/NONCOMPILED_TESTS_PASS $(TESTDIR)/NONCOMPILED_TESTS_FAIL
# Make the libraries and programs
progs : lib progs_message $(PROGS)
clean : clean_message
$(RM) -rf $(BUILDDIR) $(LIBDIR) $(TESTDIR) $(PROGDIR)
@# The echo is just so the user can see what's happening
@if test $(STORE_FILES_ELSEWHERE) = 'true'; then \
echo $(RM) -rf $(STORAGE_DIRECTORY)/$(BUILDDIR) \
$(STORAGE_DIRECTORY)/$(LIBDIR) \
$(STORAGE_DIRECTORY)/$(TESTDIR) $(STORAGE_DIRECTORY)/$(PROGDIR); \
$(RM) -rf $(STORAGE_DIRECTORY)/$(BUILDDIR) $(STORAGE_DIRECTORY)/$(LIBDIR) \
$(STORAGE_DIRECTORY)/$(TESTDIR) $(STORAGE_DIRECTORY)/$(PROGDIR); \
fi
dist : dist_message distdir
@$(call sub_step_msg,Making distribution file...)
$(MV) $(TEMPDIR) $(DISTFILE)
$(TAR) cf $(DISTFILE).tar $(DISTFILE)
$(RM) -f $(DISTFILE).tar.gz
$(GZIP) -9 $(DISTFILE).tar
$(RM) -rf $(DISTFILE)
windist : windist_message windistdir
@$(call sub_step_msg,Making distribution file...)
$(MV) $(TEMPDIR) $(DISTFILE)
$(ZIP) $(DISTFILE)-win.zip $(DISTFILE)/*
$(RM) -rf $(DISTFILE)
################################### MESSAGES ##################################
###############################################################################
check_programs_message :
@$(call sub_step_msg,Checking that programs exist...)
compiled_tests_message :
@$(call sub_step_msg,Building compiled test cases into tests directory)
noncompiled_tests_message :
@$(call sub_step_msg,Copying noncompiled test cases to tests directory)
lib_message :
@$(call main_step_msg,Making library $(LIBRARY_NAME))
check_message :
@$(call main_step_msg,Checking build environment...)
progs_message :
@$(call main_step_msg,Making programs)
clean_message :
@$(call main_step_msg,Making clean)
dist_message :
@$(call main_step_msg,Making $(DISTFILE).tar.gz)
windist_message :
@$(call main_step_msg,Making $(DISTFILE).zip)
################################# SUBROUTINES #################################
###############################################################################
# A subroutine to make a directory
make_directory = @ \
if test ! -d $(1); then \
if test $(STORE_FILES_ELSEWHERE) = 'true'; then \
echo '--' Creating directory $(STORAGE_DIRECTORY)/$(1)...; \
echo $(MKDIRHIER) $(STORAGE_DIRECTORY)/$(1); \
$(MKDIRHIER) $(STORAGE_DIRECTORY)/$(1); \
if test ! -e `$(BASEDIR) $(1)`; then \
echo '--' Making symbolic link from $(STORAGE_DIRECTORY)/`$(BASEDIR) $(1)` to `$(BASEDIR) $(1)`...; \
echo $(LN) -s $(STORAGE_DIRECTORY)/`$(BASEDIR) $(1)` `$(BASEDIR) $(1)`; \
$(LN) -s $(STORAGE_DIRECTORY)/`$(BASEDIR) $(1)` `$(BASEDIR) $(1)`; \
fi; \
else \
echo '--' Creating directory $(1)...; \
echo $(MKDIRHIER) $(1); \
$(MKDIRHIER) $(1); \
fi; \
fi
# Subroutines to issue colored alerts
main_step_msg = \
if test $(DISABLE_COLORS) = 'false'; then \
$(COLORS) $(MAIN_STEP_FOREGROUND) $(MAIN_STEP_BACKGROUND); \
fi; \
echo -n '===> $(1)'; \
if test $(DISABLE_COLORS) = 'false'; then \
$(COLORS) $(DEFAULT_FOREGROUND) $(DEFAULT_BACKGROUND); \
fi; \
echo
sub_step_msg = \
if test $(DISABLE_COLORS) = 'false'; then \
$(COLORS) $(SUB_STEP_FOREGROUND) $(SUB_STEP_BACKGROUND); \
fi; \
echo -n '> $(1)'; \
if test $(DISABLE_COLORS) = 'false'; then \
$(COLORS) $(DEFAULT_FOREGROUND) $(DEFAULT_BACKGROUND); \
fi; \
echo
warning_msg = \
if test $(DISABLE_COLORS) = 'false'; then \
$(COLORS) $(WARNING_FOREGROUND) $(WARNING_BACKGROUND); \
fi; \
echo -n '> $(1)'; \
if test $(DISABLE_COLORS) = 'false'; then \
$(COLORS) $(DEFAULT_FOREGROUND) $(DEFAULT_BACKGROUND); \
fi; \
echo
error_msg = \
if test $(DISABLE_COLORS) = 'false'; then \
$(COLORS) $(ERROR_FOREGROUND) $(ERROR_BACKGROUND); \
fi; \
echo -n '\#\#\#> $(1)'; \
if test $(DISABLE_COLORS) = 'false'; then \
$(COLORS) $(DEFAULT_FOREGROUND) $(DEFAULT_BACKGROUND); \
fi; \
echo
############################# SUPPORTING TARGETS ##############################
###############################################################################
check_programs : check_programs_message $(patsubst %,%.checkprogram,$(PROGRAMS))
%.checkprogram:
@if !($* --help 2>&1 | grep -i '\(usage\|option\|invalid\)' > /dev/null); then \
$(call warning_msg,Could not find program $*. You may not need it--check the makefile.); \
fi
# -----------------------------------------------------------------------------
check_colors:
@echo Now checking colors. You may want to set DISABLE_COLORS to true.
@$(call main_step_msg,This is a main step message.)
@$(call sub_step_msg,This is a sub-step message.)
@$(call warning_msg,This is a warning!)
@$(call error_msg,This is an error!)
########################### DEPENDENCY GENERATION #############################
###############################################################################
# Cancel the normal implicit rules to make sure we get our own ones
%.c : %.$(YACCFILEEXT)
%.c : %.$(LEXFILEEXT)
# Dependency generation for object files
# Rule to make .o.d files from .$(CCFILEEXT) files
$(BUILDDIR)/%.o.d : $(SRCDIR)/%.$(CCFILEEXT)
$(call make_directory,$(shell $(DIRNAME) $@))
@$(call sub_step_msg,Making dependencies file $@)
@set -e; rm -f $@; \
$(MAKEDEPEND) -- $(CXX) -MM $(CFLAGS) $< -o $(call compute_ofile,$<) > $@.$$$$; \
sed 's,\($(call compute_ofile,$<)\)[ :]*,\1 $@: ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
# Rule to make .o.d files from .$(CFILEEXT) files
$(BUILDDIR)/%.o.d : $(SRCDIR)/%.$(CFILEEXT)
$(call make_directory,$(shell $(DIRNAME) $@))
@$(call sub_step_msg,Making dependencies file $@)
@set -e; rm -f $@; \
$(MAKEDEPEND) -- $(CC) -MM $(CFLAGS) $< -o $(call compute_ofile,$<) > $@.$$$$; \
sed 's,\($(call compute_ofile,$<)\)[ :]*,\1 $@: ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
# Rule to make .o.d files from generated .$(CCFILEEXT) files
# This is pretty yucky. We pass -MG to tell the GNU compiler to treat missing
# headers as generated. Then we have to patch up the paths so that the
# dependencies will refer to files in the build directory
$(BUILDDIR)/%.o.d : $(BUILDDIR)/%.$(CCFILEEXT)
$(call make_directory,$(shell $(DIRNAME) $@))
@$(call sub_step_msg,Making dependencies file $@)
@set -e; rm -f $@; \
$(MAKEDEPEND) -- $(CXX) -MM -MG $(CFLAGS) $< -o $(call compute_ofile,$<) > $@.$$$$; \
sed 's,\($(call compute_ofile,$<)\)[ :]*,\1 $@: ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$; \
mv $@ $@.$$$$; \
sed 's, \($(shell $(DIRNAME) $*)\), $(BUILDDIR)/\1,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
# Dependency generation for library files
format_files=$(subst $(SPACE),$(SPACE)\\\\\\n$(SPACE)$(SPACE),$1)
$(BUILDDIR)/$(LIBDIR)/%.a.d :
$(call make_directory,$(shell $(DIRNAME) $@))
@$(call sub_step_msg,Making dependencies file $@)
@set -e; rm -f $@; \
echo -e '$(LIBDIR)/$*.a: \\'"\\n $(call format_files,$(call compute_ofiles,$(patsubst lib%,%,$*)))\\n" > $@
# Dependency generation for generated files
$(BUILDDIR)/%.$(CCFILEEXT).d : $(SRCDIR)/%.$(LEXFILEEXT)
$(call make_directory,$(shell $(DIRNAME) $@))
@$(call sub_step_msg,Making dependencies file $@)
@set -e; rm -f $@; \
echo -e '$(BUILDDIR)/$*.$(CCFILEEXT) $@: \\'"\\n $<\\n" > $@
$(BUILDDIR)/%.$(CCFILEEXT).d : $(SRCDIR)/%.$(YACCFILEEXT)
$(call make_directory,$(shell $(DIRNAME) $@))
@$(call sub_step_msg,Making dependencies file $@)
@set -e; rm -f $@; \
echo -e '$(BUILDDIR)/$*.$(CCFILEEXT) $(BUILDDIR)/$*.h $@: \\'"\\n $<\\n" > $@
# -----------------------------------------------------------------------------
# Include the dependencies (will automatically generate them). We guard this
# so that you can always run "make clean" without having to worry about
# generating dependencies
ifneq ($(MAKECMDGOALS),clean)
-include $(addsuffix .d,$(GENERATED_SRC_FILES)) \
$(BUILDDIR)/$(LIBDIR)/lib$(LIBRARY_NAME).a.d \
$(addsuffix .d,$(OBJFILES))
endif
########################### DISTRIBUTION TARGETS ##############################
###############################################################################
distdir:
@$(call sub_step_msg,Copying files to temporary directory...)
rm -rf $(TEMPDIR)
$(MKDIR) $(TEMPDIR)
$(CP) $(MAKEFILE_NAME) $(EXTRA_DIST_FILES) $(TEMPDIR)
$(CP) -r $(SRCDIR) $(ETCDIR) $(UTILSDIR) $(DOCUMENTDIR) $(TEMPDIR)
windistdir: $(patsubst $(SRCDIR)/%.$(YACCFILEEXT),$(BUILDDIR)/%.$(CCFILEEXT),$(wildcard $(SRCDIR)/*/*.$(YACCFILEEXT))) \
$(patsubst $(SRCDIR)/%.$(LEXFILEEXT),$(BUILDDIR)/%.$(CCFILEEXT),$(wildcard $(SRCDIR)/*/*.$(LEXFILEEXT))) \
$(patsubst $(SRCDIR)/%.$(YACCFILEEXT),$(BUILDDIR)/%.h,$(wildcard $(SRCDIR)/*/*.$(YACCFILEEXT)))
@$(call sub_step_msg,Copying files to temporary directory...)
rm -rf $(TEMPDIR)
$(MKDIR) $(TEMPDIR)
$(CP) $(MAKEFILE_NAME) $(EXTRA_DIST_FILES) $(TEMPDIR)
$(CP) -r $(SRCDIR) $(ETCDIR) $(UTILSDIR) $(DOCUMENTDIR) $(TEMPDIR)
$(MKDIR) $(TEMPDIR)/$(BUILDDIR)
$(CP) $^ $(TEMPDIR)/$(BUILDDIR)
@$(call sub_step_msg,Converting files to DOS format...)
@for file in `$(FIND) $(TEMPDIR) -type f`; do \
$(UNIX2DOS) $$file 2>/dev/null; \
done
############################## TESTING TARGETS ################################
###############################################################################
# -----------------------------------------------------------------------------
compiled_tests : lib compiled_tests_message $(COMPILED_TESTS)
@$(call main_step_msg,Running compiled tests)
@export COMPILED_TESTS_PASS="0"; \
export COMPILED_TESTS_FAIL="0"; \
for test in $(COMPILED_TESTS); do \
echo -n $(BACKGROUND); echo -n $(FOREGROUND); echo -n $(CYAN)'> Running test '"$$test... "$(TEXTCOLOR); \
if $$test 1> $$test.stdout 2>$$test.stderr ; then \
COMPILED_TESTS_PASS=`$(EXPR) $$COMPILED_TESTS_PASS + 1`; \
echo PASS; \
$(RM) $$test.stdout $$test.stderr; \
else \
COMPILED_TESTS_FAIL=`$(EXPR) $$COMPILED_TESTS_FAIL + 1`; \
echo "FAIL (See $$test.stdout and $$test.stderr)"; \
fi; \
done; \
echo $$COMPILED_TESTS_PASS > $(TESTDIR)/COMPILED_TESTS_PASS; \
echo $$COMPILED_TESTS_FAIL > $(TESTDIR)/COMPILED_TESTS_FAIL
noncompiled_tests : $(PROGS) noncompiled_tests_message $(NONCOMPILED_TESTS)
@$(call main_step_msg,Running noncompiled tests)
@export NONCOMPILED_TESTS_PASS="0"; \
export NONCOMPILED_TESTS_FAIL="0"; \
for test in $(NONCOMPILED_TESTS); do \
echo -n $(BACKGROUND); echo -n $(FOREGROUND); echo -n $(CYAN)'> Running test '"$$test... "$(TEXTCOLOR); \
if $$test 1>$$test.stdout 2>$$test.stderr ; then \
NONCOMPILED_TESTS_PASS=`$(EXPR) $$NONCOMPILED_TESTS_PASS + 1`; \
echo PASS; \
$(RM) $$test.stdout $$test.stderr; \
else \
NONCOMPILED_TESTS_FAIL=`$(EXPR) $$NONCOMPILED_TESTS_FAIL + 1`; \
echo "FAIL (See $$test.stdout and $$test.stderr)"; \
fi; \
done; \
echo $$NONCOMPILED_TESTS_PASS > $(TESTDIR)/NONCOMPILED_TESTS_PASS; \
echo $$NONCOMPILED_TESTS_FAIL > $(TESTDIR)/NONCOMPILED_TESTS_FAIL
############################## COMPILE TARGETS ################################
###############################################################################
# Cancel the normal implicit rules to make sure we get our own ones
%.o : %.$(CCFILEEXT)
%.o : %.$(CFILEEXT)
%.o : %.$(FFILEEXT)
# Rules to compile .$(CCFILEEXT) files into .o files.
$(BUILDDIR)/%.o : $(SRCDIR)/%.$(CCFILEEXT)
$(call make_directory,$(shell $(DIRNAME) $@))
$(CXX) $(CFLAGS) -c $< -o $@
# In case we have .$(CCFILEXT) files generated by other source. (e.g. from lex
# and yacc)
$(BUILDDIR)/%.o : $(BUILDDIR)/%.$(CCFILEEXT)
$(call make_directory,$(shell $(DIRNAME) $@))
$(CXX) $(CFLAGS) -c $< -o $@
# Rules to compile .$(CFILEEXT) files into .o files.
$(BUILDDIR)/%.o : $(SRCDIR)/%.$(CFILEEXT)
$(call make_directory,$(shell $(DIRNAME) $@))
$(CC) $(CFLAGS) -c $< -o $@
# In case we have .$(CFILEXT) files generated by other source. (e.g. from lex
# and yacc)
$(BUILDDIR)/%.o : $(BUILDDIR)/%.$(CFILEEXT)
$(call make_directory,$(shell $(DIRNAME) $@))
$(CC) $(CFLAGS) -c $< -o $@
# Rule to compile .f files into .o files.
$(BUILDDIR)/%.o : $(SRCDIR)/%.f
$(call make_directory,$(shell $(DIRNAME) $@))
$(FC) $(FFLAGS) -c $< -o $@
# Rule to compile .$(LEXFILEEXT) files into .$(CCFILEEXT) files.
$(BUILDDIR)/%.$(CCFILEEXT) : $(SRCDIR)/%.$(LEXFILEEXT)
$(call make_directory,$(shell $(DIRNAME) $@))
$(LEX) -o$@ $<
# Rule to compile test binaries
$(TESTDIR)/% : $(LIBDIR)/lib$(LIBRARY_NAME).a $(BUILDDIR)/tests/%.o
$(call make_directory,$(shell $(DIRNAME) $@))
@$(call sub_step_msg,Making test case $@)
$(LD) $(LDFLAGS) $(CFLAGS) $(BUILDDIR)/tests/$*.o $(LIB_FLAGS) -o $@
# Rule to copy tests which are scripts
$(TESTDIR)/%.$(SCRIPTFILEEXT) : $(PROGS) $(SRCDIR)/$(TESTDIR)/%.$(SCRIPTFILEEXT)
$(call make_directory,$(shell $(DIRNAME) $@))
@$(call sub_step_msg,Copying test case $@)
$(CP) $(SRCDIR)/$(TESTDIR)/$*.$(SCRIPTFILEEXT) $@
@$(CHMOD) a+x $@
# Rule to compile non-test binaries
$(PROGDIR)/% : $(LIBDIR)/lib$(LIBRARY_NAME).a $(BUILDDIR)/progs/%.o
$(call make_directory,$(shell $(DIRNAME) $@))
@$(call sub_step_msg,Making program $@)
$(LD) $(LDFLAGS) $(CFLAGS) $(BUILDDIR)/progs/$*.o $(LIB_FLAGS) -o $@
# Rule to create the library
$(LIBDIR)/lib$(LIBRARY_NAME).a : $(call compute_ofiles,$(SRC_DIRS_PATTERN))
@$(call sub_step_msg,Making library $@)
@$(call make_directory,$(shell $(DIRNAME) $@))
@$(AR) rv $@ $^
@ranlib $@
# Rule to generate parser .$(CCFILEEXT) files from .$(YACCFILEEXT) files
$(BUILDDIR)/%.$(CCFILEEXT) $(BUILDDIR)/%.h : $(SRCDIR)/%.$(YACCFILEEXT)
$(call make_directory,$(shell $(DIRNAME) $@))
$(YACC) -p $(notdir $*)_ -d -o $(basename $@).$(CCFILEEXT) $<
if test -e $(basename $@).$(CCFILEEXT).h ; then \
$(MV) $(basename $@).$(CCFILEEXT).h $(basename $@).h; \
else if test -e $(basename $@).hpp ; then \
$(MV) $(make_pattern = \($(subst $(SPACE),\|,$(1))\)