# Compaq COBOL
User Manual

Previous | Contents | Index

To specify that a linker input file is a library file, use the /LIBRARY qualifier. This qualifier causes the linker to search for a file with the name you specify and the default file type .OLB. If you specify a file that the linker cannot locate, a fatal error occurs and linking terminates.

The sections that follow describe the order in which the linker searches libraries that you specify explicitly, default user libraries, and system libraries.

For more information about object module libraries, refer to the OpenVMS Linker Utility Manual.

Defining the Search Order for Libraries

When you specify libraries as input for the linker, you can specify as many as you want; there is no practical limit. More than one library can contain a definition for the same module name. The linker uses the following conventions to search libraries specified in the command string:

- A library is searched only for definitions that are unresolved in the previously specified input files.
- If you specified more than one object module library, the libraries are searched in the order in which they are specified.

For example:

    $ LINK METRIC,DEFLIB/LIBRARY,APPLIC

The library DEFLIB will be searched only for unresolved references in the object module METRIC. It is not searched to resolve references in the object module APPLIC. However, this command can also be entered as follows:

    $ LINK METRIC,APPLIC,DEFLIB/LIBRARY

In this case, DEFLIB.OLB is searched for all references that are not resolved between METRIC and APPLIC. After the linker has searched all libraries specified in the command, it searches default user libraries, if any, and then the default system libraries.

### 1.2.3.5 Creating Shareable Images

You can create Compaq COBOL subprograms as shareable images by using the LINK qualifier /SHARE. A shareable image is a single copy of a subprogram that can be shared by many users or applications. Using shareable images provides the following benefits:

- Saves system resources, since one physical copy of a set of procedures can be shared by more than one application or user
- Facilitates the linking of very large applications by allowing you to break down the whole application into manageable segments
- Allows you to modify one or more sections of a large application without having to relink the entire program

The following steps describe one way to create a Compaq COBOL subprogram as a shareable image:

1. Create the main program used to call the subprogram.
2. Create the subprogram.
3. Link the subprogram as a shareable image by using the /SHARE qualifier and including the options file containing the symbol vector in the LINK command as an input file. (See the sections Using Symbol Vectors with Shareable Images (OpenVMS Alpha) and Using Transfer Vectors (OpenVMS VAX) for information about vectors.)
4. Define a logical name to point to your shareable image.
5. Install the shareable image subprogram, using the OpenVMS Install utility (INSTALL).
6. Link the main program with the shareable image.

Once you have completed these steps, you can run the main program to access the subprogram installed as a shareable image.

Refer to the OpenVMS Linker Utility Manual and the Guide to Creating OpenVMS Modular Procedures for more information about shareable images.

The following sample programs and command procedures provide an example of how to create and link a subprogram as a shareable image, as described in the preceding steps.

Note Do not use the /SHARE qualifier when you link a main program. Creating a main program as a shareable image is unsupported.

Example 1-2 shows the main program CALLER.COB and the two subprograms (SUBSHR1.COB and SUBSHR2.COB). Only the subprograms are shareable images.

Example 1-2 Main Program and Subprograms

    * CALLER.COB
    IDENTIFICATION DIVISION.
    PROGRAM-ID. CALLER.
    ******************************************************************
    * This program calls a subprogram installed as a shareable image.*
    ******************************************************************
    PROCEDURE DIVISION.
    0.
         CALL "SUBSHR1"
             ON EXCEPTION
                 DISPLAY "First CALL failed. Program aborted."
         END-CALL.
         STOP RUN.
    END PROGRAM CALLER.

    * SUBSHR1.COB
    IDENTIFICATION DIVISION.
    PROGRAM-ID. SUBSHR1.

    ******************************************************************
    * This subprogram is linked as a shareable image. When it is called,*
    * it calls another subprogram installed as a shareable image.       *
    ******************************************************************
    PROCEDURE DIVISION.
    0.
         DISPLAY "Call to SUBSHR1 successful. Calling SUBSHR2.".
         CALL "SUBSHR2"
             ON EXCEPTION
                 DISPLAY "Second call failed. Control returned to CALLER."
         END-CALL.
    END PROGRAM SUBSHR1.

    * SUBSHR2.COB
    IDENTIFICATION DIVISION.
    PROGRAM-ID. SUBSHR2.
    ****************************************************************
    * This subprogram is linked as a shareable image and is called by *
    * another shareable image.                                     *
    ****************************************************************
    PROCEDURE DIVISION.
    0.
         DISPLAY "Call to SUBSHR2 successful!".
    END PROGRAM SUBSHR2.

