COBOLJCLMainframe

COBOL JCL: Compile, Link-Edit, and Run on z/OS

TT
TopicTrick
COBOL JCL: Compile, Link-Edit, and Run on z/OS

Every COBOL program on z/OS goes through the same lifecycle: source editing, compilation, link-editing, and execution — each as a separate JCL step. Understanding this lifecycle is essential for any mainframe developer. You will not truly understand why COBOL works the way it does until you have read the compiler output, fixed a link-edit error, and traced an abend back to the object module it came from.

The Three-Step Compile-Link-Go Pattern

The classic z/OS COBOL build process is a three-step job:

jcl
//BLDCOBOL JOB (ACCT),'BUILD COBOL PGM',CLASS=A,MSGCLASS=X
//*
//*-----------------------------------------------------------*
//* STEP 1: COMPILE COBOL SOURCE                             *
//*-----------------------------------------------------------*
//COMPILE  EXEC PGM=IGYCRCTL,
//         PARM='RENT,OBJECT,LIB,APOST,TRUNC(OPT),NODYNAM'
//STEPLIB  DD DSN=IGY.V6R3M0.SIGYCOMP,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSIN    DD DSN=PROD.COBOL.SOURCE(ACCTPROC),DISP=SHR
//SYSLIB   DD DSN=PROD.COPYLIB.RECORDS,DISP=SHR
//         DD DSN=PROD.COPYLIB.DB2,DISP=SHR
//         DD DSN=PROD.COPYLIB.COMMON,DISP=SHR
//SYSLIN   DD DSN=&&OBJMOD,UNIT=SYSDA,
//            SPACE=(TRK,(10,5)),DISP=(NEW,PASS)
//SYSUT1   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT2   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT3   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT4   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT5   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT6   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT7   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//*
//*-----------------------------------------------------------*
//* STEP 2: LINK-EDIT                                        *
//*-----------------------------------------------------------*
//LINKEDIT EXEC PGM=IEWBLINK,COND=(4,LT,COMPILE),
//         PARM='RENT,REUS,LIST,XREF,MAP'
//SYSPRINT DD SYSOUT=*
//SYSLIN   DD DSN=&&OBJMOD,DISP=(OLD,DELETE)
//         DD *
  ENTRY ACCTPROC
