Getting started with
GMKPACK
CNRM / GMAP / ALGO
Version 6.1
2005-04-04
This document has been written in order to help people to use the procedure gmkpack.
gmkpack is a procedure that has been written by GCO and myself in order to create an environment to compile and make binaries from Arpege, Aladin, ODB, ... or others libraries.
The previous version of this precedure, named mkpack,
was based on the use of makefiles.
It solved the problem of the dependencies research between
source files. But unfortunately it was not properly adapted to handle the
so-called "duplicated" subroutines of Aladin. Furthermore the research
of dependencies was very slow.
The present procedure is an improvement of the previous system ; it is composed of "home-made" scripts, written in Perl or Shell. Though one can find it less user-friendly, it solves the problem of duplicated subroutines. It is also faster than the previous one as far as dependencies compilation is concerned.
Like the previous system using makefiles, this one will find for you what should be compiled (or re-compiled), by checking the dependencies (due to the use of fortran modules), and by checking whether or not a source file is more recent than its corresponding object file. It will also provide for you all the necessary links to reach the source codes, object libraries, etc.
Nevertheless, there are several differences between the
two systems in the way it works as in the way it should be used.
For instance, packs from mkpack and packs from
gmkpack
are not compatible.
-----------------------------------------------------------------------------------------------------
When you want to compile source codes, you have to copy
your modified source codes "somewhere" (usually : a directory).
This "somewhere" is somehow a "pack".
A pack is a directory, containing specific subdirectories
and files, that will be all created by running gmkpack.
Below this directory, you will compile your modifications
and make your libraries and executables.
The use of Arpege/Aladin is made complicated by the need
of various "include" files, modules and libraries to achieve an executable.
Gmkpack will provide for you all this environment
that you will need.
Therefore, the pack that you will create in your user
must depend on a pre-defined "environment", described by an existing Arpege
reference cycle.
More generally, we can try to define a pack as follows
:
A pack is a consistent ensemble of scripts, source
files, libraries and executables
of all ClearCase projects related to Arpege/Aladin
(ie : arp, ald, tfl, tal, odb, uti, ...)
-----------------------------------------------------------------------------------------------------
Preliminary tests showed that while mkpack.pl looked
well designed for GCO purpose, it is actually not properly designed for
developers. Gmkpack is a procedure which fits
developers' work, and which is supposed to fit as well GCO's work later
on.
gmkpack is a procedure to create
a pack and generate script files
to compile your modified source
codes and to make libraries or executables.
-----------------------------------------------------------------------------------------------------
Before starting to create a pack, you should add the following
lines in your file .profile
on the machine where you will operate on your packs ("tora" at this time
for Météo-France) :
Example :
export GMKROOT=/u/gp/mrpm/mrpm602/gmkpack
export ROOTPACK=/u/dp/marp/marp001/pub
export GMKFILE=VPP5000.TORA
export HOMEPACK=$HOME/pack
export HOMEBIN=$WORKDIR/binpack
export PATH=$PATH:$GMKROOT/util
export CATMAN=$CATMAN:$GMKROOT/man
export GMKTMP=$TMPDIR
-----------------------------------------------------------------------------------------------------
Before starting, one
should have in mind that making a pack with
gmkpack
is very similar to getting a ClearCase
view with cc_getview
As when you create a ClearCase
branch upon an existing GCO release,
you will always create a pack
upon an existing GCO pack.
Therefore you will have to define the characteristics of the GCO pack (called : "reference pack" or "source pack") upon which your own pack will be built.
To get the usage of
gmkpack,
type :
gmkpack
The system will answer
:
Usage: gmkpack -r release [-b branch ]
[-n local-pack-version ] [-a -s | -u target-pack [-v reference-pack-version
]] [-l compiler-label ] [-o compiling-flag ] [-f rootpack-directory ] [-p
project|program ] [-O] [-m]
Parameters :
--------
-r = reference release label
-u = target pack name
-b = reference branch name (optional,
default is "main")
-v = reference pack version number
(optional, default is the latest)
-l = reference compiler version
(optional, default is "L0209")
-o = compiler options family, (optional,
"x" : optimal [default], "g" : debug, "b" : bound checking)
-f = alternative rootpack directory
(optional)
-p = project|program name for the
compilation script
-m = quiet mode (optional ; to make
the compilation script only)
-O = Observations handling libraries
(optional)
-a = To create a main pack (optional)
-n = local pack version number (optional,
default is the latest existing one)
-s = To create the scripts to compile
the system programs
To start with, let's consider only the mandatory parameter :
-r : ARPEGE
reference release label under Clearcase ; in other words : the main
Arpege cycle to be considered.
You can get the list
of existing releases by typing : rlspack
Two more arguments are very important, however :
-u : User's target pack : you can set the name of your choice (it is recommended
to choose a name which refers to your corresponding ClearCase branch).
If you do not provide this argument the system will build one anyhow.
-p : Program
name to make an executable ; the possible values are listed below.
If you do not provide this argument, gmkpack will create a pack
without any script to compile or load. Anyhow it will be still possible
to generate such scripts later.
Possible program names :
adbiasFor example, let's make a pack named test0 upon the Arpege release CY24T1, with a script for compiling and loading aladin :
adscan
aladin
aldodb
arome
arpege
arpodb
atstprog
bator
biascv
blend
blendsur
cabias
cascan
check_limits
ctrodb
ctroulan
cybias
cyprep
cyscan
cysele
ddhc
ddhr
ddht
eatstpro
etestadj
fcqodb
gobptout
gptosp
ioassign
lamflag_odb
lecbdap
mandalay
odbtools
progrid
qscat_25to50
qscat_bufr
qscat_dconeqc
qscat_filter
sptogp
testadj
testfa
Displayed lines :
/u/gp/mrpm/mrpm602/gmkpack.6.1/util/gmkpack starts.
Creating pack /u/gp/mrpm/mrpm602/pack/test0 upon /u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack
...
Basic directories :
src
src/local
lib
bin -> /work08/mrpm602/binpack/test0/bin
Unsatisfied external references directories :
src/unsxref/quiet
src/unsxref/verboose
Sources control directory :
src/.gmak
Sources view :
local
main
Links :
src/main -> /u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main
Background source descriptors files :
main.sds
"main" tree for ald ...
"main" tree for arp ...
"main" tree for coh ...
"main" tree for odb ...
"main" tree for ost ...
"main" tree for sat ...
"main" tree for tal ...
"main" tree for tfl ...
"main" tree for uti ...
"main" tree for xrd ...
libald.a -> /u/dp/marp/marp001/tampon/lib/ald/al26/al26t1_main.01.L0209.x.a
libarp.a -> /u/dp/marp/marp001/tampon/lib/arp/cy26/cy26t1_main.01.L0209.x.a
libcoh.a -> /u/dp/marp/marp001/tampon/lib/coh/co26/co26t1_main.01.L0209.x.a
libobs.a -> /u/dp/marp/marp001/tampon/lib/obs/ob26/ob26t1_main.01.L0209.x.a
libodb.a -> /u/dp/marp/marp001/tampon/lib/odb/od26/od26t1_main.01.L0209.x.a
libodb.cma-main.a -> /u/dp/marp/marp001/tampon/lib/odb/od26/od26t1_cma-main.01.L0209.x.a
libodb.scr-main.a -> /u/dp/marp/marp001/tampon/lib/odb/od26/od26t1_scr-main.01.L0209.x.a
libost.a -> /u/dp/marp/marp001/tampon/lib/ost/os26/os26t1_main.01.L0209.x.a
libsat.a -> /u/dp/marp/marp001/tampon/lib/sat/sa26/sa26t1_main.01.L0209.x.a
libsct.a -> /u/dp/marp/marp001/tampon/lib/sct/st26/st26t1_main.01.L0209.x.a
libssa.a -> /u/dp/marp/marp001/tampon/lib/ssa/ss26/ss26t1_main.01.L0209.x.a
libssm.a -> /u/dp/marp/marp001/tampon/lib/ssm/sm26/sm26t1_main.01.L0209.x.a
libtal.a -> /u/dp/marp/marp001/tampon/lib/tal/ta26/ta26t1_main.01.L0209.x.a
libtfl.a -> /u/dp/marp/marp001/tampon/lib/tfl/tf26/tf26t1_main.01.L0209.x.a
libuti.a -> /u/dp/marp/marp001/tampon/lib/uti/ut26/ut26t1_main.01.L0209.x.a
libuti.ddl-main.a -> /u/dp/marp/marp001/tampon/lib/uti/ut26/ut26t1_ddl-main.01.L0209.x.a
libxrd.a -> /u/dp/marp/marp001/tampon/lib/xrd/xr26/xr26t1_main.01.L0209.x.a
Background include/module paths ...
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/ald/module
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/arp/module
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/coh/module
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/odb/misc
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/odb/module
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/ost/module
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/sat/module
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/tal/module
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/tfl/module
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/uti/module
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/xrd/module
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/arp/ald_inc/function
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/arp/ald_inc/interface
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/arp/ald_inc/namelist
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/arp/common
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/arp/function
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/arp/interface
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/arp/namelist
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/coh/common
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/coh/namelist
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/odb/CCMA
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/odb/ECMA
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/odb/ECMASCR
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/odb/include
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/odb/interface
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/ost/common
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/ost/interface
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/ost/namelist
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/tal/interface
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/tfl/interface
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/uti/include
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/uti/namelist
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/xrd/ddh
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/xrd/fa
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/xrd/grib_io/include
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/xrd/include
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/xrd/lfi
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/xrd/svipc/include
-I/u/dp/marp/marp001/pub/cy26t1_main.01.L0209.x.pack/src/main/xrd/utilities/include
done.
Genesis :
/u/gp/mrpm/mrpm602/gmkpack.5.4/util/gmkpack -r cy26t1 -b main -v 01
-u test0 -l L0209 -o x -p aladin
The following line has been appended to your file ~/.kshrc :
alias test0='cd $HOMEPACK/test0;ls -l'
Prepare script(s) ...
> copy compilation and load script on /u/gp/mrpm/mrpm602/pack/test0/ics_aladin
...
/u/gp/mrpm/mrpm602/gmkpack.5.4/util/gmkpack ends.
Comments :
Now let's visit the pack test0
you have just created :
%test0
total 64
lrwxrwxrwx | 1 logname group |
30
|
MM dd hh:mm bin -> $HOMEBIN/test0/bin |
-rw-r--r-- | 1 logname group |
6958
|
MM dd hh:mm ics_aladin |
drwxr-xr-x | 2 logname group |
512
|
MM dd hh:mm lib |
drwxr-xr-x | 3 logname group |
512
|
MM dd hh:mm src |
Comments :
You will have to put your
modified source files below local/ppp
at the proper place,
as you would do in a ClearCase
session below the project ppp !
-----------------------------------------------------------------------------------------------------
Let's comment the script ics_aladin for compilation and load (click here) :
Submitting the job of compilation and load, if the
job is sucessfull, you will get libraries of your modifications and possibly
a binary to execute as well. The procedure will usually generate one library
per project involved in your modification, with the name : lib$project.local.a
If not, the tail of the output will tell you why the
job failed.
Note that meanwhile, if you had already existing libraries
or binaries, they will be removed for security reasons.
-----------------------------------------------------------------------------------------------------
We shall now explain the optional parameters of gmkpack :
-b
: reference branch name
Like a branch in ClearCase, you may have to work upon
a reference pack that is a modification of a main release : this is typically
the case for a bugfix.
Therefore you will have to invoke gmkpack giving
with : -b branch_name
The default is "main",
which correspond to the main release (like in ClearCase).
-v
: reference pack version number
The version number of the pack related to the branch
name and release (even if the branch name is "main"). In that case, you
will have also to invoke gmkpack with : -v
: version_number
By default, the procedure
selects the highest existing version number for the selected branch and
release.
-l
: reference compiler version
This
is a label for the machine compiler version used while building the reference
pack. This parameter should not be used so often.
-o
: reference compiler option
This
is a character to symbolize the compiling options used for building the
reference pack. This parameter should not be used so often. The option
"g" stands for a debugging pack, to be used when we really are in a big
mess.
-O
: Observations handling libraries
Those who work on data assimilation will need to link
more libraries : to force the use of observation libraries one should invoke
gmkpack
with the option -O ;
anyhow this option should no more be used since it is possible to get these
libraries linked if the program name has been properly chosen (example
:
arpodb or aldodb instead of
arpege
or aladin).
- a : to create a reference pack
This option is used to create a reference pack which
should contain everything needed. Usually this option is used by administrators
only, though anybody can make his own "main" packs.
-n : to select the version of a pack to create.
By default you start with 1. To increment the version
you can set the number of your choice, but it is recomended to set "-n
+" : that way the system will consider the highest exiting version number
and will increment it.
-f : alternative rootpack directory
This is to be used if you create your packs over a reference
pack which does not belong the the official administrator (ROOTPACK)
-s : system program script
For those who makes reference pack : this option creates
the script to build some system programs (precompilers) like odb98.x
-m : Quiet mode
One may be interested in simulating the creation of a
pack without making the pack itself. For that you should invoke
gmkpack with the option -m ; this option will disable
the creation of the pack but it will generate the name of the reference
pack and a local script file for compilation and load,
that you can check. This option is mainly used to develop the procedure.
Example : Create a pack named mydevs,
based on the branch op4 of cycle 26t1,
and with a script to compile odbtools program :
%gmkpack -r26t1 -bop4 -umydevs -podbtools
More details are given in the man page of gmkpack.
-----------------------------------------------------------------------------------------------------
rmpack | to remove a pack |
flushpack | from the current directory : to recursively remove all files except the source files |
clearpack | from the current directory : to recursively remove all the files except source files and object files |
lspack | from the current directory : to recursively list all the files |
scanpack | from the current directory : to recursively list all the source files |
vipack | to find and edit files |
usrpack | to list the user's existing packs |
admpack | to list administrator's existing packs |
rlspack | to list administrator's existing releases |
envpack | to display current environment variables for gmkpack |
genpack | to display the genesis of a pack |
logpack | to print the logfile of a pack |
progpack | to list all possible program names handled by gmkpack |
resetpack | to remove some control files in case of strange behavior of the system. |
-----------------------------------------------------------------------------------------------------
All procedures described have man pages. For more information
you are invited to read them !
For example, type : %man gmkpack
-----------------------------------------------------------------------------------------------------
Le script construit par Gmkpack, baptisé du générique "ics" (Initiative de Compilations Simultanées) par manque de modestie évidente, s'articule en 3 parties :
La compilation vise à compiler les sources
présents dans le pack, sous réserve que :
- le fichier-objet pour un fichier-source
donné n'existe pas,
ou
- le fichier-objet est plus ancien
que son fichier-source correspondant.
On parlera alors de fichier-objet "périmé"
pour le fichier-source en question.
A cette compilation dite "locale" (car directement liée
aux fichiers-sources modifiés par l'utilisateur) s'ajoute de façon
optionnelle une "compilation des dépendances" : il s'agit de recompiler
tous les fichiers qui se trouvent modifiés par le jeu des dépendances
des sources les uns par rapport aux autres, sans que leur codes soient
eux-même modifiés par l'utilisateur.
La compilation de toutes les dépendances est,
en principe, nécessaire avant la constitution de toute librairie
de code-objet. On peut cependant s'en affranchir si les 2 conditions suivantes
sont respectées (au moins sur les machines Fujitsu) :
1/ un module de données n'est
modifié que par l'ajout de nouvelles variables à la fin
du code du module en question
2/ un module modifié n'est
pas lui-même utilisé par un autre module
Voici les étapes successives pour élaborer
la compilation :
Toute compilation réussie implique la fabrication
d'une librairie de code-objet contenant les modifications faites.
Il y a en réalité autant de librairies
fabriquées que de "projets" (au sens Clearcase) concernés,
afin de différentier les sous-programmes dits "dupliqués"
(on peut éventuellement créer plusieurs sous-librairies pour
un même projet - non détaillé ici pour le moment, mais
effectif pour odb et uti).
En cas d'ambigüité fortuite (2 fichiers-objets
de même nom essaient d'entrer dans la même librairie), la procédure
envoie un message d'erreur et s'interrompt (ce cas peut se produire si
un élément du pack a été écrit dans
un mauvais répertoire, et que le jeux des dépendances implique
la recompilation de ce même élément).
Si une librairie existe déjà (à
la suite d'une compilation antérieure) et qu'une recompilation effective
a eu lieu, cette librairie est détruite, puis recréée
avec les fichiers-objets présent dans le pack.
Que la compilation échoue ou pas, toutes les librairies
existantes susceptibles de dépendre de la compilation sont
détruites.
Si une librairie existante devient inutile à l'édition
de lien (car plus aucune modification n'y affaire), elle est détruite.
Dans les autres cas, une librairie existante n'est pas
remise à jour si la liste des fichiers-objets du pack est identique
à celle de la librairie et que la date de création de chacun
de ces fichiers-objets est antérieure à celle de la librairie.
L'édition de lien est conditionnée par
la définition (par l'utilisateur) d'un point d'entrée. L'utilisateur
garde la main sur le choix et l'ordre des librairies à charger (la
procédure propose un choix par défaut aussi "juste" que possible)
ainsi que sur les options de chargement.
Avant l'édition de lien proprement dite, on vérifie
que toutes les librairies sont présentes sur disque. Si ce n'est
pas le cas pour une librairie de *GCO*, on essaie de la récupérer
depuis la machine d'archivage (par l'utilisation de la commande gget).
La procédure renvoie la liste ordonnée des librairies effectivement
utilisées (en suivant les liens symboliques). Si une librairie est
portée manquante, la procédure envoie un message d'erreur
et s'interrompt.
On recherche ensuite le point d'entrée en explorant
les éléments du pack. Si le point d'entrée n'est pas
trouvé, la procédure envoie un message d'erreur et s'interrompt.
L'édition de lien se fait sur un répertoire
temporaire (GMKTMP)
mais l'executable est sauvegardé dans un sous-répertoire
du répertoire HOMEBIN,
ce qui rend l'executable volatile dans la mesure où HOMEBIN
est souvent lui-même défini comme un sous-répertoire
de la WORKDIR
: ce choix est préféré à celui d'un répertoire
de sauvegarde permanent car les executables sont très volumineux.
Avant l'édition de lien, les librairies à
charger sont symboliquement liées sur le répertoire temporaire
avec des noms très courts (lib[*])
: ce choix est consécutif à un incident : il semble qu'il
y ait une limite à la longueur de la ligne de commande du chargeur
(par la même occasion, cela rend l'écho de la commande plus
lisible).
1/ Sélection d'un pack à interfaces
explicites ou pas :
Pour chaque projet on commence par définir à
partir de quel cycle-clé on traite les interfaces explicites auto-générées
("intfb").
Si cette définition est omise, c'est qu'on traite
l'intfb. Par défaut pour les projets existants autre que arp et
ald, le cycle-clé est mis à 99.
Ensuite, dans les scripts de compilation on définit
systématiquement une variable listant les projets supplémentaires
à interfaces
explicites. Pour un pack utilisateur, par défaut
il n'y a aucun "projet supplémentaire à interface explicite".
Pour un pack administrateur, par défaut on définit
les "projets supplémentaires à interfaces explicites" en
fonction du cycle et
des fichiers de configuration pour les intfb.
Ainsi un pack administrateur traite les intfb indiqués
dans le script ; tandis qu'un pack utilisateur traite les intfb indiqués
dans le script ainsi que ceux du pack-source.
2/Localisation des interfaces explicites dans les packs
:
elles son placées dans un répertoire caché
(".intfb" par défaut) sous chacune des branches (afin de conserver
l'usage de la procédure d'élaboration de la liste des dépendances)
et sous chaque projet (c'est plus simple que de créer les arborescences
complètes).
Au niveau de la liste des répertoires d'inclusion
pour la compilation on rajoute systématiquement les répertoires
d'intfb locaux.
3/Etablissement du contenu du pack local :
Les procédures d'exploration (scanpack, lspack)
ignorent le répertoire .intfb
Les procédures de nettoyage (clearpack,flushpack)
explorent le répertoire .intfb s'il existe.
En prélude à l'établissement du
contenu définitif du pack, et sous réserve que le pack n'est
pas un pack administrateur, on détruit toutes les intfb qui ne correspondent
pas à une procédure présente dans le pack local (cas
d'un sous-programme retiré du pack local).
Pour toutes les procédures (mais pas les modules)
Fortran 90 du pack local qui appartiennent à l'ensemble des projets
à interfaces explicites on génère l'interface explicite
dans un répertoire temporaire si elle n'existe pas déjà
ou si la procédure de référence est plus récente
que l'intfb existante ; si cette intfb n'est pas "à jour", on la
copie dans le pack local.
=> Pour définir si une intfb est "à jour"
on recherche d'abord s'il existe déjà une intfb dans la "vue"
du pack ("local", sinon
branches, sinon "main" ... en mélangeant tous
les projets pour ne pas créer d'interfaces dupliquées) ;
l'intfb est "à jour" si il
existe déjà une intfb dans la "vue" et
que celle-ci est identique à celle qui a été générée.
On ajoute les nouvelles intfb à la liste du contenu
du pack.
4/Compilation :
=> On exécute un précompilateur qui réalise
les trois tâches suivantes :
- Contrôle des intfb en trop :
Une intfb en trop est l'apparition d'une directive d'inclusion
d'une intfb dans une procédure alors que cette procédure
n'appelle pas le sous-programme interfacé par
l'intfb. En cas d'intfb en trop on signale l'erreur et on aborte la compilation
de
la procédure incriminée.
- Contrôle des intfb manquantes :
Une intfb manquante est l'absence d'une directive d'inclusion
d'une intfb alors que le sous-programme concerné est appelé,
qu'il n'est pas associé à un fichier-interface
explicite dans le code-source, et qu'il appartient aux projets à
interfaces
explicites (nécessite de définir la liste
des intfb à inclure et la comparer à celle qui est effectivement
utilisée). En cas d'intfb
manquante on signale l'erreur et on aborte la compilation
de la procédure incriminée.
- Exécution du "norms checker" dont le diagnostic
sera copié en fin de listing et (partiellement) sur la "dayfile"
de compilation.
Le but ultime de cet opération est de ne plus
utiliser les options non-standards de l'éditeur de liens symboliques.
le traitement ci-dessous n'est cependant pas complètement au point.
Mais il fonctionne assez pour traiter des packs administrateurs de type
"export".
Une référence insatisfaite est soit :
- l'apparition d'une directive d'inclusion dans une procédure,
pour laquelle le fichier à inclure n'est pas disponible
- l'appel à un sous-programme ou une fonction
dans une procédure, pour lequel le fichier-objet correspondant n'est
pas disponible.
Pour traiter ces problèmes, un ébauche
de solution est en place : un répertoire est créé
au même niveau que le répertoire des fichiers-source locaux.
Ce répertoire est lui-même subdivisé en deux sous-répertoire.
On y loge dans l'un ou l'autre chacun des fichiers manquant. Quand il s'agit
d'un fichier à inclure autre qu'une intfb, un fichier vide du même
nom suffit. Si il s'agit d'une intfb il faut que ce fichier contienne au
moins une ligne pour "passer" le "norms checker. Pour les sous-programmes
et les fonction, il suffit d'un fichier vide dont le nom soit celui de
la référence insatisfaite suivie d'un caractère "underscore"(par
exemple : le sous-programme manquant "toto" sera résolu par l'apparition
d'un fichier vide nommé "toto_").
La liste des références insatisfaites est
scindée de façon à différencier un comportement
purement passif d'un comportement verbeux ("should not be called"). Elle
reprend la liste des procédures externes non-exportées du
pack de référence à la création du pack local
via des librairies-objets supplémentaires.
La grande nouveauté c'est que les sources accessibles
pour modification d'un pack donné se trouvent toujours dans un répertoire
qui porte le même nom (par exemple : "local"), quelque soit l'utilisateur.
Pour tout sur-pack, les "branches" sont des liens sur le répertoire
local d'un autre pack.
Cette innovation a la vertu d'unifier la gestion des
packs utilisateurs, "main", branche sur "main" ou sur un autre utilisateur.
Une complication de gestion apparait au niveau des recherches
de dépendances :
- le fichier-descripteur des fichiers-source ("gmak.pl"
chez gco, "local.sds" sous gmkpack) doit être sauvegardé et
devient un fichier caché (sous un répertoire ".gmak" sous
le répertoire de tous les fichiers-source) pour éviter tout
erreur de manipulation de la part de son propriétaire (effacement,
modification incontrôlée).
A la création d'un sur-pack, les fichiers-descripteurs
des branches non-locales doivent être importés et modifiés
dans le
pack local afin d'y remplacer le nom de branche "local"
par celui de la branche-lien correspondante (sauf dans le cas "gco"
ou le fichier est bon tel que : il suffit alors de faire
un lien dessus). Dans tous les cas il serait préférable à
terme de supprimer ce second champ (information redondante entre la localisation
ou le nom du fichier, et son contenu !!)
Sous re répertoire .gmak on trouvera également
d'autres fichiers de contrôle sauvegardés, dont le but est
d'accélérer le processus de compilation lorsque certains
de ces fichiers de contrôle se trouvent être "à jour"
(analyse par rapport au non-changement des inter-dépendances entre
les fichiers-source du pack). Néammoins, cette fonction peut être
"remise à zéro" en exécutant la commande "resetpack"
qui détruira certains fichiers sous ce répertoire .gmak (la
destruction des fichiers-descripteurs venant des autres branches serait
fatale au pack !).
C'est le cas en particulier du précompilateur
"odb98.x".
On prévoit l'utilisation d'un compilateur odb
externalisé : cf variable ODBNAME du fichier de configuration.
Si cette variable est vide, on fabrique le compilateur
dans le pack "main", et on utilise le compilateur du pack main pour les
packs-utilisateurs. Sinon on utilise le compilateur externe.
La variable GMKSYS représente le répertoire
principal pour l'installation de programmes-système (non-encore
externalisés) liés à l'utilisation
de gmkpack (typiquement : odb98)
Ce répertoire n'est créé que pour
un pack "main". On ne crée ces programmes-système que si
GMKSYS est non-vide.
On crée un lien (un peu maladroit !) entre une
fonction externe (comme ODBNAME) et la fonction-remplaçante interne,
par
nom (obsolete !).
Gmkpack lancé avec l'option "-s" fabrique un script
de fabrication pour ce programme-système (répertorié
dans les fichiers de configuration) mais il n'est pas nécessaire
de l'utiliser : une compilation générale d'un "pack" de base
créera ce précompilateur "dans la foulée".
Les fichiers *.ddl sont transcodés par odb98.x
en fichiers une série de fichiers : *.ddl_, *.h et *.c qu'on rajoute
dans le pack le
cas échéant (c'est à dire : si le
fichier *.ddl_ est différent du fichier *.ddl). On applique en premier
lieu le préprocesseur cpp,
ce qui permet de travailler de façon indépendante
de l'organisation des fichiers-source. Il est ainsi inutile de recopier
sous chaque "base" les fichiers d'inclusion nécessaires. par contre,
chaque "base" doit absolument contenir son fichier *.ddl à côté
des requètes .sql, car c'est la seule façon sûre de
précompiler les requètes .sql sans faire d'hypothèse
sur les noms des fichiers .c qui seront créés par le précompilateur
odb98.x ; ainsi, à la première compilation, un répértoire
contenant des requètes .sql ne devrait contenir que des fichiers
.ddl.