Example 1-3 shows a command procedure that compiles and links the sample program and subprograms in Example 1-2 on an OpenVMS Alpha system. (Example 1-4 shows an equivalent command procedure for OpenVMS VAX.)

Example 1-3 Command Procedure to Compile and Link Subprograms as Shareable Images (OpenVMS Alpha)

    $! Create the main program and subprograms.
    $! In this example CALLER.COB is the main program.
    $! SUBSHR1.COB and SUBSHR2.COB are the subprograms to be installed
    $! as shareable images.
    $!
    $! Compile the main program and subprograms.
    $!
    $  COBOL CALLER.COB
    $  COBOL SUBSHR1.COB
    $  COBOL SUBSHR2.COB
    $!
    $! Create an options file containing all the universal symbols
    $! (entry points and other data symbols) for the subprograms.
    $!
    $  COPY SYS$INPUT OPTIONS1.OPT
    $  DECK
       SYMBOL_VECTOR=(SUBSHR1=PROCEDURE,SUBSHR2=PROCEDURE)
    $  EOD
    $!
    $! Link the subprograms using the /SHARE qualifier to the
    $! shareable library and the options file.  For more information
    $! on options files, refer to the OpenVMS Linker Utility Manual.
    $!
    $  LINK/SHARE=MYSHRLIB SUBSHR1,SUBSHR2,OPTIONS1/OPT
    $!
    $! Assign a logical name for the shareable images.
    $!
    $  ASSIGN DEVICE:[DIRECTORY]MYSHRLIB.EXE MYSHRLIB
    $!
    $! Create a second options file to map the main program to the
    $! shareable image library.
    $!
    $  COPY SYS$INPUT OPTIONS2.OPT
    $  DECK
       MYSHRLIB/SHAREABLE
    $  EOD
    $!
    $! Link the main program with the shareable image subprograms
    $! through the options file.
    $!
    $  LINK CALLER,OPTIONS2/OPT
    $!
    $! Now you can run the main program.

Using Symbol Vectors with Shareable Images (OpenVMS Alpha)

To make symbols in the shareable image available for other modules to link against, you must declare the symbols as universal. You declare universal symbols by creating a symbol vector. You create a symbol vector by specifying the SYMBOL_VECTOR=option clause in a linker options file. List all of the symbols you want to be universal in the order in which you want them to appear in the symbol vector.

If you use symbol vectors, you can modify the contents of shareable images and avoid relinking user programs bound to the shareable image when you modify the image. Once you have created the symbol vector, you can install the subprograms using the OpenVMS Install utility (INSTALL) and link the main program to the shareable library. Symbol vectors, if used according to the coding conventions, can also provide upward compatibility.

For more information about symbol vectors, refer to the OpenVMS Linker Utility Manual. <>

Linking a Subprogram as a Shareable Image (OpenVMS VAX)

Example 1-4 shows a command procedure that compiles, links, and installs the sample programs in Example 1-2 on OpenVMS VAX systems.