/*
//SYSLMOD  DD DSN=PROD.LOADLIB(ACCTPROC),DISP=SHR
//SYSUT1   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//*
//*-----------------------------------------------------------*
//* STEP 3: EXECUTE                                          *
//*-----------------------------------------------------------*
//EXECUTE  EXEC PGM=ACCTPROC,COND=(4,LT,LINKEDIT)
//STEPLIB  DD DSN=PROD.LOADLIB,DISP=SHR
//CUSTMST  DD DSN=PROD.CUSTOMER.VSAM.KSDS,DISP=SHR
//TRANSIN  DD DSN=PROD.TRANSACTIONS.INPUT,DISP=SHR
//RPTOUT   DD SYSOUT=*
//SYSOUT   DD SYSOUT=*

Step 1: COBOL Compilation (IGYCRCTL)

Key DD Statements

DD NamePurpose
SYSINCOBOL source code (PDS member or inline)
SYSLIBCopy libraries — searched for COPY members
SYSLINOutput object module (passed to link-edit)
SYSPRINTCompiler listing — diagnostics, cross-reference
SYSUTnCompiler work datasets (1–7 required)
STEPLIBPoints to COBOL compiler load library

Common Compiler Options

Compiler options in the PARM field control compiler behavior:

OptionMeaning
RENTProduce reentrant code (required for CICS)
OBJECTGenerate object module (default)
LIBEnable COPY statement processing
APOSTUse apostrophe ' as string delimiter
QUOTEUse double-quote " as string delimiter
TRUNC(OPT)Allow optimizer to truncate binary fields at machine word boundaries (performance)
TRUNC(BIN)Always truncate binary fields at byte boundaries (correctness, default)
NODYNAMStatic CALL linking
DYNAMDynamic CALL linking
NUMCHECKRuntime numeric validation
TESTGenerate debugging tables for IBM Debug
SSRANGERuntime subscript range checking
MAPInclude data map in listing
XREFInclude cross-reference in listing
OPTEnable code optimization

For production compiles: RENT,OBJECT,LIB,APOST,TRUNC(OPT),NODYNAM,OPT(FULL)

For development/testing: RENT,OBJECT,LIB,APOST,TRUNC(BIN),NODYNAM,TEST,SSRANGE,MAP,XREF

Reading Compiler Messages

The SYSPRINT listing contains diagnostic messages of three severity levels:

  • I (Informational) — no action needed
  • W (Warning) — potential problem, program still compiled
  • E (Error) — syntax error, program may not work correctly; object module may not be produced
  • S (Severe) — serious error, object module not produced

The compile return code: 0 = clean, 4 = warnings only, 8 = errors present, 12 = severe errors.

text
IGY-MESSAGE-NUMBER SEVERITY: MESSAGE TEXT
IGZ0001I   LINE 42    ADD 1 TO WS-COUNTER.
              ^^^^^^^^ IL            : RESULT OUT OF RANGE

DB2 Precompile Step

Programs containing embedded SQL need a precompile step before the COBOL compiler:

jcl
//PRECOMP  EXEC PGM=DSNHPC,
//         PARM='HOST(COB2),APOST,VERSION(AUTO)'
//STEPLIB  DD DSN=DB2.V13R1M0.SDSNLOAD,DISP=SHR
//DBRMLIB  DD DSN=PROD.DBRM.LIBRARY(ACCTPROC),DISP=SHR
//SYSCIN   DD DSN=&&PRECSRC,UNIT=SYSDA,
//            SPACE=(TRK,(10,5)),DISP=(NEW,PASS)
//SYSIN    DD DSN=PROD.COBOL.SOURCE(ACCTPROC),DISP=SHR
//SYSLIB   DD DSN=PROD.COPYLIB.DB2,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSUT1   DD UNIT=SYSDA,SPACE=(CYL,(1,1))

//* Then COMPILE step uses &&PRECSRC instead of original source:
//COMPILE  EXEC PGM=IGYCRCTL,...,COND=(4,LT,PRECOMP)
//SYSIN    DD DSN=&&PRECSRC,DISP=(OLD,DELETE)

After DSNHPC runs, the DBRM must be bound to a DB2 package:

jcl
//BIND     EXEC PGM=IKJEFT01,DYNAMNBR=20
//STEPLIB  DD DSN=DB2.V13R1M0.SDSNLOAD,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSTSIN  DD *
  DSN SYSTEM(DB2P)
  BIND PACKAGE(PRODPKG) MEMBER(ACCTPROC) -
       QUALIFIER(PRODDB) -
       ISOLATION(CS) -
       VALIDATE(BIND)
  END
/*

CICS Translator Step

CICS programs (containing EXEC CICS statements) need a CICS translator step before compilation:

jcl
//CICSTRAN EXEC PGM=DFHEAP1$,
//         PARM='COBOL3,QUOTE'
//STEPLIB  DD DSN=CICS.SDFHLOAD,DISP=SHR
//SYSIN    DD DSN=PROD.COBOL.SOURCE(ACCTCICS),DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSLIN   DD DSN=&&TRNSRC,UNIT=SYSDA,
//            SPACE=(TRK,(10,5)),DISP=(NEW,PASS)

//* COMPILE uses translated source:
//COMPILE  EXEC PGM=IGYCRCTL,...,COND=(4,LT,CICSTRAN)
//SYSIN    DD DSN=&&TRNSRC,DISP=(OLD,DELETE)

For programs using both CICS and DB2, the order is: CICS translate → DB2 precompile → COBOL compile → link-edit.

Step 2: Link-Edit (IEWBLINK)

The link-editor combines object modules into an executable load module.

Key DD Statements

DD NamePurpose
SYSLINInput object modules (from COMPILE step)
SYSLMODOutput load library (PDS member)
SYSPRINTLink-edit map, cross-reference, error messages
SYSUT1Work dataset

Inline Link-Edit Control Statements

After the DD * card in SYSLIN, you can add link-edit control statements:

text
  ENTRY ACCTPROC          /* Define entry point */
  INCLUDE SYSLIB(SUBFUNC) /* Include a pre-linked subroutine */
  REPLACE OLDSUB          /* Replace an older module */
  NAME ACCTPROC(R)        /* Name the output module (R=replace) */

