Richard,
As far as 'make' scripts go, we use them extensively here, for all our hand-coded development (RPG, CL, PL/I, etc.)...
As an example, we have a file called QCMPSRC that contains one member per compile command. So for instance, there is an RPGLE member in there called CRTBNDRPG which has the following in it:
[font=Courier New]H*
H* This is an external source member which is referenced with an X*
H* compile preprocessor flag in each RPGLE source member which should
H* compiled as a *PGM using the CRTBNDRPG command. Any defaults
H* specified here will be overridden using Z* compile preprocessor
H* lines appearing after the X* line which references this member.
H*
Z* CRTBNDRPG
Z* DBGVIEW(*SOURCE)
Z* CVTOPT(*DATETIME)
Z* OPTION(*NODEBUGIO)
Z* DFTACTGRP(*NO)
Z* ACTGRP(*CALLER)
Z* BNDDIR(QC2LE Y1BNDDIR)
[font]
Then, every RPGLE source member that should be compiled as a bound program simply contains the following compile preprocessor (CP) directive:
[font=Courier New]X* QCMPSRC,CRTBNDRPG[font]
and it will be compiled using the defaults in the CRTBNDRPG member. Of course, a specific member which wants to use slightly different defaults might contain the following
[font=Courier New]X* QCMPSRC,CRTBNDRPG
Z* ACTGRP(TESTACTGRP)
[font]
Additionally, we have a file called QSRVSRC which contains one member per service program. So for instance, there is a member called YGNRPRCS1R which has the following:
[font=Courier New]/*X: QCMPSRC,CRTSRVPGM */
/*Y: SRVPGM(&L/&E) + */
/*Y: MODULE(YGNRPRC + */
/*Y: YCHKOBJC + */
/*Y: YSYSVALR + */
/*Y: YSPCCHRR + */
/*Y: YSPDLUMX + */
/*Y: YSPDLUMR) + */
/*Y: BNDDIR(QC2LE Y1BNDDIR) + */
/*Y: TEXT('Generic procedures (I)') */
STRPGMEXP LVLCHK(*NO)
EXPORT SYMBOL(@generic) /* Proc */
EXPORT SYMBOL(@unspec) /* Proc */
EXPORT SYMBOL(@binary) /* Proc */
EXPORT SYMBOL(@max) /* Proc */
...
[font]
In each of the constituent modules, there are the following lines:
[font=Courier New]X* QCMPSRC,CRTRPGMOD
X* QSRVSRC,YGNRPRCS1R
[font]
In this case, whenever any one of the modules that are bound into the YGNRPRCS1R service program is recompiled, it uses the defaults from the CRTRPGMOD member in QCMPSRC to compile the module and then a copy of the YGNRPRCS1R service program is created (in the same library as the module) using the defaults from the CRTSRVPGM member in QCMPSRC plus the specific information in the Y* CP directives in the YGNRPRCS1R member in QSRVSRC...
Easy, eh?
You can get pretty fancy, with nested CP directives and stuff like that.
As far as including all this stuff with 2E, there is a document which describes how to create EXCUSRSRC which includes multiple CP directives. You should be able to get it from Support, or it is (I believe) included in the r8.5 User Guide.
Rory