Example 1-4 Command Procedure to Compile, Link, and Install Subprograms as Shareable Images (OpenVMS VAX)

    $! Create the main program and subprograms to be installed as shareable
    $! images. In this example CALLER.COB is the main program. SUBSHR1.COB
    $! and SUBSHR2.COB are the subprograms to be installed as
    $! shareable images.
    $!
    $! Compile the main program and subprograms.
    $!
    $  COBOL CALLER.COB
    $  COBOL SUBSHR1.COB
    $  COBOL SUBSHR2.COB
    $!
    $! Create an options file to map the entry points of the subprograms.
    $!
    $  COPY SYS$INPUT OPTIONS1.OPT
    $  DECK
       UNIVERSAL=SUBSHR1,SUBSHR2
    $  EOD
    $!
    $! Link the subprograms using the /SHARE qualifier to the shareable library
    $! and the options file. For more information on options files, refer to
    $! the documentation on the OpenVMS Linker.
    $!
    $  LINK/SHARE=MYSHRLIB SUBSHR1,SUBSHR2,OPTIONS1/OPT
    $!
    $! Copy the shareable images to SYS$LIBRARY. To perform this
    $! you must have [SYSLIB] access privileges. Alternatively,
    $! you can perform the same function by doing a local assignment.
    $!
    $! COPY MYSHRLIB.EXE SYS$LIBRARY:*
    $!      or
    $  ASSIGN DEVICE:[DIRECTORY]MYSHRLIB.EXE MYSHRLIB
    $!
    $! Install the shareable images in a shareable library.
    $! This will allow multiple users to use a single copy of the
    $! shareable image.
    $!
    $! If you do not install the shareable library,
    $! multiple users will each link to their own run-time copy of
    $! the image.
    $!
    $! Note that to install an image in a shareable library, you must have
    $! PRMGBL, SYSGBL, or CMKRNL privileges.
    $!
    $! Prior to installing the shareable image, check to see if there is
    $! enough global symbol space.
    $! MCR INSTALL
    $! /GLOBAL
    $! ^Z
    $!
    $! Also check to see if there are available global sectors and pages.
    $! MCR SYSGEN
    $! /GBLSE
    $! /GBLPA
    $! ^Z
    $!
    $! The /WRITE qualifier is required if you want to install writable PSECTS.
    $  MCR INSTALL
       device:[directory]MYSHRLIB/SHARE/WRITE
    $!
    $! Create a second options file to map the main program to the shareable
    $! image library.
    $  COPY SYS$INPUT OPTIONS2.OPT
    $  DECK
       MYSHRLIB/SHAREABLE
    $  EOD
    $!
    $! Link the main program with the shareable image subprograms through the
    $! options file.
    $  LINK CALLER,OPTIONS2/OPT
    $!
    $! Now you can run the main program.

Using Transfer Vectors (OpenVMS VAX)

Using transfer vectors can be helpful when creating shareable images for the following reasons:

- They make it easy for you to modify the contents of shareable images.
- They allow you to avoid relinking user programs bound to the shareable image if you modify the image.

The command procedure in Example 1-5 shows how to create a transfer vector table and how to link the main program and subprograms (shown in Example 1-2) with the transfer vector table.

Example 1-5 Transfer Vectors (OpenVMS VAX)

    $!
    $! Create a transfer vector table (TRAVEC.MAR).
    $  MACRO /OBJ=TRAVEC SYS$INPUT
        .PSECT TRANSFER_VECTOR
    ;
    ;
    ; The transfer vector table is used to map entry points at
    ; run time to a shareable library. If you make changes to the
    ; shareable library, you only have to relink the library.
    ; You do not have to relink all the programs linked to the
    ; library.
    ;
    ; This example transfer vector table maps the entry points
    ; of the shareable subprograms: SUBSHR1, SUBSHR2.
    ;
        .TRANSFER   SUBSHR1
        .MASK       SUBSHR1
        BRW         SUBSHR1+2
        RET
        .QUAD
        .TRANSFER   SUBSHR2
        .MASK       SUBSHR2
        BRW         SUBSHR2+2
        RET
        .QUAD
    ;
    ; Note that there must be an entry point for each shareable image.
    ; Any future additions should be made at the end of the vector.
    ; The order of the entries must remain intact once established.
    ; Do not delete any entries (even if the shareable image is deleted).
    $
    $  LINK/SHARE=MYSHRLIB SUBSHR1,SUBSHR2,TRAVEC

Once you have created the transfer vector table, you can install the subprograms and link the main program to the shareable library as shown in Example 1-4.

For more information on transfer vectors, refer to the documentation on the OpenVMS Linker. <>

### 1.2.3.6 Interpreting Messages from the Linker

If the linker detects any errors while linking object modules, it displays system messages indicating their cause and severity. If any error or fatal error conditions occur, the linker does not produce an image file. Refer to the OpenVMS Linker Utility Manual for complete information about the format of linker options.

Linker messages are self-explanatory; you do not usually need additional information to determine the specific error.

Common Linking Errors to Avoid

