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:
//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 Name | Purpose |
|---|---|
SYSIN | COBOL source code (PDS member or inline) |
SYSLIB | Copy libraries — searched for COPY members |
SYSLIN | Output object module (passed to link-edit) |
SYSPRINT | Compiler listing — diagnostics, cross-reference |
SYSUTn | Compiler work datasets (1–7 required) |
STEPLIB | Points to COBOL compiler load library |
Common Compiler Options
Compiler options in the PARM field control compiler behavior:
| Option | Meaning |
|---|---|
RENT | Produce reentrant code (required for CICS) |
OBJECT | Generate object module (default) |
LIB | Enable COPY statement processing |
APOST | Use apostrophe ' as string delimiter |
QUOTE | Use 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) |
NODYNAM | Static CALL linking |
DYNAM | Dynamic CALL linking |
NUMCHECK | Runtime numeric validation |
TEST | Generate debugging tables for IBM Debug |
SSRANGE | Runtime subscript range checking |
MAP | Include data map in listing |
XREF | Include cross-reference in listing |
OPT | Enable 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 neededW(Warning) — potential problem, program still compiledE(Error) — syntax error, program may not work correctly; object module may not be producedS(Severe) — serious error, object module not produced
The compile return code: 0 = clean, 4 = warnings only, 8 = errors present, 12 = severe errors.
IGY-MESSAGE-NUMBER SEVERITY: MESSAGE TEXT
IGZ0001I LINE 42 ADD 1 TO WS-COUNTER.
^^^^^^^^ IL : RESULT OUT OF RANGEDB2 Precompile Step
Programs containing embedded SQL need a precompile step before the COBOL compiler:
//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:
//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:
//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 Name | Purpose |
|---|---|
SYSLIN | Input object modules (from COMPILE step) |
SYSLMOD | Output load library (PDS member) |
SYSPRINT | Link-edit map, cross-reference, error messages |
SYSUT1 | Work dataset |
Inline Link-Edit Control Statements
After the DD * card in SYSLIN, you can add link-edit control statements:
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:
//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=SHRIf 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:
//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 succeededREGION=128M— maximum virtual storage for the stepTIME=1440— maximum CPU time in seconds (1440 = 24 hours, effectively unlimited)
Common JCL Abend Codes
| Abend | Cause |
|---|---|
S0C7 | Data exception — numeric field contains non-numeric data |
S0CB | Division by zero |
S222 | Job cancelled by operator |
S322 | CPU time limit exceeded |
S806 | Program not found in STEPLIB or LINKLIST |
S878 | Insufficient virtual storage (increase REGION) |
S913 | RACF authorization failure |
S9CA | VSAM serious error |
SOC4 | Storage 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:
//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=SHRIGYWCLG 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.
