Nyshell used in conjunction with Nypatchy is intended to replace the use of Fcasplit of Patchy version 4, and that part of the "make" utility which has to do with the re-compilation of modified routines.
Remember: Ypatchy of version 4 writes the EXE selected decks together to an ASM file. Fcasplit reads this file, splitting the routines into separate files, writing out a shell-script (or a make file) to compile all the routines.
With Patchy version 5, the splitting onto separate files is done already by Nypatchy, which writes on a log file the names of all routines written, together with the logical stream name of each routine. Using this log Nyshell will create a shell-script to compile the routines which need compilation.
Moreover, if the splitting has been done to a physical stream
established with +ASM,...,T=MODIFY,LOG
the re-compilation
of unchanged
routines can be avoided. But this implies that at least the .f files are
retained indefinitely (the .o files could be restored from the library).
T=SPLIT
In this mode the use of Nyshell is straight-forward, Nyshell simply converts the log file into a shell-script to compile all routines.
T=MODIFY
The log file from Nypatchy will contain one line for each routine,
giving the stream name and the file name. Unchanged routines have
additional information: the "same" flag plus the names of the files
called with +INCLUDE
, if any; something like:
fort:1 chdirf.f cc:1 chdiri.c fort:1 getenvf.f same cc:1 geteni.c same cc:1 getpidf.c fort:1 getwdf.f cc:1 getwdi.c same cc:1 fzincc.c same fzinc.h mzinc.h(This last line indicates that on stream cc:1 the source file fzincc.c is unchanged, and that it calls the include files fzinc.h and mzinc.h, also unchanged, and also residing in the same source directory as everybody else.)
In MODIFY
mode we can avoid re-compiling routines which have not changed.
But we need more: routine names may have changed, or some routines may
have been removed from the Pam file. Also, the previous run may have
abended, such that the new .f files have not yet been compiled, but
the second Nypatchy run will see unchanged .f files.
Nyshell has been programmed to handle the following frequent situation: the current working directory contains all and only the .o files of all the routines of the program (or the package) being dealt with. When the compilation is done, all .o files will be collected into one .a library file.
In this situation one gives the U (uptodate) option to Nyshell which will then do the following:
INCLUDE
files called, if any;
.f
is .FOR
, .s
is .MAR
,
.o
is .OBJ
and .a
is .OLB
.
Nyshell has a default set-up built into it on how to compile normally on the machine it is running on. The default set-up can be seen by typing
nyshell - hThis default set-up can be changed by control-lines given in the cradle. The cradle may be given as a here-document read from standard input; it may be declared to be empty by giving
EOF
as file name; or it may be
read from a file whose name is given on the command line in the "read"
position. If, with this last case, the file does not exist, this does
not create an error but is accepted as a signal to use the default
set-up as is.
As an example, here are the cradle lines which would produce the default set-up on the Apollo:
fo:1 -opt 3 fo:2 -opt 0 fo:3 =:1 fo:4 =:2 fopt -bounds_violation -info 1 -indexl -cpu mathlib_sr10 fc /com/ftn fort:1 ${FC} ${s}$*.ftn ${FO_1}; mv $*.bin $*.o fort:2 ${FC} ${s}$*.ftn ${FO_2}; mv $*.bin $*.o fort:3 =:1 fort:4 =:2 co:1 -O co:2 co:3 =:1 co:4 =:2 copt -c cc cc cc:1 ${CC} ${CO_1} ${s}$*.c cc:2 ${CC} ${CO_2} ${s}$*.c cc:3 =:1 cc:4 =:2 ao:1 ao:2 =:1 ao:3 =:1 ao:4 =:2 aopt as as as:1 ${AS} ${AO_1} ${s}$*.s as:2 =:1 as:3 =:1 as:4 =:2 start # Script from Nyshell for file f.e end # End of the shell script
The tag on the left identifies the information given for it on the right. Thus "fc", "cc", and "as", specify the command verbs to be used to call the compiler for Fortran, C, and assembler, respectively.
"fopt" gives the compiler options to be used for all logical streams;
whilst "fo:i" gives the extra options to be used for stream FORT:i
.
"fort:i" specifies the complete command to be given to the shell to
compile one routine, the escape $*
indicating the place(s) where the
routine name has to be inserted.
The value "=:1"
means: same as stream 1.
Tag "sdir" may be used to explicitly set the directory where the source files are; by default this is the directory where the log file is found.
The default set-up assumes that routines coming to streams :1 and :3 are to be compiled normally, and that routines coming to streams :2 and :4 have problems and should be compiled without optimisation.
One may over-rule the default with a line like:
fopt -bounds_violation -info 1 -indexl -cpu mathlib_sr10 -dbsor one may add to the default with a line like:
+fopt -dbsFrom the set-up Nyshell constructs shell parameter definitions followed by the shell commands to compile. As an example, here is the shell script delivered for the latest re-making of my debug version of KERNLIB on Apollo:
#!/bin/csh -f # Script from Nyshell for file ../source.log set FILE = source set s = "../" set FO_1 = "-bounds_violation -info 1 -indexl -cpu mathlib_sr10 -dbs -opt 3" set FC = "/com/ftn" set CO_1 = "-c -g -O" set CC = "cc" ${CC} ${CO_1} ${s}geteni.c ${CC} ${CO_1} ${s}getgidf.c ${CC} ${CO_1} ${s}getpidf.c ${CC} ${CO_1} ${s}getuidf.c ${CC} ${CO_1} ${s}getwdi.c ${FC} ${s}gshowf.ftn ${FO_1}; mv gshowf.bin gshowf.o ${FC} ${s}ccopiv.ftn ${FO_1}; mv ccopiv.bin ccopiv.o ${FC} ${s}ccosub.ftn ${FO_1}; mv ccosub.bin ccosub.o ${FC} ${s}mxmad.ftn ${FO_1}; mv mxmad.bin mxmad.o ${FC} ${s}mxmlrt.ftn ${FO_1}; mv mxmlrt.bin mxmlrt.o ${FC} ${s}mxtrp.ftn ${FO_1}; mv mxtrp.bin mxtrp.o ${FC} ${s}mxuty.ftn ${FO_1}; mv mxuty.bin mxuty.o # End of the shell scriptresulting from this call to Nyshell:
nyshell ../source.log u .go <</ +fopt -dbs +copt -g /On the VAX, Nyshell will itself substitute the parameter values into the compilation command lines; for this the parameters have to have the curly brackets as shown; Nyshell will look for the tokens
${s}, ${FC}, ${FO_1}
, etc.
Note that Nyshell itself and the resulting shell-script source.shfca
must be run in the directory where the .o files are or are to be.
The last step in the execution of Nyshell is to write to a file, the ".xqtlog" file, a list of all the routines involved and their properties. This contains the compiler options for each stream, and the names of all routines belonging to each stream.
Next time round, Nyshell reads the .xqtlog file from the last run to check for each routine that its compiler options are unchanged. Thus the complete set of conditions for a routine not to need re-compilation is:
1) Nypatchy sends the "same" flag; 2) the current compiler options are the same as on .xqtlog; 3) the .o file exists and is more recent than the .f (or .c) file, and more recent than any .h file used;The use of the input .xqtlog file can be by-passed with the "B" option; the "E" option requests by-passing if this file is not existing. If neither B nor E is given, Nyshell will trigger recompilation of all routines if it does not find the .xqtlog file in the current directory to be valid.
The name of the .xqtlog file is derived from the name of the log
file given to Nyshell; in the examples given in this paper this
name would be source.xqtlog
.
Note that Nyshell does of course not analyse the meaning of the compiler options, thus any trivial change will force recompilation.
nyshell x.log options read print "x.log": the input log file having been created by Nypatchy; the output files delivered will be x.shfca the shell script to be run for compilation x.xqtlog remembering the compilation options "options": A all - compile or re-compile all files B bypass the use of the input .xqtlog file E empty - bypass the .xqtlog file if it is empty H help - print the help information only Q quick - do not display the set-up information U uptodate - check that all .o files in the current directory are ready to be put into the last-version library V verbose - display the complete set-up. "read": name of the file with the user set-up commands, EOF if default set-up to be used as is, default: standard input "print": printed output file, default: standard output
#!/bin/csh -v -f # Create Patchy 5 library and modules set PRO = ~/bin set NEW = ~/p5/dev set PAM = ~/p5/wyl/patchy.car set KERNLIB = ~/kern/inst/libkerndbg.a set EXTRA = ' ' setenv ACTION MODIFY setenv MACHINE APOLLO set LOAD = ld if (-d wk_patchy == 0) mkdir wk_patchy cd wk_patchy $PRO/nypatchy $PAM .go <<\\ +ASM, FORT, T=${ACTION}, LOG .source.log +EXE. +USE, *PATCHY, ${MACHINE}. +USE, QDEBUG, TESTR. +OPT, MAP. +PAM. \\ set rc = $status if ($rc != 0) exit $PRO/nyshell source u .go <<\\ +fopt -dbs \\ set rc = $status if ($rc != 0) exit csh -f -v source.shfca if (-f p5lib.a) rm p5lib.a ar rc p5lib.a *.o $LOAD -o $NEW/nypatchy npatch.o p5lib.a $KERNLIB $EXTRA $LOAD -o $NEW/nyindex nindex.o p5lib.a $KERNLIB $EXTRA $LOAD -o $NEW/nylist nlist.o p5lib.a $KERNLIB $EXTRA $LOAD -o $NEW/nyshell nshell.o p5lib.a $KERNLIB $EXTRA
#!/bin/csh -f -v # Shell script to create short KERN libraries on Apollo setenv KERNMACH ~/kern/pam/kernapo.car setenv KERNFOR ~/kern/pam/kernfor.car set KERNLIB = ~/kern/inst/libkernsh.a set KERNLIBDB = ~/kern/inst/libkerndbg.a set MICKYLIB = ~/kern/lib/libmicky.a set MICKYPAM = ~/kern/pam/micky.car cd ~/kern/inst if (-d wk_kern == 0) mkdir wk_kern cd wk_kern nypatchy .go <<\\ +ASM, FORT, T=MODIFY, LOG .source.log +EXE. +USE, *KAPO. +PAM, T=ATTACH .$KERNMACH +PAM, T=ATTACH .$KERNFOR +QUIT. \\ if ($status != 0) exit # ----------------------------------------- compile debug library if (-d wk_dbg == 0) mkdir wk_dbg cd wk_dbg | cd is inst/wk_kern/wk_dbg | nyshell ../source u .go <<\\ | +fopt -dbs | take the source from ../ +copt -g | and re-compile the changes \\ | into ./ if ($status != 0) exit csh -f -v source.shfca if (-f $KERNLIBDB) rm $KERNLIBDB ar rc $KERNLIBDB *.o cd ../ # ----------------------------------------- compile normal library nyshell source uq eof .go | | cd is inst/wk_kern if ($status != 0) exit | take the source from here | and re-compile the changes csh -f -v source.shfca | into here | if (-f $KERNLIB) rm $KERNLIB ar rc $KERNLIB *.o cd ../ # ----------------------------------------- Run Micky test job nypatchy $MICKYPAM mickyrun .go <<\\ +EXE, MICKY, D=MIMAIN. +USE, *MAPO. +PAM. \\ /com/ftn mickyrun -bounds_violation -info 1 -indexl -cpu mathlib_sr10 ld -o mickyrun mickyrun.bin $MICKYLIB $KERNLIB mickyrun
Here we use +XDIVERT
to make two streams into 2 separate subdirectories.
#!/bin/csh -f # Shell script to create the ZEBRA libraries set PAM = ~/zebra/pro/zebraq.car set ZLIB = ~/zebra/pro/zebra.a set ZLIBTE = ~/zebra/pro/zebrate.a cd ~/zebra/pro if (-d wk_lib == 0) mkdir wk_lib if (-d wk_test == 0) mkdir wk_test nypatchy $PAM .go <<\\ +ASM, FORT, T=MODIFY, PREFIX, LOG .wk_lib/source.log +ASM, FORT:3, T=MODIFY, PREFIX, LOG .wk_test/source.log +EXE. +USE, QTESTLIB, T=XDIV, TRANS. +USE, *ZEBRAL. +USE, FZCONV, T=INH. +OPTION, ALL, MAP. +PAM. +QUIT. \\ if ($status != 0) exit # ------------------------------ Compile for library zebra.a cd wk_lib if (-f $ZLIB) ar xo $ZLIB | restore the .o files nyshell source u eof .go set rc = $status | if ($rc == 1) goto libok | status 1: no new compilations if ($rc != 0) exit | 2: error csh -f -v source.shfca if (-f $ZLIB) rm $ZLIB ar rc $ZLIB *.o libok: touch $ZLIB rm *.o | delete the .o files # ------------------------------ Compile for library zebrate.a cd ../wk_test nyshell source u eof .go if ($status != 0) exit csh -f -v source.shfca if (-f $ZLIBTE) rm $ZLIBTE ar rc $ZLIBTE *.o
In this example we delete the .o files and restore them on the next run from the library file; this saves disk space but costs time.
With these commands in the login file login.com
to switch between
VAX and Alpha:
$ if f$getsyi("ARCH_NAME").eqs."VAX" $ then DOING :== VAX $ assign disk$support:[zoll.vaxnew] NEW $ assign disk$support:[zoll.vaxexe] EXE $ assign disk$support:[zoll.vaxlib] LIB $ else DOING :== ALPHA $ assign disk$support:[zoll.alphanew] NEW $ assign disk$support:[zoll.alphaexe] EXE $ assign disk$support:[zoll.alphalib] LIB $ endifwe can run this:
$ set verify = procedure $ set verify = noimage $ on error then $ goto exit $ on control_y then $ goto exit $! $! COM-file to create nypatchy.EXE etc. using Patchy 5 for VAX or ALPHA $! $ assign [zoll.p5.dev] OPDIR $ assign [zoll.p5.wyl] SRCDIR $ assign lib:kernlib KERNLIB $ assign lib:p5lib P5LIB $ ACTION :== MODIFY $! $ set default OPDIR $ set default [.wk_patchy] $ nypatchy SRCDIR:patchy.car .go +ASM, FORT, T=${ACTION}, LOG .source.log +EXE. +USE, *PATCHY, VAX. +OPTION, MAPASM. +PAM. +QUIT. $ set default [.wk_'DOING] $ nyshell ../source.log u eof .go $ if $status .ne. 1 then goto exit $ @source.shfca $ purge/nolog $ lib/create P5LIB *.obj $ ULIB :== KERNLIB/LIB,SYS$LIBRARY:VAXCRTL/LIB $ link/nomap/exe=NEW:nypatchy P5LIB/INC=npatch/LIB,'ULIB $ link/nomap/exe=NEW:nyindex P5LIB/INC=nindex/LIB,'ULIB $ link/nomap/exe=NEW:nylist P5LIB/INC=nlist/LIB,'ULIB $ link/nomap/exe=NEW:nyshell P5LIB/INC=nshell/LIB,'ULIB $exit: $ set default OPDIR $ set noverify $ exit