$ZROutines

$ZRO[UTINES] contains a string value specifying a directory or list of directories containing object files. Each object directory may also have an associated directory, or list of directories, containing the corresponding source files. These directory lists are used by certain GT.M functions, primarily auto-ZLINK, to locate object and source files. The order in which directories appear in a given list determines the order in which they are searched for the appropriate item.

Searches that use $ZROUTINES treat files as either object or source files. GT.M treats files with an extension of .o as object files and files with an extension of .m as source files.

[Note] Note

Paths used in $ZROUTINES to locate routines must not include embedded spaces, as $ZROUTINES uses spaces as delimiters.

Establishing the Value from $gtmroutines

When the environment variable gtmroutines is defined, GT.M initializes $ZROUTINES to the value of gtmroutines. Otherwise, GT.M initializes $ZROUTINES to ".". When $ZROUTINES is ".", GT.M attempts to locate all source and object files in the current working directory. $ZROUTINES="" is equivalent to $ZROUTINES=".".

Commands or functions such as DO, GOTO, ZGOTO, ZBREAK, ZPRINT, and $TEXT may auto-ZLINK and thereby indirectly use $ZROUTINES. If their argument does not specify a directory, ZEDIT and explicit ZLINK use $ZROUTINES. ZPRINT and $TEXT use $ZROUTINES to locate a source file if GT.M cannot find the source file pointed to by the object file. For more information on ZLINK and auto-ZLINK, see the Development Cycle and Commands chapters.

Setting a Value for $ZROutines

$ZRO[UTINES] is a read-write Intrinsic Special Variable, so M can also SET the value.

By default, each directory entry in $ZROUTINES is assumed to contain both object and source files. However, each object directory may have an associated directory or list of directories to search for the corresponding source files. This is done by specifying the source directory list, in parentheses, following the object directory specification.

If the command specifies more than one source directory for an object directory, the source directories must be separated by spaces, and the entire list must be enclosed in parentheses ( ) following the object directory-specification. If the object directory should also be searched for source, the name of that directory must be included in the parentheses, (usually as the first element in the list). Directory-specifications may also include empty parentheses, directing GT.M to proceed as if no source files exist for objects located in the qualified directory.

To set $ZROUTINES outside of M, use the appropriate shell command to set gtmroutines. Because gtmroutines is a list, enclose the value in quotation marks (" ").

Changes to the value of $ZROUTINES during a GT.M invocation only last for the current invocation, and do not change the value of gtmroutines.

Directory specifications may include an environment variable. When GT.M SETs $ZROUTINES, it translates all environment variables and verifies the syntax and the existence of all specified directories. If $ZROUTINES is set to an invalid value, GT.M generates a run-time error and does not change the value of $ZROUTINES. Because the environment variables are translated when $ZROUTINES is set, any changes to their definition have no effect until $ZROUTINES is set again.

$ZROutines Examples

Example:

GTM>s $zroutines=".(../src) $gtm_dist"

This example directs GTM to look for object modules first in your current directory, then in the distribution directory that contains the percent routines. GT.M locates sources for objects in your current directory in the sibling /src directory.

Example:

$ gtmroutines="/usr/jones /usr/smith"
$ export gtmroutines
$ gtm
GTM>write $zroutines
"/usr/jones /usr/smith"
GTM>set $zro="/usr/jones/utl /usr/smith/utl"
GTM>write $zroutines
"/usr/jones/utl /usr/smith/utl"
GTM>halt
$ echo $gtmroutines
/usr/jones /usr/smith

This example defines the environment variable gtmroutines. Upon entering GT.M Direct Mode $zroutines has the value supplied by gtmroutines. The SET command changes the value. When the GT.M image terminates, the shell echo command demonstrates that gtmroutines has not been modified by the M SET command.

Example:

GTM>SET $ZRO=". /usr/smith"

This example sets $zroutines to a list containing two directories.

Example:

GTM>set $zro="/usr/smith(/usr/smith/tax /usr/smith/fica)"

This example specifies that GT.M should search the directory /usr/smith for object files, and the directories /usr/smith/tax and /usr/smith/fica for source files. Note that in this example. GT.M does not search /usr/smith for source files.

