npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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.mk files
  • 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/codermake

Quick Start

1. Set up environment variables

On IBM i (local build):

export BUILD_LIBRARY=DEVLIB

On 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  # Optional

Multi-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.dspf

3. Build

codermake

Rules.mk Syntax

Basic Rule Format

target: prerequisites

Supported 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 .file target)
  • .msgf - Message file CL commands (when first prerequisite of .msgf target)
  • .bnddir - Binding directory CL commands (when first prerequisite of .bnddir target)
  • .exports or .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.rpgle

Service Program:

mymod.module: source.rpgle
mysrvpgm.srvpgm: mymod.module myexports.exports

# Without export list (exports all procedures via EXPORT(*ALL)):
mysrvpgm.srvpgm: mymod.module

Program 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.srvpgm

Note: 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.json

CL Programs:

# ILE CL
hellocl.pgm: hellocl.clle

# OPM CL
simpgm.pgm: simpgm.clp

# CL Module
mathmod.module: mathmod.clle
mathpgm.pgm: mathmod.module

Printer File:

helloprt.file: helloprt.prtf

SQL 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.file

Order-Only Prerequisites:

mypgm.pgm: source.rpgle | mybnddir.bnddir

Order-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:

codermake

Build specific target:

codermake hellor.pgm

Parallel build:

codermake -j4

Dry run:

codermake -n

Clean:

codermake clean

Debug preprocessing:

codermake --print-rules

Project 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=auto

CODERMAKE_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.srvpgm

The 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.rpgle

Optional: 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

  1. Platform Detection: Detects IBM i vs Unix-like system
  2. Rules Discovery: Finds all Rules.mk files in subdirectories (flat or multi-library layout)
  3. Preprocessing: Transforms simplified rules into full GNU Make syntax
  4. Recipe Inference: Automatically determines build recipes from file extensions
  5. 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