Go to the previous, next section.
This is the sequence of steps I did to convert James Theiler's xyplot to use autoconf.
There are a few subdirectories involved: `xydoc', `xyplot', `xysee'.
First you have to do the mechanical stuff.
cd xydoc cp Makefile Makefile.orig # save the originals mv Makefile Makefile.in autoheader cd ..
Then do the same in the other subdirectories (xyplot and xysee).
At the end, I did the top level directory:
cd xydoc cp Makefile Makefile.orig # save the originals mv Makefile Makefile.in autoscan mv configure.scan configure.in autoheader autoconf cd ..
Note that I only did `autoheader' in the subdirectories, but I did the full `autoconf' in the top level directory.
Now some things have to be changed in `configure.in':
dnl Most of these things are boiler plate (from autoscan); dnl but here's some of my stuff dnl BEGIN MARK's BLOCK OF STUFF dnl NOTHING IN HERE YET dnl END MARK's BLOCK OF STUFF
AC_OUTPUT(xyview/Makefile xysee/Makefile xydoc/Makefile xyplot/Makefile Makefile)
with
AC_OUTPUT(xyview/Makefile xysee/Makefile xydoc/Makefile xyplot/Makefile Makefile, echo timestamp > stamp-h)
This will allow me to create rules for re-configuring automatically when various `.in' files change.
Then re-run autoconf in the top level directory.
At this point you should be able to try it out by typing something like
./configure --prefix=`pwd`/work makeand if all goes well, you should get almost exactly the same results as before you started this exercise.
I then went in to make the Makefiles look a bit more like standard GNU makefiles, with all the targets and variables.
I changed all the `Makefile.in' files to have the following boiler-plate stuff at the top:
SHELL = /bin/sh VPATH = @srcdir@ subdirs = @subdirs@ top_srcdir = @top_srcdir@ srcdir = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = $(exec_prefix)/bin infodir = $(prefix)/info libdir = $(prefix)/lib/gnudl mandir = $(prefix)/man/man1 CC = @CC@ CPPFLAGS = @CPPFLAGS@ CFLAGS = $(CPPFLAGS) @CFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ INSTALL = @INSTALL@
And this stuff at the bottom, so that "make" will automatically reconfigure if the `.in' files change.
# automatic re-running of configure if the ocnfigure.in file has changed
${srcdir}/configure: configure.in aclocal.m4
cd ${srcdir} && autoconf
# autoheader might not change config.h.in, so touch a stamp file
${srcdir}/config.h.in: stamp-h.in
${srcdir}/stamp-h.in: configure.in aclocal.m4
cd ${srcdir} && autoheader
echo timestamp > ${srcdir}/stamp-h.in
config.h: stamp-h
stamp-h: config.h.in config.status
./config.status
Makefile: Makefile.in config.status
./config.status
config.status: configure
./config.status --recheck
Having added these GNU-friendly variables to the `Makefile.in', I removed the original `Makefile.in' material that did similar things, and replaced it with these variables. This is almost always straightforward.
The effect of adding the rules for `config.h', `configure' and
so forth is that the programmer never has to remember if she or he has
run autoconf or configure recently: the make will figure it out
and run what has to be run.
It would help if you were to add some of the standard GNU targets to
your `Makefile.in', targets such as clean, distclean,
install, uninstall.
Here are examples of how that was done for xyplot. Note that xyplot has several `Makefile.in' files. I will show these rules from the top level `$(srcdir)/Makefile.in' (which does very little work: it just invokes the rules from the subdirectories and knows how to make snapshots) and the `$(srcdir)/xyplot/Makefile.in' which is the main workhorse. Keep in mind that xyplot is free software, and you can find it by anonymous ftp from ftp://nis-ftp.lanl.gov/pub/users/jt/Software
Here are some targets from the top level `$(srcdir)/Makefile.in':
all:
@for dir in ${subdirs}; do \
(cd $$dir && $(MAKE) all) \
|| case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
install:
@for dir in ${subdirs}; do \
(cd $$dir && $(MAKE) install) \
|| case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
clean:
/bin/rm -f *~
@for dir in ${subdirs}; do \
(cd $$dir && $(MAKE) clean) \
|| case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
distclean: clean
/bin/rm -f Makefile config.h config.status config.cache config.log
@for dir in ${subdirs}; do \
(cd $$dir && $(MAKE) distclean) \
|| case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
# a rule to make snapshots
snapshot: $(SOURCES) $(DOCS) $(OTHERFILES)
@echo
@echo "->Note: The version for now is hacked into Makefile.in as"
@echo "->" $(VERS)
@echo
@echo "->copying all release files to the directory " xyplot-$(VERS)
@echo
tar cf - $(SOURCES) $(DOCS) $(OTHERFILES) | gzip > xyplot-$(VERS).tar.gz
-mkdir xyplot-$(VERS)
gzcat xyplot-$(VERS).tar.gz | (cd xyplot-$(VERS); tar xf -)
/bin/rm -f xyplot-$(VERS).tar.gz
@echo
@echo "->making the compressed tar file " xyplot-$(VERS).tar.gz
@echo
tar cf - xyplot-$(VERS) | gzip > xyplot-$(VERS).tar.gz
@echo
# @echo "->placing the snapshot for anonymous ftp in " $(FTPDIR)
# @echo
# rcp xyplot-$(VERS).tar.gz $(FTPDIR)
echo "->removnig the temporary directory " xyplot-$(VERS)
/bin/rm -rf xyplot-$(VERS) # remove the old directory
And here are some targets from `$(srcdir)/xyplot/Makefile.in':
install: all $(top_srcdir)/mkinstalldirs $(bindir) $(top_srcdir)/mkinstalldirs $(libdir) $(INSTALL) xyplot $(bindir) $(INSTALL) xyps $(bindir) $(INSTALL) xyug $(bindir) $(INSTALL) xypost $(libdir) uninstall: -/bin/rm -f $(bindir)/xyplot -/bin/rm -f $(bindir)/xyps -/bin/rm -f $(bindir)/xyug -/bin/rm -f $(libdir)/xypost # removes whatever can be built with make except xypost clean: /bin/rm -f *.o *~ xyplot xyps squeeze xyug distclean: /bin/rm -f Makefile config.h config.status config.cache config.log
You might have noticed that the install: rules used a couple of
programs `mkinstalldirs' and $(INSTALL). You should include
a copy of `mkinstalldirs' in the top level directory of your
distribution. The $(INSTALL) variable gets set by
`configure' to be a Berkeley--style install program. If the user
does not have a BSD--compatible install program, it is important for you
provide the `install-sh' shell script in the top level directory.
So you should grab `mkinstalldirs' and `install-sh' from some other GNU program (such as autoconf, for example) and put them in your distribution.
Another nice thing that GNU programs almost always do is to create a `program-versionnumber' directory when you unbundle them. The best way to do this is to have a script or a `Makefile.in' target which makes a directory called program-version and copies all the files that need to be distributed into that directory, and then makes a gzipped tar archive of that directory.
You can look at the snapshot: target shown above for xyplot. It
first uses a `tar' pipeline to copy the essential files into an
appropriately named directory (in this case `xyplot-2.6.0'). Then
it uses `tar' and `gzip' to make the file
`xyplot-2.6.0.tar.gz', which is ready to be sent out to the world.
It goes without saying that you should try the installation procedure with this `.tar.gz' file on as many versions of UNIX as possible before you publicize the release.
Go to the previous, next section.