root@ogcvax.UUCP (Bruce Jerrick) (10/04/84)
There seems to be a trend toward interactive configuration and installation of contributed software. I think that unless this is done carefully, there are going to be maintainability problems. The problem is that some installation procedures permanently and irrevokably alter the distribution. Then, six months later when someone says "I have a new version of XYZ, can you install it here?", the question will arise (or at least, should arise): "How does this differ from what we have, and which version do we want?" And of course this is complicated by local mods. Normally one can use something like RCS to retain the originals, then make mods, and still be able to check out a completely original version, to do, say, "diff -r ..." against a new version. Some auto-configuring distributions I have seen make it difficult to keep virgin copies of the distribution; for example, XYZ might "sed" its Makefile then copy it back onto itself. It is also difficult to foresee what an auto-configure procedure is going to alter, so one doesn't know what to save. So, I would like to suggest these guidelines, so that a maintainer can get the distribution back to the same state in which it was received: 1. If the auto-configuration procedure modifies files, have it start with a template version of the file, or create it from scratch, rather than modifying the file in place. E.g., do this: sed ... Makefile.templ > Makefile or: Makefile.SH (as in Larry Wall's trick "rn" distribution) instead of: sed ... Makefile > tmp cp tmp Makefile Doing it the first way allows one to make mods to Makefile.templ or Makefile.SH, which doesn't change by itself. Otherwise, one has to make mods to a moving target. 2. Have a "clean:" target in the Makefile that will get rid of files created in the auto-configuration procedure. Doing a "make clean", then checking the original versions back out should get everything back to the state as it was when distributed. Intelligent comments are welcome -- Bruce Jerrick Oregon Graduate Center (503) 645-1121 ex. 355 CSNet: bruce@Oregon-Grad UUCP: ...tektronix!ogcvax!bruce -- Bruce Jerrick Oregon Graduate Center
greg@sdcsvax.UUCP (Greg Noel) (10/06/84)
In article <421@ogcvax.UUCP> root@ogcvax.UUCP (Bruce Jerrick) has some good comments about reasonable ways to provide software that runs on a variety of Unix variants. I agree with all of it, but I wish to pick a nit with this: > >2. Have a "clean:" target in the Makefile that will get rid of > files created in the auto-configuration procedure. Doing > a "make clean", then checking the original versions back out > should get everything back to the state as it was when distributed. > The idea is good, but the actual name of the target should not be "clean:" if you want to use it on AT&T variants. The names "all:", "install:", "clean:", and "clobber:" are conventionally used as targets for compile, compile/install, remove intermediate files, and remove all created files. (These targets are used by the automated remake scripts and show up in a lot of makefiles. It would be hard to change.) Perhaps "reset:" or "startover:" would be a better name. The referenced note also went to net.sources so I am doing the same for this note. Future discussion, if any, should be confined to unix-wizards. -- -- Greg Noel, NCR Torrey Pines Greg@sdcsvax.UUCP or Greg@nosc.ARPA
rcj@burl.UUCP (R. Curtis Jackson) (10/10/84)
I agree with the original author of the referenced article; here is one 'safe' way to go about it. I use as an example a package of mine to build a product called 'pds3': pds3 comes with a makefile template (pds3.mk), and a makefile localizer (pds3local.l) written using lex(1). When you get the package, if you type 'make' you get (of course) nothing because there is nothing called '[Mm]akefile'. To localize, the READ_ME file tells you to type 'make local'. This lex's and compiles the localizer, runs the localizer, pds3local. pds3local uses pds3.mk and user input (in the form of answers to questions like "Path to directory where you wish executable to reside?") and outputs an edited/filled-in version of pds3.mk called 'makefile'. It then tells the user to type 'make' to make the package (usually I have an 'install' rule, but for these customers that was automatic). Here is the portion of the original pds3.mk that has to do with localizing: local: pds3local pds3local -@echo "\n\nMakefile has been localized; please type 'make' again" -@echo "to make $(XMODULE); it can run in background this time.\n" pds3local: pds3local.c $(CC) $(CFLAGS) -DMAKENAME="\"%Z% %P% %I% %G%\"" -o pds3local pds3local.c -ll The %Z% %P% %I% %G%, of course, would be expanded by SCCS.... After localization, the 'local' rule in 'makefile' looks like this: local: -@echo "\nTo re-localize, do the following:\n" -@echo "\tmake -f pds3.mk local\n" No original source is modified. A couple of other hints you might want to take advantage of: a) Put in a '-v' (or '-V') switch in every program that will give a short one-line functional name for the program and end with release and version info, like this: PDS Section 3 Builder (pds3) -- Version 2 released 9/25/84 This can be easily accomplished on Unix by using SCCS to store your code and having %R% and %G% in place of the version number and date above -- every time you release a new version (say, version X), just do a 'get -e -rX s.foo.h', and delta it back (it will go back into SCCS as X.1). b) Do not put ANY hardwired includes (except system includes) or pathnames in your programs; put it all in your makefile and use cpp(1)'s -D option to define them from the makefile and !!USE MAKE VARIABLES FOR EVERYTHING!!; this means you can quickly and easily override them from the make command-line. c) Use SCCS to your advantage -- be sure to include some string of keywords (in the files on our project, it is "%Z% %P% %I% %G%", which expands to "@(#) <pathname-of-SCCS-file> <SID> <date-last-delta>") in every file you have. Use: char *FILENAME = "%Z% %P% %I% %G%"; (where FILENAME is the filename in CAPS (to avoid load conflicts)) for program source. For include files included by multiple modules, have one designated 'command' module that defines a symbol (I use ZPIG) and have the include file contain: # ifdef ZPIG char *INCFILENAME = "%Z% %P% %I% %G%"; # endif In the same 'command' module, have something that looks like this: char *MAKEFILE = ZPIGMK; and have your makefile use: -DZPIGMK="\"%Z% %P% %I% %G%\"" as one of the compilation switches. By various tricks such as these, you can get an executable that you can do a what(1) on and get something like this: $ what /emsp/dev/bin/gus /emsp/dev/bin/gus: /emsp/cmf/emsp/proto/sccs/C/as/asgu/s.asguasc.md 2.2 10/8/84 /proto/sccs/C/as/asgc/s.asgcmystr.c 2.1 10/5/84 /emsp/cmf/emsp/proto/sccs/C/as/asgu/s.asguau.y 2.2 10/7/84 /emsp/cmf/emsp/proto/sccs/C/as/asgu/s.asgucs.y 2.4 10/9/84 /emsp/cmf/emsp/proto/sccs/C/as/asgu/s.asgups.y 2.2 10/7/84 /emsp/cmf/emsp/proto/sccs/C/as/asgu/s.asgul.l 2.3 10/7/84 /emsp/cmf/emsp/proto/sccs/C/as/asgu/s.asgu.c 2.6 10/9/84 /proto/sccs/C/as/asgc/s.asgc.mk 2.2 10/7/84 /emsp/cmf/emsp/proto/sccs/C/as/asgu/s.asgu.md 2.1 10/5/84 /proto/sccs/C/as/asgc/s.asgcascfrm.l 2.1 10/5/84 /proto/sccs/C/as/asgc/s.asgclk.cf 2.1 10/5/84 /emsp/cmf/emsp/proto/sccs/C/as/asgu/s.asgu.h 2.3 10/7/84 /proto/sccs/C/as/asgc/s.asgcmystr.h 2.1 10/5/84 $ Put this list into a file (I call mine for gus 'asgu.sl', for S-list) and put it under SCCS with a comment each delta like 'Version 3' and you will suddenly have the ability to: 1) Run (or have a remote user run!!) one command (<prog> -v) to tell him/her what version s/he is using. 2) If you have incremental releases between official versions, you can now do a what(1) on any executable and see exactly what it is made up of. 3) Return to any version, no matter how old, with practically no effort. Enough rambling for one night!! Thanks for your time, and I hope some of this has been of some help, -- The MAD Programmer -- 919-228-3313 (Cornet 291) alias: Curtis Jackson ...![ ihnp4 ulysses cbosgd mgnetp ]!burl!rcj ...![ ihnp4 cbosgd akgua masscomp ]!clyde!rcj