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