L'ILE sur IBM i, un programme fait de briques
Ce qu'est l'Integrated Language Environment, pourquoi IBM l'a créé, et comment le mettre en place : un programme RPG full free qui appelle une fonction écrite en C et une procédure écrite en CL, lié d'abord en un seul programme, puis à un programme de service. Tout a été compilé, exécuté et débogué sur un IBM i 7.5.
En une phrase
Avec l'ILE, un compilateur ne produit plus un programme mais un module ; on lie ensuite des modules, écrits si l'on veut en RPG, en C, en COBOL ou en CL, pour obtenir un programme ou un programme de service que d'autres programmes partagent.
L'ILE, c'est quoi
L'ILE (Integrated Language Environment) est un ensemble d'outils et de mécanismes du système pour construire des programmes. Seuls les compilateurs ILE en profitent : ILE RPG (le RPG IV), ILE COBOL, ILE C, ILE C++ et ILE CL. Il repose sur quelques objets :
| Objet | Nom | Rôle |
|---|---|---|
*MODULE | Module | Ce que produit un compilateur ILE (CRTRPGMOD, CRTCMOD, CRTCLMOD…). Il contient des procédures, mais ne s'exécute pas seul. |
*PGM | Programme | Un ou plusieurs modules liés, dont un porte la procédure d'entrée. Il s'appelle par CALL. |
*SRVPGM | Programme de service | Des modules liés, sans procédure d'entrée : une boîte à outils de procédures, partagée par les programmes qui s'y lient. |
*BNDDIR | Répertoire de liage | Une liste de modules et de programmes de service, où le binder cherche les procédures appelées. |
Groupe d'activation | (pas un objet) | La partie du travail où un programme ILE s'exécute : ses variables, sa mémoire, ses fichiers ouverts. |
Pourquoi l'ILE existe
Sur l'AS/400 des débuts, le modèle de programmes est l'OPM (Original Program Model) : on compile un source, on obtient un programme, et un programme en appelle un autre par un appel dynamique, coûteux en ressources. Les applications étaient donc faites de quelques gros programmes, pour limiter les appels. Pour le C et le Pascal, IBM ajoute en V1R2 un modèle étendu, l'EPM. Le 16 février 1993, IBM annonce que la V2R3 d'OS/400 apportera l'ILE.
Ce que l'ILE change, d'après IBM :
- La liaison. Une procédure appelle une procédure d'un autre module par un appel lié, plus rapide que l'appel dynamique entre programmes. Découper devient rentable.
- La modularité. On recompile un petit module au lieu d'un gros programme, et la maintenance porte sur des morceaux plus petits.
- Le mélange des langages. Un même programme peut réunir des modules RPG, COBOL, C, C++ et CL : chacun écrit dans le langage le plus adapté.
- Des composants réutilisables, rangés dans des programmes de service.
- La coexistence. Les programmes ILE et OPM s'appellent les uns les autres : on passe à l'ILE progressivement.
- Un débogueur source commun, qui passe d'un langage à l'autre (démonstration plus bas).
- Un meilleur contrôle des ressources, grâce aux groupes d'activation.
L'exemple : un programme RPG, un module C, un module CL
Le programme STKCLE liste les articles du fichier ARTICLE (celui de la page Coder en RPG III) avec une clé de contrôle calculée par une fonction C, et affiche l'utilisateur rendu par une procédure CL.
Le module principal, en RPG full free
**FREE
// STKCLE : liste les articles avec leur cle de controle, calculee
// par le module C CLECTL, et l'utilisateur, rendu par le module CL CLUSER.
dcl-f ARTICLE keyed;
// Les procedures des autres modules : un prototype par procedure
dcl-pr cleControle int(10) extproc('cleControle');
code char(5) const;
end-pr;
dcl-pr utilisateur extproc('CLUSER');
user char(10);
end-pr;
dcl-s user char(10);
dcl-s cle int(10);
utilisateur(user);
dsply ('Utilisateur : ' + %trim(user));
read ARTICLE;
dow not %eof(ARTICLE);
cle = cleControle(ARTCOD);
dsply (ARTCOD + ' cle ' + %char(cle));
read ARTICLE;
enddo;
*inlr = *on;
dcl-pr cleControle int(10) extproc('cleControle');- Le prototype de la fonction C. Le nom entre apostrophes est le nom exact de la fonction :
la casse compte. Sans EXTPROC, RPG chercherait
CLECONTROLE, en majuscules, et le liage échouerait. code char(5) const;- Le code article, passé par référence : la fonction C le reçoit comme un
const char *. dcl-pr utilisateur extproc('CLUSER');- La procédure du module CL porte le nom du module, CLUSER, comme le montre plus bas la liste des
procédures exportées. Le prototype RPG peut, lui, s'appeler autrement (
utilisateur). cle = cleControle(ARTCOD);- Un appel de procédure, sans CALL : c'est un appel lié.
Le module C
/* CLECTL : cle de controle d'un code article de 5 caracteres. */
/* Les chiffres de rang pair comptent double ; la cle complete */
/* la somme a la dizaine superieure. */
#include <ctype.h>
int cleControle(const char *code)
{
int i;
int somme = 0;
for (i = 0; i < 5; i++) {
if (isdigit((unsigned char) code[i])) {
int chiffre = code[i] - '0';
somme += (i % 2 == 0) ? chiffre * 2 : chiffre;
}
}
return (10 - somme % 10) % 10;
}
Une fonction C ordinaire. Sur IBM i, les chiffres sont en EBCDIC (X'F0' à X'F9'), mais ils se suivent
comme en ASCII : code[i] - '0' donne bien la valeur du chiffre.
Le module CL
/* CLUSER : rend le nom de l'utilisateur du travail */
PGM PARM(&USER)
DCL VAR(&USER) TYPE(*CHAR) LEN(10)
RTVJOBA USER(&USER)
ENDPGM
Le même source qu'un programme CL : PGM, PARM, ENDPGM. Ce qui en fait un module, c'est la commande qui le compile.
Mettre en place 1 : trois modules, un programme
Chaque source se compile en module, avec le compilateur de son langage :
CRTRPGMOD MODULE(JOBIILE/STKCLE) SRCFILE(JOBIILE/QRPGLESRC) DBGVIEW(*SOURCE) | Le module RPG (attribut RPGLE) |
CRTCMOD MODULE(JOBIILE/CLECTL) SRCFILE(JOBIILE/QCSRC) DBGVIEW(*SOURCE) | Le module C (attribut CLE) |
CRTCLMOD MODULE(JOBIILE/CLUSER) SRCFILE(JOBIILE/QCLSRC) DBGVIEW(*SOURCE) | Le module CL (attribut CLLE) |
Puis CRTPGM lie les trois modules en un programme. ENTMOD désigne le module qui porte la procédure d'entrée, celle qui démarre quand on appelle le programme :
CRTPGM PGM(JOBIILE/STKCLE) MODULE(JOBIILE/STKCLE JOBIILE/CLECTL JOBIILE/CLUSER) ENTMOD(JOBIILE/STKCLE)
CALL STKCLE


