RPGLE Modules and NOMAIN Reference

An RPGLE source member compiles into a module, and the module type decides whether it can start a program, whether it carries the RPG cycle, and what you may code outside a procedure. This page is the lookup for the three module types, the NOMAIN and MAIN keywords, the export and import rules, and the create command each module needs.

It is a lookup, not a build walkthrough. To build a service program step by step, read Build an ILE RPG Service Program. For the packaging model in plain terms, read IBM i Modules, Bound Programs, and Binding Directories Explained. For procedure basics, read Subprocedures and Service Programs in RPGLE.

Module types at a glance

IBM’s ILE RPG Reference describes three kinds of module. The keyword on the control specification decides which one you get.

Module typeKeywordRPG cycleMain procedureCan be the program-entry module
Cycle-mainnoneYesImplicit: everything before the first procedureYes
Linear-mainMAIN(procedure-name)NoA named subprocedureYes
No mainNOMAINNoNoneNo

Two further rules come from the same chapter:

  • A linear-main procedure can only be called through a program call. It cannot be called with a bound call.
  • A NOMAIN module contains only subprocedures. IBM says it “cannot be the program-entry module of a program, since it has no main procedure”.

NOMAIN

NOMAIN marks a module with no main procedure and no cycle code. It is the normal home for procedures that other programs call.

**free
ctl-opt nomain;

dcl-proc refDouble export;
  dcl-pi *n int(10);
    inNumber int(10) const;
  end-pi;
  return inNumber * 2;
end-proc;

dcl-proc refLabel export;
  dcl-pi *n varchar(30);
    inNumber int(10) const;
  end-pi;
  return 'Number ' + %char(inNumber);
end-proc;

The export keyword on dcl-proc makes the procedure available to other modules. A module like this is created with CRTRPGMOD, which makes a *MODULE that cannot run by itself:

CRTRPGMOD MODULE(MYLIB/REFUTIL) SRCFILE(MYLIB/QRPGLESRC) SRCMBR(REFUTIL) DBGVIEW(*SOURCE)

The examples on this page were compiled from source file members. On the IBM i V7R5M0 system used to check them, the same commands with SRCSTMF stream-file source failed with RNS9339: Unable to open file, so the page does not rely on SRCSTMF. SRCSTMF is a documented parameter, and it may work on your system.

What NOMAIN changes:

RuleDetail
No program entryA NOMAIN module has no program entry procedure, so CRTBNDRPG cannot create a program from it
How to use itBind it into a program with CRTPGM, next to a module that has a program entry procedure, or create a service program with CRTSRVPGM
No cycleLanguage features that depend on the cycle must not be specified
Main source sectionAllows full-procedural files, input specifications, definitions, declarative calculations and exception output. It does not allow primary or secondary files, heading, detail or total output, executable calculations (including *INZSR) or *ENTRY PLIST
InitializationHappens when the first procedure in the module is called
CleanupA linear module has no implicit closing of global files and no implicit unlocking of data areas. They stay open or locked until the code closes or unlocks them

IBM adds a tip: convert cycle modules to NOMAIN modules, except those that hold the program entry procedure, to remove unneeded cycle code.

MAIN (linear-main)

MAIN names one subprocedure as the program entry point and still leaves the cycle out.

**free
ctl-opt main(refMain) dftactgrp(*no) actgrp('REFDEMO');

dcl-proc refMain;
  dcl-pi *n extpgm('REFMAIN');
  end-pi;
  dsply 'Linear-main program';
end-proc;

IBM’s rules for the linear-main procedure:

  • A prototype for it must specify EXTPGM. If there is no prototype but there is a procedure interface, the interface must specify EXTPGM.
  • If the program has no parameters and is not called from an RPG program, neither a prototype nor a procedure interface is required.
  • It cannot be exported: EXPORT is not allowed on its procedure.
  • A recursive call to it is a dynamic program call.

Cycle-main modules that export procedures

