Alcatel-Lucent nmake Product Builder
Built-in Common Actions
Feature Description
A set of frequently used actions are provided in the default base rules
and do not need to be defined in the user makefiles. There are approximately
30 common actions provided, the most popular being install,
clobber and clean.
Impact
Productivity
- Development time is saved by not having to implement the common actions.
- The size and complexity of makefiles is reduced.
- Brings consistency among developers and projects.
Build Accuracy
- For the
clobberandcleancommon actions nmake determines automatically which files to delete by knowing what it generated. - Small and simple makefiles are less error prone.
Consequence of Not Having the Feature
- Makefiles become more complex and error prone.
- Errors may arise if the user defined actions, such as
clobber, are not kept up-to-date with the makefile as targets or objects are added or removed from the makefile. - Inconsistency may rise from developers implementing actions
differently. One
clobbermay produce different results from another.
Examples
The following examples use the default install directories relative to
INSTALLROOT, but the directories can be changed if desired.
The example makefile builds two targets, an executable and an archive
library.
INSTALLROOT = $(VROOT) :ALL: abc :: a.c b.c c.c libxyz.a :: x.c y.c z.c
Running nmake will generate the targets.
$ nmake + cc -O -I- -c a.c + cc -O -I- -c b.c + cc -O -I- -c c.c + cc -O -o abc a.o b.o c.o + cc -O -I- -c x.c + cc -O -I- -c y.c + cc -O -I- -c z.c + ar r libxyz.a x.o y.o z.o ar: creating libxyz.a + rm -f x.o y.o z.o
Running nmake install will update (if necessary) and
install the targets. In this case the targets are already up-to-date
so they are only installed. By default executables are placed in
bin and libraries in lib. If a target
directory does not exist it will be created. If the files have already
been installed they will not be re-installed unless they have changed,
and old files are backed up to filename.old. The
:INSTALL: and :INSTALLDIR: operators can be
used to install any files into specified directories.
$ nmake install + mkdir -p ../../bin + 2> /dev/null + cp abc ../../bin/abc + mkdir -p ../../lib + 2> /dev/null + cp libxyz.a ../../lib/libxyz.a
Running nmake clobber.install will delete the installed files.
$ nmake clobber.install + ignore rm -f -r ../../bin/abc ../../lib/libxyz.a
Running nmake clean will delete the intermediate object files.
$ nmake clean + ignore rm -f c.o b.o a.o
Running nmake clobber will delete the intermediate and final
target files (but not the installed files.) The objects deleted in the
previous example have been regenerated for this example.
$ nmake clobber + ignore rm -f libxyz.a c.o b.o a.o abc Makefile.mo Makefile.ms
Example using standard make tool
The following makefile implements similar actions to the above examples using standard make.
INSTALLROOT = ../..
OBJECTS = a.o b.o c.o
LIBOBJECTS = x.o y.o z.o
TARGETS = abc libxyz.a
all : $(TARGETS)
abc : $(OBJECTS)
cc -o $@ $(OBJECTS)
libxyz.a : $(LIBOBJECTS)
ar cr $@ $?
clean:
rm -f $(OBJECTS) $(LIBOBJECTS)
clobber: clean
rm -f $(TARGETS)
clobber.install:
rm -f $(INSTALLROOT)/bin/abc $(INSTALLROOT)/bin/libxyz.a
install: $(TARGETS)
test -d $(INSTALLROOT)/bin || mkdir $(INSTALLROOT)/bin
cmp -s abc $(INSTALLROOT)/bin/abc || { test -f $(INSTALLROOT)/bin/abc \
&& mv $(INSTALLROOT)/bin/abc $(INSTALLROOT)/bin/abc.old \
cp abc $(INSTALLROOT)/bin ; }
test -d $(INSTALLROOT)/lib || mkdir $(INSTALLROOT)/lib
cmp -s libxyz.a $(INSTALLROOT)/lib/libxyz.a || {
test -f $(INSTALLROOT)/lib/libxyz.a && \
mv $(INSTALLROOT)/lib/libxyz.a $(INSTALLROOT)/lib/libxyz.a.old \
cp libxyz.a $(INSTALLROOT)/lib ; }
$ make install
cc -c a.c
cc -c b.c
cc -c c.c
cc -o abc a.o b.o c.o
cc -c x.c
cc -c y.c
cc -c z.c
ar cr libxyz.a x.o y.o z.o
test -d ../../bin || mkdir ../../bin
cmp -s abc ../../bin/abc || { test -f ../../bin/abc && mv ../../bin/abc ../
../bin/abc.old ; cp abc ../../bin ; }
test -d ../../lib || mkdir ../../lib
cmp -s libxyz.a ../../lib/libxyz.a || { test -f ../../lib/libxyz.a && mv ..
/../lib/libxyz.a ../../lib/libxyz.a.old ; cp libxyz.a ../../lib ; }