The following are some common errors to avoid when linking COBOL programs:

- Trying to link a module that produced warning or error messages during compilation. Although you can usually link compiled modules for which the compiler generated system messages, you should verify that the modules actually produce the expected output during program execution.
- Forgetting to specify a file type for an input file that has a file type other than the default on the command line. The linker searches for a file that has a file type .OBJ by default. When the linker cannot locate an object file and you have not identified your input file with the appropriate file type, the linker signals an error message and does not produce an image file.
- Trying to link a nonexistent module. The linker signals an error message if you misspell a module name on the command line or if the compilation contains fatal messages.
- Omitting required module or library names from the command line. The linker cannot locate the definition for a specified global symbol reference.
  Consider, for example, the following LINK command for a main program module, OCEAN.OBJ, that calls the subprograms REEF, SHELLS, and SEAWEED:

      $ LINK OCEAN,REEF,SHELLS

  If the routine SEAWEED.OBJ does not exist in the directory from which the command is issued, an error occurs and the linker issues the following diagnostic messages:

      %LINK-W-NUDFSYMS, 1 undefined symbol
      %LINK-I-UDFSYMS,        SEAWEED
      %LINK-W-USEUNDEF, undefined symbol SEAWEED referenced
              in psect $CODE offset %X0000000C
              in module OCEAN file DEVICE$:[COBOL.EXAMPLES]PROG.OBJ;1
      %LINK-W-USEUNDEF, undefined symbol SEAWEED referenced
              in psect $CODE offset %X00000021
              in module OCEAN file DEVICE$:[COBOL.EXAMPLES]PROG.OBJ;1

  If an error occurs when you link modules, you can often correct it by reentering the command string and specifying the correct modules or libraries. For a complete list of linker options, refer to the OpenVMS Linker Utility Manual. For further information on a particular linker message, refer to the online OpenVMS Help Message utility.

## 1.2.4 Running a Compaq COBOL Program

After you compile and link your program, use the RUN command to execute it. In its simplest form the RUN command has the following format:

    $ RUN myprog

In the preceding example MYPROG.EXE is the file specification of the image you want to run. If you omit the file type from the file specification, the system automatically provides a default value. The default file type is .EXE. If you omit a path specification, the system will expect MYPROG.EXE to be in the current directory.

When you run your application it makes calls to the Compaq COBOL Run-Time Library (RTL) installed on your system. If your application is run on a system other than the one where the application was compiled, there are two requirements that must be met:

- The Compaq COBOL Run-Time Library must be installed.
- The RTL version must match (or be higher than) the version of the RTL on the system where the application was compiled. Otherwise, the system displays a diagnostic message each time you run the application.

### 1.2.4.1 Accessing Command-Line Arguments at Run Time (Alpha)

Your Compaq COBOL programs can read command-line arguments and access (read and write) system logicals. Command-line arguments enable you to provide information to a program at run time. Your program provides the logic to parse the command line, identify command-line options, and act upon them. For example, you might develop a program named MYPROG that will extract a given amount of data from a specified file, where both the number of records to read and the file name are highly dynamic, changing for each activation of your program. In this case your program would contain code that reads a command-line argument for the number of records to read and a second argument for the file specification.

To run the program with command-line arguments, you must define it as a foreign command, as follows:

    $ MYPROG :== "$device:[dir]MYPROG.EXE"

When you use this command, you will replace device and dir with the valid device:[dir] names where MYPROG.EXE is located. Your program execution command could then look like the following:

    $ MYPROG 1028 POWERS.DAT

In this hypothetical case, the program MYPROG would read 1,028 records from the file POWERS.DAT.

Multiple command-line arguments are delimited by spaces, as shown in the preceding example. If an argument itself contains spaces, enclose that argument in quotation marks (" ") as follows:

    $ myprog2 "all of this is argument 1" argument2

In this example the returned value of argument1 will be the entire string "all of this is argument1", and argument2 will be simply "argument2".

You provide definitions for the command-line arguments with the
SPECIAL-NAMES paragraph in your program's Environment Division, and include ACCEPT and DISPLAY statements in the Procedure Division to parse the command line and access the arguments. Detailed information about command-line argument capability is in the ACCEPT and DISPLAY sections in the Compaq COBOL Reference Manual.

