QEF home page
12. A Multi-Directory Application and Mkvernum

In this section we look at controlling a multi-directory application.


Table of Contents
Previous Page
Next Page

First we need to chdir to the root of the object tree:
% qd -R / ; pwd  # chdir to root of current tree
Using 46 cook 3.4 object dt gobo linux2_0i /g/dt/cook/obj ...
/g/dt/cook/obj
treedirs: to create missing directories

Then we need to create the tree for appl:

% treedirs -a appl  # create appl part of the tree
+ mkdir appl
+ mkdir appl/appl
+ mkdir appl/cmd
+ mkdir appl/lib
+ mkdir appl/man
Note: The --a is required as otherwise directories not in the working directory will not be created.
qefdirs: The multi-directory script generator

Now chdir into appl and look at the qeffile.

% cd appl; cats qeffile
Begin   qefdirs

All = Install Man	# Bind All target to Install and Man

appl     I       # appl has Install constructions
lib      IL      # appl has Install and Local constructions

+		# '+' lines start new levels

cmd      IL      lib	# cmd depends on lib
man      m       # m == Man, but only if @NO_MAN not set

For this directory the script generator is qefdirs. This program will transform the above into a mimk script that provides a variety of selectable targets as listed by the following:

% qef -Ptargets
Local:          do local constructions
Local<N>:       do local constructions for level <N>
Install:        do installations
Install<N>:     do installations for level <N>
Man:            install manual sections
Man<N>:         install manual sections for level <N>
-D<Key>to=<N>:  Specifies that <Key> actions up to level N
            done where <Key> is `I' for Install, `M'
		    for Man, etc.
-DDoto=<N>:     Do up to level <N>

<dir>~I:        do Install for directory <dir>
<dir>~<key>:    do <key> action for directory <dir>

RemoveObjs:     remove objects created in current directory
RemoveInst:     remove objects installed into other directories
RemoveAll:      combine RemoveObjs & RemoveInst
                Any of above can be followed by `List' which
                suppresses removals and leaves list in place.

All:            implies: Install Man
qefdirs levels

In the current qeffile there are two levels. The qefdirs flag --L shows the levels and the constructions in those levels.

% qefdirs -L
Install 1       appl lib
        2       cmd
Man     2       man

The division of the directory list into levels allows the user to select ranges of directories for selection which in larger projects can sometimes be useful. For example, if a compilation error in the 15th level causes a build to fail, the ability to restart the build suppressing the first fourteen levels can be a real time saver. The command to do that would be:

    % qef -DIto=14  # Installs done to level 14

The appl directory was created to illustrate a typical application package. Its directories are:

appl	# header directory
lib	# appl API
cmd	# the main programs
man	# the manual sections
A Multi- Directory Project

Despite the small size of this project, its qeffiles are representative of the qeffiles that would be used in similar directories in much bigger projects. The qeffiles are actually encoded to accommodate large numbers of source files.

% lash -o 'cat `sls %1/qeffile`' `l -d`  # see below
+ cat `sls appl/qeffile`
set Suffixes    h       # limit sls to *.h files
Begin
# Install *.h files into destination's hdrs/appl/
instfls -d _DestDir_/hdrs/appl @argv~x/h/

+ cat `sls cmd/qeffile`
addpath LibPath ../lib  # -lappl is in ../lib
Begin
program -v appl.c	
commands @argv    @# Just in case we add any new files ...
# Note that appl.c already processed above so not done again

+ cat `sls lib/qeffile`
Begin
library -v -n appl @argv @# Create appl library, add a
	version file

+ cat `sls man/qeffile`
set Suffixes 1
Begin
cmds_man @argv  @# Install all the manual sections
    # commands @argv would have worked as well

lash is a command that interprets its first argument as a shell command after replacing "%..." sequences by the remaining arguments in turn. The l --d command lists the directories in the current directory.

Multi-Directory Build

Let's do the default build (i.e., Local):

% qef  # default build usually Local
#{ @gobo 2003/07/20 05:17:25
# QEFHALTFILE: /g/dt/cook/obj/appl/%qef32208b.hlt
#-{ -d lib Local @gobo 2003/07/20 05:17:25
New:    /p/cook/s3.4/appl/lib/rtn.c
Warning: "qmkhist._" does not exist -- all will be redone
    See warnMimk1(x-qmisc)
+ cc -c -I.. -I/p/cook/s3.4/appl -I/g/dt/cook/dest/hdrs \
    /p/cook/s3.4/appl/lib/rtn.c
+ arupdate -V libappl -r libappl.a rtn.o
- mkvernum -blib -o _vlappl.c libappl
- cc -c _vlappl.c
- /usr/bin/ar qv libappl.a rtn.o _vlappl.o
a - rtn.o
a - _vlappl.o
- ranlib libappl.a
- rm _vlappl.c rtn.o _vlappl.o
#-} E0 gobo@/g/dt/cook/obj/appl/lib 2003/07/20 05:17:27(2)
#-{ -d cmd Local @gobo 2003/07/20 05:17:27
New:    /p/cook/s3.4/appl/cmd/appl.c
Warning: "qmkhist._" does not exist -- all will be redone
    See warnMimk1(x-qmisc)
+ cc -c -I.. -I/p/cook/s3.4/appl -I/g/dt/cook/dest/hdrs \
    /p/cook/s3.4/appl/cmd/appl.c
+ vcc -m appl -bdefl cc -o appl appl.o +VFILE+
	../lib/libappl.a
#-} E0 gobo@/g/dt/cook/obj/appl/cmd 2003/07/20 05:17:29(2)
#} E0 gobo@/g/dt/cook/obj/appl 2003/07/20 05:17:29(4)
wot version is it?

The --v options used in the qeffiles for lib and cmd result in the embedding of version strings in the library libappl.a and the program appl.

% wot lib/libappl.a cmd/appl  # see below
lib/libappl.a:
    Libappl 3.4(7) - 2003/07/20 05:17:27 - Linux-2.0.34-i686

cmd/appl:
    Appl    3.4(4) - 2003/07/20 05:17:29 - Linux-2.0.34-i686
    Libappl 3.4(7) - 2003/07/20 05:17:27 - Linux-2.0.34-i686

The program wot is similar to SCCS's what. The version strings are embedded in libraries and programs prefixed by a "@(#)" string.

mkvernum generated version strings

The numbers in parentheses after the release number (e.g., "(4)" and "(7)") are retrieved from the qdsrv database server. One of the databases maintained by qdsrv is a log of build numbers. On request, qdsrv increments the build number for the named module, records the request in the database, and returns the build number. Given the universal nature of the qdsrv, this number is unique across all platforms and users hence uniquely identifies the module. The record in the database also contains the host, directory, and user of the build thus using the build number and the qdsrv build record one can retrieve the information necessary to rebuild the module. These mkvernum generated strings (vcc is just a link to mkvernum) can take a variety of forms for use in arbitrary files. For example, the relinfo file in the root of the qef product tree contains in part:

% cat $QTREE/relinfo
Qtree(full) 9.1(57) - Linux-2.0.34-i686 - 2003/07/19
		07:00:44 EDT
    dt on gobo in /p/qtree/linux2_0i/o9.1
Using:
    Tcl/tk 7.4(5) - Linux-2.0.34-i686 - 2003/07/03 EST 01:46:07
Qvrs settings:
              AsSuffix  s
             BeginLine  qefdirs
                Branch  .
               BuildDt  1
             BuildHost  gobo
# rest of settings elided

The Qtree and Tcl/Tk version lines were both generated by mkvernum.


cook22.qh - 1.19 - 03/10/24 QEF home page Table of Contents Previous Page Next Page