DSPPGM PGM(JOBIILE/STKCLE) DETAIL(*MODULE) : les trois modules et leur langage.Ici, les modules sont liés par copie : leur code est recopié dans le programme. Le
groupe d'activation n'a pas été précisé : avec ACTGRP(*ENTMOD), la valeur par défaut, un
module d'entrée RPGLE fait tourner le programme dans le groupe QILE.
Mettre en place 2 : un programme de service
Les procédures C et CL serviront à d'autres programmes : on les range dans un programme de service. Son source de liage dit ce qu'il exporte, dans un ordre qui ne doit plus changer (on ajoute les nouvelles procédures à la fin, pour garder la compatibilité) :
/* OUTILS : les procedures exportees par le programme de service */
STRPGMEXP PGMLVL(*CURRENT)
EXPORT SYMBOL('cleControle')
EXPORT SYMBOL(CLUSER)
ENDPGMEXP
CRTSRVPGM SRVPGM(JOBIILE/OUTILS) MODULE(JOBIILE/CLECTL JOBIILE/CLUSER) SRCFILE(JOBIILE/QSRVSRC) SRCMBR(OUTILS)
CRTBNDDIR BNDDIR(JOBIILE/OUTILS)
ADDBNDDIRE BNDDIR(JOBIILE/OUTILS) OBJ((JOBIILE/OUTILS *SRVPGM))