Link-Edit Libraries

The link-editor searches these libraries for unresolved external references:

jcl
//SYSLIB   DD DSN=PROD.LOADLIB,DISP=SHR
//         DD DSN=CICS.SDFHLOAD,DISP=SHR
//         DD DSN=DB2.V13R1M0.SDSNLOAD,DISP=SHR
//         DD DSN=CEE.SCEERUN,DISP=SHR
//         DD DSN=SYS1.COB2LIB,DISP=SHR

If the link-edit fails with IEW2456E UNRESOLVED EXTERNAL REFERENCE, a called program's object module is missing from SYSLIB. Add the library that contains it.

Link-edit return code: 0 = clean, 4 = warnings, 8 = errors (load module created but may not work), 12 = severe errors (no load module).

Step 3: Execute

The execution step runs the compiled load module:

jcl
//EXECUTE  EXEC PGM=ACCTPROC,
//         COND=(4,LT,LINKEDIT),
//         TIME=1440,
//         REGION=128M
//STEPLIB  DD DSN=PROD.LOADLIB,DISP=SHR
//CUSTMST  DD DSN=PROD.CUSTOMER.VSAM.KSDS,DISP=SHR
//TRANSIN  DD DSN=PROD.TRANSACTIONS.DAILY,DISP=SHR
//RPTOUT   DD SYSOUT=*,DCB=(RECFM=FBA,LRECL=133)
//SORTWORK DD UNIT=SYSDA,SPACE=(CYL,(5,2))
//SORTWK01 DD UNIT=SYSDA,SPACE=(CYL,(5,2))
//SORTWK02 DD UNIT=SYSDA,SPACE=(CYL,(5,2))
//SYSOUT   DD SYSOUT=*
  • COND=(4,LT,LINKEDIT) — skip EXECUTE if link-edit return code is less than 4, i.e., run only if link-edit succeeded
  • REGION=128M — maximum virtual storage for the step
  • TIME=1440 — maximum CPU time in seconds (1440 = 24 hours, effectively unlimited)

Common JCL Abend Codes

AbendCause
S0C7Data exception — numeric field contains non-numeric data
S0CBDivision by zero
S222Job cancelled by operator
S322CPU time limit exceeded
S806Program not found in STEPLIB or LINKLIST
S878Insufficient virtual storage (increase REGION)
S913RACF authorization failure
S9CAVSAM serious error
SOC4Storage protection exception — subscript out of bounds or null pointer

One-Step Compile-Link-Go (CLG)

For quick development, use the CLG cataloged procedure or an in-stream equivalent:

jcl
//QUICKBLD JOB (ACCT),'QUICK CLG',CLASS=A,MSGCLASS=X
//CLG      EXEC IGYWCLG,
//         PARM.COBOL='RENT,LIB,APOST,SSRANGE'
//COBOL.SYSIN DD DSN=DEV.COBOL.SOURCE(TESTPGM),DISP=SHR
//COBOL.SYSLIB DD DSN=PROD.COPYLIB.RECORDS,DISP=SHR
//GO.SYSOUT DD SYSOUT=*
//GO.INFILE DD DSN=TEST.INPUT.DATA,DISP=SHR

IGYWCLG is the IBM-supplied three-step procedure that compiles, link-edits to a temporary load module, and immediately executes it — useful for unit testing single programs.

Next Steps

JCL gives you the toolchain to build and run COBOL programs. The final topic in this curriculum is modern COBOL features — JSON PARSE/GENERATE, XML support, and the FUNCTION catalogue that makes COBOL relevant to contemporary architectures. See Modern COBOL Features, or return to the COBOL Mastery course.