Example:

GTM>set $zro="/usr/smith(/usr/smith /usr/smith/tax /usr/smith/fica)"

This example specifies that GT.M should search the directory /usr/smith for object files and the directories /usr/smith/tax and /usr/smith/fica for source files. Note that the difference between this example and the previous one is that GT.M searches /usr/smith for both object and source files.

Example:

GTM>set $zro="/usr/smith /usr/smith/tax() /usr/smith/fica"

This specifies that GT.M should search /usr/smith and /usr/smith/fica for object and source files. However, because the empty parentheses indicate directories searched only for object files, GT.M does not search /usr/smith/tax for source files.

Omitting the parentheses indicates that GT.M can search the directory for both source and object files. $ZROUTINES=/usr/smith is equivalent to $ZROUTINES=/usr/smith(/usr/smith).

$ZROutines Search Types

GT.M uses $ZRO[UTINES] to perform three types of searches:

  • Object-only when the command or function using $ZROUTINES requires a .o file extension.

  • Source-only when the command or function using $ZROUTINES requires a file extension other than .o.

  • Object-source match when the command or function using $ZROUTINES does not specify a file extension.

An explicit ZLINK that specifies a non .OBJ .o extension is considered as a function that has not specified a file extension for the above searching purposes.

All searches proceed from left to right through $ZROUTINES. By default, GT.M searches directories for both source and object files. GT.M searches directories followed by empty parentheses ( ) for object files only. GT.M searches directories in parentheses only for source files.

Once an object-matching search locates an object file, the source search becomes limited. If the directory containing the object file has an attached parenthetical list of directories, GT.M only searches the directories in the attached list for matching source files. If the directory containing the object files does not have following parentheses, GT.M restricts the search for matching source files to the same directory. If the object module is in a directory qualified by empty parentheses, GT.M cannot perform any operation that refers to the source file.

The following table shows GT.M commands and functions using $ZROUTINES and the search types they support.

GT.M Commands and $ZROUTINES Search Types

SEARCH/
FUNCTION

FILE 
EXTENSION
SPECIFIED

SEARCH TYPE

   

OBJ-ONLY

SRC-ONLY

MATCH

EXPLICIT

ZLINK

.o

X

   
 

Not .o

   

X

 

None

   

X

AUTO-ZLINK

None

   

X

ZEDIT

Not .o

 

X

 

ZPRINT

None

 

X

 

$TEXT

None

 

X

 

If ZPRINT or $TEXT() require a source module for a routine that is not in the current image, GT.M first performs an auto-ZLINK with a matching search.

ZPRINT or $TEXT locate the source module using a file specification for the source file located in the object module. If GT.M finds the source module in the directory where it was when it was compiled, the run-time system does not use $ZROUTINES. If GT.M cannot find the source file in the indicated location, the run-time system uses $ZROUTINES.

$ZROutines Search Examples

This section describes a model for understanding $ZROUTINES operations and the illustrating examples, which may assist you if you wish to examine the topic closely.

You may think of $ZROUTINES as supplying a two dimensional matrix of places to look for files. The matrix has one or more rows. The first row in the matrix contains places to look for object and the second and following rows contain places to look for source. Each column represents the set of places that contain information related to the object modules in the first row of the column.

Example:

GTM>s $zro=". /usr/smi/utl() /usr/jon/utl
(/usr/jon/utl/so /usr/smi/utl)"

The following table illustrates the matrix view of this $ZROUTINES.

$ZROUTINES Search Matrix

SEARCH FOR

Column 1

Column 2

Column 3

OBJECTS

.

/usr/smi/utl

/usr/jon/utl

SOURCE

.

 

/usr/jon/utl/so

     

/usr/smi/utl

To perform object-only searches, GT.M searches only the directories or object libraries in the top 'objects' row for each column starting at column one. If GT.M does not locate the object file in a directory or object library in the 'objects' row of a column, GT.M begins searching again in the next column. If GT.M cannot locate the file in any of the columns, it issues a run-time error.

As illustrated in the preceding table, GT.M searches for object files in the directories . ,/usr/smi/utl and /usr/jon/utl.

