.. |_| unicode:: 0xA0 :trim: .. role:: small-caps :class: small-caps .. include:: .. index:: single:Invoking .. index:: single:Compile Compile ======= This chapter describes how to compile COBOL programs using GnuCOBOL. .. _CompilerAoptions: .. index:: single:Compiler options Compiler options ---------------- The compiler \ :code:`cobc`\ accepts the options described in this section. The compiler arguments follow the general syntax \ :code:`cobc [ ...]`\ . A complete list of options can be displayed by using the option \ :code:`--help`\ . .. _HelpAoptions: .. index:: single:Help options Help options ~~~~~~~~~~~~ The following switches display information about the compiler: * \ :code:`--help, -h`\ Display help screen ( :ref:`Appendix A `). No further actions will be taken. * \ :code:`--version, -V`\ Display compiler version, author package date and executable build date. No further actions will be taken. * \ :code:`-dumpversion`\ Display internal compiler version (plain string of numbers). No further actions will be taken. * \ :code:`--info`\ Display build information along with the default and current compiler configurations. No further actions will be taken except for further display options. * \ :code:`--verbose, -v`\ Verbosely display the programs invoked during compilation and additional diagnostics. Use multiple times to increase the verbosity. * \ :code:`--list-reserved`\ Display reserved words ( :ref:`Appendix B `). A Yes/No output shows if the word is supported [#]_ , context sensitive and its aliases. The given options for reserved words specified for example by option \ :code:`-std=`\ will be taken into account. No further actions will be taken except for further display options. * \ :code:`--list-intrinsics`\ Display intrinsic functions ( :ref:`Appendix C `). A Y/N field shows if the function is implemented. No further actions will be taken except for further display options. * \ :code:`--list-system`\ Display system routines ( :ref:`Appendix D `). No further actions will be taken except for further display options. * \ :code:`--list-mnemonics`\ Display mnemonic names ( :ref:`Appendix E `). No further actions will be taken except for further display options. * \ :code:`--list-exceptions`\ Display exception names ( :ref:`Appendix F `). No further actions will be taken except for further display options. .. _BuildAtarget: .. index:: single:Build target Build target ~~~~~~~~~~~~ The compiler :command:`cobc` treats files like :file:`\*.cob`, :file:`\*.cbl` as COBOL source code, :file:`\*.c` as C source code, :file:`\*.o` as object code, :file:`\*.i` as preprocessed code and :file:`\*.so` as dynamic modules and knows how to handle such files in the generation, compilation, and linking steps. The special input name :file:`-` takes input from :file:`stdin` which is assumed to be COBOL source, and uses a default output name of :file:`a.out` (or :file:`a.so/c/o/i`, selected as appropriate) for the build type. You may also use :file:`-` as output name for the listing file or the preprocessor result, for example with \ :code:`cobc -t - prog.cob`\ / \ :code:`cobc -P- prog.cob`\ . By default, the compiler builds a dynamically loadable module. The following options specify the target type produced by the compiler: * \ :code:`-E`\ Preprocess only: compiler directives are executed, comment lines are removed and \ :code:`COPY`\ statements are expanded. The output is sent to stdout, allowing you to directly use it as input for another process. You can manually set an output file using \ :code:`-o`\ . * \ :code:`-C`\ Translation only. COBOL source files are translated into C files. The output is saved in file :file:`\*.c`. * \ :code:`--save-temps`\ Normal compilation with additional storing the preprocessed files as :file:`\*.i` and the translated C files as file :file:`\*.c`. * \ :code:`-S`\ Compile only. Translated C files are compiled by the C compiler to assembler code. The output is saved in file :file:`\*.s`. * \ :code:`-c`\ Compile and assemble. This is equivalent to \ :code:`cc -c`\ . The output is saved in file :file:`\*.o`. * \ :code:`-m`\ Compile, assemble, and build a dynamically loadable module (i.e., a shared library). The output is saved in file :file:`\*.so`. [#]_ This is the default behaviour. * \ :code:`-b`\ Compile, assemble, and combine all input files into a single dynamically loadable module. Unless \ :code:`-o`\ is also used, the output is saved using the first filename as :file:`\*.so`. * \ :code:`-x`\ Include the main function in the output, creating an executable image. The main entry point being the first program in the file. This option takes effect at the translation stage. If you give this option with \ :code:`-C`\ , you will see the main function at the end of the generated C file. * \ :code:`-j, -job, -j=, -job=`\ Run job after compilation. Either from executable with \ :code:`-x`\ , or with :command:`cobcrun` when compiling a module. Optional arguments , if given, are passed to the program or module command line. * \ :code:`-I `\ Add to copy/include search path. * \ :code:`-L `\ Add to library search path. * \ :code:`-l `\ Link the library . * \ :code:`-D `\ Pass to the COBOL compiler. * \ :code:`-o `\ Place the output into . .. _SourceAformat: .. index:: single:Source format Source format ~~~~~~~~~~~~~ GnuCOBOL supports fixed, free, Micro Focus' Variable, X/Open Free-form, ICOBOL xCard and Free-form, ACUCOBOL-GT Terminal, and COBOLX source formats. By default, the compiler tries to autodetect the format using the indicator on the first line, using the fixed format for correct indicators and the free format for incorrect ones. This can be overridden either by the \ :code:`>>SOURCE [FORMAT] [IS] {FIXED|FREE|COBOL85|VARIABLE|XOPEN|XCARD|CRT|TERMINAL|COBOLX|AUTO}`\ directive, or by one of the following options: * \ :code:`-free, -F, -fformat=free`\ Free format. The program-text area starts in column 1 and continues till the end of line (effectively 255 characters in GnuCOBOL). * \ :code:`-fixed, -fformat=fixed`\ Fixed format. Source code is divided into: columns 1-6, the sequence number area; column 7, the indicator area; columns 8-72, the program-text area; and columns 72-80 as the reference area. [#]_ * \ :code:`-fformat=cobol85`\ Fixed format with enforcements on the use of Area A. * \ :code:`-fformat=variable`\ Micro Focus' Variable format. Identical to the fixed format above except for the program-text area which extends up to column 250 instead of 72. * \ :code:`-fformat=xcard`\ ICOBOL xCard format. Variable format with right margin set at column 255 instead of 250. * \ :code:`-fformat=xopen`\ X/Open Free-form format. The program-text area may start in column 1 unless an indicator is present, and lines may contain up to 255 characters. Indicator for debugging lines is '\ :code:`D`\ ' (D followed by a space) instead of '\ :code:`D`\ ' or '\ :code:`d`\ '. * \ :code:`-fformat=crt`\ ICOBOL Free-form format (CRT). Similar to the X/Open format above, with lines containing up to 320 characters and single-character debugging line indicators ('\ :code:`D`\ ' or '\ :code:`d`\ '). * \ :code:`-fformat=terminal`\ ACUCOBOL-GT Terminal format. Similar to the CRT format above, with indicator for debugging lines being '\ :code:`\D`\ ' instead of '\ :code:`D`\ ' or '\ :code:`d`\ '. This format is mostly compatible with VAX COBOL terminal source format. * \ :code:`-fformat=cobolx`\ COBOLX format. This format is similar to the CRT format above, except that the indicator area is always present in column 1; the program-text area starts in column 2 and extends up to the end of the record. Lines may contain up to 255 characters. * \ :code:`-fformat=auto`\ Autodetection of format. The compiler will use the first line of the file to detect whether the file is in fixed format (with a correct indicator at position 7), or in free format. Note that with source formats \ :code:`XOPEN`\ , \ :code:`CRT`\ , \ :code:`TERMINAL`\ , and \ :code:`COBOLX`\ , missing spaces are not inserted within continued alphanumeric literals that are truncated before the right margin. \ **Area A**\ denotes the source code that spans between margin A and margin B, and Area B spans from the latter to the end of the record. \ **Area A enforcement**\ checks the contents of Area A, and reports any item that does not belong to the correct Area: this feature helps in developping COBOL programs that are portable to actual mainframe environments. In general, division, section, and paragraph names must start in Area A. In the \ :code:`DATA DIVISION`\ , level numbers '\ :code:`01`\ ' and '\ :code:`77`\ ', must also start in Area A. In the \ :code:`PROCEDURE DIVISION`\ s, statements and separator periods must fit within Area B. Every source format listed above may be subject to Area A enforcement, except \ :code:`FIXED`\ , \ :code:`FREE`\ , and \ :code:`XOPEN`\ . Note that Area A enforcement enables recovery from missing periods between paragraphs and sections. .. _WarningAoptions: .. index:: single:Warning options Warning options ~~~~~~~~~~~~~~~ Warnings are diagnostic messages that report constructions that are not inherently erroneous but that are risky or suggest there may have been an error. The following options do not enable specific warnings but control the kinds of diagnostics produced by :command:`cobc`. * \ :code:`-fsyntax-only`\ Check Check the code for syntax errors, but don’t do anything beyond that. * \ :code:`-fmax-errors=`\ Limits the maximum number of error messages to , at which point :command:`cobc` bails out rather than attempting to continue processing the source code. If is 0, there is no limit on the number of error messages produced. If \ :code:`-Wfatal-errors`\ is also specified, then \ :code:`-Wfatal-errors`\ takes precedence over this option. * \ :code:`-w`\ Inhibit all warning messages. * \ :code:`-Werror`\ Make all warnings into errors. * \ :code:`-Werror=`\ Make the specified into an error. The specifier for a warning is appended; for example \ :code:`-Werror=obsolete`\ turns the warnings controlled by \ :code:`-Wobsolete`\ into errors. This switch takes a negative form, to be used to negate \ :code:`-Werror`\ for specific warnings; for example \ :code:`-Wno-error=obsolete`\ makes \ :code:`-Wobsolete`\ warnings not be errors, even when \ :code:`-Werror`\ is in effect. The warning message for each controllable warning includes the option that controls the warning. That option can then be used with \ :code:`-Werror=`\ and \ :code:`-Wno-error=`\ as described above. (Printing of the option in the warning message can be disabled using the \ :code:`-fno-diagnostics-show-option`\ flag.) Note that specifying \ :code:`-Werror=foo`\ automatically implies \ :code:`-Wfoo`\ . However, \ :code:`-Wno-error=foo`\ does not imply anything. * \ :code:`-Wfatal-errors`\ This option causes the compiler to abort compilation on the first error occurred rather than trying to keep going and printing further error messages. You can request many specific warnings with options beginning with '\ :code:`-W`\ ', for example \ :code:`-Wimplicit-define`\ to request warnings on implicit declarations. Each of these specific warning options also has a negative form beginning '\ :code:`-Wno`\ ' to turn off warnings; for example, \ :code:`-Wno-implicit-define`\ . This manual lists only one of the two forms, whichever is not the default. Some options, such as \ :code:`-Wall`\ and \ :code:`-Wextra`\ , turn on other options, such as \ :code:`-Wtruncate`\ . The combined effect of positive and negative forms is that more specific options have priority over less specific ones, independently of their position in the command-line. For options of the same specificity, the last one takes effect. * \ :code:`-Wall`\ Enable all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning). The list of warning flags turned on by this option is shown in \ :code:`--help`\ . * \ :code:`-Wextra, -W`\ Enable every possible warning that is not dialect specific. This includes more information than \ :code:`-Wall`\ would normally provide. (This option used to be called \ :code:`-W`\ . The older name is still supported, but the newer name is more descriptive.) * \ :code:`-W`\ Enable single warning . * \ :code:`-Wno-`\ Disable single warning . * \ :code:`-Warchaic`\ Warn if archaic features are used, such as continuation lines or the \ :code:`NEXT SENTENCE`\ statement. * \ :code:`-Wcall-params`\ Warn if non-01/77-level items are used as arguments in a \ :code:`CALL`\ statement. This is \ **not**\ set with \ :code:`-Wall`\ . * \ :code:`-Wcolumn-overflow`\ Warn if text after column 72 in FIXED format. This is \ **not**\ set with \ :code:`-Wall`\ . * \ :code:`-Wconstant`\ Warn inconsistent constant * \ :code:`-Wimplicit-define`\ Warn if implicitly defined data items are used. * \ :code:`-Wlinkage`\ Warn dangling \ :code:`LINKAGE`\ items. This is \ **not**\ set with \ :code:`-Wall`\ . * \ :code:`-Wobsolete`\ Warn if obsolete features are used. * \ :code:`-Wparentheses`\ Warn about any lack of parentheses around \ :code:`AND`\ within \ :code:`OR`\ . * \ :code:`-Wredefinition`\ Warn about incompatible redefinitions of data items. * \ :code:`-Wstrict-typing`\ Warn about type mismatch strictly. * \ :code:`-Wterminator`\ Warn about the lack of scope terminator END-XXX. This is \ **not**\ set with \ :code:`-Wall`\ . * \ :code:`-Wtruncate`\ Warn on possible field truncation. This is \ **not**\ set with \ :code:`-Wall`\ . * \ :code:`-Wconstant-expression`\ * \ :code:`-Wconstant-numlit-expression`\ Warn about expressions that always resolve to true/false and therefore lead to unreachable code. * \ :code:`-Wunreachable`\ Warn if statements are likely unreachable. This is \ **not**\ set with \ :code:`-Wall`\ . * \ :code:`-Wadditional`\ Enable warnings that don't have an own warning flag. .. _ConfigurationAoptions: .. index:: single:Configuration options Configuration options ~~~~~~~~~~~~~~~~~~~~~ The compiler uses many dialect specific options. These may be set via a defined dialect by \ :code:`-std=`\ , a configuration file by \ :code:`-conf=`\ or by using the single dialect flags directly. :ref:`Appendix G `, and :file:`config/\*.conf`. Note concerning the defined dialects: The GnuCOBOL compiler tries to limit both the feature-set and reserved words to the specified compiler when the "strict" dialects are used. COBOL sources compiled with these dialects are therefore \ **likely**\ to compile with the specified compiler and vice versa: sources that were compiled on the specified compiler should compile without any issues with GnuCOBOL. With the "non-strict" dialects GnuCOBOL will activate the complete feature-set where it doesn't directly conflict with the specified dialect, including reserved words. COBOL sources compiled with these dialects therefore may work only with GnuCOBOL. COBOL sources may need a change because of reserved words in GnuCOBOL, otherwise offending words and may be removed by \ :code:`-fno-reserved=,`\ . The dialects COBOL-85, X/Open COBOL, and are always "strict". * \ :code:`-std=`\ Compiler uses the given to determine certain compiler features and warnings. * \ :code:`-std=default`\ GnuCOBOL dialect, supporting many of the and features, many extensions found in other dialects and its own feature-set * \ :code:`-std=cobol85`\ COBOL-85 without any extensions other than the amendment Intrinsic Function Module (1989), source compiled with this dialect is likely to compile with most COBOL compilers * \ :code:`-std=xopen`\ X/Open COBOL (based on COBOL-85) without any vendor extensions, source compiled with this dialect is likely to compile with most COBOL compilers; will warn items that "should not be used in a conforming source program" * \ :code:`-std=cobol2002, -std=cobol2014`\ / without any vendor extensions, use \ :code:`-Warchaic`\ and \ :code:`-Wobsolete`\ if archaic/obsolete features should be flagged * \ :code:`-std=ibm-strict, -std=ibm`\ IBM compatible * \ :code:`-std=mvs-strict, -std=mvs`\ MVS compatible * \ :code:`-std=mf-strict, -std=mf`\ Micro Focus compatible * \ :code:`-std=bs2000-strict, -std=bs2000`\ BS2000 compatible * \ :code:`-std=acu-strict, -std=acu`\ ACUCOBOL-GT compatible * \ :code:`-std=rm-strict, -std=rm`\ RM/COBOL compatible * \ :code:`-std=realia-strict, -std=realia`\ CA Realia II compatible * \ :code:`-std=gcos-strict, -std=gcos`\ GCOS compatible * \ :code:`-freserved-words=`\ Compiler uses the given to determine the reserved words. * \ :code:`-conf=`\ User-defined dialect configuration. * \ :code:`-febcdic-table=/`\ EBCDIC/ASCII translation table to use; either read from , or one of the existing from the configuration directory (see \ :code:`cobc --info`\ ) which have a .ttbl extension, for example \ :code:`-febcdic-table=alternate`\ . See the :file:`default.ttbl` file for detailed information about the format. You can override each single configuration entry by using compiler configuration options on the command line. Examples: * \ :code:`-frelax-syntax-checks`\ * \ :code:`-frenames-uncommon-levels=warning`\ * \ :code:`-fnot-reserved=CHAIN,SCREEN`\ * \ :code:`-ftab-width=4`\ :ref:`Appendix A `. .. _ListingAoptions: .. index:: single:Listing options Listing options ~~~~~~~~~~~~~~~ * \ :code:`-t=`\ Generate and place the standard print listing into :file:``. * \ :code:`-T=`\ Generate and place a wide print listing into :file:`\*`. * \ :code:`--tlines=`\ Specify lines per page in print listing, default = 55. Set to zero for no additional page breaks. * \ :code:`-ftsymbols`\ Generate symbol table in listing. * \ :code:`-fno-theader`\ Suppress all headers from listing while keeping page breaks. * \ :code:`-fno-tmessages`\ Suppress warning and error summary from listing. * \ :code:`-fno-tsource`\ Suppress actual source from listing (for example to only produce the cross-reference). * \ :code:`-P, -P, -P=`\ Generate and place a preprocessed listing (old format) into :file:`.lst`, :file:`/.lst`, :file:``. * \ :code:`-Xref`\ * \ :code:`-X`\ Generate cross reference in the listing. Here is an example program listing with the options \ :code:`-t -ftsymbols`\ : :: GnuCOBOL 3.0.0 test.cbl Mon May 14 10:23:45 2018 Page 0001 LINE PG/LN A...B........................................................... 000001 IDENTIFICATION DIVISION. 000002 PROGRAM-ID. prog. 000003 ENVIRONMENT DIVISION. 000004 CONFIGURATION SECTION. 000005 DATA DIVISION. 000006 WORKING-STORAGE SECTION. 000007 COPY 'values.cpy'. 000001C 78 I VALUE 20. 000002C 78 J VALUE 5000. 000003C 78 M VALUE 5. 000008 01 SETUP-REC. 000009 05 FL1 PIC X(04). 000010 05 FL2 PIC ZZZZZ. 000011 05 FL3 PIC 9(04). 000012 05 FL4 PIC 9(08) COMP. 000013 05 FL5 PIC 9(04) COMP-4. 000014 05 FL6 PIC Z,ZZZ.99. 000015 05 FL7 PIC S9(05) SIGN LEADING SEPARATE. 000016 05 FL8 PIC X(04). 000017 05 FL9 REDEFINES FL8 PIC 9(04). 000018 05 FLA. 000019 10 FLB OCCURS I TIMES. 000020 15 FLC PIC X(02). 000021 10 FLD PIC X(20). 000022 05 FLD1 PIC X(100). 000023 05 FLD2 OCCURS M TO J TIMES DEPENDING ON FL5. 000024 10 FILLER PIC X(01). 000025 05 FLD3 PIC X(3). 000026 05 FLD4 PIC X(4). 000027 PROCEDURE DIVISION. 000028 STOP RUN. The first part of the listing lists the program text. If the program text is a COPY the line number reflects the COPY line number and is appended with a '\ :code:`C`\ '. When the wide list option \ :code:`-T`\ is specified, the \ :code:`SEQUENCE`\ columns (for fixed-form reference-format) are included in the listing. The second part of the listing file is the listing of the Symbol Table: :: GnuCOBOL 3.0.0 test.cbl Mon May 14 10:23:45 2018 Page 0002 SIZE TYPE LVL NAME PICTURE 5204 GROUP 01 SETUP-REC 0004 ALPHANUMERIC 05 FL1 X(04) 0005 ALPHANUMERIC 05 FL2 ZZZZZ 0004 ALPHANUMERIC 05 FL3 9(04) 0004 NUMERIC 05 FL4 9(08) COMP 0002 NUMERIC 05 FL5 9(04) COMP 0008 ALPHANUMERIC 05 FL6 Z,ZZZ.99 0006 ALPHANUMERIC 05 FL7 S9(05) 0004 ALPHANUMERIC 05 FL8 X(04) 0004 ALPHANUMERIC-R 05 FL9 9(04) 0060 ALPHANUMERIC 05 FLA 0040 ALPHANUMERIC 10 FLB OCCURS 20 0002 ALPHANUMERIC 15 FLC X(02) 0020 ALPHANUMERIC 10 FLD X(20) 0100 ALPHANUMERIC 05 FLD1 X(100) 5000 ALPHANUMERIC 05 FLD2 OCCURS 5 TO 5000 0001 ALPHANUMERIC 10 FILLER X(01) 0003 ALPHANUMERIC 05 FLD3 X(3) 0004 ALPHANUMERIC 05 FLD4 X(4) If the symbol redefines another variable the \ :code:`TYPE`\ is marked with '\ :code:`R`\ '. If the symbol is an array the \ :code:`OCCURS`\ phrase is in the \ :code:`PICTURE`\ field. The last part of the listing file is the summary of warnings an error in the compilation group: :: 0 warnings in compilation group 2 errors in compilation group .. _DebugAswitches: .. index:: single:Debug switches Debug switches ~~~~~~~~~~~~~~ * \ :code:`-g`\ Produce C debugging information in the output. * \ :code:`--debug, -d`\ Enable all run-time error checks. * \ :code:`-fmemory-check=scope`\ Enable checking of internal storage during CALL (implied by \ :code:`--debug`\ . * \ :code:`-fec=exception-name, -fno=ec=exception-name`\ Enable/disable specified exception checks, :ref:`Appendix F `; \ :code:`--debug`\ implies \ :code:`-fec=ALL`\ . * \ :code:`-fsource-location`\ Generate source location code (implied by \ :code:`--debug`\ , \ :code:`-fdump`\ and \ :code:`-fec`\ ). * \ :code:`-fstack-check`\ Enable \ :code:`PERFORM`\ stack checking (implied by \ :code:`--debug`\ or \ :code:`-g`\ ). * \ :code:`-ftrace`\ Generate trace code (log executed procedures, if tracing is enabled). * \ :code:`-ftraceall`\ Generate trace code (log executed procedures and statements, if tracing is enabled). * \ :code:`-fdebugging-line`\ Enable debugging lines ('\ :code:`D`\ ' in indicator column; '\ :code:`>>D`\ ' directive). * \ :code:`-O`\ Enable optimization of code size and execution speed. See your C compiler documentation, for example \ :code:`man gcc`\ for details. * \ :code:`-O2`\ Optimize even more. * \ :code:`-Os`\ Optimize for size. Optimizer will favour code size over execution speed. * \ :code:`-fnotrunc`\ Do not truncate binary fields according to PICTURE. .. _Miscellaneous: .. index:: single:Miscellaneous Miscellaneous ~~~~~~~~~~~~~ * \ :code:`-ext `\ Add default file extension. * \ :code:`-fintrinsics=[ALL|intrinsic function name(,name,...)]`\ Allow use of all or specific intrinsic functions without \ :code:`FUNCTION`\ keyword. Note: defining this within your source with \ :code:`CONFIGURATION SECTION. REPOSITORY.`\ is preferred. * \ :code:`-ffold-copy=LOWER`\ Fold \ :code:`COPY`\ subject to lower case (default no transformation). * \ :code:`-ffold-copy=UPPER`\ Fold \ :code:`COPY`\ subject to upper case (default no transformation). * \ :code:`-save-temps(=)`\ Save intermediate files (by default, in current directory). * \ :code:`-fimplicit-init`\ Do automatic initialization of the COBOL runtime system. .. _MultipleAsources: .. index:: single:Multiple sources Multiple sources ---------------- This section describes how to compile a program from multiple source files. This section also describes how to build a shared library that can be used by any COBOL program and how to use external libraries in COBOL programs. .. _StaticAlinking: .. index:: single:Static linking Static linking ~~~~~~~~~~~~~~ The easiest way of combining multiple files is to compile them into a single executable. One way is to compile all the files in one command: :: $ cobc -x -o prog main.cob subr1.cob subr2.cob Another way is to compile each file with the option \ :code:`-c`\ , and link them at the end. The top-level program must be compiled with the option \ :code:`-x`\ . :: $ cobc -c subr1.cob $ cobc -c subr2.cob $ cobc -c -x main.cob $ cobc -x -o prog main.o subr1.o subr2.o You can link C routines as well using either method: :: $ cobc -o prog main.cob subrs.c or :: $ cobc -c subrs.c $ cobc -c -x main.cob $ cobc -x -o prog main.o subrs.o Any number of functions can be contained in a single C file. The linked programs will be called dynamically; that is, the symbol will be resolved at run time. For example, the following COBOL statement :: CALL "subr" USING X. will be converted into equivalent C code like this: :: int (*func)() = cob_resolve("subr"); if (func != NULL) func (X); With the compiler option \ :code:`-fstatic-call`\ , more efficient code will be generated: :: subr(X); Please notice that this option only takes effect when the called program name is in a literal (like \ :code:`CALL "subr"`\ ). With a data name (like \ :code:`CALL SUBR`\ ), the program is still called dynamically. .. _DynamicAlinking: .. index:: single:Dynamic linking Dynamic linking ~~~~~~~~~~~~~~~ There are two methods to achieve this: a driver program, or compiling the main program and subprograms separately. .. index:: single:Driver program Driver program ^^^^^^^^^^^^^^ Compile all programs with the option \ :code:`-m`\ : :: $ cobc -m main.cob subr.cob This creates the shared object files :file:`main.so` and :file:`subr.so`. [#]_ Before running the main program, install the module files in your library directory: :: $ cp subr.so /your/cobol/lib Set the runtime variable \ :code:`COB_LIBRARY_PATH`\ to your library directory, and run the main program: :: $ export COB_LIBRARY_PATH=/your/cobol/lib (\ **Please notice:**\ You may set the variable via a runtime configuration file, :ref:`Appendix I `. You may also set the variable to directly point to the directory where you compiled the sources.) Now execute your program: :: $ cobcrun main .. index:: single:Compiling programs separately Compiling programs separately ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The main program is compiled as usual: :: $ cobc -x -o main main.cob Subprograms are compiled with the option \ :code:`-m`\ : :: $ cobc -m subr.cob This creates a module file :file:`subr.so` [#]_ . Before running the main program, install the module files in your library directory: :: $ cp subr.so /your/cobol/lib Now, set the environment variable \ :code:`COB_LIBRARY_PATH`\ to your library directory, and run the main program: :: $ export COB_LIBRARY_PATH=/your/cobol/lib $ ./main .. _BuildingAlibrary: .. index:: single:Building library Building library ~~~~~~~~~~~~~~~~ You can build a shared library by combining multiple COBOL programs and even C routines: :: $ cobc -c subr1.cob $ cobc -c subr2.cob $ cc -c subr3.c $ cc -shared -o libsubrs.so subr1.o subr2.o subr3.o .. _UsingAlibrary: .. index:: single:Using library Using library ~~~~~~~~~~~~~ You can use a shared library by linking it with your main program. Before linking the library, install it in your system library directory: :: $ cp libsubrs.so /usr/lib or install it somewhere else and set \ :code:`LD_LIBRARY_PATH`\ : :: $ cp libsubrs.so /your/cobol/lib $ export LD_LIBRARY_PATH=/your/cobol/lib Then, compile the main program, linking the library as follows: :: $ cobc -x main.cob -L/your/cobol/lib -lsubrs .. _CAinterface: .. index:: single:C interface C interface ----------- This chapter describes how to combine C programs with COBOL programs. .. _MainACAprogram: .. index:: single:Writing Main Program in C Writing Main Program in C ~~~~~~~~~~~~~~~~~~~~~~~~~ Include :file:`libcob.h` in your C program and call \ :code:`cob_init`\ before using any COBOL module. Do a cleanup afterwards, either by calling \ :code:`cob_stop_run`\ (if your program should terminate) or by calling \ :code:`cob_tidy`\ (if your program should execute further on without any more COBOL calls). Calling \ :code:`cob_init`\ , one or several GnuCOBOL modules and then \ :code:`cob_tidy`\ in this sequence can be done multiple times). :: #include int main (int argc, char **argv) { /* initialize your program */ ... /* initialize the COBOL run-time library */ cob_init (argc, argv); /* rest of your program */ ... /* Clean up and terminate - This does not return */ cob_stop_run (return_status); } You can write \ :code:`cobc_init(0, NULL);`\ if you do not want to pass command line arguments to COBOL. The easiest option to compile and/or link your C program is by passing the work to \ :code:`cobc`\ as follows: :: cobc -x main.c possibly running in verbose mode to see what cobc does: :: cobc -x --verbose main.c # using -x -v or -xv would be also possible or with several steps: :: cobc -c main.c cobc -x main.o As an alternative you can use the \ :code:`cob-config`\ tool to get the necessary options to be passed to the C compiler / linker. :: cc -c `cob-config --cflags` main.c # compile only cc -o main main.o `cob-config --libs` # link only .. _StaticACAtoACOBOL: .. index:: single:Static linking with COBOL programs Static linking with COBOL programs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Let's call the following COBOL module from a C program: :: ---- say.cob --------------------------- IDENTIFICATION DIVISION. PROGRAM-ID. say. ENVIRONMENT DIVISION. DATA DIVISION. LINKAGE SECTION. 01 hello PIC X(7). 01 world PIC X(6). PROCEDURE DIVISION USING hello world. DISPLAY hello world. GOBACK. ---------------------------------------- This program accepts two arguments, displays them, and exits. From the viewpoint of C, this is equivalent to a function having the following prototype: :: extern int say(char *hello, char *world); So, your main program will look like as follows: :: ---- hello.c --------------------------- #include extern int say(char *hello, char *world); int main() { int ret; char hello[8] = "Hello, "; char world[7] = "world!"; /* initialize the COBOL run-time library */ cob_init(0, NULL); /* call the static module and store its return code */ ret = say(hello, world); /* shutdown the COBOL run-time library, keep program running */ (void)cob_tidy(); return ret; } ---------------------------------------- Compile and run these programs as follows: :: $ cobc -x hello.c say.cob $ ./hello Hello, world! or, more split and directly using the C compiler: :: $ cc -c `cob-config --cflags` hello.c $ cobc -c -static say.cob $ cobc -x -o hello hello.o say.o $ ./hello Hello, world! Note: The biggest benefits of static linking are that all programs are verified to be available in the resulting binary. Furthermore there is a slightly performance benefit in this type of CALL (not visible for "normal" programs). .. _DynamicACAtoACOBOL: .. index:: single:Dynamic linking with COBOL programs Dynamic linking with COBOL programs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can find a COBOL module having a specific name by using the C function \ :code:`cob_resolve`\ , which takes the module name as a string and returns a pointer to the module function. \ :code:`cob_resolve`\ returns \ :code:`NULL`\ if there is no module. In this case, the function \ :code:`cob_resolve_error`\ returns the error message. Let's see an example: :: ---- hello-dynamic.c ------------------- #include static int (*say)(char *hello, char *world); int main() { int ret; char hello[8] = "Hello, "; char world[7] = "world!"; /* initialize the COBOL run-time library */ cob_init(0, NULL); /* Find the module with PROGRAM-ID "say". */ say = cob_resolve("say"); /* If there is no such module, show error and exit. */ if(say == NULL) { fprintf(stderr, "%s\n", cob_resolve_error()); exit(1); } /* Call the module found ... */ ret = say(hello, world); /* ...and exit with the return code. */ cob_stop_run(ret); } ---------------------------------------- Compile and run these programs as follows: :: $ cobc -x -o hello hello-dynamic.c $ cobc -m say.cob $ export COB_LIBRARY_PATH=. $ ./hello Hello, world! The check of the module load as written above can be directly done in libcob as follows: :: ---- hello-dynamic2.c ------------------ #include int main() { int ret; char hello[8] = "Hello, "; char world[7] = "world!"; void *cob_argv[2]; cob_argv[0] = hello; cob_argv[1] = world; /* initialize the COBOL run-time library */ cob_init(0, NULL); /* do a CALL, expecting the module to exist, otherwise exiting with an error. */ ret = cob_call ("say", 2, cob_argv); /* ...and exit with the return code. */ cob_stop_run(ret); } ---------------------------------------- In any case be aware that all errors that happen within COBOL will exit your program, as same as a \ :code:`STOP RUN`\ will do. Depending on the application you possibly want to register C signal handlers; error and/or exit handlers in C and/or COBOL to do cleanups, logging or anything else. There is one way to handle all these scenarios with a call, too, using \ :code:`cob_call_with_exception_check`\ instead of \ :code:`cob_call`\ as follows: :: ---- hello-dynamic3.c ------------------ #include int main() { int ret; char hello[8] = "Hello, "; char world[7] = "world!"; void *cob_argv[2]; cob_argv[0] = hello; cob_argv[1] = world; /* initialize the COBOL run-time library */ cob_init(0, NULL); /* do a CALL, catching all possible results, */ ret = cob_call_with_exception_check ("say", 2, cob_argv); switch (ret) { case 0: /* program coming back */ /* Clean up and terminate runtime */ cob_runtime_hint("program exited with return code %d", cob_last_exit_code ()); cob_tidy (); break; case 1: /* normal exit */ cob_runtime_hint("STOP RUN with return code %d", cob_last_exit_code ()); break; case -1: /* error exit */ cob_runtime_hint("error exit with return code %d and error \"%s\"", cob_last_exit_code (), cob_last_runtime_error ()); break; case -2: /* hard error exit */ cob_runtime_hint("hard error exit with return code %d and error \"%s\"", cob_last_exit_code (), cob_last_runtime_error ()); break; case -3: /* signal handler exit */ cob_runtime_hint("signal handler exit with signal %d and error \"%s\"", cob_last_exit_code (), cob_last_runtime_error ()); break; default: cob_runtime_hint("unexpected return from cob_call_with_exception_check," " last exit code %d, last error \"%s\"", cob_last_exit_code (), cob_last_runtime_error ()); break; } /* ...and exit with zero if no error happened */ exit(ret != 0 && ret != 1); } ---------------------------------------- .. _StaticACOBOLAtoAC: .. index:: single:Static linking with C programs Static linking with C programs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Let's call the following C function from COBOL: :: ---- say.c ----------------------------- int say(char *hello, char *world) { int i; for(i = 0; i < 7; i++) putchar(hello[i]); for(i = 0; i < 6; i++) putchar(world[i]); putchar('\n'); return 0; } ---------------------------------------- This program is equivalent to the program in :file:`say.cob` above. Note that, unlike C, the arguments passed from COBOL programs are not terminated by the null character (i.e., '\ :code:`\0`\ '). You can call this function in the same way you call COBOL programs: :: ---- hello.cob ------------------------- IDENTIFICATION DIVISION. PROGRAM-ID. hello. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 hello PIC X(7) VALUE "Hello, ". 01 world PIC X(6) VALUE "world!". PROCEDURE DIVISION. CALL "say" USING hello world. STOP RUN. ---------------------------------------- Compile these programs as follows: :: $ cobc -x -o hello -static hello.cob say.c $ ./hello Hello, world! or separate: :: $ cc -c say.c $ cobc -c -static -x hello.cob $ cobc -x -o hello hello.o say.o $ ./hello Hello, world! .. _DynamicACOBOLAtoAC: .. index:: single:Dynamic linking with C programs Dynamic linking with C programs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can create a dynamically-linked module from a C program by compiling it with cobc ... :: $ cobc -m say.c $ cobc -x hello.cob $ export COB_LIBRARY_PATH=. $ ./hello Hello, world! or with most C compilers by passing option \ :code:`-shared`\ to the C compiler: :: $ cc -shared -o say.so say.c $ cobc -x hello.cob $ export COB_LIBRARY_PATH=. $ ./hello Hello, world! Mind that for COBOL to be able to load the module via CALL the name of the binary must either be identical to the CALL name or the binary containing the entry-point must have been loaded before (by a previous call or COB_PRE_LOAD). .. _InterfaceAfunctionsAforAC: .. index:: single:Redirecting output to a (FILE \*) Redirecting output to a (FILE \*) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From a module written in C you can call \ :code:`cob_set_runtime_option`\ to set the exact \ :code:`(FILE *)`\ which is used to write trace data to. In :file:`common.h` is the following: :: enum cob_runtime_option_switch { COB_SET_RUNTIME_TRACE_FILE /* 'p' is FILE * */ COB_SET_RUNTIME_DISPLAY_PRINTER_FILE /* 'p' is FILE * */ COB_SET_RUNTIME_RESCAN_ENV /* rescan environment variables */ COB_SET_RUNTIME_DISPLAY_PUNCH_FILE /* 'p' is FILE * */ }; COB_EXPIMP void cob_set_runtime_option (enum cob_runtime_option_switch opt, void *p); So from you C code you can tell the GnuCOBOL runtime to redirect TRACE output by: :: cob_set_runtime_option (COB_SET_RUNTIME_TRACE_FILE, (void*)((FILE*)myfd)); You could also redirect all \ :code:`DISPLAY UPON PRINTER`\ output to a file by: :: cob_set_runtime_option (COB_SET_RUNTIME_DISPLAY_PRINTER_FILE, (void*)((FILE*)myfd)); You could also redirect all \ :code:`DISPLAY UPON SYSPUNCH`\ output to a file by: :: cob_set_runtime_option (COB_SET_RUNTIME_DISPLAY_PUNCH_FILE, (void*)((FILE*)myfd)); Another routine can be used to return the current value of the option. :: COB_EXPIMP void * cob_get_runtime_option (enum cob_runtime_option_switch opt); .. _LoadingAtranslationAtables: .. index:: single:Loading EBCDIC/ASCII translation tables (collating sequences) Loading EBCDIC/ASCII translation tables (collating sequences) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When an EBCDIC/ASCII translation table is needed (for instance when calling sort functions), you can can call the \ :code:`cob_load_collation`\ function to retrieve such tables: :: COB_EXPIMP int cob_load_collation (const char *col_name, cob_u8_t *ebcdic_to_ascii, cob_u8_t *ascii_to_ebcdic) .. _Customize: .. [#] Support may be partial or complete. .. [#] The extension varies depending on your host. .. [#] Historically, fixed format was based on 80-character punch cards. .. [#] The extension used depends on your operating system. .. [#] The extension used depends on your operating system.