@profoundlogic/codermake 1.6.3 → 2.0.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 +67 -1
- package/dist/bin/index.js +1 -1
- package/dist/bin/preprocess-rpg-copy.js +1 -1
- package/dist/bin/rdf-to-dds.js +1 -1
- package/dist/lib/discovery.js +1 -1
- package/dist/lib/ejs-to-dds.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/rpg-copy-preprocessor.js +1 -1
- package/dist/lib/ssh.js +1 -1
- package/dist/lib/writer.js +1 -1
- package/dist/makefiles/Makefile +34 -0
- package/dist/makefiles/base.mk +70 -9
- package/dist/makefiles/ibmi.mk +101 -48
- package/dist/makefiles/unix.mk +122 -67
- package/package.json +3 -2
- package/skills/codermake/SKILL.md +37 -4
- package/skills/codermake/references/file-types.md +18 -0
package/dist/makefiles/unix.mk
CHANGED
|
@@ -4,14 +4,25 @@
|
|
|
4
4
|
######
|
|
5
5
|
|
|
6
6
|
######
|
|
7
|
-
#
|
|
7
|
+
# Output library configuration. Two modes:
|
|
8
|
+
# - Single-library: IBMI_BUILD_LIBRARY required (today's behavior).
|
|
9
|
+
# - Multi-library: CODERMAKE_LIBRARY_MAP drives per-target output libraries.
|
|
10
|
+
# LIBRARY is intentionally undefined; recipes use TARGET_LIB
|
|
11
|
+
# (= $(or $(TARGET_LIBRARY),$(LIBRARY))) which resolves via
|
|
12
|
+
# the target-specific TARGET_LIBRARY emitted by the
|
|
13
|
+
# preprocessor for each output rule.
|
|
8
14
|
######
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
$(
|
|
15
|
+
ifndef CODERMAKE_LIBRARY_MAP
|
|
16
|
+
ifeq (,$(IBMI_BUILD_LIBRARY))
|
|
17
|
+
$(error Required variable IBMI_BUILD_LIBRARY is not set.)
|
|
18
|
+
endif
|
|
19
|
+
ifneq (1,$(words [$(IBMI_BUILD_LIBRARY)]))
|
|
20
|
+
$(error IBMI_BUILD_LIBRARY variable is not set correctly. Set to a valid library name and try again.)
|
|
21
|
+
endif
|
|
22
|
+
LIBRARY := $(IBMI_BUILD_LIBRARY)
|
|
23
|
+
LIBRARY_PATH := /qsys.lib/$(LIBRARY).lib
|
|
14
24
|
endif
|
|
25
|
+
|
|
15
26
|
ifeq (,$(IBMI_HOST))
|
|
16
27
|
$(warning Warning: Required variable IBMI_HOST is not set.)
|
|
17
28
|
endif
|
|
@@ -20,10 +31,10 @@ ifeq (,$(IBMI_USER))
|
|
|
20
31
|
endif
|
|
21
32
|
|
|
22
33
|
######
|
|
23
|
-
#
|
|
34
|
+
# Resolved per-recipe library and library path.
|
|
24
35
|
######
|
|
25
|
-
|
|
26
|
-
|
|
36
|
+
TARGET_LIB = $(or $(TARGET_LIBRARY),$(LIBRARY))
|
|
37
|
+
TARGET_LIB_PATH = /qsys.lib/$(TARGET_LIB).lib
|
|
27
38
|
|
|
28
39
|
######
|
|
29
40
|
# Shell configuration.
|
|
@@ -58,14 +69,14 @@ SSH := $(SSH) $(IBMI_USER)@$(IBMI_HOST)
|
|
|
58
69
|
######
|
|
59
70
|
define CREATE_SOURCE_MEMBER
|
|
60
71
|
$(SSH) $(QSHELL) <<'EOF'
|
|
61
|
-
if [ ! -e '$(
|
|
62
|
-
system "crtsrcpf file($(
|
|
72
|
+
if [ ! -e '$(TARGET_LIB_PATH)/$(2).file' ]; then
|
|
73
|
+
system "crtsrcpf file($(TARGET_LIB)/$(2))"
|
|
63
74
|
fi
|
|
64
|
-
if [ ! -e '$(
|
|
65
|
-
system "addpfm file($(
|
|
75
|
+
if [ ! -e '$(TARGET_LIB_PATH)/$(2).file/$(basename $(notdir $(1))).mbr' ]; then
|
|
76
|
+
system "addpfm file($(TARGET_LIB)/$(2)) mbr($(basename $(notdir $(1)))) srctype($(subst .,,$(suffix $(1))))"
|
|
66
77
|
fi
|
|
67
78
|
EOF
|
|
68
|
-
cat '$(1)' | $(SSH) "$(QSHELL) -c 'Rfile -Qw \"$(
|
|
79
|
+
cat '$(1)' | $(SSH) "$(QSHELL) -c 'Rfile -Qw \"$(TARGET_LIB)/$(2)($(basename $(notdir $(1))))\"'"
|
|
69
80
|
endef
|
|
70
81
|
|
|
71
82
|
######
|
|
@@ -75,40 +86,30 @@ endef
|
|
|
75
86
|
######
|
|
76
87
|
define BUILD_FROM_CL_FILE
|
|
77
88
|
$(call REMOTE_BUILD,$(2), \
|
|
78
|
-
rm -rf '$(
|
|
79
|
-
export LIBRARY=$(
|
|
89
|
+
rm -rf '$(TARGET_LIB_PATH)/$(notdir $(1))' && \
|
|
90
|
+
export LIBRARY=$(TARGET_LIB) && \
|
|
80
91
|
export NAME=$(basename $(notdir $(1))) && \
|
|
81
92
|
( \
|
|
82
93
|
echo "$(file < $<)" | while IFS= read -r line; do \
|
|
83
94
|
system "$$line"; \
|
|
84
95
|
done \
|
|
85
|
-
) || (rm -rf '$(
|
|
96
|
+
) || (rm -rf '$(TARGET_LIB_PATH)/$(notdir $(1))'; exit 1) \
|
|
86
97
|
)
|
|
87
98
|
endef
|
|
88
99
|
|
|
89
100
|
######
|
|
90
101
|
# Utility to output "Creating X..." message and redirect recipe output to log file.
|
|
102
|
+
# In multi-library mode, logs nest under the target's library to avoid collisions.
|
|
91
103
|
######
|
|
104
|
+
LOG_DIR = tmp/logs$(if $(TARGET_LIBRARY),/$(TARGET_LIBRARY))
|
|
92
105
|
define SETUP_LOG
|
|
93
106
|
@echo "Creating $(1)"
|
|
94
|
-
|
|
107
|
+
$(MKDIR) -p '$(LOG_DIR)'
|
|
108
|
+
exec > '$(LOG_DIR)/$(1).log' 2>&1
|
|
95
109
|
endef
|
|
96
110
|
|
|
97
111
|
######
|
|
98
112
|
# Reusable utility for remote builds via SSH.
|
|
99
|
-
# Handles the complete pattern of:
|
|
100
|
-
# 1. Creating an uncompressed tar archive of source files locally (preserving paths)
|
|
101
|
-
# 2. Creating a temporary directory on IBM i and uploading the tar
|
|
102
|
-
# 3. Extracting the tar (recreating directory structure), then executing build command with library list set
|
|
103
|
-
# 4. Cleaning up temp directories (local and remote) and propagating exit codes
|
|
104
|
-
#
|
|
105
|
-
# $(1) = space-separated list of local files to upload
|
|
106
|
-
# $(2) = build command to execute (typically a 'system' command)
|
|
107
|
-
#
|
|
108
|
-
# Files are archived with their full paths, so 'src/myfile.rpgle' will extract to
|
|
109
|
-
# '$$REMOTE_DIR/src/myfile.rpgle' on the remote system.
|
|
110
|
-
#
|
|
111
|
-
# Build command runs with current directory set to the remote temp directory.
|
|
112
113
|
######
|
|
113
114
|
######
|
|
114
115
|
# $(1) = source root directory to tar from (use '.' for current directory)
|
|
@@ -140,30 +141,47 @@ endef
|
|
|
140
141
|
|
|
141
142
|
######
|
|
142
143
|
# Original REMOTE_BUILD is now a convenience wrapper (source root = '.')
|
|
143
|
-
# $(1) = space-separated list of local files to upload
|
|
144
|
-
# $(2) = build command to execute
|
|
145
144
|
######
|
|
146
145
|
define REMOTE_BUILD
|
|
147
146
|
$(call REMOTE_BUILD_FROM,.,$(1),$(2))
|
|
148
147
|
endef
|
|
149
148
|
|
|
150
149
|
######
|
|
151
|
-
# Prerun actions.
|
|
150
|
+
# Prerun actions and banner.
|
|
152
151
|
######
|
|
153
152
|
$(info ===)
|
|
154
153
|
$(info Target IBM i: $(IBMI_HOST))
|
|
155
|
-
|
|
154
|
+
ifdef CODERMAKE_LIBRARY_MAP
|
|
155
|
+
$(info Library map: $(CODERMAKE_RESOLVED_LIBRARY_MAP))
|
|
156
|
+
ifdef CODERMAKE_LIBRARY_LIST
|
|
157
|
+
$(info Library list: $(CODERMAKE_LIBRARY_LIST))
|
|
158
|
+
else
|
|
159
|
+
$(info Library list: (inherited from job/profile))
|
|
160
|
+
endif
|
|
161
|
+
else
|
|
162
|
+
$(info Target library: $(LIBRARY))
|
|
163
|
+
endif
|
|
156
164
|
$(info Build user: $(IBMI_USER))
|
|
157
165
|
$(info ===)
|
|
158
166
|
$(shell mkdir -p build)
|
|
159
167
|
|
|
160
168
|
######
|
|
161
|
-
# Library creation target
|
|
169
|
+
# Library creation. Single-library mode keeps today's specific-target file
|
|
170
|
+
# marker (`build/<LIBRARY>.lib` is a regular touched file). Multi-library mode
|
|
171
|
+
# uses a pattern rule where the directory itself (`build/<lib>.lib/`) is the
|
|
172
|
+
# library-existence marker — created by the recipe alongside the remote crtlib.
|
|
162
173
|
######
|
|
174
|
+
ifndef CODERMAKE_LIBRARY_MAP
|
|
163
175
|
build/$(LIBRARY).lib:
|
|
164
176
|
$(call SETUP_LOG,$(notdir $@))
|
|
165
177
|
$(SSH) "test -e $(LIBRARY_PATH) || system \"crtlib $(LIBRARY) *test aut(*use) crtaut(*use)\""
|
|
166
178
|
touch '$@'
|
|
179
|
+
else
|
|
180
|
+
build/%.lib:
|
|
181
|
+
$(call SETUP_LOG,$(notdir $@))
|
|
182
|
+
$(SSH) "test -e /qsys.lib/$*.lib || system \"crtlib $* *test aut(*use) crtaut(*use)\""
|
|
183
|
+
mkdir -p '$@'
|
|
184
|
+
endif
|
|
167
185
|
|
|
168
186
|
######
|
|
169
187
|
# Recipe utilities (callable functions for preprocessor-generated rules)
|
|
@@ -173,7 +191,7 @@ build/$(LIBRARY).lib:
|
|
|
173
191
|
define BUILD_RPGLE_PGM
|
|
174
192
|
$(call SETUP_LOG,$(notdir $@))
|
|
175
193
|
$(call RPG_PREPROCESS_SOURCES,$(filter-out build/%,$^))
|
|
176
|
-
$(call REMOTE_BUILD_FROM,$$RPG_SRC_ROOT,$(filter-out build/%,$^),system "crtbndrpg pgm($(
|
|
194
|
+
$(call REMOTE_BUILD_FROM,$$RPG_SRC_ROOT,$(filter-out build/%,$^),system "crtbndrpg pgm($(TARGET_LIB)/$(basename $(@F))) srcstmf('$<') incdir('.') tgtccsid(*job) output(*print) dbgview(*all)")
|
|
177
195
|
$(call RPG_CLEANUP_SOURCES)
|
|
178
196
|
touch '$@'
|
|
179
197
|
endef
|
|
@@ -182,7 +200,7 @@ endef
|
|
|
182
200
|
define BUILD_SQLRPGLE_PGM
|
|
183
201
|
$(call SETUP_LOG,$(notdir $@))
|
|
184
202
|
$(call RPG_PREPROCESS_SOURCES,$(filter-out build/%,$^))
|
|
185
|
-
$(call REMOTE_BUILD_FROM,$$RPG_SRC_ROOT,$(filter-out build/%,$^),system "crtsqlrpgi obj($(
|
|
203
|
+
$(call REMOTE_BUILD_FROM,$$RPG_SRC_ROOT,$(filter-out build/%,$^),system "crtsqlrpgi obj($(TARGET_LIB)/$(basename $(@F))) objtype(*pgm) srcstmf('$<') cvtccsid(*job) output(*print) rpgppopt(*lvl2) compileopt('incdir(''.'') tgtccsid(*job) output(*print)') dbgview(*source)")
|
|
186
204
|
$(call RPG_CLEANUP_SOURCES)
|
|
187
205
|
touch '$@'
|
|
188
206
|
endef
|
|
@@ -191,7 +209,7 @@ endef
|
|
|
191
209
|
define BUILD_RPGLE_MODULE
|
|
192
210
|
$(call SETUP_LOG,$(notdir $@))
|
|
193
211
|
$(call RPG_PREPROCESS_SOURCES,$(filter-out build/%,$^))
|
|
194
|
-
$(call REMOTE_BUILD_FROM,$$RPG_SRC_ROOT,$(filter-out build/%,$^),system "crtrpgmod module($(
|
|
212
|
+
$(call REMOTE_BUILD_FROM,$$RPG_SRC_ROOT,$(filter-out build/%,$^),system "crtrpgmod module($(TARGET_LIB)/$(basename $(@F))) srcstmf('$<') incdir('.') tgtccsid(*job) output(*print) dbgview(*all)")
|
|
195
213
|
$(call RPG_CLEANUP_SOURCES)
|
|
196
214
|
touch '$@'
|
|
197
215
|
endef
|
|
@@ -200,15 +218,29 @@ endef
|
|
|
200
218
|
define BUILD_SQLRPGLE_MODULE
|
|
201
219
|
$(call SETUP_LOG,$(notdir $@))
|
|
202
220
|
$(call RPG_PREPROCESS_SOURCES,$(filter-out build/%,$^))
|
|
203
|
-
$(call REMOTE_BUILD_FROM,$$RPG_SRC_ROOT,$(filter-out build/%,$^),system "crtsqlrpgi obj($(
|
|
221
|
+
$(call REMOTE_BUILD_FROM,$$RPG_SRC_ROOT,$(filter-out build/%,$^),system "crtsqlrpgi obj($(TARGET_LIB)/$(basename $(@F))) objtype(*module) srcstmf('$<') cvtccsid(*job) output(*print) rpgppopt(*lvl2) compileopt('incdir(''.'') tgtccsid(*job) output(*print)') dbgview(*source)")
|
|
204
222
|
$(call RPG_CLEANUP_SOURCES)
|
|
205
223
|
touch '$@'
|
|
206
224
|
endef
|
|
207
225
|
|
|
226
|
+
# Build ILE COBOL program (bound)
|
|
227
|
+
define BUILD_CBLLE_PGM
|
|
228
|
+
$(call SETUP_LOG,$(notdir $@))
|
|
229
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtbndcbl pgm($(TARGET_LIB)/$(basename $(@F))) srcstmf('$<') tgtccsid(*job) output(*print) dbgview(*all)")
|
|
230
|
+
touch '$@'
|
|
231
|
+
endef
|
|
232
|
+
|
|
233
|
+
# Build ILE COBOL module
|
|
234
|
+
define BUILD_CBLLE_MODULE
|
|
235
|
+
$(call SETUP_LOG,$(notdir $@))
|
|
236
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtcblmod module($(TARGET_LIB)/$(basename $(@F))) srcstmf('$<') tgtccsid(*job) output(*print) dbgview(*all)")
|
|
237
|
+
touch '$@'
|
|
238
|
+
endef
|
|
239
|
+
|
|
208
240
|
# Build ILE CL program (bound)
|
|
209
241
|
define BUILD_CLLE_PGM
|
|
210
242
|
$(call SETUP_LOG,$(notdir $@))
|
|
211
|
-
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtbndcl pgm($(
|
|
243
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtbndcl pgm($(TARGET_LIB)/$(basename $(@F))) srcstmf('$<') incdir('.') tgtccsid(*job) output(*print) dbgview(*all)")
|
|
212
244
|
touch '$@'
|
|
213
245
|
endef
|
|
214
246
|
|
|
@@ -218,7 +250,7 @@ $(call SETUP_LOG,$(notdir $@))
|
|
|
218
250
|
$(call CREATE_SOURCE_MEMBER,$<,qclsrc)
|
|
219
251
|
$(SSH) $(QSHELL) <<'EOF'
|
|
220
252
|
$(SET_LIBL)
|
|
221
|
-
system "crtclpgm pgm($(
|
|
253
|
+
system "crtclpgm pgm($(TARGET_LIB)/$(basename $(@F))) srcfile($(TARGET_LIB)/qclsrc) output(*print)"
|
|
222
254
|
EOF
|
|
223
255
|
touch '$@'
|
|
224
256
|
endef
|
|
@@ -226,7 +258,7 @@ endef
|
|
|
226
258
|
# Build ILE CL module
|
|
227
259
|
define BUILD_CLLE_MODULE
|
|
228
260
|
$(call SETUP_LOG,$(notdir $@))
|
|
229
|
-
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtclmod module($(
|
|
261
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtclmod module($(TARGET_LIB)/$(basename $(@F))) srcstmf('$<') incdir('.') tgtccsid(*job) output(*print) dbgview(*all)")
|
|
230
262
|
touch '$@'
|
|
231
263
|
endef
|
|
232
264
|
|
|
@@ -235,7 +267,7 @@ define BUILD_MODULE_TO_PGM
|
|
|
235
267
|
$(call SETUP_LOG,$(notdir $@))
|
|
236
268
|
$(SSH) $(QSHELL) <<'EOF'
|
|
237
269
|
$(SET_LIBL)
|
|
238
|
-
system "crtpgm pgm($(
|
|
270
|
+
system "crtpgm pgm($(TARGET_LIB)/$(basename $(@F))) $(MODULE_PARM) $(BNDSRVPGM_PARM) $(BNDDIR_PARM)"
|
|
239
271
|
EOF
|
|
240
272
|
touch '$@'
|
|
241
273
|
endef
|
|
@@ -243,7 +275,7 @@ endef
|
|
|
243
275
|
# Build service program from modules
|
|
244
276
|
define BUILD_MODULE_TO_SRVPGM
|
|
245
277
|
$(call SETUP_LOG,$(notdir $@))
|
|
246
|
-
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtsrvpgm srvpgm($(
|
|
278
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtsrvpgm srvpgm($(TARGET_LIB)/$(basename $(@F))) $(MODULE_PARM) export(*srcfile) srcstmf('$(filter %.exports %.bnd,$^)') $(BNDSRVPGM_PARM) $(BNDDIR_PARM)")
|
|
247
279
|
touch '$@'
|
|
248
280
|
endef
|
|
249
281
|
|
|
@@ -252,7 +284,7 @@ define BUILD_MODULE_TO_SRVPGM_ALL
|
|
|
252
284
|
$(call SETUP_LOG,$(notdir $@))
|
|
253
285
|
$(SSH) $(QSHELL) <<'EOF'
|
|
254
286
|
$(SET_LIBL)
|
|
255
|
-
system "crtsrvpgm srvpgm($(
|
|
287
|
+
system "crtsrvpgm srvpgm($(TARGET_LIB)/$(basename $(@F))) $(MODULE_PARM) export(*all) $(BNDSRVPGM_PARM) $(BNDDIR_PARM)"
|
|
256
288
|
EOF
|
|
257
289
|
touch '$@'
|
|
258
290
|
endef
|
|
@@ -263,7 +295,7 @@ $(call SETUP_LOG,$(notdir $@))
|
|
|
263
295
|
$(call CREATE_SOURCE_MEMBER,$<,qddssrc)
|
|
264
296
|
$(SSH) $(QSHELL) <<'EOF'
|
|
265
297
|
$(SET_LIBL)
|
|
266
|
-
system "crtdspf file($(
|
|
298
|
+
system "crtdspf file($(TARGET_LIB)/$(basename $(@F))) srcfile($(TARGET_LIB)/qddssrc)"
|
|
267
299
|
EOF
|
|
268
300
|
touch '$@'
|
|
269
301
|
endef
|
|
@@ -275,7 +307,7 @@ $(call SETUP_LOG,$(notdir $@))
|
|
|
275
307
|
$(call CREATE_SOURCE_MEMBER,tmp/$(basename $(@F)).dspf,qddssrc)
|
|
276
308
|
$(SSH) $(QSHELL) <<'EOF'
|
|
277
309
|
$(SET_LIBL)
|
|
278
|
-
system "crtdspf file($(
|
|
310
|
+
system "crtdspf file($(TARGET_LIB)/$(basename $(@F))) srcfile($(TARGET_LIB)/qddssrc) enhdsp(*yes)"
|
|
279
311
|
EOF
|
|
280
312
|
rm -f 'tmp/$(basename $(@F)).dspf'
|
|
281
313
|
touch '$@'
|
|
@@ -287,7 +319,7 @@ $(call SETUP_LOG,$(notdir $@))
|
|
|
287
319
|
$(call CREATE_SOURCE_MEMBER,$<,qddssrc)
|
|
288
320
|
$(SSH) $(QSHELL) <<'EOF'
|
|
289
321
|
$(SET_LIBL)
|
|
290
|
-
system "crtpf file($(
|
|
322
|
+
system "crtpf file($(TARGET_LIB)/$(basename $(@F))) srcfile($(TARGET_LIB)/qddssrc)"
|
|
291
323
|
EOF
|
|
292
324
|
touch '$@'
|
|
293
325
|
endef
|
|
@@ -298,7 +330,7 @@ $(call SETUP_LOG,$(notdir $@))
|
|
|
298
330
|
$(call CREATE_SOURCE_MEMBER,$<,qddssrc)
|
|
299
331
|
$(SSH) $(QSHELL) <<'EOF'
|
|
300
332
|
$(SET_LIBL)
|
|
301
|
-
system "crtlf file($(
|
|
333
|
+
system "crtlf file($(TARGET_LIB)/$(basename $(@F))) srcfile($(TARGET_LIB)/qddssrc)"
|
|
302
334
|
EOF
|
|
303
335
|
touch '$@'
|
|
304
336
|
endef
|
|
@@ -309,7 +341,7 @@ $(call SETUP_LOG,$(notdir $@))
|
|
|
309
341
|
$(call CREATE_SOURCE_MEMBER,$<,qddssrc)
|
|
310
342
|
$(SSH) $(QSHELL) <<'EOF'
|
|
311
343
|
$(SET_LIBL)
|
|
312
|
-
system "crtprtf file($(
|
|
344
|
+
system "crtprtf file($(TARGET_LIB)/$(basename $(@F))) srcfile($(TARGET_LIB)/qddssrc)"
|
|
313
345
|
EOF
|
|
314
346
|
touch '$@'
|
|
315
347
|
endef
|
|
@@ -317,28 +349,28 @@ endef
|
|
|
317
349
|
# Build SQL table
|
|
318
350
|
define BUILD_SQLTABLE_TO_FILE
|
|
319
351
|
$(call SETUP_LOG,$(notdir $@))
|
|
320
|
-
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(
|
|
352
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(TARGET_LIB))")
|
|
321
353
|
touch '$@'
|
|
322
354
|
endef
|
|
323
355
|
|
|
324
356
|
# Build SQL index
|
|
325
357
|
define BUILD_SQLINDEX_TO_FILE
|
|
326
358
|
$(call SETUP_LOG,$(notdir $@))
|
|
327
|
-
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(
|
|
359
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(TARGET_LIB))")
|
|
328
360
|
touch '$@'
|
|
329
361
|
endef
|
|
330
362
|
|
|
331
363
|
# Build SQL view
|
|
332
364
|
define BUILD_SQLVIEW_TO_FILE
|
|
333
365
|
$(call SETUP_LOG,$(notdir $@))
|
|
334
|
-
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(
|
|
366
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(TARGET_LIB))")
|
|
335
367
|
touch '$@'
|
|
336
368
|
endef
|
|
337
369
|
|
|
338
370
|
# Build SQL procedure
|
|
339
371
|
define BUILD_SQLPROC_TO_PGM
|
|
340
372
|
$(call SETUP_LOG,$(notdir $@))
|
|
341
|
-
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(
|
|
373
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(TARGET_LIB))")
|
|
342
374
|
touch '$@'
|
|
343
375
|
endef
|
|
344
376
|
|
|
@@ -361,13 +393,16 @@ define BUILD_MENU
|
|
|
361
393
|
$(call SETUP_LOG,$(notdir $@))
|
|
362
394
|
$(SSH) $(QSHELL) <<'EOF'
|
|
363
395
|
$(SET_LIBL)
|
|
364
|
-
system "crtmnu menu($(
|
|
396
|
+
system "crtmnu menu($(TARGET_LIB)/$(basename $(@F))) type(*dspf) dspf($(basename $(notdir $(filter %.file,$^)))) msgf($(basename $(notdir $(filter %.msgf,$^)))) cmdlin(*none) dspkey(*no)"
|
|
365
397
|
EOF
|
|
366
398
|
touch '$@'
|
|
367
399
|
endef
|
|
368
400
|
|
|
369
401
|
######
|
|
370
|
-
# Platform-specific clean
|
|
402
|
+
# Platform-specific clean. Each target's path encodes its library, so the
|
|
403
|
+
# library segment is extracted per-target. Works for both modes — in
|
|
404
|
+
# single-library mode every target path is `build/<obj>.<ext>` (no library
|
|
405
|
+
# segment), so we fall back to $(LIBRARY) for the IBM i delete.
|
|
371
406
|
######
|
|
372
407
|
.PHONY: platform-clean
|
|
373
408
|
platform-clean:
|
|
@@ -375,19 +410,39 @@ platform-clean:
|
|
|
375
410
|
rm -rf tmp/logs
|
|
376
411
|
rm -rf tmp/codermake_*.tar
|
|
377
412
|
rm -rf tmp/rpg-pp-*
|
|
378
|
-
@
|
|
379
|
-
if [ -n "$$CLEAN_TARGETS" ]; then
|
|
413
|
+
@if [ -n "$(TARGETS)" ]; then
|
|
380
414
|
$(SSH) $(QSHELL) <<EOF
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
415
|
+
# Two passes over all targets so dependent objects (e.g. SQL views/indexes
|
|
416
|
+
# over a table) get deleted in the first pass, freeing the underlying object
|
|
417
|
+
# for deletion in the second pass.
|
|
418
|
+
for pass in 1 2; do
|
|
419
|
+
for target in $(TARGETS); do
|
|
420
|
+
# Strip "build/" prefix to get the relative portion.
|
|
421
|
+
rel="\$${target#build/}"
|
|
422
|
+
if [ "\$$rel" = "\$$target" ]; then
|
|
423
|
+
continue
|
|
424
|
+
fi
|
|
425
|
+
# If "rel" contains a "/", it's "<lib>.lib/<obj>" (multi-library).
|
|
426
|
+
# Otherwise it's just "<obj>" (single-library, fall back to \$$LIBRARY).
|
|
427
|
+
case "\$$rel" in
|
|
428
|
+
*/*)
|
|
429
|
+
lib_part="\$${rel%%/*}"
|
|
430
|
+
lib="\$${lib_part%.lib}"
|
|
431
|
+
obj="\$${rel#*/}"
|
|
432
|
+
;;
|
|
433
|
+
*)
|
|
434
|
+
lib="$(LIBRARY)"
|
|
435
|
+
obj="\$$rel"
|
|
436
|
+
;;
|
|
437
|
+
esac
|
|
438
|
+
if [ -d "/qsys.lib/\$$lib.lib" ]; then
|
|
439
|
+
if [ "\$${obj%.file}" != "\$$obj" ]; then
|
|
440
|
+
system "dltf \$$lib/\$${obj%.file}" > /dev/null 2>&1 || true
|
|
386
441
|
else
|
|
387
|
-
rm -rf "
|
|
442
|
+
rm -rf "/qsys.lib/\$$lib.lib/\$$obj" 2>/dev/null || true
|
|
388
443
|
fi
|
|
389
|
-
|
|
444
|
+
fi
|
|
390
445
|
done
|
|
391
|
-
|
|
446
|
+
done
|
|
392
447
|
EOF
|
|
393
448
|
fi
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@profoundlogic/codermake",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.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",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"test:dist:integration": "CODERMAKE_E2E_TEST=true node --test --test-concurrency=1 dist/test/integration/**/*.test.js",
|
|
22
22
|
"lint": "eslint . --ignore-pattern dist/",
|
|
23
23
|
"start": "./bin/index.js",
|
|
24
|
-
"
|
|
24
|
+
"check:multi-library-env": "node -e \"import('dotenv/config').then(() => { if (!process.env.CODERMAKE_E2E_LIBRARY_MAP || !process.env.CODERMAKE_E2E_LIBRARY_MAP.trim()) { console.error('CODERMAKE_E2E_LIBRARY_MAP must be set for prepublish (e.g. \\\"LIBA=DEVLIBA LIBB=DEVLIBB\\\"). Gates the multi-library output integration tests.'); process.exit(1); } })\"",
|
|
25
|
+
"prepublishOnly": "npm run check:multi-library-env && npm run lint && npm test && npm run build && npm run test:dist"
|
|
25
26
|
},
|
|
26
27
|
"author": "Profound Logic Software",
|
|
27
28
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
@@ -5,7 +5,7 @@ description: Build IBM i objects from source code.
|
|
|
5
5
|
|
|
6
6
|
# codermake
|
|
7
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.
|
|
8
|
+
codermake is a Make-based build tool for IBM i projects. It compiles RPG, COBOL, 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
9
|
|
|
10
10
|
## Key constraints
|
|
11
11
|
|
|
@@ -76,6 +76,20 @@ Files with a path separator are treated as relative to the project root (not the
|
|
|
76
76
|
mysrvpgm.srvpgm: mymod.module common/api.exports
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
+
In a multi-library project (sources organized under library-equivalent directories like `LIBA/qrpglesrc/`), two-segment paths whose first segment is a known library directory and whose second segment is a bare object filename with an output extension are recognized as **cross-library object qualifiers**:
|
|
80
|
+
|
|
81
|
+
```makefile
|
|
82
|
+
# In LIBA/qrpglesrc/Rules.mk -- depend on a srvpgm in LIBB
|
|
83
|
+
crossbnd.pgm: crossbnd.rpgle | LIBB/utils.srvpgm
|
|
84
|
+
|
|
85
|
+
# Library-qualified target: source in LIBA's tree, output lands in LIBB
|
|
86
|
+
LIBB/installer.pgm: installer.rpgle
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Two-segment paths whose second segment has a *source* extension, or three-or-more-segment paths, are cross-library *source* passthroughs (e.g. `LIBB/qcpysrc/shared.rpgle`).
|
|
90
|
+
|
|
91
|
+
A library qualifier whose first segment is not a known library directory is an error — codermake will tell you which token failed validation.
|
|
92
|
+
|
|
79
93
|
### Message files and binding directories (dual-purpose pattern)
|
|
80
94
|
|
|
81
95
|
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:
|
|
@@ -135,6 +149,8 @@ ENDPGMEXP
|
|
|
135
149
|
| `.rpgle` | `.module` | Module (*MODULE) | `CRTRPGMOD` |
|
|
136
150
|
| `.sqlrpgle` | `.pgm` | Program (*PGM) | `CRTSQLRPGI OBJTYPE(*PGM)` |
|
|
137
151
|
| `.sqlrpgle` | `.module` | Module (*MODULE) | `CRTSQLRPGI OBJTYPE(*MODULE)` |
|
|
152
|
+
| `.cblle` | `.pgm` | Program (*PGM) | `CRTBNDCBL` |
|
|
153
|
+
| `.cblle` | `.module` | Module (*MODULE) | `CRTCBLMOD` |
|
|
138
154
|
| `.clle` | `.pgm` | Program (*PGM) | `CRTBNDCL` |
|
|
139
155
|
| `.clle` | `.module` | Module (*MODULE) | `CRTCLMOD` |
|
|
140
156
|
| `.clp` / `.cl` | `.pgm` | Program (*PGM) | `CRTCLPGM` |
|
|
@@ -184,7 +200,7 @@ existing.srvpgm: existing_mod.module newmod.module existing.exports
|
|
|
184
200
|
|
|
185
201
|
## Troubleshooting
|
|
186
202
|
|
|
187
|
-
Build logs are in `tmp/logs/<target>.log`. When a build fails:
|
|
203
|
+
Build logs are in `tmp/logs/<target>.log`. In multi-library output mode (when `CODERMAKE_LIBRARY_MAP` is set) logs are nested under the IBM i library: `tmp/logs/<libraryName>/<target>.log`. When a build fails:
|
|
188
204
|
|
|
189
205
|
1. Open the log file for the failing target.
|
|
190
206
|
2. Search for error message IDs (e.g., `RNF`, `SQL`, `CPF`, `CPD`).
|
|
@@ -192,6 +208,12 @@ Build logs are in `tmp/logs/<target>.log`. When a build fails:
|
|
|
192
208
|
4. For DDS/CL, look for `CPF` or `CPD` message IDs in the output.
|
|
193
209
|
5. Use `codermake --print-rules` to verify the generated Makefile if the target is not being built at all.
|
|
194
210
|
|
|
211
|
+
Common errors:
|
|
212
|
+
|
|
213
|
+
- **`Invalid library qualifier '<lib>/<obj>.<ext>': '<lib>' is not a known library directory.`** — the first segment of a two-segment qualifier doesn't match any discovered library directory. Either fix the typo or add the missing directory to the project layout.
|
|
214
|
+
- **`<envvar> and CODERMAKE_LIBRARY_MAP are mutually exclusive.`** — only one output-mode variable can be set. Pick `BUILD_LIBRARY`/`IBMI_BUILD_LIBRARY` (single library) **or** `CODERMAKE_LIBRARY_MAP` (per-library output).
|
|
215
|
+
- **`CODERMAKE_LIBRARY_MAP is missing entries for: <dir1>, <dir2>`** — every discovered library directory must appear in an explicit map. Add the missing entries, or switch to `CODERMAKE_LIBRARY_MAP=auto` for natural mapping.
|
|
216
|
+
|
|
195
217
|
For detailed guidance on reading compile listings, see [references/compile-listings.md](references/compile-listings.md).
|
|
196
218
|
|
|
197
219
|
## Environment variables
|
|
@@ -202,7 +224,7 @@ codermake reads its configuration from environment variables (typically set in a
|
|
|
202
224
|
|
|
203
225
|
| Variable | Description |
|
|
204
226
|
|---|---|
|
|
205
|
-
| `IBMI_BUILD_LIBRARY` | Target IBM i library for compiled objects |
|
|
227
|
+
| `IBMI_BUILD_LIBRARY` | Target IBM i library for compiled objects (single-library output mode) |
|
|
206
228
|
| `IBMI_HOST` | IBM i hostname or IP address |
|
|
207
229
|
| `IBMI_USER` | SSH username on the IBM i |
|
|
208
230
|
| `IBMI_KEY` | Path to SSH private key (optional) |
|
|
@@ -211,4 +233,15 @@ codermake reads its configuration from environment variables (typically set in a
|
|
|
211
233
|
|
|
212
234
|
| Variable | Description |
|
|
213
235
|
|---|---|
|
|
214
|
-
| `BUILD_LIBRARY` | Target IBM i library for compiled objects |
|
|
236
|
+
| `BUILD_LIBRARY` | Target IBM i library for compiled objects (single-library output mode) |
|
|
237
|
+
|
|
238
|
+
### Multi-library output (alternative to BUILD_LIBRARY / IBMI_BUILD_LIBRARY)
|
|
239
|
+
|
|
240
|
+
When the project has a multi-library layout, `CODERMAKE_LIBRARY_MAP` enables per-library output — each library-equivalent source directory builds into a distinct IBM i library. Mutually exclusive with `BUILD_LIBRARY` / `IBMI_BUILD_LIBRARY`.
|
|
241
|
+
|
|
242
|
+
| Variable | Description |
|
|
243
|
+
|---|---|
|
|
244
|
+
| `CODERMAKE_LIBRARY_MAP` | Either `auto` (natural mapping: dir name → library name) or explicit `LIBA=APPLIBA LIBB=APPLIBB` pairs. Mutually exclusive with `BUILD_LIBRARY` / `IBMI_BUILD_LIBRARY`. |
|
|
245
|
+
| `CODERMAKE_LIBRARY_LIST` | Optional. Space-separated, ordered IBM i library list. Replaces the user portion of the build job's library list. Only valid alongside `CODERMAKE_LIBRARY_MAP`. |
|
|
246
|
+
|
|
247
|
+
When using multi-library output, refer to objects in another library with the qualifier syntax `<libraryDir>/<bareobj>.<ext>` (see *Cross-directory references* above).
|
|
@@ -24,6 +24,16 @@ mypgm.pgm: mypgm.sqlrpgle
|
|
|
24
24
|
|
|
25
25
|
**CL command:** `CRTSQLRPGI OBJ(LIB/MYPGM) OBJTYPE(*PGM) SRCSTMF('src/mypgm.sqlrpgle')`
|
|
26
26
|
|
|
27
|
+
### ILE COBOL program from .cblle
|
|
28
|
+
|
|
29
|
+
Compiles an ILE COBOL source file into a bound program.
|
|
30
|
+
|
|
31
|
+
```makefile
|
|
32
|
+
mypgm.pgm: mypgm.cblle
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**CL command:** `CRTBNDCBL PGM(LIB/MYPGM) SRCSTMF('src/mypgm.cblle')`
|
|
36
|
+
|
|
27
37
|
### ILE CL program from .clle
|
|
28
38
|
|
|
29
39
|
Compiles an ILE CL source file into a bound program.
|
|
@@ -88,6 +98,14 @@ mymod.module: mymod.sqlrpgle
|
|
|
88
98
|
|
|
89
99
|
**CL command:** `CRTSQLRPGI OBJ(LIB/MYMOD) OBJTYPE(*MODULE) SRCSTMF('src/mymod.sqlrpgle')`
|
|
90
100
|
|
|
101
|
+
### ILE COBOL module from .cblle
|
|
102
|
+
|
|
103
|
+
```makefile
|
|
104
|
+
mymod.module: mymod.cblle
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**CL command:** `CRTCBLMOD MODULE(LIB/MYMOD) SRCSTMF('src/mymod.cblle')`
|
|
108
|
+
|
|
91
109
|
### ILE CL module from .clle
|
|
92
110
|
|
|
93
111
|
```makefile
|