To perform source-only searches, GT.M looks down to the 'source' row at the bottom of each column, excluding columns headed by object-only directories (that is, those object directories, which consist of an empty list of source directories) or object libraries. If GT.M cannot locate the source file in the 'source' row of a column, it searches the next eligible column.

To perform object-source match searches, GT.M looks at each column starting at column one. GT.M does an object-only search in the 'objects' row of a column and a source-only search in the 'source' row(s) of a column. If GT.M locates either the object-file or the souce-file, the search is completed. Else, GT.M starts searching the next column. If GT.M cannot locate either the object file or the source file in any of the columns, it issues a run-time error.

As illustrated in the preceding table, GT.M searches for source-files in the directory "." in column one. If GT.M cannot locate the source file in ".", it omits column two because it is an object-only directory and instead searches column three. Since column three specifies /usr/jon/utl/so and /usr/smi/utl, GT.M searches for the source-file in these directories in column three and not in /usr/jon/utl. If GT.M cannot locate the source-file in column three, it terminates the search and issues a run-time error.

Once the object-source match search is done, GT.M now has either the object-file or source-file or both available. GT.M then recompiles the source-file based on certain conditions, before linking the object-file into the current image. See “ZLink” for more information on those conditions.

If auto-ZLINK or ZLINK determines that the source file requires [re]compilation, GT.M places the object file in the above object directory in the same column as the source file. For example, if GT.M locates the source file in /usr/smi/utl in column three, GT.M places the resultant object file in /usr/jon/utl.

Shared Library File Specification in $ZROUTINES

The $ZROUTINES ISV allows individual UNIX shared library file names to be specified in the search path. During a search for auto-ZLINK, when a shared library is encountered, it is probed for a given routine and, if found, that routine is linked/loaded into the image. During an explicit ZLINK, all shared libraries in $ZROUTINES are ignored and are not searched for a given routine.

$ZROUTINES syntax contains a file-specification indicating shared library file path. GT.M does not require any designated extension for the shared library component of $ZROUTINES. Any file specification that does not name a directory is treated as shared library. However, it is recommended that the extension commonly used on a given platform for shared library files be given to any GT.M shared libraries. See “Linking GT.M Shared Images”. A shared library component cannot specify source directories. GT.M reports an error at an attempt to associate any source directory with a shared library in $ZROUTINES.

The following traits of $ZROUTINES help support shared libraries:

  • The $ZROUTINES search continues to find objects in the first place, processing from left to right, that holds a copy; it ignores any copies in subsequent locations. However, now for auto-ZLINK, shared libraries are accepted as object repositories with the same ability to supply objects as directories.

  • Explicit ZLINK, never searches Shared Libraries. This is because explicit ZLINK is used to link a newly created routine or re-link a modified routine and there is no mechanism to load new objects into an active shared library.

  • ZPRINT and $TEXT() of the routines in a shared library, read source file path from the header of the loaded routine. If the image does not contain the routine, an auto-ZLINK is initiated. If the source file path recorded in the routine header when the module was compiled cannot be located, ZPRINT and $TEXT() initiate a search from the beginning of $ZROUTINES, skipping over the shared library file specifications. If the located source does not match the code in image (checked via checksum), ZPRINT generates an object-source mismatch status and $TEXT() returns a null string.

  • ZEDIT, when searching $ZROUTINES, skips shared libraries like explicit ZLINK for the same reasons. $ZSOURCE ISV is implicitly set to the appropriate source file.

For example, if libshare.so is built with foo.o compiled from ./shrsrc/foo.m, the following commands specify that GT.M should search the library ./libshare.so for symbol foo when do ^foo is encountered.

GTM>SET $ZROUTINES="./libshare.so ./obj(./shrsrc)"
GTM>DO ^foo;auto-ZLINK foo - shared
GTM>ZEDIT "foo";edit ./shrsrc/foo.m
GTM>W $ZSOURCE,!;prints foo
GTM>ZPRINT +0^foo;issues a source-object mismatch status TXTSRCMAT error message
GTM>ZLINK "foo";re-compile ./shrsrc/foo.m to generate ./obj/foo.o.
GTM>W $TEXT(+0^foo);prints foo

