@profoundlogic/codermake 1.7.0 → 2.0.1
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 +89 -50
- package/dist/makefiles/unix.mk +110 -69
- package/package.json +3 -2
- package/skills/codermake/SKILL.md +34 -3
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,7 +218,7 @@ 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
|
|
@@ -208,21 +226,21 @@ endef
|
|
|
208
226
|
# Build ILE COBOL program (bound)
|
|
209
227
|
define BUILD_CBLLE_PGM
|
|
210
228
|
$(call SETUP_LOG,$(notdir $@))
|
|
211
|
-
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtbndcbl pgm($(
|
|
229
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtbndcbl pgm($(TARGET_LIB)/$(basename $(@F))) srcstmf('$<') tgtccsid(*job) output(*print) dbgview(*all)")
|
|
212
230
|
touch '$@'
|
|
213
231
|
endef
|
|
214
232
|
|
|
215
233
|
# Build ILE COBOL module
|
|
216
234
|
define BUILD_CBLLE_MODULE
|
|
217
235
|
$(call SETUP_LOG,$(notdir $@))
|
|
218
|
-
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtcblmod module($(
|
|
236
|
+
$(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtcblmod module($(TARGET_LIB)/$(basename $(@F))) srcstmf('$<') tgtccsid(*job) output(*print) dbgview(*all)")
|
|
219
237
|
touch '$@'
|
|
220
238
|
endef
|
|
221
239
|
|
|
222
240
|
# Build ILE CL program (bound)
|
|
223
241
|
define BUILD_CLLE_PGM
|
|
224
242
|
$(call SETUP_LOG,$(notdir $@))
|
|
225
|
-
$(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)")
|
|
226
244
|
touch '$@'
|
|
227
245
|
endef
|
|
228
246
|
|
|
@@ -232,7 +250,7 @@ $(call SETUP_LOG,$(notdir $@))
|
|
|
232
250
|
$(call CREATE_SOURCE_MEMBER,$<,qclsrc)
|
|
233
251
|
$(SSH) $(QSHELL) <<'EOF'
|
|
234
252
|
$(SET_LIBL)
|
|
235
|
-
system "crtclpgm pgm($(
|
|
253
|
+
system "crtclpgm pgm($(TARGET_LIB)/$(basename $(@F))) srcfile($(TARGET_LIB)/qclsrc) output(*print)"
|
|
236
254
|
EOF
|
|
237
255
|
touch '$@'
|
|
238
256
|
endef
|
|
@@ -240,7 +258,7 @@ endef
|
|
|
240
258
|
# Build ILE CL module
|
|
241
259
|
define BUILD_CLLE_MODULE
|
|
242
260
|
$(call SETUP_LOG,$(notdir $@))
|
|
243
|
-
$(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)")
|
|
244
262
|
touch '$@'
|
|
245
263
|
endef
|
|
246
264
|
|
|
@@ -249,7 +267,7 @@ define BUILD_MODULE_TO_PGM
|
|
|
249
267
|
$(call SETUP_LOG,$(notdir $@))
|
|
250
268
|
$(SSH) $(QSHELL) <<'EOF'
|
|
251
269
|
$(SET_LIBL)
|
|
252
|
-
system "crtpgm pgm($(
|
|
270
|
+
system "crtpgm pgm($(TARGET_LIB)/$(basename $(@F))) $(MODULE_PARM) $(BNDSRVPGM_PARM) $(BNDDIR_PARM)"
|
|
253
271
|
EOF
|
|
254
272
|
touch '$@'
|
|
255
273
|
endef
|
|
@@ -257,7 +275,7 @@ endef
|
|
|
257
275
|
# Build service program from modules
|
|
258
276
|
define BUILD_MODULE_TO_SRVPGM
|
|
259
277
|
$(call SETUP_LOG,$(notdir $@))
|
|
260
|
-
$(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)")
|
|
261
279
|
touch '$@'
|
|
262
280
|
endef
|
|
263
281
|
|
|
@@ -266,7 +284,7 @@ define BUILD_MODULE_TO_SRVPGM_ALL
|
|
|
266
284
|
$(call SETUP_LOG,$(notdir $@))
|
|
267
285
|
$(SSH) $(QSHELL) <<'EOF'
|
|
268
286
|
$(SET_LIBL)
|
|
269
|
-
system "crtsrvpgm srvpgm($(
|
|
287
|
+
system "crtsrvpgm srvpgm($(TARGET_LIB)/$(basename $(@F))) $(MODULE_PARM) export(*all) $(BNDSRVPGM_PARM) $(BNDDIR_PARM)"
|
|
270
288
|
EOF
|
|
271
289
|
touch '$@'
|
|
272
290
|
endef
|
|
@@ -277,7 +295,7 @@ $(call SETUP_LOG,$(notdir $@))
|
|
|
277
295
|
$(call CREATE_SOURCE_MEMBER,$<,qddssrc)
|
|
278
296
|
$(SSH) $(QSHELL) <<'EOF'
|
|
279
297
|
$(SET_LIBL)
|
|
280
|
-
system "crtdspf file($(
|
|
298
|
+
system "crtdspf file($(TARGET_LIB)/$(basename $(@F))) srcfile($(TARGET_LIB)/qddssrc)"
|
|
281
299
|
EOF
|
|
282
300
|
touch '$@'
|
|
283
301
|
endef
|
|
@@ -289,7 +307,7 @@ $(call SETUP_LOG,$(notdir $@))
|
|
|
289
307
|
$(call CREATE_SOURCE_MEMBER,tmp/$(basename $(@F)).dspf,qddssrc)
|
|
290
308
|
$(SSH) $(QSHELL) <<'EOF'
|
|
291
309
|
$(SET_LIBL)
|
|
292
|
-
system "crtdspf file($(
|
|
310
|
+
system "crtdspf file($(TARGET_LIB)/$(basename $(@F))) srcfile($(TARGET_LIB)/qddssrc) enhdsp(*yes)"
|
|
293
311
|
EOF
|
|
294
312
|
rm -f 'tmp/$(basename $(@F)).dspf'
|
|
295
313
|
touch '$@'
|
|
@@ -301,7 +319,7 @@ $(call SETUP_LOG,$(notdir $@))
|
|
|
301
319
|
$(call CREATE_SOURCE_MEMBER,$<,qddssrc)
|
|
302
320
|
$(SSH) $(QSHELL) <<'EOF'
|
|
303
321
|
$(SET_LIBL)
|
|
304
|
-
system "crtpf file($(
|
|
322
|
+
system "crtpf file($(TARGET_LIB)/$(basename $(@F))) srcfile($(TARGET_LIB)/qddssrc)"
|
|
305
323
|
EOF
|
|
306
324
|
touch '$@'
|
|
307
325
|
endef
|
|
@@ -312,7 +330,7 @@ $(call SETUP_LOG,$(notdir $@))
|
|
|
312
330
|
$(call CREATE_SOURCE_MEMBER,$<,qddssrc)
|
|
313
331
|
$(SSH) $(QSHELL) <<'EOF'
|
|
314
332
|
$(SET_LIBL)
|
|
315
|
-
system "crtlf file($(
|
|
333
|
+
system "crtlf file($(TARGET_LIB)/$(basename $(@F))) srcfile($(TARGET_LIB)/qddssrc)"
|
|
316
334
|
EOF
|
|
317
335
|
touch '$@'
|
|
318
336
|
endef
|
|
@@ -323,7 +341,7 @@ $(call SETUP_LOG,$(notdir $@))
|
|
|
323
341
|
$(call CREATE_SOURCE_MEMBER,$<,qddssrc)
|
|
324
342
|
$(SSH) $(QSHELL) <<'EOF'
|
|
325
343
|
$(SET_LIBL)
|
|
326
|
-
system "crtprtf file($(
|
|
344
|
+
system "crtprtf file($(TARGET_LIB)/$(basename $(@F))) srcfile($(TARGET_LIB)/qddssrc)"
|
|
327
345
|
EOF
|
|
328
346
|
touch '$@'
|
|
329
347
|
endef
|
|
@@ -331,28 +349,28 @@ endef
|
|
|
331
349
|
# Build SQL table
|
|
332
350
|
define BUILD_SQLTABLE_TO_FILE
|
|
333
351
|
$(call SETUP_LOG,$(notdir $@))
|
|
334
|
-
$(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))")
|
|
335
353
|
touch '$@'
|
|
336
354
|
endef
|
|
337
355
|
|
|
338
356
|
# Build SQL index
|
|
339
357
|
define BUILD_SQLINDEX_TO_FILE
|
|
340
358
|
$(call SETUP_LOG,$(notdir $@))
|
|
341
|
-
$(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))")
|
|
342
360
|
touch '$@'
|
|
343
361
|
endef
|
|
344
362
|
|
|
345
363
|
# Build SQL view
|
|
346
364
|
define BUILD_SQLVIEW_TO_FILE
|
|
347
365
|
$(call SETUP_LOG,$(notdir $@))
|
|
348
|
-
$(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))")
|
|
349
367
|
touch '$@'
|
|
350
368
|
endef
|
|
351
369
|
|
|
352
370
|
# Build SQL procedure
|
|
353
371
|
define BUILD_SQLPROC_TO_PGM
|
|
354
372
|
$(call SETUP_LOG,$(notdir $@))
|
|
355
|
-
$(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))")
|
|
356
374
|
touch '$@'
|
|
357
375
|
endef
|
|
358
376
|
|
|
@@ -375,13 +393,16 @@ define BUILD_MENU
|
|
|
375
393
|
$(call SETUP_LOG,$(notdir $@))
|
|
376
394
|
$(SSH) $(QSHELL) <<'EOF'
|
|
377
395
|
$(SET_LIBL)
|
|
378
|
-
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)"
|
|
379
397
|
EOF
|
|
380
398
|
touch '$@'
|
|
381
399
|
endef
|
|
382
400
|
|
|
383
401
|
######
|
|
384
|
-
# 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.
|
|
385
406
|
######
|
|
386
407
|
.PHONY: platform-clean
|
|
387
408
|
platform-clean:
|
|
@@ -389,19 +410,39 @@ platform-clean:
|
|
|
389
410
|
rm -rf tmp/logs
|
|
390
411
|
rm -rf tmp/codermake_*.tar
|
|
391
412
|
rm -rf tmp/rpg-pp-*
|
|
392
|
-
@
|
|
393
|
-
if [ -n "$$CLEAN_TARGETS" ]; then
|
|
413
|
+
@if [ -n "$(TARGETS)" ]; then
|
|
394
414
|
$(SSH) $(QSHELL) <<EOF
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
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
|
|
400
441
|
else
|
|
401
|
-
rm -rf "
|
|
442
|
+
rm -rf "/qsys.lib/\$$lib.lib/\$$obj" 2>/dev/null || true
|
|
402
443
|
fi
|
|
403
|
-
|
|
444
|
+
fi
|
|
404
445
|
done
|
|
405
|
-
|
|
446
|
+
done
|
|
406
447
|
EOF
|
|
407
448
|
fi
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@profoundlogic/codermake",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
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",
|
|
@@ -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:
|
|
@@ -186,7 +200,7 @@ existing.srvpgm: existing_mod.module newmod.module existing.exports
|
|
|
186
200
|
|
|
187
201
|
## Troubleshooting
|
|
188
202
|
|
|
189
|
-
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:
|
|
190
204
|
|
|
191
205
|
1. Open the log file for the failing target.
|
|
192
206
|
2. Search for error message IDs (e.g., `RNF`, `SQL`, `CPF`, `CPD`).
|
|
@@ -194,6 +208,12 @@ Build logs are in `tmp/logs/<target>.log`. When a build fails:
|
|
|
194
208
|
4. For DDS/CL, look for `CPF` or `CPD` message IDs in the output.
|
|
195
209
|
5. Use `codermake --print-rules` to verify the generated Makefile if the target is not being built at all.
|
|
196
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 depth-1 directory with a `Rules.mk` must appear in an explicit map (sibling dirs without a `Rules.mk` are not required). Add the missing entries, or switch to `CODERMAKE_LIBRARY_MAP=auto` for natural mapping.
|
|
216
|
+
|
|
197
217
|
For detailed guidance on reading compile listings, see [references/compile-listings.md](references/compile-listings.md).
|
|
198
218
|
|
|
199
219
|
## Environment variables
|
|
@@ -204,7 +224,7 @@ codermake reads its configuration from environment variables (typically set in a
|
|
|
204
224
|
|
|
205
225
|
| Variable | Description |
|
|
206
226
|
|---|---|
|
|
207
|
-
| `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) |
|
|
208
228
|
| `IBMI_HOST` | IBM i hostname or IP address |
|
|
209
229
|
| `IBMI_USER` | SSH username on the IBM i |
|
|
210
230
|
| `IBMI_KEY` | Path to SSH private key (optional) |
|
|
@@ -213,4 +233,15 @@ codermake reads its configuration from environment variables (typically set in a
|
|
|
213
233
|
|
|
214
234
|
| Variable | Description |
|
|
215
235
|
|---|---|
|
|
216
|
-
| `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).
|