### 1.2.4.2 Accessing System Logicals at Run Time (Alpha)

You can read and write system logicals at run time through your Compaq COBOL program.

Example 1-6 allows the user to specify a file specification by putting the directory in the value of the logical COBOLPATH and the file name in a command-line argument.

Example 1-6 Accessing Logicals and Command-Line Arguments (Alpha)

    IDENTIFICATION DIVISION.
    PROGRAM-ID. EXAMPLE.
    ENVIRONMENT DIVISION.
    CONFIGURATION SECTION.
    SPECIAL-NAMES.
        SYSERR              IS STANDARD-ERROR
        ENVIRONMENT-NAME    IS NAME-OF-LOGICAL
        ENVIRONMENT-VALUE   IS LOGICAL-VALUE
        ARGUMENT-NUMBER     IS POS-OF-COMMAND-LINE-ARGUMENT
        ARGUMENT-VALUE      IS COMMAND-LINE-ARGUMENT.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01 howmany-records PIC 9(5).
    01 env-dir PIC x(50).
    01 file-name PIC x(50).
    01 file-spec PIC x(100).
    PROCEDURE DIVISION.
    BEGIN.
        ACCEPT howmany-records FROM COMMAND-LINE-ARGUMENT
          ON EXCEPTION
            DISPLAY "No arguments specified"
              UPON STANDARD-ERROR
            STOP RUN
        END-ACCEPT.

        DISPLAY "COBOLPATH" UPON NAME-OF-LOGICAL.
        ACCEPT env-dir FROM LOGICAL-VALUE
          ON EXCEPTION
            DISPLAY "Logical COBOLPATH is not set"
              UPON STANDARD-ERROR
            END-DISPLAY
                       NOT ON EXCEPTION
            ACCEPT file-name FROM COMMAND-LINE-ARGUMENT
              ON EXCEPTION
                DISPLAY
                "Attempt to read beyond end of command line"
                  UPON STANDARD-ERROR
                END-DISPLAY
              NOT ON EXCEPTION
                STRING env-dir file-name delimited by " " into file-spec
                DISPLAY "Would have read " howmany-records " records from " file-spec
            END-ACCEPT
        END-ACCEPT.

Example 1-6 assumes that the logical COBOLPATH is set as follows:

    $ define COBOLPATH MYDEV:[MYDIR]

When you execute the following command line:

    $ MYPROG 1028 powers.dat

The following will result:

- howmany-records will contain 1028.
- file-path will contain MYDEV:[MYDIR]
- file-name will contain powers.dat
- file-spec will contain MYDEF:[MYDIR]powers.dat

For additional information, refer to the ACCEPT and DISPLAY statements in the Compaq COBOL Reference Manual. <>

### 1.2.4.3 Accessing Input and Output Devices at Run Time

ACCEPT and DISPLAY statements may interact with the input and output devices by referring to them through the environment variables COBOL_INPUT and COBOL_OUTPUT, respectively. See Chapter 11 for more information.

### 1.2.4.4 Debugging Environment

Perhaps the most common qualifier added to the RUN command line is DEBUG. The form of the RUN command with DEBUG is as follows:

`RUN [/[NO]DEBUG] file-spec`

In the preceding syntax format, file-spec is the name of the executable image to be run. A typical example would be:

    $ RUN /DEBUG MYPROG

In this example, MYPROG is the name of the executable image to be run. You would specify the /DEBUG qualifier to invoke the OpenVMS Debugger if the image was not linked with it. You cannot use /DEBUG on images linked with the /NOTRACEBACK qualifier. If the image (in this case, MYPROG) was linked with the /DEBUG qualifier and you do not want the debugger to prompt you, use the /NODEBUG qualifier. The default action depends on whether or not the file was linked with the /DEBUG qualifier.

Note Using the /DEBUG qualifier with the RUN command does not produce symbol table information if you did not specify the /DEBUG qualifier when you compiled and linked your program.

The following example executes the image MYPROG.EXE without invoking the debugger:

    $ RUN MYPROG/NODEBUG

See Appendix C for more information about debugging programs.

Previous | Next | Contents | Index