Note that ZPRINT reports an error, as foo.m does not match the routine already linked into image. Also note that, to recompile and re-link the ZEDITed foo.m, its source directory needs to be attached to the object directory [./obj] in $ZROUTINES. The example assumes the shared library (libshare.so) has been built using shell commands. For the procedure to build a shared library from a list of GT.M generated object (.o) files, see “Linking GT.M Shared Images”.

Linking GT.M Shared Images

Following are the steps (UNIX system commands, and GT.M commands) that need to be taken to use GT.M shared image linking with $ZROUTINES.

Compile source (.m) files to object (.o) files

In order to share M routines, GT.M generates objects (.o) with position independent code, a primary requirement for shared libraries, done automatically by GT.M V4.4-000 and later releases. No change to the compiling procedures is needed. However, any objects generated by a previous release must be recompiled.

Create a shared library from object (.o) files

To create a shared library, use the following syntax:

ld -brtl -G -bexpfull -bnoentry -b64 -o libshr.so file1.o file2.o (on AIX)
ld -shared -o libshr.so file1.o file2.o (on Linux)

Where libshr.so is replaced with name of the shared library one wishes to create. The file1.o and file2.o are replaced with one or more object files created by the GT.M compiler that the user wishes to put into the shared library. Note that the list of input files can also be put into a file and then specified on the command line with the -f option (AIX). Refer to the ld man page on specific platform for details on each option mentioned above.

[Note] Notes
  • Source directories cannot be specified with a shared library in $ZROUTINES, as GT.M does not support additions or modifications to active shared libraries.

  • Searching for a routine in a shared library is a two step process:

    • Load the library

    • Lookup the symbol corresponding to the M entryref

    Since GT.M always performs the first step (even on platforms with no shared binary support), use shared libraries in $ZROUTINES with care to keep the process footprint minimal. On all platforms, it is strongly recommended not to include unused shared libraries in $ZROUTINES.

  • There are some tools on AIX that can aid in mitigating the problems of shared library allocation. The /usr/bin/genkld command on AIX lists all of the shared libraries currently loaded. This command requires root privileges on AIX 4.3.3 but seems to be a general user command on AIX 5. The /usr/sbin/slibclean command requires root privileges and will purge the shared library segment of unused shared libraries making room for new libraries to be loaded.

Establish $ZROUTINES from gtmroutines

When the environment variable gtmroutines is defined, GT.M initializes $ZROUTINES to the value of gtmroutines. The $ZROUTINES ISV can also be modified using SET command.

Example:

$ gtmroutines="./libabc.so ./obj(./src)"
$ export gtmroutines
$ mumps -direct
GTM>w $ZROUTINES,!;writes "./libabc.so ./obj(./src)"
GTM>do ^a;runs ^a from libabc.so
GTM>do ^b;runs ^b from libabc.so
GTM>do ^c;runs ^c from libabc.so
GTM>h
$
$ZROUTINES settings for auto-relink

By suffixing one or more directory names in $ZROUTINES with a single asterisk (*), processes can subscribe to updates of object files published in those directories. At the invocation of DO, GOTO, or ZGOTO, extrinsic functions, $TEXT(), or ZPRINT that specify an entryref which includes a routine name (vs. a label without a routine name), mumps processes (and mupip processes executing trigger logic) automatically relink ("auto-relink") and execute published new versions of routines.

  • Label references (that is, without a routine name), whether direct or through indirection, always refer to the current routine, and do not invoke auto-relink logic.

  • Use shell quoting rules when appending asterisks to directory names in the gtmroutines environment variable - asterisks must be passed in to GT.M, and not expanded by the shell.

  • GT.M accepts but ignores asterisk suffixes to directory names on 32-bit Linux on x86 platforms, where it does not provide auto-relinking.

  • Changing $ZROUTINES causes all routines linked from auto-relink-enabled directories in the process to be re-linked.

  • Note that a relink does not automatically reload a routine every time. When GT.M initiates a relink and the object file (object hash) is the same as the existing one, GT.M bypasses the relink and uses the existing object file.

The ZRUPDATE command publishes of new versions of routines to subscribers.