1# $NetBSD: Makefile,v 1.360 2025/05/03 07:54:08 rillig Exp $
2#
3# Unit tests for make(1)
4#
5# The main targets are:
6#
7# all:
8#         run all the tests
9# test:
10#         run 'all', and compare to expected results
11# accept:
12#         move generated output to expected results
13#
14# Settable variables
15#
16# TEST_MAKE
17#         The make program to be tested.
18#
19#
20# Adding a test case
21#
22# Each feature should get its own set of tests in its own suitably
23# named makefile (*.mk), with its own set of expected results (*.exp),
24# and it should be added to the TESTS list.
25#
26# Any added files must also be added to src/distrib/sets/lists/tests/mi.
27# To do that, run "make sync-mi" in this directory.
28#
29
30.MAIN: all
31
32# we use these below but we might be an older make
33.MAKE.OS?= ${uname -s:L:sh}
34.MAKE.UID?= ${id -u:L:sh}
35
36# for many tests we need a TMPDIR that will not collide
37# with other users.
38.if ${.OBJDIR} != ${.CURDIR}
39# easy
40TMPDIR:=  ${.OBJDIR}/tmp
41.elif defined(TMPDIR)
42TMPDIR:=  ${TMPDIR}/uid${.MAKE.UID}
43.else
44TMPDIR:=  /tmp/uid${.MAKE.UID}
45.endif
46# make sure it exists
47.if !exist(${TMPDIR})
48_!= mkdir -p ${TMPDIR}
49.endif
50# and clean it up - outside the context of
51# any target that might be using it.
52.END: rm-tmpdir
53rm-tmpdir:          .NOMETA
54          @rm -rf ${TMPDIR}
55
56# Each test is in a sub-makefile.
57# Keep the list sorted.
58# Any test that is commented out must be ignored in
59# src/tests/usr.bin/make/t_make.sh as well.
60TESTS+=             archive
61TESTS+=             archive-suffix
62TESTS+=             cmd-errors
63TESTS+=             cmd-errors-jobs
64TESTS+=             cmd-errors-lint
65TESTS+=             cmd-interrupt
66TESTS+=             cmdline
67TESTS+=             cmdline-redirect-stdin
68TESTS+=             cmdline-undefined
69TESTS+=             comment
70TESTS+=             compat-error
71TESTS+=             cond-cmp-numeric
72TESTS+=             cond-cmp-numeric-eq
73TESTS+=             cond-cmp-numeric-ge
74TESTS+=             cond-cmp-numeric-gt
75TESTS+=             cond-cmp-numeric-le
76TESTS+=             cond-cmp-numeric-lt
77TESTS+=             cond-cmp-numeric-ne
78TESTS+=             cond-cmp-string
79TESTS+=             cond-cmp-unary
80TESTS+=             cond-eof
81TESTS+=             cond-func
82TESTS+=             cond-func-commands
83TESTS+=             cond-func-defined
84TESTS+=             cond-func-empty
85TESTS+=             cond-func-exists
86TESTS+=             cond-func-make
87TESTS+=             cond-func-make-main
88TESTS+=             cond-func-target
89TESTS+=             cond-late
90TESTS+=             cond-op
91TESTS+=             cond-op-and
92TESTS+=             cond-op-and-lint
93TESTS+=             cond-op-not
94TESTS+=             cond-op-or
95TESTS+=             cond-op-or-lint
96TESTS+=             cond-op-parentheses
97TESTS+=             cond-short
98TESTS+=             cond-token-number
99TESTS+=             cond-token-plain
100TESTS+=             cond-token-string
101TESTS+=             cond-token-var
102TESTS+=             cond-undef-lint
103TESTS+=             counter
104TESTS+=             counter-append
105TESTS+=             dep
106TESTS+=             dep-colon
107TESTS+=             dep-colon-bug-cross-file
108TESTS+=             dep-double-colon
109TESTS+=             dep-double-colon-indep
110TESTS+=             dep-duplicate
111TESTS+=             dep-exclam
112TESTS+=             dep-none
113TESTS+=             dep-op-missing
114TESTS+=             dep-percent
115TESTS+=             dep-var
116TESTS+=             dep-wildcards
117TESTS+=             depsrc
118TESTS+=             depsrc-end
119TESTS+=             depsrc-exec
120TESTS+=             depsrc-ignore
121TESTS+=             depsrc-made
122TESTS+=             depsrc-make
123TESTS+=             depsrc-meta
124TESTS+=             depsrc-nometa
125TESTS+=             depsrc-nometa_cmp
126TESTS+=             depsrc-nopath
127TESTS+=             depsrc-notmain
128TESTS+=             depsrc-optional
129TESTS+=             depsrc-phony
130TESTS+=             depsrc-precious
131TESTS+=             depsrc-recursive
132TESTS+=             depsrc-silent
133TESTS+=             depsrc-use
134TESTS+=             depsrc-usebefore
135TESTS+=             depsrc-usebefore-double-colon
136TESTS+=             depsrc-wait
137TESTS+=             deptgt
138TESTS+=             deptgt-begin
139TESTS+=             deptgt-begin-fail
140TESTS+=             deptgt-begin-fail-indirect
141TESTS+=             deptgt-default
142TESTS+=             deptgt-delete_on_error
143TESTS+=             deptgt-end
144TESTS+=             deptgt-end-fail
145TESTS+=             deptgt-end-fail-all
146TESTS+=             deptgt-end-fail-indirect
147TESTS+=             deptgt-end-jobs
148TESTS+=             deptgt-error
149TESTS+=             deptgt-ignore
150TESTS+=             deptgt-interrupt
151TESTS+=             deptgt-main
152TESTS+=             deptgt-makeflags
153TESTS+=             deptgt-no_parallel
154TESTS+=             deptgt-nopath
155TESTS+=             deptgt-notparallel
156TESTS+=             deptgt-objdir
157TESTS+=             deptgt-order
158TESTS+=             deptgt-path
159TESTS+=             deptgt-path-suffix
160TESTS+=             deptgt-phony
161TESTS+=             deptgt-posix
162TESTS+=             deptgt-precious
163TESTS+=             deptgt-shell
164TESTS+=             deptgt-silent
165TESTS+=             deptgt-silent-jobs
166TESTS+=             deptgt-stale
167TESTS+=             deptgt-suffixes
168TESTS+=             dir
169TESTS+=             dir-expand-path
170TESTS+=             directive
171TESTS+=             directive-dinclude
172TESTS+=             directive-elif
173TESTS+=             directive-elifdef
174TESTS+=             directive-elifmake
175TESTS+=             directive-elifndef
176TESTS+=             directive-elifnmake
177TESTS+=             directive-else
178TESTS+=             directive-endfor
179TESTS+=             directive-endif
180TESTS+=             directive-error
181TESTS+=             directive-export
182TESTS+=             directive-export-env
183TESTS+=             directive-export-impl
184TESTS+=             directive-export-gmake
185TESTS+=             directive-export-literal
186TESTS+=             directive-for
187TESTS+=             directive-for-break
188TESTS+=             directive-for-empty
189TESTS+=             directive-for-errors
190TESTS+=             directive-for-escape
191TESTS+=             directive-for-generating-endif
192TESTS+=             directive-for-if
193TESTS+=             directive-for-lines
194TESTS+=             directive-for-null
195TESTS+=             directive-hyphen-include
196TESTS+=             directive-if
197TESTS+=             directive-if-nested
198TESTS+=             directive-ifdef
199TESTS+=             directive-ifmake
200TESTS+=             directive-ifndef
201TESTS+=             directive-ifnmake
202TESTS+=             directive-include
203TESTS+=             directive-include-fatal
204TESTS+=             directive-include-guard
205TESTS+=             directive-info
206TESTS+=             directive-misspellings
207TESTS+=             directive-sinclude
208TESTS+=             directive-undef
209TESTS+=             directive-unexport
210TESTS+=             directive-unexport-env
211TESTS+=             directive-warning
212TESTS+=             dollar
213TESTS+=             doterror
214TESTS+=             dotwait
215TESTS+=             error
216TESTS+=             # escape  # broken by reverting POSIX changes
217TESTS+=             export
218TESTS+=             export-all
219TESTS+=             export-env
220TESTS+=             export-variants
221TESTS+=             gnode-submake
222TESTS+=             hanoi-include
223TESTS+=             impsrc
224TESTS+=             include-main
225TESTS+=             job-flags
226TESTS+=             job-output-long-lines
227TESTS+=             job-output-null
228TESTS+=             jobs-empty-commands
229TESTS+=             jobs-empty-commands-error
230TESTS+=             jobs-error-indirect
231TESTS+=             jobs-error-nested
232TESTS+=             jobs-error-nested-make
233TESTS+=             lint
234TESTS+=             make-exported
235TESTS+=             meta-cmd-cmp
236TESTS+=             moderrs
237TESTS+=             modmisc
238.if ${.MAKE.UID} > 0
239TESTS+=             objdir-writable
240.endif
241TESTS+=             opt
242TESTS+=             opt-backwards
243TESTS+=             opt-chdir
244TESTS+=             opt-debug
245TESTS+=             opt-debug-all
246TESTS+=             opt-debug-archive
247TESTS+=             opt-debug-curdir
248TESTS+=             opt-debug-cond
249TESTS+=             opt-debug-dir
250TESTS+=             opt-debug-errors
251TESTS+=             opt-debug-errors-jobs
252TESTS+=             opt-debug-file
253TESTS+=             opt-debug-for
254TESTS+=             opt-debug-graph1
255TESTS+=             opt-debug-graph2
256TESTS+=             opt-debug-graph3
257TESTS+=             opt-debug-hash
258TESTS+=             opt-debug-jobs
259TESTS+=             opt-debug-lint
260TESTS+=             opt-debug-loud
261TESTS+=             opt-debug-meta
262TESTS+=             opt-debug-making
263TESTS+=             opt-debug-no-rm
264TESTS+=             opt-debug-parse
265TESTS+=             opt-debug-suff
266TESTS+=             opt-debug-targets
267TESTS+=             opt-debug-varraw
268TESTS+=             opt-debug-var
269TESTS+=             opt-debug-x-trace
270TESTS+=             opt-define
271TESTS+=             opt-env
272TESTS+=             opt-file
273TESTS+=             opt-ignore
274TESTS+=             opt-include-dir
275TESTS+=             opt-jobs
276TESTS+=             opt-jobs-internal
277TESTS+=             opt-jobs-no-action
278TESTS+=             opt-keep-going
279TESTS+=             opt-keep-going-indirect
280TESTS+=             opt-keep-going-multiple
281TESTS+=             opt-m-include-dir
282TESTS+=             opt-no-action
283TESTS+=             opt-no-action-at-all
284TESTS+=             opt-no-action-runflags
285TESTS+=             opt-no-action-touch
286TESTS+=             opt-query
287TESTS+=             opt-raw
288TESTS+=             opt-silent
289TESTS+=             opt-touch
290TESTS+=             opt-touch-jobs
291TESTS+=             opt-tracefile
292TESTS+=             opt-var-expanded
293TESTS+=             opt-var-literal
294TESTS+=             opt-version
295TESTS+=             opt-warnings-as-errors
296TESTS+=             opt-where-am-i
297TESTS+=             opt-x-reduce-exported
298TESTS+=             order
299TESTS+=             parse
300TESTS+=             parse-var
301TESTS+=             phony-end
302TESTS+=             posix
303TESTS+=             posix-execution
304TESTS+=             posix-expansion
305TESTS+=             posix-varassign
306TESTS+=             # posix1  # broken by reverting POSIX changes
307TESTS+=             recursive
308TESTS+=             sh
309TESTS+=             sh-dots
310TESTS+=             sh-errctl
311TESTS+=             sh-flags
312TESTS+=             sh-jobs
313TESTS+=             sh-jobs-error
314TESTS+=             sh-leading-at
315TESTS+=             sh-leading-hyphen
316TESTS+=             sh-leading-plus
317TESTS+=             sh-meta-chars
318TESTS+=             sh-multi-line
319TESTS+=             sh-single-line
320TESTS+=             shell-csh
321TESTS+=             shell-custom
322TESTS+=             shell-ksh
323TESTS+=             shell-sh
324TESTS+=             suff
325TESTS+=             suff-add-later
326TESTS+=             suff-clear-regular
327TESTS+=             suff-clear-single
328TESTS+=             suff-incomplete
329TESTS+=             suff-lookup
330TESTS+=             suff-main
331TESTS+=             suff-main-several
332TESTS+=             suff-phony
333TESTS+=             suff-rebuild
334TESTS+=             suff-self
335TESTS+=             suff-transform-debug
336TESTS+=             suff-transform-endless
337TESTS+=             suff-transform-expand
338TESTS+=             suff-transform-select
339TESTS+=             suff-use
340TESTS+=             sunshcmd
341TESTS+=             ternary
342TESTS+=             unexport
343TESTS+=             unexport-env
344TESTS+=             use-inference
345TESTS+=             var-readonly
346TESTS+=             var-scope
347TESTS+=             var-scope-cmdline
348TESTS+=             var-scope-env
349TESTS+=             var-scope-global
350TESTS+=             var-scope-local
351TESTS+=             var-scope-local-legacy
352TESTS+=             var-eval-short
353TESTS+=             var-op
354TESTS+=             var-op-append
355TESTS+=             var-op-assign
356TESTS+=             var-op-default
357TESTS+=             var-op-expand
358TESTS+=             var-op-shell
359TESTS+=             var-op-sunsh
360TESTS+=             var-recursive
361TESTS+=             varcmd
362TESTS+=             vardebug
363TESTS+=             varfind
364TESTS+=             varmisc
365TESTS+=             varmod
366TESTS+=             varmod-assign
367TESTS+=             varmod-assign-shell
368TESTS+=             varmod-defined
369TESTS+=             varmod-edge
370TESTS+=             varmod-exclam-shell
371TESTS+=             varmod-extension
372TESTS+=             varmod-gmtime
373TESTS+=             varmod-hash
374TESTS+=             varmod-head
375TESTS+=             varmod-ifelse
376TESTS+=             varmod-indirect
377TESTS+=             varmod-l-name-to-value
378TESTS+=             varmod-localtime
379TESTS+=             varmod-loop
380TESTS+=             varmod-loop-delete
381TESTS+=             varmod-loop-varname
382TESTS+=             varmod-match
383TESTS+=             varmod-match-escape
384TESTS+=             varmod-mtime
385TESTS+=             varmod-no-match
386TESTS+=             varmod-order
387TESTS+=             varmod-order-numeric
388TESTS+=             varmod-order-reverse
389TESTS+=             varmod-order-shuffle
390TESTS+=             varmod-order-string
391TESTS+=             varmod-path
392TESTS+=             varmod-quote
393TESTS+=             varmod-quote-dollar
394TESTS+=             varmod-range
395TESTS+=             varmod-remember
396TESTS+=             varmod-root
397TESTS+=             varmod-select-words
398TESTS+=             varmod-shell
399TESTS+=             varmod-subst
400TESTS+=             varmod-subst-regex
401TESTS+=             varmod-sun-shell
402TESTS+=             varmod-sysv
403TESTS+=             varmod-tail
404TESTS+=             varmod-to-abs
405TESTS+=             varmod-to-lower
406TESTS+=             varmod-to-many-words
407TESTS+=             varmod-to-one-word
408TESTS+=             varmod-to-separator
409TESTS+=             varmod-to-title
410TESTS+=             varmod-to-upper
411TESTS+=             varmod-undefined
412TESTS+=             varmod-unique
413TESTS+=             varname
414TESTS+=             varname-dollar
415TESTS+=             varname-dot-alltargets
416TESTS+=             varname-dot-curdir
417TESTS+=             varname-dot-includes
418TESTS+=             varname-dot-includedfromdir
419TESTS+=             varname-dot-includedfromfile
420TESTS+=             varname-dot-libs
421TESTS+=             varname-dot-make-dependfile
422TESTS+=             varname-dot-make-expand_variables
423TESTS+=             varname-dot-make-exported
424TESTS+=             varname-dot-make-jobs
425TESTS+=             varname-dot-make-jobs-prefix
426TESTS+=             varname-dot-make-level
427TESTS+=             varname-dot-make-makefile_preference
428TESTS+=             varname-dot-make-makefiles
429TESTS+=             varname-dot-make-meta-bailiwick
430TESTS+=             varname-dot-make-meta-created
431TESTS+=             varname-dot-make-meta-files
432.if ${.MAKE.PATH_FILEMON:Uno:Nktrace:N/dev*} == "" && ${TMPDIR:N/tmp*:N/var/tmp*} != ""
433# these tests will not work if TMPDIR is or is a subdir of
434# /tmp or /var/tmp
435TESTS+=             varname-dot-make-meta-ignore_filter
436TESTS+=             varname-dot-make-meta-ignore_paths
437TESTS+=             varname-dot-make-meta-ignore_patterns
438TESTS+=             varname-dot-make-path_filemon
439.endif
440TESTS+=             varname-dot-make-meta-prefix
441TESTS+=             varname-dot-make-mode
442TESTS+=             varname-dot-make-pid
443TESTS+=             varname-dot-make-ppid
444TESTS+=             varname-dot-make-save_dollars
445TESTS+=             varname-dot-makeflags
446TESTS+=             varname-dot-makeoverrides
447TESTS+=             varname-dot-newline
448TESTS+=             varname-dot-objdir
449TESTS+=             varname-dot-parsedir
450TESTS+=             varname-dot-parsefile
451TESTS+=             varname-dot-path
452TESTS+=             varname-dot-shell
453TESTS+=             varname-dot-suffixes
454TESTS+=             varname-dot-targets
455TESTS+=             varname-empty
456TESTS+=             varname-make
457TESTS+=             varname-make_print_var_on_error
458TESTS+=             varname-make_print_var_on_error-jobs
459TESTS+=             varname-makefile
460TESTS+=             varname-makeflags
461TESTS+=             varname-pwd
462TESTS+=             varname-vpath
463TESTS+=             varparse-dynamic
464TESTS+=             varparse-errors
465TESTS+=             varparse-mod
466TESTS+=             varparse-undef-partial
467
468# Some tests just do not work on some platforms or environments
469# so allow for some filtering.
470.if !empty(BROKEN_TESTS)
471TESTS:= ${TESTS:${BROKEN_TESTS:S,^,N,:ts:}}
472.endif
473
474# Ideas for more tests:
475#         char-0020-space.mk
476#         char-005C-backslash.mk
477#         escape-cond-str.mk
478#         escape-cond-func-arg.mk
479#         escape-varmod.mk
480#         escape-varmod-define.mk
481#         escape-varmod-match.mk
482#         escape-varname.mk
483#         escape-varassign-varname.mk
484#         escape-varassign-varname-cmdline.mk
485#         escape-varassign-value.mk
486#         escape-varassign-value-cmdline.mk
487#         escape-dependency-source.mk
488#         escape-dependency-target.mk
489#         escape-for-varname.mk
490#         escape-for-item.mk
491#         posix-*.mk (see posix.mk and posix1.mk)
492
493# Additional environment variables for some of the tests.
494# The base environment is -i PATH="$PATH".
495ENV.depsrc-optional+=   TZ=UTC
496ENV.directive-undef=          ENV_VAR=env-value
497ENV.opt-env=                  FROM_ENV=value-from-env
498ENV.opt-m-include-dir=        ${MAKEOBJDIR:DMAKEOBJDIR=${MAKEOBJDIR}}
499ENV.varmisc=                  FROM_ENV=env
500ENV.varmisc+=                 FROM_ENV_BEFORE=env
501ENV.varmisc+=                 FROM_ENV_AFTER=env
502ENV.varmod-localtime+=        TZ=Europe/Berlin
503ENV.varname-vpath+= VPATH=varname-vpath.dir:varname-vpath.dir2
504
505# Override make flags for some of the tests; default is -k.
506# If possible, write ".MAKEFLAGS: -dv" in the test .mk file instead of
507# settings FLAGS.test=-dv here, since that is closer to the test code.
508FLAGS.cond-func-make=                   via-cmdline
509FLAGS.doterror=                         # none, especially not -k
510FLAGS.jobs-error-indirect=    # none, especially not -k
511FLAGS.jobs-error-nested=      # none, especially not -k
512FLAGS.jobs-error-nested-make= # none, especially not -k
513FLAGS.varname-empty=                    -dv '$${:U}=cmdline-u' '=cmdline-plain'
514
515# Some tests need extra postprocessing.
516SED_CMDS.deptgt-phony=        ${STD_SED_CMDS.dd}
517SED_CMDS.dir=                 ${STD_SED_CMDS.dd}
518SED_CMDS.directive-include-guard= \
519          -e '/\.MAKEFLAGS/d' \
520          -e '/^Parsing .*:[1-9][0-9]*:/d' \
521          -e '/^SetFilenameVars:/d' \
522          -e '/^ParseDependency/d' \
523          -e '/^ParseEOF:/d'
524SED_CMDS.export=    -e '/^[^=_A-Za-z0-9]*=/d'
525SED_CMDS.export-all=          ${SED_CMDS.export}
526SED_CMDS.export-env=          ${SED_CMDS.export}
527SED_CMDS.job-output-long-lines= \
528          ${:D Job separators on their own line are ok. } \
529          -e '/^--- job-[ab] ---$$/d' \
530          ${:D Plain output lines are ok as well. } \
531          ${:D They may come in multiples of 1024 or as 10000. } \
532          -e '/^aa*$$/d' \
533          -e '/^bb*$$/d' \
534          ${:D The following lines should rather not occur since the job } \
535          ${:D marker should always be at the beginning of the line. } \
536          -e '/^aa*--- job-b ---$$/d' \
537          -e '/^bb*--- job-a ---$$/d'
538
539# meta line numbers can vary based on filemon implementation
540SED_CMDS.meta-ignore= -e 's,\(\.meta:\)[1-9][0-9]*:,\1<line>:,'
541
542SED_CMDS.opt-chdir=           -e 's,\(nonexistent\).[1-9][0-9]*,\1,'
543SED_CMDS.opt-debug-graph1=    ${STD_SED_CMDS.dg1}
544SED_CMDS.opt-debug-graph2=    ${STD_SED_CMDS.dg2}
545SED_CMDS.opt-debug-graph3=    ${STD_SED_CMDS.dg3}
546SED_CMDS.opt-debug-hash=      -e 's,\(entries\)=[1-9][0-9],\1=<entries>,'
547SED_CMDS.opt-debug-jobs=      -e 's,([0-9][0-9]*),(<pid>),'
548SED_CMDS.opt-debug-jobs+=     -e 's,pid [0-9][0-9]*,pid <pid>,'
549SED_CMDS.opt-debug-jobs+=     -e 's,Process [0-9][0-9]*,Process <pid>,'
550SED_CMDS.opt-debug-jobs+=     -e 's,JobFinish: [0-9][0-9]*,JobFinish: <pid>,'
551SED_CMDS.opt-debug-jobs+=     -e 's,Command: ${.SHELL:T},Command: <shell>,'
552# The "-q" may be there or not, see jobs.c, variable shells.
553SED_CMDS.opt-debug-jobs+=     -e 's,^\(.Command: <shell>\) -q,\1,'
554SED_CMDS.opt-debug-lint+=     ${STD_SED_CMDS.regex}
555SED_CMDS.opt-jobs-no-action=  ${STD_SED_CMDS.hide-from-output}
556SED_CMDS.opt-no-action-runflags= ${STD_SED_CMDS.hide-from-output}
557SED_CMDS.opt-where-am-i=      -e '/usr.obj/d'
558# For Compat_RunCommand, useShell == false.
559SED_CMDS.sh-dots=             -e 's,^.*\.\.\.:.*,<not found: ...>,'
560# For Compat_RunCommand, useShell == true.
561SED_CMDS.sh-dots+=            -e 's,^make: exec(\(.*\)) failed (.*)$$,<not found: \1>,'
562SED_CMDS.sh-dots+=            -e 's,^\(\*\*\* Error code \)[1-9][0-9]*,\1<nonzero>,'
563SED_CMDS.sh-errctl=           ${STD_SED_CMDS.dj}
564SED_CMDS.sh-flags=            ${STD_SED_CMDS.hide-from-output}
565SED_CMDS.sh-leading-hyphen=   ${STD_SED_CMDS.shell}
566SED_CMDS.suff-main+=                    ${STD_SED_CMDS.dg1}
567SED_CMDS.suff-main-several+=  ${STD_SED_CMDS.dg1}
568SED_CMDS.suff-transform-debug+=         ${STD_SED_CMDS.dg1}
569SED_CMDS.var-op-shell+=                 ${STD_SED_CMDS.shell}
570SED_CMDS.var-op-shell+=                 -e '/command/s,No such.*,not found,'
571SED_CMDS.vardebug+=           -e 's,${.SHELL},</path/to/shell>,'
572SED_CMDS.varmod-mtime+=                 -e "s,\(.*\)': .*,\1': <ENOENT>,"
573SED_CMDS.varmod-subst-regex+= ${STD_SED_CMDS.regex}
574SED_CMDS.varparse-errors+=    ${STD_SED_CMDS.timestamp}
575SED_CMDS.varname-dot-make-meta-ignore_filter+= ${SED_CMDS.meta-ignore}
576SED_CMDS.varname-dot-make-meta-ignore_paths+= ${SED_CMDS.meta-ignore}
577SED_CMDS.varname-dot-make-meta-ignore_patterns+= ${SED_CMDS.meta-ignore}
578SED_CMDS.varname-dot-parsedir=          -e '/in some cases/ s,^make: [^:]*:,make: <normalized>:,'
579SED_CMDS.varname-dot-parsefile=         -e '/in some cases/ s,^make: [^:]*:,make: <normalized>:,'
580SED_CMDS.varname-dot-shell=   -e 's, = /[^ ]*, = (details omitted),g'
581SED_CMDS.varname-dot-shell+=  -e 's,"/[^" ]*","(details omitted)",g'
582SED_CMDS.varname-dot-shell+=  -e 's,\[/[^] ]*\],[(details omitted)],g'
583SED_CMDS.varname-empty=                 ${.OBJDIR .PARSEDIR .PATH .SHELL .SYSPATH:L:@v@-e '/\\$v/d'@}
584
585# Some tests need an additional round of postprocessing.
586POSTPROC.depsrc-wait=                   sed -e '/^---/d' -e 's,^\(: Making 3[abc]\)[123]$$,\1,'
587POSTPROC.deptgt-suffixes=     awk '/^\#\*\*\* Suffixes/,/^never-stop/'
588POSTPROC.gnode-submake=                 awk '/Input graph/, /^$$/'
589POSTPROC.varname-dot-make-mode=         sed 's,^\(: Making [abc]\)[123]$$,\1,'
590
591# Some tests reuse other tests, which makes them unnecessarily fragile.
592export-all.rawout: export.mk
593unexport.rawout: export.mk
594unexport-env.rawout: export.mk
595
596# End of the configuration section.
597
598# Some standard sed commands, to be used in the SED_CMDS above.
599
600# In tests that use the debugging option -dd, ignore debugging output that is
601# only logged in -DCLEANUP mode.
602STD_SED_CMDS.dd=    -e '/^OpenDirs_Done:/d'
603STD_SED_CMDS.dd+=   -e '/^CachedDir /d'
604STD_SED_CMDS.dd+=   -e 's,  ${DEFSYSPATH:U/usr/share/mk} ,  <defsyspath> ,'
605
606# Omit details such as process IDs from the output of the -dg1 option.
607STD_SED_CMDS.dg1=   -e 's,${.CURDIR}$$,<curdir>,'
608STD_SED_CMDS.dg1+=  -e 's,  ${DEFSYSPATH:U/usr/share/mk}$$,  <defsyspath>,'
609STD_SED_CMDS.dg1+=  -e 's,^\(\.MAKE *=\) .*,\1 <details omitted>,'
610STD_SED_CMDS.dg1+=  -e 's,^\(\.MAKE\.[A-Z_]* *=\) .*,\1 <details omitted>,'
611STD_SED_CMDS.dg1+=  -e 's,^\(\.MAKE\.JOBS\.C *=\) .*,\1 <details omitted>,'
612STD_SED_CMDS.dg1+=  -e 's,^\(MACHINE[_ARCH]* *=\) .*,\1 <details omitted>,'
613STD_SED_CMDS.dg1+=  -e 's,^\(MAKE *=\) .*,\1 <details omitted>,'
614STD_SED_CMDS.dg1+=  -e 's,^\(\.SHELL *=\) .*,\1 <details omitted>,'
615STD_SED_CMDS.dg1+=  -e '/\.SYSPATH/d'
616
617STD_SED_CMDS.dg2=   ${STD_SED_CMDS.dg1}
618STD_SED_CMDS.dg2+=  -e 's,\(last modified\) ..:..:.. ... ..\, ....,\1 <timestamp>,'
619STD_SED_CMDS.dg3=   ${STD_SED_CMDS.dg2}
620
621# Omit details such as process IDs from the output of the -dj option.
622STD_SED_CMDS.dj= \
623          -e '/Process/d;/JobFinish:/d' \
624          -e 's, \(pid\) [0-9][0-9]*, \1 <pid>,' \
625          -e 's,^\( Command:\) .*,\1 <shell>,'
626
627# Reduce the noise for tests running with the -n option, since there is no
628# other way to suppress the echoing of the commands.
629STD_SED_CMDS.hide-from-output= \
630          -e '/^echo hide-from-output/d' \
631          -e 's,hide-from-output ,,' \
632          -e 's,hide-from-output,,'
633
634# Normalize the output for error messages from the shell.
635#
636# $shell -c '...'
637#         NetBSD sh ...: not found
638#         NetBSD ksh          ksh: ...: not found
639#         bash 5.0.18         bash: ...: command not found
640#         bash 5.1.0          bash: line 1: ...: command not found
641#         dash                dash: 1: ...: not found
642#
643# $shell -c '< /nonexistent'
644#         NetBSD sh sh: cannot open /nonexistent: no such file
645#         NetBSD ksh          ksh: cannot open /nonexistent: No such file or directory
646#         bash 5.0.18         bash: /nonexistent: No such file or directory
647#         bash 5.1.0          bash: line 1: /nonexistent: No such file or directory
648#         dash                dash: 1: cannot open /nonexistent: No such file
649#
650# echo '< /nonexistent' | $shell
651#         NetBSD sh sh: cannot open /nonexistent: no such file
652#         NetBSD ksh          ksh: <stdin>[1]: cannot open /nonexistent: No such file or directory
653#         bash 5.0.18         bash: line 1: /nonexistent: No such file or directory
654#         bash 5.1.0          bash: line 1: /nonexistent: No such file or directory
655#         dash                dash: 1: cannot open /nonexistent: No such file
656#
657STD_SED_CMDS.shell+=                    -e 's,^${.SHELL},${.SHELL:T},'
658STD_SED_CMDS.shell+=                    -e 's,^${.SHELL:T}: line [0-9][0-9]*: ,,'
659STD_SED_CMDS.shell+=                    -e 's,^${.SHELL:T}: [0-9][0-9]*: ,,'
660STD_SED_CMDS.shell+=                    -e 's,^${.SHELL:T}: ,,'
661STD_SED_CMDS.shell+=                    -e 's,: command not found,: not found,'
662
663# The actual error messages for a failed regcomp or regexec differ between the
664# implementations.
665STD_SED_CMDS.regex= \
666          -e 's,\(Regex compilation error:\).*,\1 (details omitted),'
667
668# Normalize timestamps from ':gmtime' or ':localtime' to '<timestamp>'.
669# See STD_SED_CMDS.dg2 for timestamps from the debug log.
670STD_SED_CMDS.timestamp= \
671          -e 's,[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [12][0-9][0-9][0-9],<timestamp>,'
672
673# End of the configuration helpers section.
674
675UNIT_TESTS:=        ${.PARSEDIR}
676.PATH: ${UNIT_TESTS}
677
678.if ${USE_ABSOLUTE_TESTNAMES:Uno} == yes
679OUTFILES= ${TESTS:@test@${.CURDIR:tA}/${test}.out@}
680.else
681OUTFILES= ${TESTS:=.out}
682.endif
683
684all: ${OUTFILES}
685
686CLEANFILES=                   *.rawout *.out *.status *.tmp *.core *.tmp
687CLEANFILES+=                  obj*.[och] lib*.a   # posix1.mk
688CLEANFILES+=                  issue* .[ab]*                 # suffixes.mk
689CLEANDIRS=                    dir dummy *.tmp               # posix1.mk
690
691clean:
692          rm -rf ${CLEANDIRS}
693          rm -f ${CLEANFILES}
694
695TEST_MAKE?=         ${.MAKE}
696TOOL_SED?=          sed
697
698# ensure consistent results from sort(1)
699LC_ALL=             C
700LANG=               C
701.export LANG LC_ALL
702
703# Some Linux systems such as Fedora have deprecated egrep in favor of grep -E.
704.if ${.MAKE.OS:NLinux} == ""
705EGREP= grep -E
706.endif
707# Keep the classical definition for all other systems.  Just as the bmake code
708# is kept compatible with C90, the tests are kept compatible with systems that
709# are several decades old and don't follow modern POSIX standards.
710EGREP?= egrep
711
712MAKE_TEST_ENV=  EGREP="${EGREP}"
713MAKE_TEST_ENV+=     MALLOC_OPTIONS="JA" # for jemalloc 100
714MAKE_TEST_ENV+=     MALLOC_CONF="junk:true"       # for jemalloc 510
715MAKE_TEST_ENV+= TMPDIR=${TMPDIR}
716
717.if ${.MAKE.OS} == "NetBSD"
718LIMIT_RESOURCES?=   ulimit -v 300000
719.endif
720LIMIT_RESOURCES?=   :
721
722# Each test is run in a sub-make, to keep the tests from interfering with
723# each other, and because they use different environment variables and
724# command line options.
725.SUFFIXES: .mk .rawout .out
726.mk.rawout:
727          @${_MKMSG_TEST:Uecho '#      test '} ${.PREFIX}
728          @set -eu; \
729          ${LIMIT_RESOURCES}; \
730          cd ${.OBJDIR}; \
731          env -i PATH="$$PATH" ${MAKE_TEST_ENV} ${ENV.${.PREFIX:T}} \
732            ${TEST_MAKE} \
733              -r -C ${.CURDIR} -f ${.IMPSRC} \
734              ${FLAGS.${.PREFIX:T}:U-k} \
735              > ${.TARGET}.tmp 2>&1 \
736          && status=$$? || status=$$?; \
737          echo $$status > ${.TARGET:R}.status
738          @mv ${.TARGET}.tmp ${.TARGET}
739
740# Postprocess the test output to make the output platform-independent.
741#
742# Replace anything after 'stopped in' with unit-tests
743_SED_CMDS+=         -e '/stopped/s, in /.*, in unit-tests,'
744# Allow the test files to be placed anywhere.
745_SED_CMDS+=         -e 's,\(\.PARSEDIR}\) = `'"/[^']*'"',\1 = <some-dir>,'
746_SED_CMDS+=         -e 's,\(\.INCLUDEDFROMDIR}\) = `'"/[^']*'"',\1 = <some-dir>,'
747_SED_CMDS+=         -e 's,${TMPDIR},<tmpdir>,g' -e 's,${TMPDIR:tA},<tmpdir>,g'
748# canonicalize ${.OBJDIR} and ${.CURDIR}
749_SED_CMDS+=         -e 's,${.CURDIR},<curdir>,g'
750.if ${.OBJDIR} != ${.CURDIR}
751# yes this is inaccurate but none of the tests expect <objdir> anywhere
752# which we get depending on how MAKEOBJDIR is set.
753_SED_CMDS+=         -e 's,${.OBJDIR},<curdir>,g' -e 's,${.OBJDIR:tA},<curdir>,g'
754.endif
755# always pretend .MAKE was called 'make'
756_SED_CMDS+=         -e 's,^${TEST_MAKE:T:S,.,\\.,g}[][0-9]*:,make:,'
757_SED_CMDS+=         -e 's,${TEST_MAKE:S,.,\\.,g},make,'
758_SED_CMDS+=         -e 's,^usage: ${TEST_MAKE:T:S,.,\\.,g} ,usage: make ,'
759_SED_CMDS+=         -e 's,${TEST_MAKE:T:S,.,\\.,g}\(\[[1-9][0-9]*\]:\),make\1,'
760_SED_CMDS+=         -e 's,<curdir>/,,g'
761_SED_CMDS+=         -e 's,${UNIT_TESTS:S,.,\\.,g}/,,g'
762_SED_CMDS+=         -e '/MAKE_VERSION/d'
763_SED_CMDS+=         -e '/EGREP=/d'
764
765.rawout.out:
766          @${TOOL_SED} ${_SED_CMDS} ${SED_CMDS.${.PREFIX:T}} \
767            < ${.IMPSRC} > ${.TARGET}.tmp
768          @${POSTPROC.${.PREFIX:T}:D \
769              ${POSTPROC.${.PREFIX:T}} < ${.TARGET}.tmp > ${.TARGET}.post \
770              && mv ${.TARGET}.post ${.TARGET}.tmp}
771          @echo "exit status `cat ${.TARGET:R}.status`" >> ${.TARGET}.tmp
772          @mv ${.TARGET}.tmp ${.TARGET}
773
774# Compare all output files
775test:     ${OUTFILES} .PHONY
776          @failed= ; \
777          for test in ${TESTS}; do \
778            diff -u ${UNIT_TESTS}/$${test}.exp $${test}.out \
779            || failed="$${failed}$${failed:+ }$${test}" ; \
780          done ; \
781          if [ -n "$${failed}" ]; then \
782            echo "Failed tests: $${failed}" ; false ; \
783          else \
784            echo "All tests passed" ; \
785            lua=${LUA:Ulua} ; \
786            have_lua=$$("$$lua" -e 'print "yes"' 2>&1) ; \
787            if [ "$$have_lua" = "yes" ]; then \
788              (cd ${.CURDIR} && "$$lua" ./check-expect.lua *.mk); \
789            fi; \
790          fi
791
792accept:
793          @for test in ${TESTS}; do \
794            cmp -s ${UNIT_TESTS}/$${test}.exp $${test}.out \
795            || { echo "Replacing $${test}.exp" ; \
796                 cp $${test}.out ${UNIT_TESTS}/$${test}.exp ; } \
797          done
798
799# Note: only works for adding tests.
800# To remove a test, the $$mi file must be edited manually.
801sync-mi:
802          @set -eu;                                                             \
803          cd "${MAKEFILE:tA:H}/../../..";                                                 \
804          mi="distrib/sets/lists/tests/mi";                                     \
805          cvs update "$$mi";                                                    \
806          testsdir="usr.bin/make/unit-tests";                                   \
807          fmt="./usr/tests/$$testsdir/%s\ttests-usr.bin-tests\tcompattestfile,atf\\n"; \
808          cat "$$mi" > "$$mi.tmp";                                              \
809          (cd "$$testsdir" && egrep '\.(exp|mk)/' CVS/Entries | cut -d/ -f2) | \
810          xargs printf "$$fmt" >> "$$mi.tmp"; \
811          distrib/sets/fmt-list "$$mi.tmp";                                     \
812          mv "$$mi.tmp" "$$mi";                                                           \
813          cvs diff "$$mi" || true
814
815.if exists(${TEST_MAKE})
816${TESTS:=.rawout}: ${TEST_MAKE}
817# in meta mode, we *know* if a target script is impacted
818# by a makefile change.
819.if ${.MAKE.MODE:Unormal:Mmeta} == ""
820${TESTS:=.rawout}: ${.PARSEDIR}/Makefile
821.endif
822.endif
823
824.-include <bsd.obj.mk>
825