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=*