cleControle (C, en minuscules) et CLUSER (CL).Le programme n'a plus besoin de citer les modules : le répertoire de liage suffit. Le même source RPG gagne une ligne de contrôle et se compile en une étape par CRTBNDRPG :
**FREE
// STKCLE2 : le meme programme, lie au programme de service OUTILS
// par le repertoire de liage OUTILS, au lieu de copier les modules.
ctl-opt dftactgrp(*no) actgrp('JOBIILE') bnddir('OUTILS');
dcl-f ARTICLE keyed;
dftactgrp(*no)- Obligatoire : avec
DFTACTGRP(*YES), qui sert à la compatibilité OPM, IBM interdit ACTGRP et BNDDIR, et un appel de procédure liée fait échouer la compilation. actgrp('JOBIILE')- Un groupe d'activation nommé, propre à l'application.
bnddir('OUTILS')- Le répertoire de liage où chercher
cleControleetCLUSER.
CRTBNDRPG PGM(JOBIILE/STKCLE2) SRCFILE(JOBIILE/QRPGLESRC) DBGVIEW(*SOURCE)

Par copie ou par référence : la preuve
Changeons le calcul du module C : les chiffres de rang pair comptent triple au lieu de double.
- somme += (i % 2 == 0) ? chiffre * 2 : chiffre;
+ somme += (i % 2 == 0) ? chiffre * 3 : chiffre;
On recompile le module, et on remplace seulement le module dans le programme de service, sans toucher aux programmes :
CRTCMOD MODULE(JOBIILE/CLECTL) SRCFILE(JOBIILE/QCSRC) DBGVIEW(*SOURCE)
UPDSRVPGM SRVPGM(JOBIILE/OUTILS) MODULE(JOBIILE/CLECTL)
CALL STKCLE
CALL STKCLE2

STKCLE contient sa propre copie de l'ancien module : il faut le relier pour qu'il change.
UPDPGM PGM(JOBIILE/STKCLE) MODULE(JOBIILE/CLECTL)

| Critère | Par copie (CRTPGM MODULE) | Par référence (programme de service) |
|---|---|---|
| Où est le code | Dans chaque programme | Une seule fois, dans le *SRVPGM |
| Changer une procédure | Relier chaque programme (UPDPGM) | UPDSRVPGM, une fois pour tous |
| Objets à livrer | Le programme | Le programme et le programme de service |
| Pour quoi | Des modules propres à un programme | Des procédures partagées par plusieurs programmes |
Déboguer d'un langage à l'autre
STRDBG suit le programme de module en module, à condition que chacun ait été compilé avec
DBGVIEW(*SOURCE). Point d'arrêt sur l'appel de la fonction C, puis F22 (Step
into, entrer dans la procédure appelée) :
STRDBG PGM(JOBIILE/STKCLE)
BREAK 22
CALL STKCLE


Dans le module C, les commandes du débogueur suivent la syntaxe du C : EVAL somme affiche
la variable, EVAL *code :c 5 les 5 caractères pointés par code.

