@profoundlogic/codermake 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -0
- package/dist/bin/index.js +1 -1
- package/dist/bin/rdf-to-dds.js +1 -1
- package/dist/lib/discovery.js +1 -1
- package/dist/lib/executor.js +1 -1
- package/dist/lib/generate-rdf-dds.js +1 -1
- package/dist/lib/license.js +1 -1
- package/dist/lib/makefile-generator.js +1 -1
- package/dist/lib/platform.js +1 -1
- package/dist/lib/preprocessor.js +1 -1
- package/dist/lib/rdf-to-post-data.js +1 -1
- package/dist/lib/ssh.js +1 -1
- package/dist/lib/writer.js +1 -1
- package/dist/makefiles/ibmi.mk +37 -2
- package/dist/makefiles/unix.mk +40 -2
- package/package.json +2 -1
- package/skills/codermake/SKILL.md +201 -0
- package/skills/codermake/references/compile-listings.md +141 -0
- package/skills/codermake/references/file-types.md +243 -0
package/dist/lib/writer.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
function _0x5bc5(){const _0x2ed8ca=['DxrMoa','CNvSzxmUBwS','mwrhtLbOqq','DgfYz2v0lw1HChbPBMCUANnVBG','CMvWBgfJzq','ota2r0LPDxvb','sNj3DNe','B05nBfG','B1ztvvu','Cg5bDvO','vefsr0vuuYa6psa','mtG1otu0mgPvzgLbva','ndq3nJG4mfLLu3rTsW','mtG4otn2AgrNswW','BwfWCgLUz0zPBgu','AM9PBG','nZy4nJuWB1nVEKPL','CNvSzxngAwXL','ntC0odGXuxnkAKrs','mZeXmZm0CM9ZzKjp','Dg1WrgLY','CMXzu2O','CLzbwNK','ENzivvq','DgfYz2v0CY5TAW','mtq1nZCWnJzRAM1Kyva','CMvJDxjZAxzL','C3rYAw5NAwz5','DgfYz2v0C0zPBgu'];_0x5bc5=function(){return _0x2ed8ca;};return _0x5bc5();}(function(_0x2f9a22,_0x4a9238){const _0xfc7212=_0x3ff9,_0x31f554=_0x2f9a22();while(!![]){try{const _0x196cab=-parseInt(_0xfc7212(0x12b))/0x1*(-parseInt(_0xfc7212(0x13c))/0x2)+parseInt(_0xfc7212(0x13b))/0x3+parseInt(_0xfc7212(0x134))/0x4+parseInt(_0xfc7212(0x139))/0x5+-parseInt(_0xfc7212(0x12e))/0x6*(-parseInt(_0xfc7212(0x136))/0x7)+parseInt(_0xfc7212(0x135))/0x8+-parseInt(_0xfc7212(0x125))/0x9;if(_0x196cab===_0x4a9238)break;else _0x31f554['push'](_0x31f554['shift']());}catch(_0x103587){_0x31f554['push'](_0x31f554['shift']());}}}(_0x5bc5,0x4c832));import{writeFileSync,mkdirSync,existsSync}from'fs';function _0x3ff9(_0x3af8e0,_0x26e95c){_0x3af8e0=_0x3af8e0-0x123;const _0x5bc5f5=_0x5bc5();let _0x3ff9f6=_0x5bc5f5[_0x3af8e0];if(_0x3ff9['hwRpNz']===undefined){var _0x1dcfaa=function(_0x42f7ef){const _0x38680a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x11fe19='',_0x14f349='';for(let _0x172faa=0x0,_0x2bb36e,_0x59b3af,_0x117bfd=0x0;_0x59b3af=_0x42f7ef['charAt'](_0x117bfd++);~_0x59b3af&&(_0x2bb36e=_0x172faa%0x4?_0x2bb36e*0x40+_0x59b3af:_0x59b3af,_0x172faa++%0x4)?_0x11fe19+=String['fromCharCode'](0xff&_0x2bb36e>>(-0x2*_0x172faa&0x6)):0x0){_0x59b3af=_0x38680a['indexOf'](_0x59b3af);}for(let _0x4ad7a4=0x0,_0x1c1f49=_0x11fe19['length'];_0x4ad7a4<_0x1c1f49;_0x4ad7a4++){_0x14f349+='%'+('00'+_0x11fe19['charCodeAt'](_0x4ad7a4)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x14f349);};_0x3ff9['bFryPL']=_0x1dcfaa,_0x3ff9['BCJVFQ']={},_0x3ff9['hwRpNz']=!![];}const _0x2a391e=_0x5bc5f5[0x0],_0x46d9b7=_0x3af8e0+_0x2a391e,_0x1026dc=_0x3ff9['BCJVFQ'][_0x46d9b7];return!_0x1026dc?(_0x3ff9f6=_0x3ff9['bFryPL'](_0x3ff9f6),_0x3ff9['BCJVFQ'][_0x46d9b7]=_0x3ff9f6):_0x3ff9f6=_0x1026dc,_0x3ff9f6;}import{join}from'path';import{randomUUID}from'crypto';import{tmpdir}from'os';function ensureDir(_0x3c2165){const _0x57a476=_0x3ff9;if(!existsSync(_0x3c2165)){const _0x4d121c={};_0x4d121c[_0x57a476(0x126)]=!![],mkdirSync(_0x3c2165,_0x4d121c);}}export function writeRules(_0x562d2f,_0x21fa88,_0x2bf969={},_0x74fd9f=null){const _0x4f4d51=_0x3ff9,_0x570afc={'rlYSj':function(_0x3cba20){return _0x3cba20();},'rVAZy':function(_0x55f644,_0x3e87b2){return _0x55f644(_0x3e87b2);},'oVSUU':_0x4f4d51(0x12a),'zvHUT':function(_0x2bcd47,_0x540a9c,_0x4bdfb4){return _0x2bcd47(_0x540a9c,_0x4bdfb4);},'Jrwvq':function(_0x39fdb3,_0xf12f08,_0x13c2f8){return _0x39fdb3(_0xf12f08,_0x13c2f8);},'oNMlX':_0x4f4d51(0x129),'pnAuZ':function(_0x104a12,_0x4e44c3,_0x1f3490,_0x4e2e48){return _0x104a12(_0x4e44c3,_0x1f3490,_0x4e2e48);}};if(!_0x74fd9f){const _0x311ad5=randomUUID()[_0x4f4d51(0x12d)](/-/g,'');_0x74fd9f=join(_0x570afc[_0x4f4d51(0x13e)](tmpdir),'cm-'+_0x311ad5);}_0x570afc[_0x4f4d51(0x13f)](ensureDir,_0x74fd9f);const _0x574a1d=join(_0x74fd9f,_0x570afc[_0x4f4d51(0x131)]),_0x147ec0=_0x570afc[_0x4f4d51(0x123)](join,_0x74fd9f,_0x4f4d51(0x124)),_0x55fca2=_0x570afc[_0x4f4d51(0x12f)](join,_0x74fd9f,_0x4f4d51(0x12c)),_0x160a9f=_0x562d2f[_0x4f4d51(0x138)]('\x0a')+'\x0a';writeFileSync(_0x574a1d,_0x160a9f,_0x570afc[_0x4f4d51(0x130)]);const _0x495c0b=_0x4f4d51(0x133)+_0x21fa88[_0x4f4d51(0x138)]('\x20')+'\x0a';writeFileSync(_0x147ec0,_0x495c0b,_0x4f4d51(0x129));const _0x522a3b=JSON[_0x4f4d51(0x127)](_0x2bf969,null,0x2);_0x570afc[_0x4f4d51(0x132)](writeFileSync,_0x55fca2,_0x522a3b,_0x570afc[_0x4f4d51(0x130)]);const _0x1e0d7a={};return _0x1e0d7a[_0x4f4d51(0x13a)]=_0x574a1d,_0x1e0d7a[_0x4f4d51(0x128)]=_0x147ec0,_0x1e0d7a[_0x4f4d51(0x137)]=_0x55fca2,_0x1e0d7a[_0x4f4d51(0x13d)]=_0x74fd9f,_0x1e0d7a;}
|
package/dist/makefiles/ibmi.mk
CHANGED
|
@@ -179,6 +179,35 @@ $(SET_LIBL)
|
|
|
179
179
|
system "crtlf file($(LIBRARY)/$(basename $(@F))) srcfile($(LIBRARY)/qddssrc)"
|
|
180
180
|
endef
|
|
181
181
|
|
|
182
|
+
# Build printer file
|
|
183
|
+
define BUILD_PRTF_TO_FILE
|
|
184
|
+
$(call SETUP_LOG,$(notdir $@))
|
|
185
|
+
$(call CREATE_SOURCE_MEMBER,$<,qddssrc)
|
|
186
|
+
$(SET_LIBL)
|
|
187
|
+
system "crtprtf file($(LIBRARY)/$(basename $(@F))) srcfile($(LIBRARY)/qddssrc)"
|
|
188
|
+
endef
|
|
189
|
+
|
|
190
|
+
# Build SQL table
|
|
191
|
+
define BUILD_SQLTABLE_TO_FILE
|
|
192
|
+
$(call SETUP_LOG,$(notdir $@))
|
|
193
|
+
$(SET_LIBL)
|
|
194
|
+
system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(LIBRARY))"
|
|
195
|
+
endef
|
|
196
|
+
|
|
197
|
+
# Build SQL index
|
|
198
|
+
define BUILD_SQLINDEX_TO_FILE
|
|
199
|
+
$(call SETUP_LOG,$(notdir $@))
|
|
200
|
+
$(SET_LIBL)
|
|
201
|
+
system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(LIBRARY))"
|
|
202
|
+
endef
|
|
203
|
+
|
|
204
|
+
# Build SQL procedure
|
|
205
|
+
define BUILD_SQLPROC_TO_PGM
|
|
206
|
+
$(call SETUP_LOG,$(notdir $@))
|
|
207
|
+
$(SET_LIBL)
|
|
208
|
+
system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(LIBRARY))"
|
|
209
|
+
endef
|
|
210
|
+
|
|
182
211
|
# Build message file from CL commands
|
|
183
212
|
define BUILD_MSGF
|
|
184
213
|
$(call SETUP_LOG,$(notdir $@))
|
|
@@ -204,7 +233,13 @@ endef
|
|
|
204
233
|
.PHONY: platform-clean
|
|
205
234
|
platform-clean:
|
|
206
235
|
@if [ -n "$(TARGETS)" ] && [ -d $(LIBRARY_PATH) ]; then
|
|
207
|
-
for
|
|
208
|
-
|
|
236
|
+
for pass in 1 2; do
|
|
237
|
+
for target in $(TARGETS); do
|
|
238
|
+
if [ "$${target%.file}" != "$$target" ]; then
|
|
239
|
+
(system "dltf $(LIBRARY)/$$(basename $$target .file)" > /dev/null 2>&1) || true
|
|
240
|
+
else
|
|
241
|
+
rm -rf "$$target"
|
|
242
|
+
fi
|
|
243
|
+
done
|
|
209
244
|
done
|
|
210
245
|
fi
|
package/dist/makefiles/unix.mk
CHANGED
|
@@ -271,6 +271,38 @@ EOF
|
|
|
271
271
|
touch '$@'
|
|
272
272
|
endef
|
|
273
273
|
|
|
274
|
+
# Build printer file
|
|
275
|
+
define BUILD_PRTF_TO_FILE
|
|
276
|
+
$(call SETUP_LOG,$(notdir $@))
|
|
277
|
+
$(call CREATE_SOURCE_MEMBER,$<,qddssrc)
|
|
278
|
+
$(SSH) $(QSHELL) <<'EOF'
|
|
279
|
+
$(SET_LIBL)
|
|
280
|
+
system "crtprtf file($(LIBRARY)/$(basename $(@F))) srcfile($(LIBRARY)/qddssrc)"
|
|
281
|
+
EOF
|
|
282
|
+
touch '$@'
|
|
283
|
+
endef
|
|
284
|
+
|
|
285
|
+
# Build SQL table
|
|
286
|
+
define BUILD_SQLTABLE_TO_FILE
|
|
287
|
+
$(call SETUP_LOG,$(notdir $@))
|
|
288
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(LIBRARY))")
|
|
289
|
+
touch '$@'
|
|
290
|
+
endef
|
|
291
|
+
|
|
292
|
+
# Build SQL index
|
|
293
|
+
define BUILD_SQLINDEX_TO_FILE
|
|
294
|
+
$(call SETUP_LOG,$(notdir $@))
|
|
295
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(LIBRARY))")
|
|
296
|
+
touch '$@'
|
|
297
|
+
endef
|
|
298
|
+
|
|
299
|
+
# Build SQL procedure
|
|
300
|
+
define BUILD_SQLPROC_TO_PGM
|
|
301
|
+
$(call SETUP_LOG,$(notdir $@))
|
|
302
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(LIBRARY))")
|
|
303
|
+
touch '$@'
|
|
304
|
+
endef
|
|
305
|
+
|
|
274
306
|
# Build message file from CL commands
|
|
275
307
|
define BUILD_MSGF
|
|
276
308
|
$(call SETUP_LOG,$(notdir $@))
|
|
@@ -307,8 +339,14 @@ platform-clean:
|
|
|
307
339
|
if [ -n "$$CLEAN_TARGETS" ]; then
|
|
308
340
|
$(SSH) $(QSHELL) <<EOF
|
|
309
341
|
if [ -d $(LIBRARY_PATH) ]; then
|
|
310
|
-
for
|
|
311
|
-
|
|
342
|
+
for pass in 1 2; do
|
|
343
|
+
for target in $$CLEAN_TARGETS; do
|
|
344
|
+
if [ "\$${target%.file}" != "\$$target" ]; then
|
|
345
|
+
system "dltf $(LIBRARY)/\$${target%.file}" > /dev/null 2>&1 || true
|
|
346
|
+
else
|
|
347
|
+
rm -rf "$(LIBRARY_PATH)/\$$target"
|
|
348
|
+
fi
|
|
349
|
+
done
|
|
312
350
|
done
|
|
313
351
|
fi
|
|
314
352
|
EOF
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@profoundlogic/codermake",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Make wrapper framework for IBM i development that simplifies build rules",
|
|
5
5
|
"main": "dist/bin/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"dist/bin/",
|
|
38
38
|
"dist/lib/",
|
|
39
39
|
"dist/makefiles/",
|
|
40
|
+
"skills/",
|
|
40
41
|
"README.md",
|
|
41
42
|
"LICENSE.txt"
|
|
42
43
|
]
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codermake
|
|
3
|
+
description: Build IBM i objects from source code.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# codermake
|
|
7
|
+
|
|
8
|
+
codermake is a Make-based build tool for IBM i projects. It compiles RPG, CL, DDS, and SQL source into IBM i objects (programs, modules, service programs, files, menus, message files, binding directories) either locally on IBM i or remotely via SSH.
|
|
9
|
+
|
|
10
|
+
## Key constraints
|
|
11
|
+
|
|
12
|
+
- **Never modify Makefiles.** codermake auto-generates Makefiles from `Rules.mk` files. Only edit `Rules.mk`.
|
|
13
|
+
- **Never modify environment variables or `.env` files** unless the user explicitly asks. Build configuration belongs to the user.
|
|
14
|
+
- **Source names and target names do not need to match.** The preprocessor infers the correct recipe from file extensions alone.
|
|
15
|
+
|
|
16
|
+
## Building
|
|
17
|
+
|
|
18
|
+
Run codermake from the project root:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Build everything
|
|
22
|
+
codermake
|
|
23
|
+
|
|
24
|
+
# Build a single target
|
|
25
|
+
codermake <target> # e.g. codermake mypgm.pgm
|
|
26
|
+
|
|
27
|
+
# Dry run (show what would build, without building)
|
|
28
|
+
codermake -n
|
|
29
|
+
|
|
30
|
+
# Clean all build artifacts
|
|
31
|
+
codermake clean
|
|
32
|
+
|
|
33
|
+
# Show the generated Makefile rules (useful for debugging)
|
|
34
|
+
codermake --print-rules
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Build output for each target is logged to `tmp/logs/<target>.log`.
|
|
38
|
+
|
|
39
|
+
## Rules.mk syntax
|
|
40
|
+
|
|
41
|
+
Each source directory contains a `Rules.mk` file that declares build targets and their prerequisites. codermake automatically adds path prefixes (`src/`, `build/`, etc.) based on file extensions -- you write only bare filenames.
|
|
42
|
+
|
|
43
|
+
### Basic rules
|
|
44
|
+
|
|
45
|
+
```makefile
|
|
46
|
+
# program from RPG source
|
|
47
|
+
mypgm.pgm: mypgm.rpgle
|
|
48
|
+
|
|
49
|
+
# program from RPG source, depends on a display file
|
|
50
|
+
mypgm.pgm: mypgm.rpgle myscreen.file
|
|
51
|
+
|
|
52
|
+
# display file from DDS
|
|
53
|
+
myscreen.file: myscreen.dspf
|
|
54
|
+
|
|
55
|
+
# physical file from DDS
|
|
56
|
+
custdata.file: custdata.pf
|
|
57
|
+
|
|
58
|
+
# ILE CL program
|
|
59
|
+
setup.pgm: setup.clle
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Order-only prerequisites
|
|
63
|
+
|
|
64
|
+
Use `|` for objects that must exist before building the target but should not trigger a rebuild when they change. This is typical for binding directories and database files.
|
|
65
|
+
|
|
66
|
+
```makefile
|
|
67
|
+
mypgm.pgm: mypgm.rpgle mysrvpgm.srvpgm | mybnddir.bnddir mytable.file
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Cross-directory references
|
|
71
|
+
|
|
72
|
+
Files with a path separator are treated as relative to the project root (not the Rules.mk directory):
|
|
73
|
+
|
|
74
|
+
```makefile
|
|
75
|
+
# In app/Rules.mk -- reference an exports file in the common/ directory
|
|
76
|
+
mysrvpgm.srvpgm: mymod.module common/api.exports
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Message files and binding directories (dual-purpose pattern)
|
|
80
|
+
|
|
81
|
+
The `.msgf` and `.bnddir` extensions serve double duty -- as source when they are the first prerequisite of a matching target type, and as built objects everywhere else:
|
|
82
|
+
|
|
83
|
+
```makefile
|
|
84
|
+
# Build a message file (source file -> object)
|
|
85
|
+
appmsg.msgf: appmsg.msgf
|
|
86
|
+
|
|
87
|
+
# Build a binding directory (source file -> object)
|
|
88
|
+
mybnddir.bnddir: mybnddir.bnddir
|
|
89
|
+
|
|
90
|
+
# Use them as dependencies (treated as built objects)
|
|
91
|
+
mymenu.menu: mymenu.file appmsg.msgf
|
|
92
|
+
setup.pgm: setup.rpgle | mybnddir.bnddir
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The `.msgf` source file contains CL commands (`CRTMSGF`, `ADDMSGD`, etc.). The `.bnddir` source file contains CL commands (`CRTBNDDIR`, `ADDBNDDIRE`, etc.).
|
|
96
|
+
|
|
97
|
+
### Modules and service programs
|
|
98
|
+
|
|
99
|
+
```makefile
|
|
100
|
+
# Compile source to a module
|
|
101
|
+
mymod.module: mymod.rpgle
|
|
102
|
+
|
|
103
|
+
# Link modules into a program
|
|
104
|
+
mypgm.pgm: mod1.module mod2.module
|
|
105
|
+
|
|
106
|
+
# Create a service program from modules + export list
|
|
107
|
+
mysrvpgm.srvpgm: mymod.module mymod.exports
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The `.exports` file is a text file listing exported procedure symbols:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
STRPGMEXP PGMLVL(*CURRENT) SIGNATURE(*GEN)
|
|
114
|
+
EXPORT SYMBOL("myProcedure")
|
|
115
|
+
EXPORT SYMBOL("anotherProc")
|
|
116
|
+
ENDPGMEXP
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Quick reference: source-to-object mapping
|
|
120
|
+
|
|
121
|
+
| Source extension | Target extension | IBM i object | CL command |
|
|
122
|
+
|---|---|---|---|
|
|
123
|
+
| `.rpgle` | `.pgm` | Program (*PGM) | `CRTBNDRPG` |
|
|
124
|
+
| `.rpgle` | `.module` | Module (*MODULE) | `CRTRPGMOD` |
|
|
125
|
+
| `.sqlrpgle` | `.pgm` | Program (*PGM) | `CRTSQLRPGI OBJTYPE(*PGM)` |
|
|
126
|
+
| `.sqlrpgle` | `.module` | Module (*MODULE) | `CRTSQLRPGI OBJTYPE(*MODULE)` |
|
|
127
|
+
| `.clle` | `.pgm` | Program (*PGM) | `CRTBNDCL` |
|
|
128
|
+
| `.clle` | `.module` | Module (*MODULE) | `CRTCLMOD` |
|
|
129
|
+
| `.clp` / `.cl` | `.pgm` | Program (*PGM) | `CRTCLPGM` |
|
|
130
|
+
| `.proc.sql` | `.pgm` | SQL Procedure (*PGM) | `RUNSQLSTM` |
|
|
131
|
+
| `.module` (1+) | `.pgm` | Program (*PGM) | `CRTPGM` |
|
|
132
|
+
| `.module` + `.exports` | `.srvpgm` | Service Program (*SRVPGM) | `CRTSRVPGM` |
|
|
133
|
+
| `.dspf` | `.file` | Display File (*FILE) | `CRTDSPF` |
|
|
134
|
+
| `.json` (RDF) | `.file` | Display File (*FILE) | `CRTDSPF` |
|
|
135
|
+
| `.pf` | `.file` | Physical File (*FILE) | `CRTPF` |
|
|
136
|
+
| `.lf` | `.file` | Logical File (*FILE) | `CRTLF` |
|
|
137
|
+
| `.prtf` | `.file` | Printer File (*FILE) | `CRTPRTF` |
|
|
138
|
+
| `.table.sql` | `.file` | SQL Table (*FILE) | `RUNSQLSTM` |
|
|
139
|
+
| `.index.sql` | `.file` | SQL Index (*FILE) | `RUNSQLSTM` |
|
|
140
|
+
| `.file` + `.msgf` | `.menu` | Menu (*MENU) | `CRTMNU` |
|
|
141
|
+
| `.msgf` (CL src) | `.msgf` | Message File (*MSGF) | `CRTMSGF` / `ADDMSGD` |
|
|
142
|
+
| `.bnddir` (CL src) | `.bnddir` | Binding Dir (*BNDDIR) | `CRTBNDDIR` / `ADDBNDDIRE` |
|
|
143
|
+
|
|
144
|
+
For full details on every type, see [references/file-types.md](references/file-types.md).
|
|
145
|
+
|
|
146
|
+
## Adding a new target
|
|
147
|
+
|
|
148
|
+
Follow this procedure when adding a new object to the build:
|
|
149
|
+
|
|
150
|
+
1. **Create the source file** in the appropriate source directory (e.g., `src/newpgm.rpgle`).
|
|
151
|
+
2. **Add a rule to `Rules.mk`** in that directory:
|
|
152
|
+
```makefile
|
|
153
|
+
newpgm.pgm: newpgm.rpgle
|
|
154
|
+
```
|
|
155
|
+
3. **Declare dependencies** on any objects that must exist first:
|
|
156
|
+
```makefile
|
|
157
|
+
newpgm.pgm: newpgm.rpgle myscreen.file mysrvpgm.srvpgm | mybnddir.bnddir
|
|
158
|
+
```
|
|
159
|
+
4. **Build and verify:**
|
|
160
|
+
```bash
|
|
161
|
+
codermake newpgm.pgm
|
|
162
|
+
```
|
|
163
|
+
5. **Check logs on failure:** `tmp/logs/newpgm.pgm.log`
|
|
164
|
+
|
|
165
|
+
If the target is a module destined for a service program or multi-module program, also add the downstream rule:
|
|
166
|
+
|
|
167
|
+
```makefile
|
|
168
|
+
newmod.module: newmod.rpgle
|
|
169
|
+
existing.srvpgm: existing_mod.module newmod.module existing.exports
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Troubleshooting
|
|
173
|
+
|
|
174
|
+
Build logs are in `tmp/logs/<target>.log`. When a build fails:
|
|
175
|
+
|
|
176
|
+
1. Open the log file for the failing target.
|
|
177
|
+
2. Search for error message IDs (e.g., `RNF`, `SQL`, `CPF`, `CPD`).
|
|
178
|
+
3. For RPG/SQL RPG, look at the message summary near the end of the listing -- severity 30+ messages are errors.
|
|
179
|
+
4. For DDS/CL, look for `CPF` or `CPD` message IDs in the output.
|
|
180
|
+
5. Use `codermake --print-rules` to verify the generated Makefile if the target is not being built at all.
|
|
181
|
+
|
|
182
|
+
For detailed guidance on reading compile listings, see [references/compile-listings.md](references/compile-listings.md).
|
|
183
|
+
|
|
184
|
+
## Environment variables
|
|
185
|
+
|
|
186
|
+
codermake reads its configuration from environment variables (typically set in a `.env` file at the project root).
|
|
187
|
+
|
|
188
|
+
### Remote builds (from Linux/macOS to IBM i via SSH)
|
|
189
|
+
|
|
190
|
+
| Variable | Description |
|
|
191
|
+
|---|---|
|
|
192
|
+
| `IBMI_BUILD_LIBRARY` | Target IBM i library for compiled objects |
|
|
193
|
+
| `IBMI_HOST` | IBM i hostname or IP address |
|
|
194
|
+
| `IBMI_USER` | SSH username on the IBM i |
|
|
195
|
+
| `IBMI_KEY` | Path to SSH private key (optional) |
|
|
196
|
+
|
|
197
|
+
### Local builds (on IBM i PASE)
|
|
198
|
+
|
|
199
|
+
| Variable | Description |
|
|
200
|
+
|---|---|
|
|
201
|
+
| `BUILD_LIBRARY` | Target IBM i library for compiled objects |
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Compile Listings Reference
|
|
2
|
+
|
|
3
|
+
Guide to finding and interpreting IBM i compile listings produced by codermake builds.
|
|
4
|
+
|
|
5
|
+
## Where to find logs
|
|
6
|
+
|
|
7
|
+
Every build target produces a log file at:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
tmp/logs/<target>.log
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
For example, building `mypgm.pgm` writes to `tmp/logs/mypgm.pgm.log`.
|
|
14
|
+
|
|
15
|
+
## RPG listings (.rpgle)
|
|
16
|
+
|
|
17
|
+
RPG compile listings from `CRTBNDRPG` or `CRTRPGMOD` follow a standard structure:
|
|
18
|
+
|
|
19
|
+
1. **Header** -- compiler version, source file path, compile options
|
|
20
|
+
2. **Source listing** -- numbered source lines (may include copy members)
|
|
21
|
+
3. **Additional diagnostics** -- cross-reference tables, data structure layouts
|
|
22
|
+
4. **Message summary** -- all diagnostic messages grouped by severity
|
|
23
|
+
|
|
24
|
+
### Reading the message summary
|
|
25
|
+
|
|
26
|
+
The message summary appears near the end of the listing. Each entry shows:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
MSG ID SEV LINE TEXT
|
|
30
|
+
RNF7031 00 12 The name or indicator is not referenced.
|
|
31
|
+
RNF7066 00 45 A semicolon is expected ...
|
|
32
|
+
RNF5377 30 78 The type of expression does not match ...
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Severity levels:**
|
|
36
|
+
|
|
37
|
+
| Severity | Meaning | Action |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| 00 | Informational | Safe to ignore |
|
|
40
|
+
| 10 | Warning | Review but usually benign |
|
|
41
|
+
| 20 | Error (recoverable) | Compiler attempted to continue; fix recommended |
|
|
42
|
+
| 30 | Severe error | Compilation failed; must fix |
|
|
43
|
+
| 40+ | Unrecoverable | Compilation failed; must fix |
|
|
44
|
+
|
|
45
|
+
Search for severity 30+ messages to find the root cause of a build failure. The `LINE` column tells you which source line triggered the error.
|
|
46
|
+
|
|
47
|
+
### Common RPG message IDs
|
|
48
|
+
|
|
49
|
+
| ID prefix | Area |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `RNF` | RPG compiler messages |
|
|
52
|
+
| `RNS` | RPG compiler (structured) |
|
|
53
|
+
| `SQL` | Embedded SQL messages (in SQLRPGLE) |
|
|
54
|
+
|
|
55
|
+
## SQL RPG listings (.sqlrpgle)
|
|
56
|
+
|
|
57
|
+
SQL RPG compilation is a two-phase process:
|
|
58
|
+
|
|
59
|
+
1. **SQL precompile** (`CRTSQLRPGI`) -- translates embedded SQL into RPG call statements
|
|
60
|
+
2. **RPG compile** -- compiles the resulting RPG source
|
|
61
|
+
|
|
62
|
+
The log contains output from both phases. When debugging:
|
|
63
|
+
|
|
64
|
+
- **SQL errors** appear in the first phase. Look for `SQL` message IDs.
|
|
65
|
+
- **RPG errors** appear in the second phase. Look for `RNF`/`RNS` message IDs.
|
|
66
|
+
- If the SQL precompile fails, the RPG compile does not run.
|
|
67
|
+
|
|
68
|
+
### SQL precompile messages
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
SQL0104 30 Position 45 Token "SELEC" was not valid. Valid tokens: ...
|
|
72
|
+
SQL0204 20 Table "MYLIB/NOTABLE" not found.
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The position or line number tells you where in the embedded SQL the error occurred.
|
|
76
|
+
|
|
77
|
+
## CL listings (.clle, .clp, .cl)
|
|
78
|
+
|
|
79
|
+
CL compile errors appear as `CPD` or `CPF` messages:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
CPD0727 30 The character value specified is not a valid name.
|
|
83
|
+
CPF0001 40 Error found on CALL command.
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
For ILE CL (`CRTBNDCL`, `CRTCLMOD`), the listing structure is similar to RPG -- source listing followed by a message summary.
|
|
87
|
+
|
|
88
|
+
For OPM CL (`CRTCLPGM`), the output is typically shorter and errors reference source sequence numbers.
|
|
89
|
+
|
|
90
|
+
## DDS listings (.dspf, .pf, .lf, .prtf)
|
|
91
|
+
|
|
92
|
+
DDS compilation errors from `CRTDSPF`, `CRTPF`, `CRTLF`, or `CRTPRTF` produce `CPD` messages:
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
CPD7302 30 Record format SCREEN1 not found in file referenced.
|
|
96
|
+
CPD7344 30 Keyword REF not valid for this type of file.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
DDS errors typically reference a specific record format and line within the source.
|
|
100
|
+
|
|
101
|
+
## SQL DDL listings (.table.sql, .index.sql, .proc.sql)
|
|
102
|
+
|
|
103
|
+
SQL DDL statements executed via `RUNSQLSTM` produce SQL messages:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
SQL0104 30 Token "CREAT" was not valid.
|
|
107
|
+
SQL0601 20 Table EMPLOYEE in MYLIB already exists.
|
|
108
|
+
SQL7905 10 Module *N in *N not found.
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- Severity 30+ means the statement failed.
|
|
112
|
+
- Severity 20 warnings (like "already exists") may or may not be a problem depending on context.
|
|
113
|
+
|
|
114
|
+
## Message files and binding directories (.msgf, .bnddir)
|
|
115
|
+
|
|
116
|
+
These execute CL commands from a source file. Errors appear as `CPF` or `CPD` messages from the individual CL commands:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
CPF2112 40 Object APPMSG type *MSGF already exists in library MYLIB.
|
|
120
|
+
CPF2105 30 Object MYSRVPGM in MYLIB type *SRVPGM not found.
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Practical example
|
|
124
|
+
|
|
125
|
+
A build of `mypgm.pgm` fails. Here is how to diagnose it:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# 1. Check the log
|
|
129
|
+
cat tmp/logs/mypgm.pgm.log
|
|
130
|
+
|
|
131
|
+
# 2. Search for high-severity messages
|
|
132
|
+
grep -E 'RNF.{4}\s+[34]0|SQL.{4}\s+[34]0|CPD.{4}\s+[34]0|CPF.{4}\s+[34]0' tmp/logs/mypgm.pgm.log
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Example output:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
RNF5377 30 42 The type of expression does not match the type expected.
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
This tells you line 42 of the RPG source has a type mismatch. Open the source file, go to line 42, and fix the expression type.
|