@profoundlogic/codermake
v2.0.5
Published
Make wrapper framework for IBM i development that simplifies build rules
Downloads
1,786
Readme
codermake
A make wrapper framework for IBM i development that simplifies build rules and abstracts platform-specific complexity.
Features
- Simplified Rules: Write clean, maintainable build rules in
Rules.mkfiles - Platform Agnostic: Same rules work on IBM i and Unix-like systems (Linux, macOS, FreeBSD, etc.)
- Automatic Discovery: Automatically finds and processes Rules.mk files in your project
- Recipe Inference: Automatically determines build recipes based on file extensions
- Remote Builds: Build from Unix-like systems to IBM i via SSH
Installation
npm install -g @profoundlogic/codermakeQuick Start
1. Set up environment variables
On IBM i (local build):
export BUILD_LIBRARY=DEVLIBOn Unix-like systems (remote build via SSH):
export IBMI_BUILD_LIBRARY=DEVLIB
export IBMI_HOST=ibmi.example.com
export IBMI_USER=devuser
export IBMI_KEY=/path/to/ssh/key # OptionalMulti-library output mode (alternative to BUILD_LIBRARY / IBMI_BUILD_LIBRARY, requires multi-library layout):
# Map source-tree library directories to IBM i libraries
export CODERMAKE_LIBRARY_MAP="LIBA=APPLIBA LIBB=APPLIBB"
# Or use the natural mapping (LIBA → LIBA, LIBB → LIBB)
export CODERMAKE_LIBRARY_MAP=auto
# Optional: replace the user portion of the IBM i library list at build time
export CODERMAKE_LIBRARY_LIST="APPLIBA APPLIBB"CODERMAKE_LIBRARY_MAP is mutually exclusive with BUILD_LIBRARY / IBMI_BUILD_LIBRARY. See Multi-library output below.
2. Create a Rules.mk file
Create src/Rules.mk:
# Simple program with display file
hellor.pgm: hellor.rpgle hellod.file
# Display file
hellod.file: hellod.dspf3. Build
codermakeRules.mk Syntax
Basic Rule Format
target: prerequisitesSupported File Types
Output Objects:
.pgm- Program.module- Module.srvpgm- Service Program.file- File (display, physical, logical, printer, SQL table/index/view).menu- Menu.msgf- Message File.bnddir- Binding Directory
Source Files:
.rpgle- ILE RPG source.sqlrpgle- SQL RPG source.clle- ILE CL source.cl- OPM CL source.clp- OPM CL source (alternate).dspf- Display file DDS.pf- Physical file DDS.lf- Logical file DDS.prtf- Printer file DDS.table.sql- SQL table definition.index.sql- SQL index definition.view.sql- SQL view definition.proc.sql- SQL procedure definition.json- Rich Display File (RDF) JSON (when first prerequisite of.filetarget).msgf- Message file CL commands (when first prerequisite of.msgftarget).bnddir- Binding directory CL commands (when first prerequisite of.bnddirtarget).exportsor.bnd- Service program export list
Note: .msgf and .bnddir files serve dual purposes:
- As source: When appearing as the first normal prerequisite of a matching target type (e.g.,
app.msgf: app.msgf) - As object: In all other contexts (e.g., as prerequisites of other target types or non-first prerequisites)
Examples
Simple Program:
mypgm.pgm: source.rpgleService Program:
mymod.module: source.rpgle
mysrvpgm.srvpgm: mymod.module myexports.exports
# Without export list (exports all procedures via EXPORT(*ALL)):
mysrvpgm.srvpgm: mymod.moduleProgram from Modules (with automatic binding):
calc.module: calc.rpgle
calc.pgm: calc.module utils.srvpgm # BNDSRVPGM(utils) added automatically
calcd.pgm: calcd.module | app.bnddir # BNDDIR(app) added automatically.srvpgm and .bnddir prerequisites work as either normal or order-only; the automatic BNDSRVPGM()/BNDDIR() parameters are generated either way. This only applies to module-based programs (CRTPGM/CRTSRVPGM), not source-based programs (e.g., CRTBNDRPG).
Program with Dependencies:
hellor.pgm: hellor.rpgle hellod.file custr.srvpgmNote: This is a source-based program (CRTBNDRPG), so custr.srvpgm is a build-ordering dependency only — no BNDSRVPGM() parameter is generated. Binding is typically handled via a BNDDIR control specification in the RPG source.
Rich Display File from JSON:
mydisplay.file: mydisplay.jsonCL Programs:
# ILE CL
hellocl.pgm: hellocl.clle
# OPM CL
simpgm.pgm: simpgm.clp
# CL Module
mathmod.module: mathmod.clle
mathpgm.pgm: mathmod.modulePrinter File:
helloprt.file: helloprt.prtfSQL Objects:
employee.file: employee.table.sql
empview.file: empview.view.sql employee.file
empname.file: empname.index.sql employee.file
getcount.pgm: getcount.proc.sql employee.fileOrder-Only Prerequisites:
mypgm.pgm: source.rpgle | mybnddir.bnddirOrder-only prerequisites must exist before building the target but do not trigger a rebuild when they change. Note: for source-based programs like the above (CRTBNDRPG), no automatic BNDDIR() parameter is generated — the binding directory is typically specified via a BNDDIR control specification in the RPG source instead.
Command-Line Options
codermake [options] [targets...]Options
--help- Show help message--version- Show version--debug- Enable debug output--print-rules- Print preprocessed rules and exit--print-makefile- Generate standalone Makefile for debugging--license-show- Show license status--license-set=<key>- Install a license key
All other options are passed through to GNU Make. See make --help for additional options.
Examples
Build all targets:
codermakeBuild specific target:
codermake hellor.pgmParallel build:
codermake -j4Dry run:
codermake -nClean:
codermake cleanDebug preprocessing:
codermake --print-rulesProject Structure
Flat layout
project/
├── src1/
│ ├── Rules.mk # Build rules for src1/
│ ├── hellor.rpgle
│ └── hellod.dspf
├── src2/
│ ├── Rules.mk # Build rules for src2/
│ └── custr.rpgle
|── tmp/ # Build outputs (gitignored)
| └── logs/ # Compiler output logs
└── build/ # Dummy IBM i objects (Unix-type systems only, gitignored)Multi-library layout
For large IBM i codebases organized by library, a two-level directory structure is supported. Library-equivalent directories contain traditional source-file directories:
project/
├── LIBA/
│ ├── qrpglesrc/
│ │ ├── Rules.mk # Source-file-level Rules.mk
│ │ └── mypgm.rpgle
│ └── qddssrc/
│ ├── Rules.mk
│ └── myscreen.dspf
├── LIBB/
│ ├── Rules.mk # Library-level Rules.mk (also supported)
│ └── qrpglesrc/
│ └── otherpgm.rpgle
├── tmp/
└── build/Rules.mk can be placed at either the library level or source-file level. Multi-library layout is auto-detected when either (a) any Rules.mk exists at depth 2, or (b) a depth-1 Rules.mk dir contains subdirectories (the typical IBM i library layout, with source-file subdirs like qrpglesrc/, qddssrc/).
For library-level Rules.mk files, paths like qrpglesrc/mypgm.rpgle are automatically prefixed with the library directory. Cross-library references (paths starting with another library's directory name) pass through unchanged.
By default a multi-library project still builds into a single output library (set via BUILD_LIBRARY / IBMI_BUILD_LIBRARY). To build each source-tree library directory into its own IBM i output library, see Multi-library output below.
Multi-library output
When the project has a multi-library layout, CODERMAKE_LIBRARY_MAP enables per-library output:
export CODERMAKE_LIBRARY_MAP="LIBA=APPLIBA LIBB=APPLIBB"Each library-equivalent source directory builds into the IBM i library named on the right side of =. The sentinel value auto enables a "natural" mapping where each directory maps to a library of the same name:
export CODERMAKE_LIBRARY_MAP=autoCODERMAKE_LIBRARY_MAP is mutually exclusive with BUILD_LIBRARY / IBMI_BUILD_LIBRARY. Setting both, or neither, is an error. Setting CODERMAKE_LIBRARY_MAP on a flat-layout project is also an error.
Cross-library object references
In multi-library output mode, a Rules.mk in one library can refer to objects produced by another library using the qualifier syntax <libraryDir>/<bareobj>.<ext>:
# In LIBA/qrpglesrc/Rules.mk
crossbnd.pgm: crossbnd.rpgle | LIBB/utils.srvpgmThe qualifier works on both prerequisites and targets. Source files in another library still use the existing 3-segment form (LIBB/qcpysrc/shared.rpgle).
A target can also be qualified to redirect the output library — useful when a single source tree compiles into multiple deployment libraries:
# Source in LIBA's tree, output goes to LIBB
LIBB/installer.pgm: installer.rpgleOptional: control the IBM i library list at build time
CODERMAKE_LIBRARY_LIST (only valid with CODERMAKE_LIBRARY_MAP) replaces the user portion of the IBM i library list with the listed libraries in declared order:
export CODERMAKE_LIBRARY_LIST="APPLIBA APPLIBB"This is useful when BNDSRVPGM() and BNDDIR() parameters need to resolve unambiguously across mapped libraries. Unqualified service-program and binding-directory references resolve via the library list at bind/runtime, by design — this preserves the developer workflow of placing a private library copy higher on the runtime liblist to override without rebuilding.
When CODERMAKE_LIBRARY_LIST is not set, codermake leaves the build job's library list untouched (whatever the job description / profile inherits).
Portability across modes
The same Rules.mk works in both single-library output mode (BUILD_LIBRARY / IBMI_BUILD_LIBRARY) and multi-library output mode (CODERMAKE_LIBRARY_MAP). In single-library mode, qualifier syntax collapses to the single output library — useful for containerized agentic builds that use one disposable library while the production IBM i build uses per-library output.
RPG /COPY resolution in multi-library projects
Set CODERMAKE_INCLUDE_PATH to control the search order for unqualified /COPY and /INCLUDE member-style references:
export CODERMAKE_INCLUDE_PATH="LIBA LIBB LIBC"Library-qualified references (e.g., /COPY LIBB/QCPYSRC,MEMBER) resolve directly regardless of this setting.
How It Works
- Platform Detection: Detects IBM i vs Unix-like system
- Rules Discovery: Finds all
Rules.mkfiles in subdirectories (flat or multi-library layout) - Preprocessing: Transforms simplified rules into full GNU Make syntax
- Recipe Inference: Automatically determines build recipes from file extensions
- Execution: Invokes GNU make with generated rules
RPG /COPY and /INCLUDE Preprocessing
codermake automatically handles legacy RPG /COPY and /INCLUDE directives written in source member style. Source member references are converted to IFS stream file paths during compilation, allowing the same source to work in both source member and stream file environments.
See design/RPG_COPY_PREPROCESSING.md for details.
Requirements
- Node.js: >= 22.0.0
- GNU Make: >= 4.0
- SSH: For remote builds from Unix-like to IBM i
Author
Profound Logic Software
