Code editors like VSCode can open, edit and save code from and into a mainframe PDS, also show syntax coloring and check the code against the syntax. However, they are not able to compile and run programs. Compilation and binding (link-edit) must be done in mainframe environment by using JCL, and IGYCRCTL (Enterprise COBOL compiler) and IEWL (Binder) programs.
At the end of the process a COBOL executable will be placed into the given LOADLIB.
Although VSCode can not compile, together with ZOWE Explorer it can:
edit JCL
submit JCL
show the spool (messages on the terminal)
show the compilation errors (IGYCRCTL and IEWL messages)
During the compiler phase, automatically launched programs:
JESMSGLG
JESJCL
JESYSMSG
Main steps toward creation of a mainframe executable:
prepare the compiler JCL
prepare the binder JCL
edit and save the source code of main program and its submodules
organize the source codes into a common PDS
submit the compiler JCL to create the object codes
check the spool for the 3 automatic job messages, correct the errors, iterate
when seems ok, submit the binder JCL to create the executable(s)
check the spool, correct the errors, iterate
Submodules can be binded (linked) into the executable of the main program , or created as independent executables. At the end of the process, all executables must be present in one or more LOADLIBs.
Modules in LOADLIB:
modules are compiled independently
compiled modules and the main program are in the LOADLIB
Pros:
modular development
faster development
less risk of errors
easier versioning
smaller load module size
CICS compatible
Cons:
more binder execution
LOADLIB will have a lot of small members
CALL overhead (calling a module is a bit slower)
Advised in large systems, bank apps, CICS programs, batch systems with many subprograms, if many programs use the same module, if subprograms often change.
Parallel with microservices.
Modules in program:
modules are compiled and linked into the main program
only the compiled program is in the LOADLIB
Pros:
faster execution
easier deploy
Cons:
any change forces the whole prorgam to be compiled
large load module, slower start-up
harder versioning
danger of code duplication (a module must be copied into the code as per every call)
not CICS-friendly
Advised in small, simple programs, educational environment, if a every module needed in one program, the effectiveness is critical and all micro-optimalization counts.
Parallel with monolithic architecture.
Components of the compiler JCL:
IGYCRCTL (Enterprise COBOL compiler)
SIGYCOMP (compiler könyvtĂ¡r)
SYSIN (COBOL forrĂ¡s)
SYSLIB (COBOL copybook; több SYSLIB-et is meg lehet adni)
SYSLIN (object code)
SYSOUT/SYSPRINT (compiler Ă¼zenetek)
LIB: the compiler produces a library listing (a formatted, human‑readable listing) instead of only object code. Contains:
source code with line numbers
compiler messages
symbol table
cross‑reference (if XREF is also used)
storage map
Useful: debugging, code review, documentation.
OBJECT: the compiler generates object code (SYSLIN), which the Binder (IEWL) will link into a load module. Without OBJECT there is no object code, nothing to link, no executable.
Always recommended.
RENT: generates reentrant (thread‑safe, reusable) code. Reentrant:
code is read‑only
data is separate
multiple tasks can run the same program simultaneously
required for LE‑enabled programs
required for CICS
required for multi‑threaded batch
If missing, the program may not run under CICS or LE.
DATA(31): the program uses 31‑bit addressing, the standard on modern z/OS. Implications:
runs above the line
more memory available
compatible with most LE routines
Most shops use DATA(31).
DATA(64): the program uses 64‑bit addressing, allowing access to huge memory spaces. Used for:
high‑performance batch
large in‑memory tables
advanced LE applications
Only works if the runtime environment supports 64‑bit LE.
OPT(n): compiler optimization level. N:
0 (no optimization)
1 (basic optimization)
2 (full optimization; fastest code, smallest executable, recommended for production)
Debugging optimized code is harder.
SSRANGE: the compiler inserts runtime checks for:
table index out of range
OCCURS overflow
substring overflow
reference modification overflow
If error is raised, the program abends with S0C4 or LE message.
Used for: debugging, development.
NOSSRANGE: disables runtime index checking.
Pros:
faster
smaller executable
Cons:
out‑of‑range index silently corrupts memory
can cause random S0C4, S0C7, storage violation
debugging becomes extremely difficult
Used for production code where performance matters and logic is proven correct.
LIST: produces a full compiler listing in SYSPRINT. Includes:
source code
generated code
symbol table
diagnostics
storage map
XREF (if enabled)
Used for: debugging, documentation, audits.
XREF: generates a cross‑reference table of:
every variable
where it is defined
where it is used
how many times it is referenced
Used for: large programs, refactoring, code analysis.
The SYSLIN as a PDS is the targeted object code container. There can be 2 strategies:
DISP=(NEW,CATLG) (prevents having old code segments in the PDS, prevents fragmentation; demands manual PDS deletion)
DISP=SHR (every compiling will overwrite existing object code, no further action is needed, but many compilation causes fragmentation, and old code can be in the PDS as well)
EXAMPLE FOR COMPILATION:
The message letters show the error weight:
I (information)
W (warning)
E (error, but the compilation continues)
S (severe, the compilation stops)
Components of the binder JCL:
IEWL (Binder, link-editor)
SYSLIN (object code)
SYSLMOD (load module)
LIST/XREF (cross-reference list)
LIST: creates a full binder listing in SYSPRINT. Contains:
module attributes
entry points
symbol table
relocation information
included modules
binder messages
Used for: debugging, audits, verifying link-edit correctness.
XREF: produces a cross-reference of all symbols:
where defined
where referenced
unresolved references
Used for: large applications, debugging unresolved externals.
MAP: generates a memory map of the load module:
text/data segments
CSECT layout
offsets
lengths
Used for: performance tuning, debugging storage violations.
RENT: marks the load module as reentrant (thread-safe). Reentrant:
code is read-only
data is separate
multiple tasks can run the same module simultaneously
Required for:
CICS
LE-enabled programs
multi-threaded batch
If missing, the program may not run under CICS.
AMODE: defines the addressing mode the program uses:
AMODE 24 (old, below-the-line addressing)
AMODE 31 (standard modern addressing)
AMODE 64 (64-bit addressing; rare, advanced)
Used for: high-performance batch, large memory applications.
RMODE: defines where the module must reside in memory:
RMODE 24 (must reside below the 16 MB line)
RMODE ANY (can reside anywhere)
RMODE 24 is required for:
some old LE routines
some system utilities
some CICS modules
Modern COBOL: RMODE ANY.
CALL: tells Binder to include external modules referenced by CALL statements.
Used for:
multi-module COBOL applications
external subprograms
LE routines
INCLUDE: forces Binder to include specific object modules, even if not referenced.
Used for:
multi-CSECT programs
static linking
utility modules
EXAMPLES FOR INCLUDE PARM:
ALIAS: creates additional entry points for the same load module.
Used for:
backward compatibility
multiple program names pointing to one module
EXAMPLE FOR ALIAS PARM:
ORDER: defines the order in which modules are processed.
Used for:
resolving symbol dependencies
controlling CSECT layout
performance tuning
EXAMPLE FOR ORDER PARM:
The binder will overwrite the targeted binded program upon existing in the targeted LOADLIB without any error messages.
EXAMPLE FOR BINDING:
The message letters show the error weight:
I (information)
W (warning)
E (error, but binding continues)
S (severe, the link-edit stops)
EXAMPLE FOR PROGRAM EXECUTION: