Annotation of 43BSD/contrib/spms/doc/4.manage.ms, revision 1.1

1.1     ! root        1: .nr PS 12
        !             2: .NH
        !             3: Software Management
        !             4: .nr PS 10
        !             5: .XS
        !             6: \*(SN Software Management
        !             7: .XE
        !             8: .PP
        !             9: Although the
        !            10: .UX 
        !            11: operating system offers a rich variety of programming tools, a frequent
        !            12: complaint is that there are too few guidelines showing how to use them
        !            13: in a coherent way. SPMS provides the `glue' for coordinating the use
        !            14: of these tools and this section describes the techniques which have been
        !            15: devised for the development and maintenance of software packages.
        !            16: .NH 2
        !            17: Program Development Techniques
        !            18: .XS
        !            19: \*(SN Program Development Techniques
        !            20: .XE
        !            21: .PP
        !            22: Before discussing the maintenance of complete software packages, it is
        !            23: worthwhile to review the basic commands for managing individual programs
        !            24: and libraries. The commands are summarized in table 2 and explained below
        !            25: in more detail.
        !            26: .KF
        !            27: 
        !            28: .SM
        !            29: .ce
        !            30: \fITable 2.\fR   Program development commands
        !            31: .NL
        !            32: 
        !            33: .so develop.tbl
        !            34: .KE
        !            35: .NH 3
        !            36: \fIProgram compilation\fR
        !            37: .XS
        !            38: \*(SN Program compilation
        !            39: .XE
        !            40: .PP
        !            41: The command
        !            42: .ID
        !            43: %  \fBmake\fR
        !            44: .DE
        !            45: compiles source files into object files and loads them together
        !            46: to produce an executable program. Although
        !            47: .I make
        !            48: uses built-in information for generating the object files
        !            49: from the source files, the decision on how to load the program is
        !            50: left to the user. By default, the program makefiles produced by
        !            51: .I mkmf
        !            52: use the C compiler for this purpose. However, if the programming
        !            53: language is not C, the LINKER macro definition in the makefile should
        !            54: be altered accordingly. For Fortran this can be done by typing the command
        !            55: .ID
        !            56: %  \fBmkmf  LINKER=f77\fR
        !            57: .DE
        !            58: and for Pascal
        !            59: .ID
        !            60: %  \fBmkmf  LINKER=pc\fR
        !            61: .DE
        !            62: .PP
        !            63: Compiler options can be specified by adding certain macros to a
        !            64: makefile.  For example, the macro
        !            65: .ID
        !            66: CFLAGS = \-O
        !            67: .DE
        !            68: causes a C program to be compiled with optimization, and the macro
        !            69: .ID
        !            70: CFLAGS = \-I../../include  \-g
        !            71: .DE
        !            72: tells the C compiler to search for header files in the directory
        !            73: `../../include' as well as in the current directory (see \(sc\|2.9.1),
        !            74: and to compile the program with debugging information. FFLAGS and
        !            75: PFLAGS can be used similarly to set options for the Fortran and Pascal
        !            76: compilers respectively.
        !            77: .NH 3
        !            78: \fIInstallation\fR
        !            79: .XS
        !            80: \*(SN Installation
        !            81: .XE
        !            82: .PP
        !            83: The command
        !            84: .ID
        !            85: %  \fBmake  install\fR
        !            86: .DE
        !            87: installs a program or library (see \(sc\|2.9.3). If any source code
        !            88: files are newer than their corresponding object files they are
        !            89: recompiled and the program or library reformed. Even if the object
        !            90: files are up-to-date, a program may still be relinked if the libraries
        !            91: on which it depends are newer than the program itself.
        !            92: .PP
        !            93: Normally a program is stripped of its symbol table and relocation
        !            94: bits when it is installed, to save space. This can be avoided
        !            95: if the
        !            96: .B \-s
        !            97: option is removed from the
        !            98: .I install
        !            99: command line in the makefile.
        !           100: .NH 3
        !           101: \fIUpdating\fR
        !           102: .XS
        !           103: \*(SN Updating
        !           104: .XE
        !           105: .PP
        !           106: If a program or library is out-of-date \- that is, some of the source
        !           107: code files are newer than the installed version \- the command
        !           108: .ID
        !           109: \fBmake update\fR
        !           110: .DE
        !           111: recompiles and reinstalls the program or library. This command is more
        !           112: powerful than \fImake install\fR because it is not affected by the
        !           113: absence of the object files. In the case of an out-of-date library, all
        !           114: the object files are extracted from the library before any
        !           115: recompilation takes place, and removed once the library has been
        !           116: reinstalled.
        !           117: .NH 3
        !           118: \fIDependency analysis\fR
        !           119: .XS
        !           120: \*(SN Dependency analysis
        !           121: .XE
        !           122: .PP
        !           123: Although the
        !           124: .I make
        !           125: program has a set of built-in rules for recompiling a program if any of
        !           126: the files on which it depends have changed since the last time it was
        !           127: constructed, these rules do not extend to included files. It is
        !           128: necessary to add explicit dependency rules to a makefile so that if
        !           129: a header file is changed, the affected source files will be recompiled
        !           130: and a new program produced. For instance, if the rule
        !           131: .ID
        !           132: vs.o:  vs.h  hash.h  list.h
        !           133: .DE
        !           134: is added to the makefile for the `vs' program, the file `vs.c' will be
        !           135: recompiled if any of the included files (see \(sc\|2.9.1) have changed
        !           136: since the last time it was compiled. The command
        !           137: .ID
        !           138: %  \fBmake depend\fR
        !           139: .DE
        !           140: calls on the
        !           141: .I mkmf
        !           142: makefile editor to insert header file dependencies into a makefile.
        !           143: .NH 3
        !           144: \fIProgram checking\fR
        !           145: .XS
        !           146: \*(SN Program checking
        !           147: .XE
        !           148: .PP
        !           149: Programs written in C can be checked for bugs, obscurities, wasteful
        !           150: or error prone constructions, type and function usage, and portability
        !           151: by the
        !           152: .I lint
        !           153: program\|[4]. If a makefile contains the line
        !           154: .ID
        !           155: lint:;  @lint $(LINTFLAGS) $(SRCS) $(LINTLIST)
        !           156: .DE
        !           157: where the LINTFLAGS macro definition specifies
        !           158: .I lint
        !           159: options, SRCS represents the source files making up the program or library,
        !           160: and LINTLIST is a list of lint libraries (see below), the command
        !           161: .ID
        !           162: %  \fBmake lint\fR
        !           163: .DE
        !           164: will check that the program or library is consistent.
        !           165: .PP
        !           166: To set up the `vs' program might be set up for ``linting'', the macro
        !           167: definitions would be
        !           168: .DS
        !           169: LINTFLAGS \kx= \-I../../include
        !           170: 
        !           171: SRCS\h'|\nxu'= vs.c
        !           172: 
        !           173: LINTLIST\h'|\nxu'= \ky../../lib/llib-lhash.ln \\\\
        !           174: \h'|\nyu'\&../../lib/llib-llist.ln \\\\
        !           175: \h'|\nyu'\-lc
        !           176: .DE
        !           177: .PP
        !           178: Just as program libraries share functions among different programs,
        !           179: lint libraries can be used to check that those functions have been used
        !           180: correctly. Lint libraries are created by \fIlint \-C\fR as shown by the
        !           181: following entry in the makefile belonging to the `hash' library
        !           182: .DS
        !           183: $(LINTLIB):  \kx$(SRCS) $(HDRS) $(EXTHDRS)
        !           184: \h'|\nxu'@echo "Loading $(LINTLIB) . . ."
        !           185: \h'|\nxu'@lint $(LINTFLAGS) \-C$(LIBNAME) $(SRCS)
        !           186: \h'|\nxu'@echo done
        !           187: .DE
        !           188: where LIBNAME is defined in the makefile as `hash', and LINTLIB is defined
        !           189: as `llib-l$(LIBNAME).ln' in accordance with standard lint library naming
        !           190: conventions.
        !           191: .NH 3
        !           192: \fIVersion control and releases\fR
        !           193: .XS
        !           194: \*(SN Version control and releases
        !           195: .XE
        !           196: .PP
        !           197: During the time that a program is being developed it is quite likely
        !           198: that it will undergo several revisions. Features are added and
        !           199: algorithms are improved. Often changes are made which are later found
        !           200: not to work and need to be undone. One way to handle these changes is
        !           201: to save a copy of each file before it is revised. However, this quickly
        !           202: becomes expensive in terms of space. A better solution is to use a
        !           203: version control system like
        !           204: .I SCCS
        !           205: (Source Code Control System)\|[6] or
        !           206: .I RCS
        !           207: (Revision Control System)\|[10] which stores only the changes made to the
        !           208: source code together with details such as when each change was made,
        !           209: why it was made, and who made it.
        !           210: .PP
        !           211: Once a program is ready for release, all of the source files should be
        !           212: stamped with a common version name or number so that it can be recreated
        !           213: at any time regardless of any subsequent changes.
        !           214: .I RCS
        !           215: has the advantage over
        !           216: .I SCCS
        !           217: in this respect because it enables the user to stamp each release with a
        !           218: unique name. For example, if the makefile and all the source files in
        !           219: release 2 of the `list' library are stamped `V2', the command sequence
        !           220: .ID
        !           221: %  \fBco  \-rV2  Makefile\fR
        !           222: %  \fBmake  VERSION=V2  co\fR
        !           223: .DE
        !           224: will create that release
        !           225: by extracting or ``checking out'' the Makefile and the source files from the
        !           226: .I RCS
        !           227: system
        !           228: using the
        !           229: .I co
        !           230: command.
        !           231: .NH 3
        !           232: \fIFunction tagging\fR
        !           233: .XS
        !           234: \*(SN Function tagging
        !           235: .XE
        !           236: .PP
        !           237: By creating a database of function names\**
        !           238: .FS
        !           239: For C, Fortran, and Pascal programs only.
        !           240: .FE
        !           241: with the command
        !           242: .ID
        !           243: %  \fBmake tags\fR
        !           244: .DE
        !           245: it is possible for the user to find and edit a function without having
        !           246: to remember the name of the file in which the function is located. For
        !           247: example, in the `src' directory of the `libhash' subproject, the
        !           248: command
        !           249: .ID
        !           250: %  \fBvi  \-t  htinit\fR
        !           251: .DE
        !           252: invokes the
        !           253: .I vi
        !           254: editor on the file `htinit.c' and positions the cursor at the beginning of the
        !           255: `htinit' hash table initialization function.
        !           256: .PP
        !           257: A list of functions which make up the program or library,
        !           258: together with the line number and file in which each is defined, can be
        !           259: obtained by the command
        !           260: .ID
        !           261: %  \fBmake index\fR
        !           262: .DE
        !           263: .NH 3
        !           264: \fIPrinting\fR
        !           265: .XS
        !           266: \*(SN Printing
        !           267: .XE
        !           268: .PP
        !           269: To print all of the program source and header files on the line printer
        !           270: .I lpr,
        !           271: type
        !           272: .ID
        !           273: %  \fBmake  print  |  lpr\fR
        !           274: .DE
        !           275: By default the files are formatted by
        !           276: .I pr
        !           277: so that the output is separated into pages headed by a date, the name of
        !           278: the file, and a page number. Another format can be specified by changing
        !           279: the PRINT macro definition in the makefile.
        !           280: .NH 3
        !           281: \fICleaning up\fR
        !           282: .XS
        !           283: \*(SN Cleaning up
        !           284: .XE
        !           285: .PP
        !           286: To save space once a program has been completed, the command
        !           287: .ID
        !           288: %  \fBmake clean\fR
        !           289: .DE
        !           290: removes object files plus any other files which can be regenerated easily.
        !           291: .NH 3
        !           292: \fITesting\fR
        !           293: .XS
        !           294: \*(SN Testing
        !           295: .XE
        !           296: .PP
        !           297: Using the test cases prepared previously (see \(sc\|3.4), it is possible
        !           298: to test an entire program or library by typing the command
        !           299: .ID
        !           300: %  \fBptest\fR
        !           301: .DE
        !           302: .I Ptest
        !           303: reports the outcome of each test \- i.e. whether it passes or fails \- and if
        !           304: it fails, saves the error diagnostics in a file called E\fItest\fR where
        !           305: .I test
        !           306: is the name of the test.
        !           307: .PP
        !           308: Because
        !           309: .I ptest
        !           310: uses a number of temporary working files for each test and creates an error
        !           311: diagnostic file for each test that fails, it is a good idea not to clutter up
        !           312: the directories that contain source code or test cases, but instead perform
        !           313: the testing in another directory such as `work' (see \(sc\|4.3.5).
        !           314: .NH 3
        !           315: \fICompound commands\fR
        !           316: .XS
        !           317: \*(SN Compound commands
        !           318: .XE
        !           319: .PP
        !           320: The
        !           321: .I make
        !           322: program can process multiple requests. For example,
        !           323: .ID
        !           324: %  \fBmake install tags clean\fR
        !           325: .DE
        !           326: installs a program or library, creates function tags, and removes
        !           327: any unneeded files. The only operation which may cause problems
        !           328: if it is used in conjunction with
        !           329: .I install
        !           330: or
        !           331: .I update
        !           332: is \fImake depend\fR because it recreates the include file dependencies
        !           333: .B after
        !           334: the
        !           335: .I make
        !           336: command has already read the makefile.
        !           337: .NH 3
        !           338: \fIUser-defined commands\fR
        !           339: .XS
        !           340: \*(SN User-defined commands
        !           341: .XE
        !           342: .PP
        !           343: Most of the tasks described above are handled by the
        !           344: .I make
        !           345: command. More complex programming tasks can also be defined by adding
        !           346: extra instructions to each makefile. However, rather than modify every
        !           347: program and library makefile in a project individually, the user can
        !           348: get
        !           349: .I mkmf
        !           350: to use alternative `p.Makefile' and `l.Makefile' makefile templates when
        !           351: creating program and library makefiles respectively, if these templates
        !           352: exist in the project `lib' directory (see fig. 3). The templates for
        !           353: project `vs' include directives for type checking and version control (see
        !           354: appendix B). It is a worthwhile exercise to compare them against the
        !           355: standard templates shown in appendix A.
        !           356: .NH 2
        !           357: Layered Construction of Software Packages
        !           358: .XS
        !           359: \*(SN Layered Construction of Software Packages
        !           360: .XE
        !           361: .PP
        !           362: A complex software package may be built and installed in \fIlayers\fR\|[2]
        !           363: as shown in table 3.
        !           364: .KF
        !           365: 
        !           366: .SM
        !           367: .ce
        !           368: \fITable 3.\fR   Layers of software
        !           369: .NL
        !           370: 
        !           371: .so layer.tbl
        !           372: .KE
        !           373: .PP
        !           374: Each layer is assigned a specific label so that it can be built individually,
        !           375: as well as a priority level so that the complete software package can be
        !           376: constructed in a predetermined sequence. Layers are implemented by attaching
        !           377: type labels to the directories which are part of the building process.
        !           378: Table 4 suggests a set of type labels for each layer. By convention, type
        !           379: label `update' is used for the construction of the entire software package.
        !           380: .KF
        !           381: 
        !           382: .SM
        !           383: .ce
        !           384: \fITable 4.\fR   Layer type labels and priority levels
        !           385: .NL
        !           386: 
        !           387: .so construct.tbl
        !           388: .KE
        !           389: .PP
        !           390: If the project `vs' is organized into layers in the manner shown in figure 11,
        !           391: .KF
        !           392: .sp 34
        !           393: .SM
        !           394: .ce
        !           395: \fIFigure 11.  \fRLayers of project `vs'
        !           396: 
        !           397: .NL
        !           398: .KE
        !           399: then the command
        !           400: .ID
        !           401: %  \fBpexec \-T\|libsrc  make  update\fR
        !           402: .DE
        !           403: brings the program libraries up-to-date, while the command
        !           404: .ID
        !           405: %  \fBpexec \-T\|cmdsrc  make  update\fR
        !           406: .DE
        !           407: does the same for the programs
        !           408: .I vs
        !           409: and
        !           410: .I vstutor.
        !           411: By typing
        !           412: .ID
        !           413: %  \fBpexec \-T\|update  make  update\fR
        !           414: .DE
        !           415: the entire software package can be updated.
        !           416: .NH 2
        !           417: Maintenance of Software Packages
        !           418: .XS
        !           419: \*(SN Maintenance of Software Packages
        !           420: .XE
        !           421: .PP
        !           422: Having established the conventions for maintaining the individual components
        !           423: of a software package, global tasks such as printing,
        !           424: testing, cleaning, etc., can now be described in more detail. The type
        !           425: labels that provide the means for coordinating these tasks are
        !           426: summarized in table 5. Some of the labels have the letter
        !           427: .I n
        !           428: to indicate priority because the directories to which they are attached
        !           429: must be processed in a particular order (see \(sc\|2.10.2). 
        !           430: .KF
        !           431: 
        !           432: .SM
        !           433: .ce
        !           434: \fITable 5.\fR   Type label conventions
        !           435: .NL
        !           436: 
        !           437: .so label.tbl
        !           438: .KE
        !           439: .NH 3
        !           440: \fICounting of source lines\fR
        !           441: .XS
        !           442: \*(SN Counting of source lines
        !           443: .XE
        !           444: .PP
        !           445: The total number of lines of source code in a software package can be counted
        !           446: by concatenating the source files in each `src' directory and piping them
        !           447: to the word count program as
        !           448: .ID
        !           449: %  \fBpexec  \-q  \-T\|src  make  PRINT=cat  print  |  wc  \-l\fR
        !           450: .DE
        !           451: where
        !           452: .B \-q
        !           453: suppresses the printing of project directory titles, and
        !           454: .B \-l
        !           455: tells
        !           456: .I wc
        !           457: to count lines only.
        !           458: .NH 3
        !           459: \fICataloging of functions\fR
        !           460: .XS
        !           461: \*(SN Cataloging of functions
        !           462: .XE
        !           463: .PP
        !           464: A list of functions, together with the line number and file in which
        !           465: each is defined, may be obtained\** for each program in a software package
        !           466: .FS
        !           467: For C, Fortran, and Pascal programs only.
        !           468: .FE
        !           469: by the command
        !           470: .ID
        !           471: %  \fBpexec  \-T\|cmdsrc  make index\fR
        !           472: .DE
        !           473: .PP
        !           474: A comprehensive index of all the library functions can be generated by
        !           475: outputting the function definitions in each library (e.g. `libhash' and
        !           476: `liblist') to the
        !           477: .I sort
        !           478: program by
        !           479: .ID
        !           480: %  \fBpexec  \-q  \-Tlibsrc  make index  | sort\fR
        !           481: .DE
        !           482: .NH 3
        !           483: \fIPrinting\fR
        !           484: .XS
        !           485: \*(SN Printing
        !           486: .XE
        !           487: .PP
        !           488: After printing all of the source code in a project by
        !           489: .ID
        !           490: %  \fBpexec  \-T\|print  make print  |  lpr\fR
        !           491: .DE
        !           492: a table of contents can be produced by
        !           493: .ID
        !           494: %  \fBpexec  \-Tprint  make \\\&"PRINT=ls \-C\^\\\&" print  |  lpr\fR
        !           495: .DE
        !           496: Backslash `\\' characters prevent the double quotes `"' from being stripped
        !           497: from the PRINT macro definition by the shell before the
        !           498: .I make
        !           499: command is executed in each directory.
        !           500: .NH 3
        !           501: \fIProgram checking\fR
        !           502: .XS
        !           503: \*(SN Program checking
        !           504: .XE
        !           505: .PP
        !           506: Software packages written in C can be cross-checked for function and type usage
        !           507: by applying the
        !           508: .I lint
        !           509: command to the source code in each of the project directories containing a
        !           510: program or library
        !           511: .ID
        !           512: %  \fBpexec  "\-T\|libsrc\||\|cmdsrc"  make lint\fR
        !           513: .DE
        !           514: .NH 3
        !           515: \fITesting\fR
        !           516: .XS
        !           517: \*(SN Testing
        !           518: .XE
        !           519: .PP
        !           520: All of the tests previously prepared for a software package are exercised
        !           521: by the command
        !           522: .ID
        !           523: %  \fBpexec  \-T\|test  ptest  >  testlog\fR
        !           524: .DE
        !           525: in the directories labeled `test'. In the case of project `vs', the
        !           526: following directories are labeled `test'
        !           527: .DS
        !           528: .so test.tbl
        !           529: .DE
        !           530: The outcome of each test \- i.e. whether it passes or fails \- is recorded
        !           531: in the file called `testlog' in the current working directory. If a test
        !           532: fails, the cause of the failure is recorded in a file bearing the
        !           533: name `E\fItest\fR' where
        !           534: .I test
        !           535: is the name of the test, located in the directory where the test is
        !           536: executed.
        !           537: .NH 3
        !           538: \fIComparing versions\fR
        !           539: .XS
        !           540: \*(SN Comparing versions
        !           541: .XE
        !           542: .PP
        !           543: The method for comparing the source code in two different versions of a
        !           544: project depends on the way in which the versions are stored. If they
        !           545: are stored in separate projects the
        !           546: .I pdiff
        !           547: command can be used to compare the contents of the directories belonging
        !           548: to each of the two projects. For example, if `nvs' is a new version of
        !           549: the project `vs', then the command
        !           550: .ID
        !           551: %  \fBpdiff  \-T\|src  ^vs  ^nvs\fR
        !           552: .DE
        !           553: will produce a summary of the differences between them. However, if the
        !           554: different versions are stored as deltas in a version control system such as
        !           555: .I SCCS
        !           556: or
        !           557: .I RCS,
        !           558: then either the
        !           559: .I sccsdiff
        !           560: command or the
        !           561: .I rcsdiff
        !           562: command must be used instead. To show how this is done with
        !           563: .I RCS,
        !           564: .ID
        !           565: %  \fBpexec  \-T\|src  make  VERSION=V2  diff\fR
        !           566: .DE
        !           567: compares the current working version of the source code in the project
        !           568: `vs' with a previous version labeled `V2'.
        !           569: .NH 3
        !           570: \fIReleases\fR
        !           571: .XS
        !           572: \*(SN Releases
        !           573: .XE
        !           574: .PP
        !           575: If the source code for a software package is stored in a version control
        !           576: system like
        !           577: .I RCS,
        !           578: it is possible to re-create any particular version of the package provided
        !           579: that all the source files in that version have previously been stamped
        !           580: with a symbolic version name\** (for example, `V2').
        !           581: .FS
        !           582: \fISCCS\fR does not have this feature.
        !           583: .FE
        !           584: The process is carried out in two stages. After removing the current version
        !           585: of the source code (hopefully, it has already been stored in the version
        !           586: control system) by the following command sequence,
        !           587: .ID
        !           588: %  \fBpexec  \-T\|src  \'rm  \`make PRINT=echo print\`  Makefile\'\fR
        !           589: .DE
        !           590: the makefile and source files for the desired version (say `V2') are
        !           591: checked out by
        !           592: .ID
        !           593: %  \fBpexec  \-T\|src  \'co  \-rV2  Makefile;  make  VERSION=V2  co\'\fR
        !           594: .DE
        !           595: .NH 3
        !           596: \fICleaning up\fR
        !           597: .XS
        !           598: \*(SN Cleaning up
        !           599: .XE
        !           600: .PP
        !           601: If a software package is in a stable state \- that is, it is not being
        !           602: modified \- then, as an economy measure, the amount of space that it
        !           603: takes up can be reduced by removing object files plus any other files
        !           604: that can be regenerated easily. This task is implemented by
        !           605: .ID
        !           606: %  \fBpexec  \-T\|clean  make clean\fR
        !           607: .DE
        !           608: assuming that the directories containing the files to be removed are
        !           609: labeled `clean'.
        !           610: 
        !           611: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.