A module with no MAIN or NOMAIN keyword is a cycle module. IBM warns against mixing the cycle with exported subprocedures:

  • An exported subprocedure can be called first, before the cycle-main procedure. When the cycle-main procedure is called later, it initializes at that time, which can reopen files or reinitialize global data the subprocedures already use.
  • Cycle-main initialization happens again if the cycle-main procedure ended abnormally or with *inlr on.

IBM’s recommendations are to move the cycle logic into a subprocedure and make the module NOMAIN, or to make it linear-main. If you must mix them, avoid *inlr, declare files USROPN and open and close them yourself.

Export and import

ItemHowNotes
Export a procedureexport on dcl-procThe name is exported in upper case unless extproc gives another name
Call an imported procedureA prototype with no extpgmProcedure names are imported implicitly into every module of the program when export is on the procedure
Export a data itemexport on a dcl-s or dcl-dsOnly one module may define it as exported. Unnamed data structures and based items cannot be exported
Import a data itemimport on the definitionIt cannot have inz. The exporting module does the initialization
Choose the external nameextproc('NAME') or extproc(*dclcase)*dclcase keeps the case you coded

Details that catch people:

  • A prototype with neither extpgm nor extproc is a procedure, and the compiler gives it the upper-case form of its name. That is why an exported refDouble is found as REFDOUBLE.
  • extproc makes the call a bound call. extpgm makes it a dynamic program call.
  • A name that starts with CEE or an underscore is treated as a system built-in. Do not name your procedures CEE....
  • The export keyword on a definition exports data only. Procedure names are exported with export on dcl-proc.

Which create command for which module

Source hasCreate withResult
Cycle-main or MAIN, to run as a programCRTBNDRPGA *PGM made from one source member
Any module type, to bind laterCRTRPGMODA *MODULE
NOMAINCRTRPGMOD, then CRTPGM or CRTSRVPGMCRTBNDRPG is not allowed

CRTBNDRPG has DFTACTGRP(*YES) as its default. IBM says static binding is not available with DFTACTGRP(*YES), so a program that uses binding directories or calls bound procedures needs DFTACTGRP(*NO). See the RPGLE Activation Groups Reference.

Common mistakes

  • Compiling a NOMAIN source with CRTBNDRPG.
  • Putting executable calculations or *INZSR in the main source section of a NOMAIN or MAIN module.
  • Exporting the linear-main procedure.
  • Mixing a cycle-main procedure with exported subprocedures and then ending with *inlr.
  • Expecting export on a data definition to export a procedure.
  • Using the call operation, which makes a dynamic program call, where a bound procedure call through a prototype is needed.
  • Forgetting that global files in a linear module stay open until your code closes them.

FAQ

What does NOMAIN do in RPGLE?

It says the module has no main procedure and no cycle code, so it holds only subprocedures. It cannot be the entry module of a program.

Can I run a NOMAIN module on its own?

No. Bind it into a program with CRTPGM, or into a service program with CRTSRVPGM, and call the procedures from another module.

What is the difference between MAIN and NOMAIN?

MAIN names a procedure that starts the program and is called by a program call. NOMAIN has no entry procedure at all. Neither includes the RPG cycle.

Do I need NOMAIN for a service program?

No, but it is the normal choice. IBM says modules in a service program may have program entry procedures, that these are ignored, and that a service program has no entry point of its own. NOMAIN states the intent, removes cycle code, and is what IBM’s tip recommends.

Summary

  • Three module types exist: cycle-main (no keyword), linear-main (MAIN) and no-main (NOMAIN).
  • NOMAIN and MAIN leave out the cycle, which limits what the main source section may hold.
  • A NOMAIN module cannot be created into a program with CRTBNDRPG. Use CRTRPGMOD and then CRTPGM or CRTSRVPGM.
  • Export procedures with export on dcl-proc. Export and import data with export and import on the definition.
  • Next: the RPGLE Service Programs Reference for what a service program is, and the RPGLE Binder Language and Signatures Reference for controlling its exports.

Sources: IBM i 7.5 ILE RPG Reference (RPG module types, NOMAIN, MAIN, DFTACTGRP, EXPORT, IMPORT, EXTPROC) and IBM i 7.5 ILE Concepts (service programs). The examples have been reviewed against that text. They have not been compiled or run.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top