Compiling a C program on z/OS

You can compile programs in USS, or with JCL. I tend to prefer JCL, but do use USS (but it takes time to get it the command right). It took me several attempts to compile and bind a program that uses USS services.

I thought people might be interested in the JCL I use, and the C Compiler options I specified.

I’ll give the JCL (so you can see how much you understand of it) then I’ll annotate it

//ADCDC4 JOB 1,MSGCLASS=H,COND=(4,LE)
//S1 JCLLIB ORDER=CBC.SCCNPRC
// SET LOADLIB=IBMUSER.LOAD
// SET LIBPRFX=CEE
//COMPILE EXEC PROC=EDCCB,
// LIBPRFX=&LIBPRFX,
// CPARM='OPTFILE(DD:SYSOPTF),NOLSEARCH,LSEARCH(/usr/include/)',
// BPARM='SIZE=(900K,124K),RENT,LIST,RMODE=ANY,AMODE=31'
//COMPILE.SYSOPTF DD *
LIST,SOURCE
aggregate(offsethex) 
xref
SEARCH(//'ADCD.C.H',//'SYS1.SIEAHDR.H')
TEST
RENT ILP32
OE
INFO(PAR,USE)
NOMARGINS EXPMAC SHOWINC XREF
LANGLVL(EXTENDED) sscom dll
DEFINE(_ALL_SOURCE)
DEBUG/*
//COMPILE.SYSIN DD *
#pragma linkage(IRRSDL00 ,OS)
#line 26
#pragma runopts(POSIX(ON))
/*Include standard libraries */
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <stdarg.h> 

int main( int argc, char *argv??(??))
{
printf("I'm here program %s. ",argv[0]);
for (int i = 1;i < argc; i++)
printf("Arg %d %s",i,argv[i]);
printf("\n");
}//BIND.SYSLMOD DD DISP=SHR,DSN=&LOADLIB.
//BIND.SYSLIB DD DISP=SHR,DSN=&LIBPRFX..SCEELKED
//BIND.OBJLIB DD DISP=SHR,DSN=COLIN.OBJLIB
//BIND.GSK DD DISP=SHR,DSN=SYS1.SIEALNKE
//BIND.CSS DD DISP=SHR,DSN=SYS1.CSSLIB
//BIND.SYSIN DD *
INCLUDE CSS(IRRSDL00)
NAME MAINPROG(R)
//ISTEST EXEC PGM=MAINPROG,REGION=0M,PARM='PARM1, Parm2'
//STEPLIB DD DISP=SHR,DSN=&LOADLIB
//SYSPRINT DD SYSOUT=,DCB=(LRECL=200) //SYSOUT DD SYSOUT=
//SYSERR DD SYSOUT=*


Annotate JCL

The compile options are defined here

  • //ADCDC4 JOB 1,MSGCLASS=H,COND=(4,LE) If the return code from each step is less equal to 4, then it does the next step. If the compile fails with return code 8, the job stops.
  • //S1 JCLLIB ORDER=CBC.SCCNPRC Use the procedures from this library
  • // SET LOADLIB=IBMUSER.LOAD A symbol used to say where to store the load module
  • // SET LIBPRFX=CEE This is used by the Compile procedure
  • //COMPILE EXEC PROC=EDCCB, Execute the C (component EDC) Compile and Bind
  • // LIBPRFX=&LIBPRFX, using this library prefix (defined above)
  • // CPARM=’OPTFILE(DD:SYSOPTF),LSEARCH(/usr/include/)’, Read C options from //SYSOPTF, and use /usr/Include to find header files
  • // BPARM=’SIZE=(900K,124K),RENT,LIST,RMODE=ANY,AMODE=31′ Binder parameters
  • //COMPILE.SYSOPTF DD * These additional C compiler options
  • LIST, Give the assembler output
  • SOURCE display the source of the program (useful for showing compile errors)
  • aggregate(offsethex) Show c structures with hex offsets
  • xref show where thing are used
  • SEARCH(//’ADCD.C.H’,//’SYS1.SIEAHDR.H’) Look for C header files in these libraries
  • TEST produce information for some debug tools.
  • RENT Produce re-entrant code
  • ILP32 produce 32 bit code ( compare to option LP64)
  • OE Use Posix standards when looking for header files
  • INFO(PAR,USE) Print out information messages. Par=Emits warning messages on unused. parameters. USE=Emits information about usage of variables ( eg defined but not used).
  • NOMARGINS Which columns to use. Default is columns 1-72
  • EXPMAC expand all macros in the source
  • SHOWINC display the source of any include in the output
  • LANGLVL(EXTENDED) Use language extensions, for example use of long long.
  • sscom Use of Slash Slash COMents “// comments…”
  • dll Produce code which can be used in a DLL. Useful for some USS type programs
  • DEFINE(_ALL_SOURCE) Create a #define ALL_SOURCE variable
  • DEBUG produce debugging information, such as line numbers in stack traces. It turns optimisation off.
  • /*
  • //COMPILE.SYSIN DD * Main program follows
  • #pragma linkage(IRRSDL00 ,OS) A C program called a z/OS function called IRRSDL00. This says it uses a standard z/OS parameter list
  • #line 26 This tells the C compiler to reset its line number – so the error messages come with the correct line number.
  • #pragma runopts(POSIX(ON)) This is so posix (Uss) posix functions can be used
  • /*Include standard libraries */
  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <string.h>
  • #include <stdarg.h>
  • int main( int argc, char *argv??(??))
  • {
  • printf(“I’m here program %s. “,argv[0]);
  • for (int i = 1;i < argc; i++)
  • printf(“Arg %d %s”,i,argv[i]);
  • printf(“\n”);
  • }
  • //BIND.SYSLMOD DD DISP=SHR,DSN=&LOADLIB. Where to store the output from the bind
  • //BIND.SYSLIB DD DISP=SHR,DSN=&LIBPRFX..SCEELKED Use these libraries to resolve external routines
  • //BIND.OBJLIB DD DISP=SHR,DSN=COLIN.OBJLIB Load the compiled output from here
  • //BIND.CSS DD DISP=SHR,DSN=SYS1.CSSLIB My program needs a z/OS specific function. Get it from here
  • //BIND.SYSIN DD *
    • INCLUDE CSS(IRRSDL00) My program needed the z/OS callable service IRRSDL00 which is in the library SYS1.CSSLIBs
  • NAME MAINPROG(R) This is the name of the program. It is stored in //BIND.SYSLMOD above
  • //ISTEST EXEC PGM=MAINPROG,REGION=0M,PARM=’PARM1, Parm2′
  • //STEPLIB DD DISP=SHR,DSN=&LOADLIB
  • //SYSPRINT DD SYSOUT=,DCB=(LRECL=200) it prints long lines of output up to 200 chars long
  • //SYSOUT DD SYSOUT=
  • //SYSERR DD SYSOUT=*

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s