EVAL somme : 2 pour A0001.
EVAL *code :c 5 : A0001.CLEAR PGM enlève tous les points d'arrêt, F12 laisse le programme finir, et
ENDDBG clôt la session.
Mettre l'ILE en place dans une application
- Sortir du mode compatible. IBM présente CRTBNDRPG avec
DFTACTGRP(*YES)comme une stratégie temporaire, pour des applications OPM qu'on ne peut pas convertir d'un coup. Les nouveaux programmes se compilent avecDFTACTGRP(*NO). - Regrouper les procédures partagées dans des programmes de service, par domaine (dates, contrôles, accès à un fichier…), avec un source de liage dont on ne change jamais l'ordre.
- Un répertoire de liage par application, cité dans le CTL-OPT : les programmes n'ont plus à connaître la liste des modules.
- Un groupe d'activation nommé par application, plutôt que *NEW à chaque appel.
- Garder les noms exacts : EXTPROC dans la casse de la procédure, surtout pour le C.
Sources
L'exemple a été construit et exécuté sur un IBM i 7.5 (voir la méthode). Les définitions et les règles viennent de ces sources, consultées le 16 octobre 2026 :
- IBM i 7.5 Programming : ILE Concepts (SC41-5606-12), IBM (PDF). Définition de l'ILE et ses compilateurs ; les avantages (liaison et appel lié plus rapide, modularité, composants réutilisables, coexistence avec l'OPM, débogueur source) ; OPM puis EPM en V1R2 ; liaison par copie et par référence ; répertoires de liage ; groupes d'activation ; signature et langage de liage.
- Integrated Language Environment, Wikipédia (en anglais). Annonce de l'ILE le 16 février 1993, avec la V2R3 d'OS/400.
- ILE RPG Reference (SC09-2508-12), IBM, IBM i 7.5 (PDF). EXTPROC : nom externe dans la casse indiquée ; sans EXTPROC, le nom du prototype en majuscules.
- ILE RPG Programmer's Guide (SC09-2507-12), IBM, IBM i 7.5 (PDF). CRTBNDRPG crée un module temporaire puis le lie ; DFTACTGRP(*YES) assure la compatibilité OPM et interdit ACTGRP et BNDDIR.
- Create Program (CRTPGM), IBM, IBM i 7.5 CL commands. MODULE, ENTMOD, BNDSRVPGM, BNDDIR ; ACTGRP(*ENTMOD) qui donne QILE pour un module d'entrée RPGLE, CBLLE ou CLLE.
- Create Service Program (CRTSRVPGM), IBM, IBM i 7.5 CL commands. Création d'un programme de service à partir de modules et d'un source de liage (EXPORT).
- Update Service Program (UPDSRVPGM), IBM, IBM i 7.5 CL commands. Remplacer un module dans un programme de service existant.
- Create C Module (CRTCMOD), IBM, IBM i 7.5 CL commands. La compilation du module C.
- Create Binding Directory (CRTBNDDIR), IBM, IBM i 7.5 CL commands. Le répertoire de liage OUTILS.
Questions fréquentes
Qu'est-ce que l'ILE sur IBM i ?
L'Integrated Language Environment est le modèle de programmes d'IBM i dans lequel un compilateur produit un module (*MODULE), et non un programme. On assemble (on lie) ensuite un ou plusieurs modules, éventuellement écrits dans des langages différents, en un programme (*PGM) ou en un programme de service (*SRVPGM). Les compilateurs ILE sont ceux de RPG, COBOL, C, C++ et CL.
Quelle différence entre un programme et un programme de service ?
Un programme (*PGM) a une procédure d'entrée et s'appelle par CALL. Un programme de service (*SRVPGM) n'a pas de procédure d'entrée : il met des procédures à disposition d'autres programmes, qui s'y lient par référence. Le modifier ne demande pas de recompiler les programmes qui l'utilisent, tant que sa liste d'exportations reste compatible (nouvelles procédures ajoutées à la fin).
Qu'est-ce qu'un répertoire de liage ?
Un objet *BNDDIR qui liste des modules et des programmes de service. On le cite au liage (BNDDIR de CRTPGM, CRTBNDRPG ou de CTL-OPT) au lieu de citer chaque objet : le binder y prend ce qui résout les procédures appelées.
Comment appeler une fonction C depuis du RPG ?
Avec un prototype DCL-PR dont EXTPROC donne le nom exact de la fonction, en respectant la casse : EXTPROC('cleControle'). Sans EXTPROC, RPG cherche le nom du prototype en majuscules. Un paramètre CHAR CONST passé par référence arrive en C comme un const char *.
Faut-il recompiler un programme quand on modifie un module ?
Si le module a été copié dans le programme (CRTPGM MODULE), il faut relier le programme, par exemple avec UPDPGM. S'il est dans un programme de service, on met à jour le programme de service (UPDSRVPGM) et les programmes qui s'y lient prennent la nouvelle version à leur prochaine activation, sans être recompilés, si les exportations n'ont pas changé.