tag bmake-20200902
This commit is contained in:
parent
c5f0cecf5a
commit
14ecce503c
2735
20200902/ChangeLog
Normal file
2735
20200902/ChangeLog
Normal file
File diff suppressed because it is too large
Load Diff
644
20200902/FILES
Normal file
644
20200902/FILES
Normal file
@ -0,0 +1,644 @@
|
||||
ChangeLog
|
||||
FILES
|
||||
LICENSE
|
||||
Makefile
|
||||
Makefile.config.in
|
||||
PSD.doc/Makefile
|
||||
PSD.doc/tutorial.ms
|
||||
README
|
||||
VERSION
|
||||
aclocal.m4
|
||||
arch.c
|
||||
bmake.1
|
||||
bmake.cat1
|
||||
boot-strap
|
||||
bsd.after-import.mk
|
||||
buf.c
|
||||
buf.h
|
||||
compat.c
|
||||
cond.c
|
||||
config.h.in
|
||||
configure
|
||||
configure.in
|
||||
dir.c
|
||||
dir.h
|
||||
dirname.c
|
||||
enum.c
|
||||
enum.h
|
||||
filemon/filemon.h
|
||||
filemon/filemon_dev.c
|
||||
filemon/filemon_ktrace.c
|
||||
find_lib.sh
|
||||
for.c
|
||||
getopt.c
|
||||
hash.c
|
||||
hash.h
|
||||
install-sh
|
||||
job.c
|
||||
job.h
|
||||
lst.c
|
||||
lst.h
|
||||
machine.sh
|
||||
main.c
|
||||
make-bootstrap.sh.in
|
||||
make-conf.h
|
||||
make.1
|
||||
make.c
|
||||
make.h
|
||||
make_malloc.c
|
||||
make_malloc.h
|
||||
makefile.in
|
||||
meta.c
|
||||
meta.h
|
||||
metachar.c
|
||||
metachar.h
|
||||
missing/sys/cdefs.h
|
||||
mkdeps.sh
|
||||
nonints.h
|
||||
os.sh
|
||||
parse.c
|
||||
pathnames.h
|
||||
ranlib.h
|
||||
realpath.c
|
||||
setenv.c
|
||||
sigcompat.c
|
||||
str.c
|
||||
stresep.c
|
||||
strlcpy.c
|
||||
strlist.c
|
||||
strlist.h
|
||||
suff.c
|
||||
targ.c
|
||||
trace.c
|
||||
trace.h
|
||||
unit-tests/Makefile
|
||||
unit-tests/Makefile.config.in
|
||||
unit-tests/archive.exp
|
||||
unit-tests/archive.mk
|
||||
unit-tests/archive-suffix.exp
|
||||
unit-tests/archive-suffix.mk
|
||||
unit-tests/cmd-interrupt.exp
|
||||
unit-tests/cmd-interrupt.mk
|
||||
unit-tests/cmdline.exp
|
||||
unit-tests/cmdline.mk
|
||||
unit-tests/comment.exp
|
||||
unit-tests/comment.mk
|
||||
unit-tests/cond-cmp-numeric-eq.exp
|
||||
unit-tests/cond-cmp-numeric-eq.mk
|
||||
unit-tests/cond-cmp-numeric-ge.exp
|
||||
unit-tests/cond-cmp-numeric-ge.mk
|
||||
unit-tests/cond-cmp-numeric-gt.exp
|
||||
unit-tests/cond-cmp-numeric-gt.mk
|
||||
unit-tests/cond-cmp-numeric-le.exp
|
||||
unit-tests/cond-cmp-numeric-le.mk
|
||||
unit-tests/cond-cmp-numeric-lt.exp
|
||||
unit-tests/cond-cmp-numeric-lt.mk
|
||||
unit-tests/cond-cmp-numeric-ne.exp
|
||||
unit-tests/cond-cmp-numeric-ne.mk
|
||||
unit-tests/cond-cmp-numeric.exp
|
||||
unit-tests/cond-cmp-numeric.mk
|
||||
unit-tests/cond-cmp-string.exp
|
||||
unit-tests/cond-cmp-string.mk
|
||||
unit-tests/cond-func.exp
|
||||
unit-tests/cond-func.mk
|
||||
unit-tests/cond-func-commands.exp
|
||||
unit-tests/cond-func-commands.mk
|
||||
unit-tests/cond-func-defined.exp
|
||||
unit-tests/cond-func-defined.mk
|
||||
unit-tests/cond-func-empty.exp
|
||||
unit-tests/cond-func-empty.mk
|
||||
unit-tests/cond-func-exists.exp
|
||||
unit-tests/cond-func-exists.mk
|
||||
unit-tests/cond-func-make.exp
|
||||
unit-tests/cond-func-make.mk
|
||||
unit-tests/cond-func-target.exp
|
||||
unit-tests/cond-func-target.mk
|
||||
unit-tests/cond-late.exp
|
||||
unit-tests/cond-late.mk
|
||||
unit-tests/cond-op-and.exp
|
||||
unit-tests/cond-op-and.mk
|
||||
unit-tests/cond-op-not.exp
|
||||
unit-tests/cond-op-not.mk
|
||||
unit-tests/cond-op-or.exp
|
||||
unit-tests/cond-op-or.mk
|
||||
unit-tests/cond-op-parentheses.exp
|
||||
unit-tests/cond-op-parentheses.mk
|
||||
unit-tests/cond-op.exp
|
||||
unit-tests/cond-op.mk
|
||||
unit-tests/cond-short.exp
|
||||
unit-tests/cond-short.mk
|
||||
unit-tests/cond-token-number.exp
|
||||
unit-tests/cond-token-number.mk
|
||||
unit-tests/cond-token-plain.exp
|
||||
unit-tests/cond-token-plain.mk
|
||||
unit-tests/cond-token-string.exp
|
||||
unit-tests/cond-token-string.mk
|
||||
unit-tests/cond-token-var.exp
|
||||
unit-tests/cond-token-var.mk
|
||||
unit-tests/cond1.exp
|
||||
unit-tests/cond1.mk
|
||||
unit-tests/cond2.exp
|
||||
unit-tests/cond2.mk
|
||||
unit-tests/counter.exp
|
||||
unit-tests/counter.mk
|
||||
unit-tests/dep-colon.exp
|
||||
unit-tests/dep-colon.mk
|
||||
unit-tests/dep-double-colon.exp
|
||||
unit-tests/dep-double-colon.mk
|
||||
unit-tests/dep-exclam.exp
|
||||
unit-tests/dep-exclam.mk
|
||||
unit-tests/dep-none.exp
|
||||
unit-tests/dep-none.mk
|
||||
unit-tests/dep-var.exp
|
||||
unit-tests/dep-var.mk
|
||||
unit-tests/dep-wildcards.exp
|
||||
unit-tests/dep-wildcards.mk
|
||||
unit-tests/dep.exp
|
||||
unit-tests/dep.mk
|
||||
unit-tests/depsrc-exec.exp
|
||||
unit-tests/depsrc-exec.mk
|
||||
unit-tests/depsrc-ignore.exp
|
||||
unit-tests/depsrc-ignore.mk
|
||||
unit-tests/depsrc-made.exp
|
||||
unit-tests/depsrc-made.mk
|
||||
unit-tests/depsrc-make.exp
|
||||
unit-tests/depsrc-make.mk
|
||||
unit-tests/depsrc-meta.exp
|
||||
unit-tests/depsrc-meta.mk
|
||||
unit-tests/depsrc-nometa.exp
|
||||
unit-tests/depsrc-nometa.mk
|
||||
unit-tests/depsrc-nometa_cmp.exp
|
||||
unit-tests/depsrc-nometa_cmp.mk
|
||||
unit-tests/depsrc-nopath.exp
|
||||
unit-tests/depsrc-nopath.mk
|
||||
unit-tests/depsrc-notmain.exp
|
||||
unit-tests/depsrc-notmain.mk
|
||||
unit-tests/depsrc-optional.exp
|
||||
unit-tests/depsrc-optional.mk
|
||||
unit-tests/depsrc-phony.exp
|
||||
unit-tests/depsrc-phony.mk
|
||||
unit-tests/depsrc-precious.exp
|
||||
unit-tests/depsrc-precious.mk
|
||||
unit-tests/depsrc-recursive.exp
|
||||
unit-tests/depsrc-recursive.mk
|
||||
unit-tests/depsrc-silent.exp
|
||||
unit-tests/depsrc-silent.mk
|
||||
unit-tests/depsrc-use.exp
|
||||
unit-tests/depsrc-use.mk
|
||||
unit-tests/depsrc-usebefore.exp
|
||||
unit-tests/depsrc-usebefore.mk
|
||||
unit-tests/depsrc-usebefore-double-colon.exp
|
||||
unit-tests/depsrc-usebefore-double-colon.mk
|
||||
unit-tests/depsrc-wait.exp
|
||||
unit-tests/depsrc-wait.mk
|
||||
unit-tests/depsrc.exp
|
||||
unit-tests/depsrc.mk
|
||||
unit-tests/deptgt-begin.exp
|
||||
unit-tests/deptgt-begin.mk
|
||||
unit-tests/deptgt-default.exp
|
||||
unit-tests/deptgt-default.mk
|
||||
unit-tests/deptgt-delete_on_error.exp
|
||||
unit-tests/deptgt-delete_on_error.mk
|
||||
unit-tests/deptgt-end.exp
|
||||
unit-tests/deptgt-end.mk
|
||||
unit-tests/deptgt-error.exp
|
||||
unit-tests/deptgt-error.mk
|
||||
unit-tests/deptgt-ignore.exp
|
||||
unit-tests/deptgt-ignore.mk
|
||||
unit-tests/deptgt-interrupt.exp
|
||||
unit-tests/deptgt-interrupt.mk
|
||||
unit-tests/deptgt-main.exp
|
||||
unit-tests/deptgt-main.mk
|
||||
unit-tests/deptgt-makeflags.exp
|
||||
unit-tests/deptgt-makeflags.mk
|
||||
unit-tests/deptgt-no_parallel.exp
|
||||
unit-tests/deptgt-no_parallel.mk
|
||||
unit-tests/deptgt-nopath.exp
|
||||
unit-tests/deptgt-nopath.mk
|
||||
unit-tests/deptgt-notparallel.exp
|
||||
unit-tests/deptgt-notparallel.mk
|
||||
unit-tests/deptgt-objdir.exp
|
||||
unit-tests/deptgt-objdir.mk
|
||||
unit-tests/deptgt-order.exp
|
||||
unit-tests/deptgt-order.mk
|
||||
unit-tests/deptgt-path-suffix.exp
|
||||
unit-tests/deptgt-path-suffix.mk
|
||||
unit-tests/deptgt-path.exp
|
||||
unit-tests/deptgt-path.mk
|
||||
unit-tests/deptgt-phony.exp
|
||||
unit-tests/deptgt-phony.mk
|
||||
unit-tests/deptgt-precious.exp
|
||||
unit-tests/deptgt-precious.mk
|
||||
unit-tests/deptgt-shell.exp
|
||||
unit-tests/deptgt-shell.mk
|
||||
unit-tests/deptgt-silent.exp
|
||||
unit-tests/deptgt-silent.mk
|
||||
unit-tests/deptgt-stale.exp
|
||||
unit-tests/deptgt-stale.mk
|
||||
unit-tests/deptgt-suffixes.exp
|
||||
unit-tests/deptgt-suffixes.mk
|
||||
unit-tests/deptgt.exp
|
||||
unit-tests/deptgt.mk
|
||||
unit-tests/dir.exp
|
||||
unit-tests/dir.mk
|
||||
unit-tests/dir-expand-path.exp
|
||||
unit-tests/dir-expand-path.mk
|
||||
unit-tests/directive-elif.exp
|
||||
unit-tests/directive-elif.mk
|
||||
unit-tests/directive-elifdef.exp
|
||||
unit-tests/directive-elifdef.mk
|
||||
unit-tests/directive-elifmake.exp
|
||||
unit-tests/directive-elifmake.mk
|
||||
unit-tests/directive-elifndef.exp
|
||||
unit-tests/directive-elifndef.mk
|
||||
unit-tests/directive-elifnmake.exp
|
||||
unit-tests/directive-elifnmake.mk
|
||||
unit-tests/directive-else.exp
|
||||
unit-tests/directive-else.mk
|
||||
unit-tests/directive-endif.exp
|
||||
unit-tests/directive-endif.mk
|
||||
unit-tests/directive-error.exp
|
||||
unit-tests/directive-error.mk
|
||||
unit-tests/directive-export-env.exp
|
||||
unit-tests/directive-export-env.mk
|
||||
unit-tests/directive-export-literal.exp
|
||||
unit-tests/directive-export-literal.mk
|
||||
unit-tests/directive-export.exp
|
||||
unit-tests/directive-export.mk
|
||||
unit-tests/directive-for.exp
|
||||
unit-tests/directive-for.mk
|
||||
unit-tests/directive-for-generating-endif.exp
|
||||
unit-tests/directive-for-generating-endif.mk
|
||||
unit-tests/directive-if.exp
|
||||
unit-tests/directive-if.mk
|
||||
unit-tests/directive-ifdef.exp
|
||||
unit-tests/directive-ifdef.mk
|
||||
unit-tests/directive-ifmake.exp
|
||||
unit-tests/directive-ifmake.mk
|
||||
unit-tests/directive-ifndef.exp
|
||||
unit-tests/directive-ifndef.mk
|
||||
unit-tests/directive-ifnmake.exp
|
||||
unit-tests/directive-ifnmake.mk
|
||||
unit-tests/directive-info.exp
|
||||
unit-tests/directive-info.mk
|
||||
unit-tests/directive-undef.exp
|
||||
unit-tests/directive-undef.mk
|
||||
unit-tests/directive-unexport-env.exp
|
||||
unit-tests/directive-unexport-env.mk
|
||||
unit-tests/directive-unexport.exp
|
||||
unit-tests/directive-unexport.mk
|
||||
unit-tests/directive-warning.exp
|
||||
unit-tests/directive-warning.mk
|
||||
unit-tests/directive.exp
|
||||
unit-tests/directive.mk
|
||||
unit-tests/directives.exp
|
||||
unit-tests/directives.mk
|
||||
unit-tests/dollar.exp
|
||||
unit-tests/dollar.mk
|
||||
unit-tests/doterror.exp
|
||||
unit-tests/doterror.mk
|
||||
unit-tests/dotwait.exp
|
||||
unit-tests/dotwait.mk
|
||||
unit-tests/envfirst.exp
|
||||
unit-tests/envfirst.mk
|
||||
unit-tests/error.exp
|
||||
unit-tests/error.mk
|
||||
unit-tests/escape.exp
|
||||
unit-tests/escape.mk
|
||||
unit-tests/export-all.exp
|
||||
unit-tests/export-all.mk
|
||||
unit-tests/export-env.exp
|
||||
unit-tests/export-env.mk
|
||||
unit-tests/export-variants.exp
|
||||
unit-tests/export-variants.mk
|
||||
unit-tests/export.exp
|
||||
unit-tests/export.mk
|
||||
unit-tests/forloop.exp
|
||||
unit-tests/forloop.mk
|
||||
unit-tests/forsubst.exp
|
||||
unit-tests/forsubst.mk
|
||||
unit-tests/hash.exp
|
||||
unit-tests/hash.mk
|
||||
unit-tests/impsrc.exp
|
||||
unit-tests/impsrc.mk
|
||||
unit-tests/include-main.exp
|
||||
unit-tests/include-main.mk
|
||||
unit-tests/include-sub.mk
|
||||
unit-tests/include-subsub.mk
|
||||
unit-tests/lint.exp
|
||||
unit-tests/lint.mk
|
||||
unit-tests/make-exported.exp
|
||||
unit-tests/make-exported.mk
|
||||
unit-tests/misc.exp
|
||||
unit-tests/misc.mk
|
||||
unit-tests/moderrs.exp
|
||||
unit-tests/moderrs.mk
|
||||
unit-tests/modmatch.exp
|
||||
unit-tests/modmatch.mk
|
||||
unit-tests/modmisc.exp
|
||||
unit-tests/modmisc.mk
|
||||
unit-tests/modts.exp
|
||||
unit-tests/modts.mk
|
||||
unit-tests/modword.exp
|
||||
unit-tests/modword.mk
|
||||
unit-tests/opt-backwards.exp
|
||||
unit-tests/opt-backwards.mk
|
||||
unit-tests/opt-chdir.exp
|
||||
unit-tests/opt-chdir.mk
|
||||
unit-tests/opt-debug.exp
|
||||
unit-tests/opt-debug.mk
|
||||
unit-tests/opt-debug-g1.exp
|
||||
unit-tests/opt-debug-g1.mk
|
||||
unit-tests/opt-define.exp
|
||||
unit-tests/opt-define.mk
|
||||
unit-tests/opt-env.exp
|
||||
unit-tests/opt-env.mk
|
||||
unit-tests/opt-file.exp
|
||||
unit-tests/opt-file.mk
|
||||
unit-tests/opt-ignore.exp
|
||||
unit-tests/opt-ignore.mk
|
||||
unit-tests/opt-include-dir.exp
|
||||
unit-tests/opt-include-dir.mk
|
||||
unit-tests/opt-jobs-internal.exp
|
||||
unit-tests/opt-jobs-internal.mk
|
||||
unit-tests/opt-jobs.exp
|
||||
unit-tests/opt-jobs.mk
|
||||
unit-tests/opt-keep-going.exp
|
||||
unit-tests/opt-keep-going.mk
|
||||
unit-tests/opt-m-include-dir.exp
|
||||
unit-tests/opt-m-include-dir.mk
|
||||
unit-tests/opt-no-action-at-all.exp
|
||||
unit-tests/opt-no-action-at-all.mk
|
||||
unit-tests/opt-no-action.exp
|
||||
unit-tests/opt-no-action.mk
|
||||
unit-tests/opt-query.exp
|
||||
unit-tests/opt-query.mk
|
||||
unit-tests/opt-raw.exp
|
||||
unit-tests/opt-raw.mk
|
||||
unit-tests/opt-silent.exp
|
||||
unit-tests/opt-silent.mk
|
||||
unit-tests/opt-touch.exp
|
||||
unit-tests/opt-touch.mk
|
||||
unit-tests/opt-tracefile.exp
|
||||
unit-tests/opt-tracefile.mk
|
||||
unit-tests/opt-var-expanded.exp
|
||||
unit-tests/opt-var-expanded.mk
|
||||
unit-tests/opt-var-literal.exp
|
||||
unit-tests/opt-var-literal.mk
|
||||
unit-tests/opt-warnings-as-errors.exp
|
||||
unit-tests/opt-warnings-as-errors.mk
|
||||
unit-tests/opt-where-am-i.exp
|
||||
unit-tests/opt-where-am-i.mk
|
||||
unit-tests/opt-x-reduce-exported.exp
|
||||
unit-tests/opt-x-reduce-exported.mk
|
||||
unit-tests/opt.exp
|
||||
unit-tests/opt.mk
|
||||
unit-tests/order.exp
|
||||
unit-tests/order.mk
|
||||
unit-tests/phony-end.exp
|
||||
unit-tests/phony-end.mk
|
||||
unit-tests/posix.exp
|
||||
unit-tests/posix.mk
|
||||
unit-tests/posix1.exp
|
||||
unit-tests/posix1.mk
|
||||
unit-tests/qequals.exp
|
||||
unit-tests/qequals.mk
|
||||
unit-tests/recursive.exp
|
||||
unit-tests/recursive.mk
|
||||
unit-tests/sh-dots.exp
|
||||
unit-tests/sh-dots.mk
|
||||
unit-tests/sh-jobs-error.exp
|
||||
unit-tests/sh-jobs-error.mk
|
||||
unit-tests/sh-jobs.exp
|
||||
unit-tests/sh-jobs.mk
|
||||
unit-tests/sh-leading-at.exp
|
||||
unit-tests/sh-leading-at.mk
|
||||
unit-tests/sh-leading-hyphen.exp
|
||||
unit-tests/sh-leading-hyphen.mk
|
||||
unit-tests/sh-leading-plus.exp
|
||||
unit-tests/sh-leading-plus.mk
|
||||
unit-tests/sh-meta-chars.exp
|
||||
unit-tests/sh-meta-chars.mk
|
||||
unit-tests/sh-multi-line.exp
|
||||
unit-tests/sh-multi-line.mk
|
||||
unit-tests/sh-single-line.exp
|
||||
unit-tests/sh-single-line.mk
|
||||
unit-tests/sh.exp
|
||||
unit-tests/sh.mk
|
||||
unit-tests/suffixes.exp
|
||||
unit-tests/suffixes.mk
|
||||
unit-tests/sunshcmd.exp
|
||||
unit-tests/sunshcmd.mk
|
||||
unit-tests/sysv.exp
|
||||
unit-tests/sysv.mk
|
||||
unit-tests/ternary.exp
|
||||
unit-tests/ternary.mk
|
||||
unit-tests/unexport-env.exp
|
||||
unit-tests/unexport-env.mk
|
||||
unit-tests/unexport.exp
|
||||
unit-tests/unexport.mk
|
||||
unit-tests/use-inference.exp
|
||||
unit-tests/use-inference.mk
|
||||
unit-tests/var-class-cmdline.exp
|
||||
unit-tests/var-class-cmdline.mk
|
||||
unit-tests/var-class-env.exp
|
||||
unit-tests/var-class-env.mk
|
||||
unit-tests/var-class-global.exp
|
||||
unit-tests/var-class-global.mk
|
||||
unit-tests/var-class-local-legacy.exp
|
||||
unit-tests/var-class-local-legacy.mk
|
||||
unit-tests/var-class-local.exp
|
||||
unit-tests/var-class-local.mk
|
||||
unit-tests/var-class.exp
|
||||
unit-tests/var-class.mk
|
||||
unit-tests/var-op-append.exp
|
||||
unit-tests/var-op-append.mk
|
||||
unit-tests/var-op-assign.exp
|
||||
unit-tests/var-op-assign.mk
|
||||
unit-tests/var-op-default.exp
|
||||
unit-tests/var-op-default.mk
|
||||
unit-tests/var-op-expand.exp
|
||||
unit-tests/var-op-expand.mk
|
||||
unit-tests/var-op-shell.exp
|
||||
unit-tests/var-op-shell.mk
|
||||
unit-tests/var-op.exp
|
||||
unit-tests/var-op.mk
|
||||
unit-tests/varcmd.exp
|
||||
unit-tests/varcmd.mk
|
||||
unit-tests/vardebug.exp
|
||||
unit-tests/vardebug.mk
|
||||
unit-tests/varfind.exp
|
||||
unit-tests/varfind.mk
|
||||
unit-tests/varmisc.exp
|
||||
unit-tests/varmisc.mk
|
||||
unit-tests/varmod-assign.exp
|
||||
unit-tests/varmod-assign.mk
|
||||
unit-tests/varmod-defined.exp
|
||||
unit-tests/varmod-defined.mk
|
||||
unit-tests/varmod-edge.exp
|
||||
unit-tests/varmod-edge.mk
|
||||
unit-tests/varmod-exclam-shell.exp
|
||||
unit-tests/varmod-exclam-shell.mk
|
||||
unit-tests/varmod-extension.exp
|
||||
unit-tests/varmod-extension.mk
|
||||
unit-tests/varmod-gmtime.exp
|
||||
unit-tests/varmod-gmtime.mk
|
||||
unit-tests/varmod-hash.exp
|
||||
unit-tests/varmod-hash.mk
|
||||
unit-tests/varmod-head.exp
|
||||
unit-tests/varmod-head.mk
|
||||
unit-tests/varmod-ifelse.exp
|
||||
unit-tests/varmod-ifelse.mk
|
||||
unit-tests/varmod-l-name-to-value.exp
|
||||
unit-tests/varmod-l-name-to-value.mk
|
||||
unit-tests/varmod-localtime.exp
|
||||
unit-tests/varmod-localtime.mk
|
||||
unit-tests/varmod-loop.exp
|
||||
unit-tests/varmod-loop.mk
|
||||
unit-tests/varmod-match-escape.exp
|
||||
unit-tests/varmod-match-escape.mk
|
||||
unit-tests/varmod-match.exp
|
||||
unit-tests/varmod-match.mk
|
||||
unit-tests/varmod-no-match.exp
|
||||
unit-tests/varmod-no-match.mk
|
||||
unit-tests/varmod-order-reverse.exp
|
||||
unit-tests/varmod-order-reverse.mk
|
||||
unit-tests/varmod-order-shuffle.exp
|
||||
unit-tests/varmod-order-shuffle.mk
|
||||
unit-tests/varmod-order.exp
|
||||
unit-tests/varmod-order.mk
|
||||
unit-tests/varmod-path.exp
|
||||
unit-tests/varmod-path.mk
|
||||
unit-tests/varmod-quote-dollar.exp
|
||||
unit-tests/varmod-quote-dollar.mk
|
||||
unit-tests/varmod-quote.exp
|
||||
unit-tests/varmod-quote.mk
|
||||
unit-tests/varmod-range.exp
|
||||
unit-tests/varmod-range.mk
|
||||
unit-tests/varmod-remember.exp
|
||||
unit-tests/varmod-remember.mk
|
||||
unit-tests/varmod-root.exp
|
||||
unit-tests/varmod-root.mk
|
||||
unit-tests/varmod-select-words.exp
|
||||
unit-tests/varmod-select-words.mk
|
||||
unit-tests/varmod-shell.exp
|
||||
unit-tests/varmod-shell.mk
|
||||
unit-tests/varmod-subst-regex.exp
|
||||
unit-tests/varmod-subst-regex.mk
|
||||
unit-tests/varmod-subst.exp
|
||||
unit-tests/varmod-subst.mk
|
||||
unit-tests/varmod-sysv.exp
|
||||
unit-tests/varmod-sysv.mk
|
||||
unit-tests/varmod-tail.exp
|
||||
unit-tests/varmod-tail.mk
|
||||
unit-tests/varmod-to-abs.exp
|
||||
unit-tests/varmod-to-abs.mk
|
||||
unit-tests/varmod-to-lower.exp
|
||||
unit-tests/varmod-to-lower.mk
|
||||
unit-tests/varmod-to-many-words.exp
|
||||
unit-tests/varmod-to-many-words.mk
|
||||
unit-tests/varmod-to-one-word.exp
|
||||
unit-tests/varmod-to-one-word.mk
|
||||
unit-tests/varmod-to-separator.exp
|
||||
unit-tests/varmod-to-separator.mk
|
||||
unit-tests/varmod-to-upper.exp
|
||||
unit-tests/varmod-to-upper.mk
|
||||
unit-tests/varmod-undefined.exp
|
||||
unit-tests/varmod-undefined.mk
|
||||
unit-tests/varmod-unique.exp
|
||||
unit-tests/varmod-unique.mk
|
||||
unit-tests/varmod.exp
|
||||
unit-tests/varmod.mk
|
||||
unit-tests/varname-dollar.exp
|
||||
unit-tests/varname-dollar.mk
|
||||
unit-tests/varname-dot-alltargets.exp
|
||||
unit-tests/varname-dot-alltargets.mk
|
||||
unit-tests/varname-dot-curdir.exp
|
||||
unit-tests/varname-dot-curdir.mk
|
||||
unit-tests/varname-dot-includes.exp
|
||||
unit-tests/varname-dot-includes.mk
|
||||
unit-tests/varname-dot-includedfromdir.exp
|
||||
unit-tests/varname-dot-includedfromdir.mk
|
||||
unit-tests/varname-dot-includedfromfile.exp
|
||||
unit-tests/varname-dot-includedfromfile.mk
|
||||
unit-tests/varname-dot-libs.exp
|
||||
unit-tests/varname-dot-libs.mk
|
||||
unit-tests/varname-dot-make-dependfile.exp
|
||||
unit-tests/varname-dot-make-dependfile.mk
|
||||
unit-tests/varname-dot-make-expand_variables.exp
|
||||
unit-tests/varname-dot-make-expand_variables.mk
|
||||
unit-tests/varname-dot-make-exported.exp
|
||||
unit-tests/varname-dot-make-exported.mk
|
||||
unit-tests/varname-dot-make-jobs-prefix.exp
|
||||
unit-tests/varname-dot-make-jobs-prefix.mk
|
||||
unit-tests/varname-dot-make-jobs.exp
|
||||
unit-tests/varname-dot-make-jobs.mk
|
||||
unit-tests/varname-dot-make-level.exp
|
||||
unit-tests/varname-dot-make-level.mk
|
||||
unit-tests/varname-dot-make-makefile_preference.exp
|
||||
unit-tests/varname-dot-make-makefile_preference.mk
|
||||
unit-tests/varname-dot-make-makefiles.exp
|
||||
unit-tests/varname-dot-make-makefiles.mk
|
||||
unit-tests/varname-dot-make-meta-bailiwick.exp
|
||||
unit-tests/varname-dot-make-meta-bailiwick.mk
|
||||
unit-tests/varname-dot-make-meta-created.exp
|
||||
unit-tests/varname-dot-make-meta-created.mk
|
||||
unit-tests/varname-dot-make-meta-files.exp
|
||||
unit-tests/varname-dot-make-meta-files.mk
|
||||
unit-tests/varname-dot-make-meta-ignore_filter.exp
|
||||
unit-tests/varname-dot-make-meta-ignore_filter.mk
|
||||
unit-tests/varname-dot-make-meta-ignore_paths.exp
|
||||
unit-tests/varname-dot-make-meta-ignore_paths.mk
|
||||
unit-tests/varname-dot-make-meta-ignore_patterns.exp
|
||||
unit-tests/varname-dot-make-meta-ignore_patterns.mk
|
||||
unit-tests/varname-dot-make-meta-prefix.exp
|
||||
unit-tests/varname-dot-make-meta-prefix.mk
|
||||
unit-tests/varname-dot-make-mode.exp
|
||||
unit-tests/varname-dot-make-mode.mk
|
||||
unit-tests/varname-dot-make-path_filemon.exp
|
||||
unit-tests/varname-dot-make-path_filemon.mk
|
||||
unit-tests/varname-dot-make-pid.exp
|
||||
unit-tests/varname-dot-make-pid.mk
|
||||
unit-tests/varname-dot-make-ppid.exp
|
||||
unit-tests/varname-dot-make-ppid.mk
|
||||
unit-tests/varname-dot-make-save_dollars.exp
|
||||
unit-tests/varname-dot-make-save_dollars.mk
|
||||
unit-tests/varname-dot-makeoverrides.exp
|
||||
unit-tests/varname-dot-makeoverrides.mk
|
||||
unit-tests/varname-dot-newline.exp
|
||||
unit-tests/varname-dot-newline.mk
|
||||
unit-tests/varname-dot-objdir.exp
|
||||
unit-tests/varname-dot-objdir.mk
|
||||
unit-tests/varname-dot-parsedir.exp
|
||||
unit-tests/varname-dot-parsedir.mk
|
||||
unit-tests/varname-dot-parsefile.exp
|
||||
unit-tests/varname-dot-parsefile.mk
|
||||
unit-tests/varname-dot-path.exp
|
||||
unit-tests/varname-dot-path.mk
|
||||
unit-tests/varname-dot-shell.exp
|
||||
unit-tests/varname-dot-shell.mk
|
||||
unit-tests/varname-dot-targets.exp
|
||||
unit-tests/varname-dot-targets.mk
|
||||
unit-tests/varname-empty.exp
|
||||
unit-tests/varname-empty.mk
|
||||
unit-tests/varname-make.exp
|
||||
unit-tests/varname-make.mk
|
||||
unit-tests/varname-make_print_var_on_error.exp
|
||||
unit-tests/varname-make_print_var_on_error.mk
|
||||
unit-tests/varname-makeflags.exp
|
||||
unit-tests/varname-makeflags.mk
|
||||
unit-tests/varname-pwd.exp
|
||||
unit-tests/varname-pwd.mk
|
||||
unit-tests/varname-vpath.exp
|
||||
unit-tests/varname-vpath.mk
|
||||
unit-tests/varname.exp
|
||||
unit-tests/varname.mk
|
||||
unit-tests/varparse-dynamic.exp
|
||||
unit-tests/varparse-dynamic.mk
|
||||
unit-tests/varquote.exp
|
||||
unit-tests/varquote.mk
|
||||
unit-tests/varshell.exp
|
||||
unit-tests/varshell.mk
|
||||
util.c
|
||||
var.c
|
||||
wait.h
|
60
20200902/LICENSE
Normal file
60
20200902/LICENSE
Normal file
@ -0,0 +1,60 @@
|
||||
The individual files in this distribution are copyright their
|
||||
original contributors or assignees.
|
||||
Including:
|
||||
|
||||
Copyright (c) 1993-2020, Simon J Gerraty
|
||||
Copyright (c) 2020, Roland Illig <rillig@NetBSD.org>
|
||||
Copyright (c) 2009-2016, Juniper Networks, Inc.
|
||||
Copyright (c) 2009, John Birrell.
|
||||
Copyright (c) 1997-2020 The NetBSD Foundation, Inc.
|
||||
Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
Copyright (c) 1989 by Berkeley Softworks
|
||||
Copyright (c) 1988, 1989, 1990, 1992, 1993
|
||||
The Regents of the University of California.
|
||||
Copyright (c) 1988, 1989 by Adam de Boor
|
||||
|
||||
With the exception of the GNU configure script, which states:
|
||||
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
#
|
||||
# This configure script is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy, distribute and modify it.
|
||||
|
||||
The license for this distribution is considered to be:
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
example (from https://opensource.org/licenses/BSD-3-Clause):
|
||||
|
||||
Copyright <YEAR> <COPYRIGHT HOLDER>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
215
20200902/Makefile
Normal file
215
20200902/Makefile
Normal file
@ -0,0 +1,215 @@
|
||||
# $Id: Makefile,v 1.112 2020/08/28 16:26:17 sjg Exp $
|
||||
|
||||
PROG= bmake
|
||||
|
||||
SRCS= \
|
||||
arch.c \
|
||||
buf.c \
|
||||
compat.c \
|
||||
cond.c \
|
||||
dir.c \
|
||||
enum.c \
|
||||
for.c \
|
||||
hash.c \
|
||||
job.c \
|
||||
lst.c \
|
||||
main.c \
|
||||
make.c \
|
||||
make_malloc.c \
|
||||
meta.c \
|
||||
metachar.c \
|
||||
parse.c \
|
||||
str.c \
|
||||
strlist.c \
|
||||
suff.c \
|
||||
targ.c \
|
||||
trace.c \
|
||||
util.c \
|
||||
var.c
|
||||
|
||||
.-include "VERSION"
|
||||
.-include "Makefile.inc"
|
||||
|
||||
# this file gets generated by configure
|
||||
.-include "Makefile.config"
|
||||
|
||||
.if !empty(LIBOBJS)
|
||||
SRCS+= ${LIBOBJS:T:.o=.c}
|
||||
.endif
|
||||
|
||||
# just in case
|
||||
prefix?= /usr
|
||||
srcdir?= ${.CURDIR}
|
||||
|
||||
DEFAULT_SYS_PATH?= ${prefix}/share/mk
|
||||
|
||||
CPPFLAGS+= -DUSE_META
|
||||
CFLAGS+= ${CPPFLAGS}
|
||||
CFLAGS+= -D_PATH_DEFSYSPATH=\"${DEFAULT_SYS_PATH}\"
|
||||
CFLAGS+= -I. -I${srcdir} ${XDEFS} -DMAKE_NATIVE
|
||||
CFLAGS+= ${COPTS.${.ALLSRC:M*.c:T:u}}
|
||||
COPTS.main.c+= "-DMAKE_VERSION=\"${_MAKE_VERSION}\""
|
||||
|
||||
# meta mode can be useful even without filemon
|
||||
# should be set by now
|
||||
USE_FILEMON ?= no
|
||||
.if ${USE_FILEMON:tl} != "no"
|
||||
.PATH: ${srcdir}/filemon
|
||||
SRCS+= filemon_${USE_FILEMON}.c
|
||||
COPTS.meta.c+= -DUSE_FILEMON -DUSE_FILEMON_${USE_FILEMON:tu}
|
||||
COPTS.job.c+= ${COPTS.meta.c}
|
||||
|
||||
.if ${USE_FILEMON} == "dev"
|
||||
FILEMON_H ?= /usr/include/dev/filemon/filemon.h
|
||||
.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
|
||||
COPTS.filemon_dev.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
|
||||
.endif
|
||||
.endif # USE_FILEMON == dev
|
||||
|
||||
.endif # USE_FILEMON
|
||||
|
||||
.PATH: ${srcdir}
|
||||
|
||||
.if make(obj) || make(clean)
|
||||
SUBDIR+= unit-tests
|
||||
.endif
|
||||
|
||||
# start-delete1 for bsd.after-import.mk
|
||||
# we skip a lot of this when building as part of FreeBSD etc.
|
||||
|
||||
# list of OS's which are derrived from BSD4.4
|
||||
BSD44_LIST= NetBSD FreeBSD OpenBSD DragonFly MirBSD Bitrig
|
||||
# we are...
|
||||
OS := ${.MAKE.OS:U${uname -s:L:sh}}
|
||||
# are we 4.4BSD ?
|
||||
isBSD44:=${BSD44_LIST:M${OS}}
|
||||
|
||||
.if ${isBSD44} == ""
|
||||
MANTARGET= cat
|
||||
INSTALL?=${srcdir}/install-sh
|
||||
.if (${MACHINE} == "sun386")
|
||||
# even I don't have one of these anymore :-)
|
||||
CFLAGS+= -DPORTAR
|
||||
.elif (${MACHINE} != "sunos")
|
||||
SRCS+= sigcompat.c
|
||||
CFLAGS+= -DSIGNAL_FLAGS=SA_RESTART
|
||||
.endif
|
||||
.else
|
||||
MANTARGET?= man
|
||||
.endif
|
||||
|
||||
# turn this on by default - ignored if we are root
|
||||
WITH_INSTALL_AS_USER=
|
||||
|
||||
# suppress with -DWITHOUT_*
|
||||
OPTIONS_DEFAULT_YES+= \
|
||||
AUTOCONF_MK \
|
||||
INSTALL_MK \
|
||||
PROG_LINK
|
||||
|
||||
OPTIONS_DEFAULT_NO+= \
|
||||
PROG_VERSION
|
||||
|
||||
# process options now
|
||||
.include <own.mk>
|
||||
|
||||
.if ${MK_PROG_VERSION} == "yes"
|
||||
PROG_NAME= ${PROG}-${_MAKE_VERSION}
|
||||
.if ${MK_PROG_LINK} == "yes"
|
||||
SYMLINKS+= ${PROG_NAME} ${BINDIR}/${PROG}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
EXTRACT_MAN=no
|
||||
# end-delete1
|
||||
|
||||
MAN= ${PROG}.1
|
||||
MAN1= ${MAN}
|
||||
|
||||
.if (${PROG} != "make")
|
||||
CLEANFILES+= my.history
|
||||
.if make(${MAN}) || !exists(${srcdir}/${MAN})
|
||||
my.history:
|
||||
@(echo ".Nm"; \
|
||||
echo "is derived from NetBSD"; \
|
||||
echo ".Xr make 1 ."; \
|
||||
echo "It uses autoconf to facilitate portability to other platforms."; \
|
||||
echo ".Pp") > $@
|
||||
|
||||
.NOPATH: ${MAN}
|
||||
${MAN}: make.1 my.history
|
||||
@echo making $@
|
||||
@sed \
|
||||
-e '/^.Dt/s/MAKE/${PROG:tu}/' \
|
||||
-e 's/^.Nx/NetBSD/' \
|
||||
-e '/^.Nm/s/make/${PROG}/' \
|
||||
-e '/^.Sh HISTORY/rmy.history' \
|
||||
-e '/^.Sh HISTORY/,$$s,^.Nm,make,' ${srcdir}/make.1 > $@
|
||||
|
||||
all beforeinstall: ${MAN}
|
||||
_mfromdir=.
|
||||
.endif
|
||||
.endif
|
||||
|
||||
MANTARGET?= cat
|
||||
MANDEST?= ${MANDIR}/${MANTARGET}1
|
||||
|
||||
.if ${MANTARGET} == "cat"
|
||||
_mfromdir=${srcdir}
|
||||
.endif
|
||||
|
||||
.include <prog.mk>
|
||||
|
||||
CPPFLAGS+= -DMAKE_NATIVE -DHAVE_CONFIG_H
|
||||
COPTS.var.c += -Wno-cast-qual
|
||||
COPTS.job.c += -Wno-format-nonliteral
|
||||
COPTS.parse.c += -Wno-format-nonliteral
|
||||
COPTS.var.c += -Wno-format-nonliteral
|
||||
|
||||
# Force these
|
||||
SHAREDIR= ${SHAREDIR.bmake:U${prefix}/share}
|
||||
BINDIR= ${BINDIR.bmake:U${prefix}/bin}
|
||||
MANDIR= ${MANDIR.bmake:U${SHAREDIR}/man}
|
||||
|
||||
.if !exists(.depend)
|
||||
${OBJS}: config.h
|
||||
.endif
|
||||
|
||||
# start-delete2 for bsd.after-import.mk
|
||||
|
||||
# make sure that MAKE_VERSION gets updated.
|
||||
main.o: ${srcdir}/VERSION
|
||||
|
||||
.if ${MK_AUTOCONF_MK} == "yes"
|
||||
CONFIGURE_DEPS += ${.CURDIR}/VERSION
|
||||
# we do not need or want the generated makefile
|
||||
CONFIGURE_ARGS += --without-makefile
|
||||
.include <autoconf.mk>
|
||||
.endif
|
||||
SHARE_MK?=${SHAREDIR}/mk
|
||||
MKSRC=${srcdir}/mk
|
||||
INSTALL?=${srcdir}/install-sh
|
||||
|
||||
.if ${MK_INSTALL_MK} == "yes"
|
||||
install: install-mk
|
||||
.endif
|
||||
|
||||
beforeinstall:
|
||||
test -d ${DESTDIR}${BINDIR} || ${INSTALL} -m 775 -d ${DESTDIR}${BINDIR}
|
||||
test -d ${DESTDIR}${MANDEST} || ${INSTALL} -m 775 -d ${DESTDIR}${MANDEST}
|
||||
|
||||
install-mk:
|
||||
.if exists(${MKSRC}/install-mk)
|
||||
test -d ${DESTDIR}${SHARE_MK} || ${INSTALL} -m 775 -d ${DESTDIR}${SHARE_MK}
|
||||
sh ${MKSRC}/install-mk -v -m 644 ${DESTDIR}${SHARE_MK}
|
||||
.else
|
||||
@echo need to unpack mk.tar.gz under ${srcdir} or set MKSRC; false
|
||||
.endif
|
||||
# end-delete2
|
||||
|
||||
# A simple unit-test driver to help catch regressions
|
||||
TEST_MAKE ?= ${.OBJDIR}/${PROG:T}
|
||||
accept test:
|
||||
cd ${.CURDIR}/unit-tests && \
|
||||
MAKEFLAGS= ${TEST_MAKE} -r -m / ${.TARGET} ${TESTS:DTESTS=${TESTS:Q}}
|
||||
|
22
20200902/Makefile.config.in
Normal file
22
20200902/Makefile.config.in
Normal file
@ -0,0 +1,22 @@
|
||||
# things set by configure
|
||||
|
||||
_MAKE_VERSION?=@_MAKE_VERSION@
|
||||
|
||||
prefix?= @prefix@
|
||||
srcdir= @srcdir@
|
||||
CC?= @CC@
|
||||
MACHINE?= @machine@
|
||||
MACHINE_ARCH?= @machine_arch@
|
||||
DEFAULT_SYS_PATH?= @default_sys_path@
|
||||
|
||||
CPPFLAGS+= @CPPFLAGS@
|
||||
CFLAGS+= ${CPPFLAGS} @DEFS@
|
||||
LDFLAGS+= @LDFLAGS@
|
||||
LIBOBJS+= @LIBOBJS@
|
||||
LDADD+= @LIBS@
|
||||
USE_META?= @use_meta@
|
||||
USE_FILEMON?= @use_filemon@
|
||||
FILEMON_H?= @filemon_h@
|
||||
BMAKE_PATH_MAX?= @bmake_path_max@
|
||||
# used if MAXPATHLEN not defined
|
||||
CPPFLAGS+= -DBMAKE_PATH_MAX=${BMAKE_PATH_MAX}
|
10
20200902/PSD.doc/Makefile
Normal file
10
20200902/PSD.doc/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
# $NetBSD: Makefile,v 1.4 2014/07/05 19:22:43 dholland Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 8/14/93
|
||||
|
||||
SECTION=reference/ref1
|
||||
ARTICLE=make
|
||||
SRCS= tutorial.ms
|
||||
MACROS= -ms
|
||||
EXTRAHTMLFILES=make1.png make2.png
|
||||
|
||||
.include <bsd.doc.mk>
|
3794
20200902/PSD.doc/tutorial.ms
Normal file
3794
20200902/PSD.doc/tutorial.ms
Normal file
File diff suppressed because it is too large
Load Diff
52
20200902/README
Normal file
52
20200902/README
Normal file
@ -0,0 +1,52 @@
|
||||
bmake
|
||||
*****
|
||||
|
||||
This directory contains a port of the BSD make tool (from NetBSD).
|
||||
Since 1993 I have run it on AIX, BSDi, Darwin, FreeBSD, HP-UX, IRIX,
|
||||
Linux, Minix, OSF, Solaris, SunOS and even UTS.
|
||||
Others have run it on many more systems.
|
||||
|
||||
Currently each release is tested on NetBSD, FreeBSD, Solaris and Linux.
|
||||
|
||||
Since 2003 bmake switched to a date based version (first was 20030714)
|
||||
which generally represents the date it was last merged with NetBSD's
|
||||
make. Since then, NetBSD's make is imported within a week of any
|
||||
interesting changes, so that bmake tracks it very closely.
|
||||
|
||||
Building
|
||||
========
|
||||
|
||||
The preferred way to bootstrap bmake is::
|
||||
|
||||
./bmake/boot-strap
|
||||
|
||||
there are a number of args - most of which get passed to configure,
|
||||
eg.
|
||||
::
|
||||
|
||||
./bmake/boot-strap --prefix=/opt
|
||||
|
||||
see the boot-strap script for details.
|
||||
|
||||
For folk that hate to read anything, since 20121212 you can also use
|
||||
the GNU standard process of::
|
||||
|
||||
./configure; make; make install
|
||||
|
||||
To make much use of bmake you will need the bsd.*.mk macros or my
|
||||
portable *.mk macros which are included with bmake since 20121212
|
||||
and separately available from
|
||||
http://www.crufty.net/ftp/pub/sjg/mk.tar.gz
|
||||
which will be links to the latest versions.
|
||||
|
||||
Porting
|
||||
=======
|
||||
|
||||
If you encounter a system that bmake does not build or work on *out of
|
||||
the box*, I welcome patches.
|
||||
If you can provide access to a suitable machine - even better.
|
||||
|
||||
More info can be found at http://www.crufty.net/help/sjg/bmake.htm
|
||||
|
||||
--sjg <sjg@crufty.net>
|
||||
|
2
20200902/VERSION
Normal file
2
20200902/VERSION
Normal file
@ -0,0 +1,2 @@
|
||||
# keep this compatible with sh and make
|
||||
_MAKE_VERSION=20200902
|
82
20200902/aclocal.m4
vendored
Normal file
82
20200902/aclocal.m4
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
dnl RCSid:
|
||||
dnl $Id: aclocal.m4,v 1.6 2017/11/26 22:39:20 sjg Exp $
|
||||
dnl
|
||||
|
||||
dnl
|
||||
dnl AC_CHECK_HEADER_HAS(HEADER, PATTERN, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]))
|
||||
|
||||
AC_DEFUN(AC_CHECK_HEADER_HAS,
|
||||
[dnl first check if header exists and if so, see if it contains PATTERN
|
||||
ac_has_hdr=`echo "ac_cv_header_$1" | sed 'y%./+-%__p_%'`
|
||||
ac_has_it=`echo "ac_cv_header_$1"_$2 | sed 'y%./+-%__p_%'`
|
||||
if eval "test \"`echo x'$'$ac_has_hdr`\" = x"; then
|
||||
AC_CHECK_HEADER($1)
|
||||
fi
|
||||
if eval "test \"`echo '$'$ac_has_hdr`\" = yes"; then
|
||||
ac_x=HAVE_`echo "$1" | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
|
||||
AC_DEFINE_UNQUOTED($ac_x)
|
||||
AC_MSG_CHECKING([if $1 has $2])
|
||||
AC_CACHE_VAL($ac_has_it,
|
||||
[eval $ac_has_it=no
|
||||
AC_EGREP_HEADER($2, $1, eval "$ac_has_it=yes")])
|
||||
|
||||
if eval "test \"`echo '$'$ac_has_it`\" = yes"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ac_x=HAVE_`echo "$1"_$2 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
|
||||
AC_DEFINE_UNQUOTED($ac_x)
|
||||
ifelse([$3], , :, [$3])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
ifelse([$4], , , [$4
|
||||
])dnl
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
dnl AC_EGREP(PATTERN, FILE, ACTION-IF-FOUND [,
|
||||
dnl ACTION-IF-NOT-FOUND])
|
||||
AC_DEFUN(AC_EGREP,
|
||||
[
|
||||
dnl Prevent m4 from eating character classes:
|
||||
changequote(, )dnl
|
||||
if egrep "$1" $2 >/dev/null 2>&1; then
|
||||
changequote([, ])dnl
|
||||
ifelse([$3], , :, [$3])
|
||||
ifelse([$4], , , [else
|
||||
$4
|
||||
])dnl
|
||||
fi
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Test for __attribute__
|
||||
dnl
|
||||
|
||||
AC_DEFUN(AC_C___ATTRIBUTE__, [
|
||||
AC_MSG_CHECKING(for __attribute__)
|
||||
AC_CACHE_VAL(ac_cv___attribute__, [
|
||||
AC_LINK_IFELSE([
|
||||
#include <stdlib.h>
|
||||
|
||||
static void foo(void) __attribute__ ((noreturn));
|
||||
|
||||
static void
|
||||
foo(void)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
foo();
|
||||
}
|
||||
],
|
||||
ac_cv___attribute__=yes,
|
||||
ac_cv___attribute__=no)])
|
||||
if test "$ac_cv___attribute__" = "yes"; then
|
||||
AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
|
||||
fi
|
||||
AC_MSG_RESULT($ac_cv___attribute__)
|
||||
])
|
||||
|
1275
20200902/arch.c
Normal file
1275
20200902/arch.c
Normal file
File diff suppressed because it is too large
Load Diff
2455
20200902/bmake.1
Normal file
2455
20200902/bmake.1
Normal file
File diff suppressed because it is too large
Load Diff
1571
20200902/bmake.cat1
Normal file
1571
20200902/bmake.cat1
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 80 KiB |
475
20200902/boot-strap
Executable file
475
20200902/boot-strap
Executable file
@ -0,0 +1,475 @@
|
||||
:
|
||||
# NAME:
|
||||
# boot-strap
|
||||
#
|
||||
# SYNOPSIS:
|
||||
# boot-strap ["options"]
|
||||
# boot-strap --prefix=/opt --install
|
||||
# boot-strap --prefix=$HOME --install-host-target -DWITH_PROG_VERSION
|
||||
# boot-strap ["options"] op=build
|
||||
# boot-strap ["options"] op=install
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# This script is used to configure/build bmake it builds for
|
||||
# each host-target in a different subdir to keep the src clean.
|
||||
# There is no requirement for an existing make(1).
|
||||
#
|
||||
# On successful completion if no '--install' flag is given,
|
||||
# it echos a command to do installation.
|
||||
#
|
||||
# The variable "op" defaults to 'all', and is affected by
|
||||
# '--install' flag as above.
|
||||
# Other values include:
|
||||
#
|
||||
# configure
|
||||
# Just run 'configure'
|
||||
#
|
||||
# build
|
||||
# If 'configure' has not been done, do it, then
|
||||
# run the build script, and finally 'test'.
|
||||
#
|
||||
# install
|
||||
# If 'build' has not been done, do it, 'test' then
|
||||
# install.
|
||||
#
|
||||
# clean
|
||||
# attempt to clean up
|
||||
#
|
||||
# test
|
||||
# run the unit-tests. Done automatically after 'build'
|
||||
# and before 'install'.
|
||||
#
|
||||
# The above are leveraged by a trivial makefile for the benefit
|
||||
# of those that have './configure; make; make install' baked
|
||||
# into them.
|
||||
#
|
||||
# Options:
|
||||
#
|
||||
# -c "rc"
|
||||
# Pick up settings from "rc".
|
||||
# We look for '.bmake-boot-strap.rc' before processing
|
||||
# options (unless SKIP_RC is set in environment).
|
||||
#
|
||||
# --share "share_dir"
|
||||
# Where to put man pages and mk files.
|
||||
# If $prefix ends in $HOST_TARGET, and $prefix/../share
|
||||
# exits, the default will be that rather than $prefix/share.
|
||||
#
|
||||
# --mksrc "mksrc"
|
||||
# Indicate where the mk files can be found.
|
||||
# Default is $Mydir/mk
|
||||
#
|
||||
# --install
|
||||
# If build and test work, run bmake install.
|
||||
# BINDIR=$prefix/bin
|
||||
# SHAREDIR=$prefix/share
|
||||
#
|
||||
# --install-host-target
|
||||
# As for '--install' but BINDIR=$prefix/$HOST_TARGET/bin
|
||||
# This is useful when $prefix/ is shared by multiple
|
||||
# machines.
|
||||
#
|
||||
# Flags relevant when installing:
|
||||
#
|
||||
# -DWITHOUT_INSTALL_MK
|
||||
# Skip installing mk files.
|
||||
# By default they will be installed to $prefix/share/mk
|
||||
#
|
||||
# -DWITH_PROG_VERSION
|
||||
# Install 'bmake' as 'bmake-$MAKE_VERSION'
|
||||
# A symlink will be made as 'bmake' unless
|
||||
# -DWITHOUT_PROG_LINK is set.
|
||||
#
|
||||
# Possibly useful configure_args:
|
||||
#
|
||||
# --without-meta
|
||||
# disable use of meta mode.
|
||||
#
|
||||
# --without-filemon
|
||||
# disable use of filemon(9) which is currently only
|
||||
# available for NetBSD and FreeBSD.
|
||||
#
|
||||
# --with-filemon=ktrace
|
||||
# on NetBSD or others with fktrace(2), use ktrace
|
||||
# version of filemon.
|
||||
#
|
||||
# --with-filemon="path/to/filemon.h"
|
||||
# enables use of filemon(9) by meta mode.
|
||||
#
|
||||
# --with-machine="machine"
|
||||
# set "machine" to override that determined by
|
||||
# machine.sh
|
||||
#
|
||||
# --with-force-machine="machine"
|
||||
# force "machine" even if uname(3) provides a value.
|
||||
#
|
||||
# --with-machine_arch="machine_arch"
|
||||
# set "machine_arch" to override that determined by
|
||||
# machine.sh
|
||||
#
|
||||
# --with-default-sys-path="syspath"
|
||||
# set an explicit default "syspath" which is where bmake
|
||||
# will look for sys.mk and friends.
|
||||
#
|
||||
# AUTHOR:
|
||||
# Simon J. Gerraty <sjg@crufty.net>
|
||||
|
||||
# RCSid:
|
||||
# $Id: boot-strap,v 1.51 2020/02/19 16:46:23 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2001 Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
Mydir=`dirname $0`
|
||||
. "$Mydir/os.sh"
|
||||
case "$Mydir" in
|
||||
/*) ;;
|
||||
*) Mydir=`cd "$Mydir" && 'pwd'`;;
|
||||
esac
|
||||
|
||||
Usage() {
|
||||
[ "$1" ] && echo "ERROR: $@" >&2
|
||||
echo "Usage:" >&2
|
||||
echo "$0 [--<configure_arg> ...][<prefix>][--install]" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
Error() {
|
||||
echo "ERROR: $@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
source_rc() {
|
||||
rc="$1"; shift
|
||||
for d in ${*:-""}
|
||||
do
|
||||
r="${d:+$d/}$rc"
|
||||
[ -f "$r" -a -s "$r" ] || continue
|
||||
echo "NOTE: reading $r"
|
||||
. "$r"
|
||||
break
|
||||
done
|
||||
}
|
||||
|
||||
cmd_args="$@"
|
||||
|
||||
# clear some things from the environment that we care about
|
||||
unset MAKEOBJDIR MAKEOBJDIRPREFIX
|
||||
# or that might be incompatible
|
||||
unset MAKE MAKEFLAGS
|
||||
|
||||
# --install[-host-target] will set this
|
||||
INSTALL_PREFIX=
|
||||
# other things we pass to install step
|
||||
INSTALL_ARGS=
|
||||
CONFIGURE_ARGS=
|
||||
MAKESYSPATH=
|
||||
# pick a useful default prefix (for me at least ;-)
|
||||
for prefix in /opt/$HOST_TARGET "$HOME/$HOST_TARGET" /usr/pkg /usr/local ""
|
||||
do
|
||||
[ -d "${prefix:-.}" ] || continue
|
||||
case "$prefix" in
|
||||
*/$HOST_TARGET)
|
||||
p=`dirname $prefix`
|
||||
if [ -d $p/share ]; then
|
||||
INSTALL_BIN=$HOST_TARGET/bin
|
||||
prefix=$p
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
echo "NOTE: default prefix=$prefix ${INSTALL_BIN:+INSTALL_BIN=$INSTALL_BIN}"
|
||||
break
|
||||
done
|
||||
srcdir=$Mydir
|
||||
mksrc=$Mydir/mk
|
||||
objdir=
|
||||
quiet=:
|
||||
|
||||
${SKIP_RC:+:} source_rc .bmake-boot-strap.rc . "$Mydir/.." "$HOME"
|
||||
|
||||
get_optarg() {
|
||||
expr "x$1" : "x[^=]*=\\(.*\\)"
|
||||
}
|
||||
|
||||
here=`'pwd'`
|
||||
if [ $here = $Mydir ]; then
|
||||
# avoid pollution
|
||||
OBJROOT=../
|
||||
fi
|
||||
|
||||
op=all
|
||||
BMAKE=
|
||||
|
||||
while :
|
||||
do
|
||||
case "$1" in
|
||||
--) shift; break;;
|
||||
--help) sed -n -e "1d;/RCSid/,\$d" -e '/^#\.[a-z]/d' -e '/^#/s,^# *,,p' $0; exit 0;;
|
||||
--prefix) prefix="$2"; shift;;
|
||||
--prefix=*) prefix=`get_optarg "$1"`;;
|
||||
--src=*) srcdir=`get_optarg "$1"`;;
|
||||
--with-mksrc=*|--mksrc=*) mksrc=`get_optarg "$1"`;;
|
||||
--share=*) share_dir=`get_optarg "$1"`;;
|
||||
--share) share_dir="$2"; shift;;
|
||||
--with-default-sys-path=*)
|
||||
CONFIGURE_ARGS="$1";;
|
||||
--with-default-sys-path)
|
||||
CONFIGURE_ARGS="$1 $2";;
|
||||
--install) INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix};;
|
||||
--install-host-target)
|
||||
INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix}
|
||||
INSTALL_BIN=$HOST_TARGET/bin;;
|
||||
--install-destdir=*) INSTALL_DESTDIR=`get_optarg "$1"`;;
|
||||
--install-prefix=*) INSTALL_PREFIX=`get_optarg "$1"`;;
|
||||
-DWITH*) INSTALL_ARGS="$INSTALL_ARGS $1";;
|
||||
-s|--src) srcdir="$2"; shift;;
|
||||
-m|--mksrc) mksrc="$2"; shift;;
|
||||
-o|--objdir) objdir="$2"; shift;;
|
||||
-q) quiet=;;
|
||||
-c) source_rc "$2"; shift;;
|
||||
--*) CONFIGURE_ARGS="$CONFIGURE_ARGS $1";;
|
||||
*=*) eval "$1"; export `expr "x$1" : "x\\(.[^=]*\\)=.*"`;;
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
AddConfigure() {
|
||||
case " $CONFIGURE_ARGS " in
|
||||
*" $1"*) ;;
|
||||
*) CONFIGURE_ARGS="$CONFIGURE_ARGS $1$2";;
|
||||
esac
|
||||
}
|
||||
|
||||
GetDir() {
|
||||
match="$1"
|
||||
shift
|
||||
fmatch="$1"
|
||||
shift
|
||||
for dir in $*
|
||||
do
|
||||
[ -d "$dir" ] || continue
|
||||
case "/$dir/" in
|
||||
*$match*) ;;
|
||||
*) continue;;
|
||||
esac
|
||||
case "$fmatch" in
|
||||
.) ;;
|
||||
*) [ -s $dir/$fmatch ] || continue;;
|
||||
esac
|
||||
case "$dir/" in
|
||||
*./*) cd "$dir" && 'pwd';;
|
||||
/*) echo $dir;;
|
||||
*) cd "$dir" && 'pwd';;
|
||||
esac
|
||||
break
|
||||
done
|
||||
}
|
||||
|
||||
FindHereOrAbove() {
|
||||
(
|
||||
_t=-s
|
||||
while :
|
||||
do
|
||||
case "$1" in
|
||||
-C) cd "$2"; shift; shift;;
|
||||
-?) _t=$1; shift;;
|
||||
*) break;;
|
||||
esac
|
||||
done
|
||||
case "$1" in
|
||||
/*) # we shouldn't be here
|
||||
[ $_t "$1" ] && echo "$1"
|
||||
return
|
||||
;;
|
||||
.../*) want=`echo "$1" | sed 's,^.../*,,'`;;
|
||||
*) want="$1";;
|
||||
esac
|
||||
here=`'pwd'`
|
||||
while :
|
||||
do
|
||||
if [ $_t "./$want" ]; then
|
||||
echo "$here/$want"
|
||||
return
|
||||
fi
|
||||
cd ..
|
||||
here=`'pwd'`
|
||||
case "$here" in
|
||||
/) return;;
|
||||
esac
|
||||
done
|
||||
)
|
||||
}
|
||||
|
||||
# is $1 missing from $2 (or PATH) ?
|
||||
no_path() {
|
||||
eval "__p=\$${2:-PATH}"
|
||||
case ":$__p:" in *:"$1":*) return 1;; *) return 0;; esac
|
||||
}
|
||||
|
||||
# if $1 exists and is not in path, append it
|
||||
add_path () {
|
||||
case "$1" in
|
||||
-?) t=$1; shift;;
|
||||
*) t=-d;;
|
||||
esac
|
||||
case "$2,$1" in
|
||||
MAKESYSPATH,.../*) ;;
|
||||
*) [ $t ${1:-.} ] || return;;
|
||||
esac
|
||||
no_path $* && eval ${2:-PATH}="$__p${__p:+:}$1"
|
||||
}
|
||||
|
||||
|
||||
srcdir=`GetDir /bmake make-bootstrap.sh.in "$srcdir" "$2" "$Mydir" ./bmake* "$Mydir"/../bmake*`
|
||||
[ -d "${srcdir:-/dev/null}" ] || Usage
|
||||
case "$mksrc" in
|
||||
none|-) # we ignore this now
|
||||
mksrc=$Mydir/mk
|
||||
;;
|
||||
.../*) # find here or above
|
||||
mksrc=`FindHereOrAbove -C "$Mydir" -s "$mksrc/sys.mk"`
|
||||
# that found a file
|
||||
mksrc=`dirname $mksrc`
|
||||
;;
|
||||
*) # guess we want mksrc...
|
||||
mksrc=`GetDir /mk sys.mk "$mksrc" "$3" ./mk* "$srcdir"/mk* "$srcdir"/../mk*`
|
||||
[ -d "${mksrc:-/dev/null}" ] || Usage "Use '-m none' to build without mksrc"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Ok, get to work...
|
||||
objdir="${objdir:-$OBJROOT$HOST_TARGET}"
|
||||
[ -d "$objdir" ] || mkdir -p "$objdir"
|
||||
[ -d "$objdir" ] || mkdir "$objdir"
|
||||
cd "$objdir" || exit 1
|
||||
# make it absolute
|
||||
objdir=`'pwd'`
|
||||
|
||||
ShareDir() {
|
||||
case "/$1" in
|
||||
/) [ -d /share ] || return;;
|
||||
*/$HOST_TARGET)
|
||||
if [ -d "$1/../share" ]; then
|
||||
echo `dirname "$1"`/share
|
||||
return
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
echo $1/share
|
||||
}
|
||||
|
||||
# make it easy to force prefix to use $HOST_TARGET
|
||||
: looking at "$prefix"
|
||||
case "$prefix" in
|
||||
*/host?target) prefix=`echo "$prefix" | sed "s,host.target,${HOST_TARGET},"`;;
|
||||
esac
|
||||
|
||||
share_dir="${share_dir:-`ShareDir $prefix`}"
|
||||
|
||||
AddConfigure --prefix= "$prefix"
|
||||
case "$CONFIGURE_ARGS" in
|
||||
*--with-*-sys-path*) ;; # skip
|
||||
*) [ "$share_dir" ] && AddConfigure --with-default-sys-path= "$share_dir/mk";;
|
||||
esac
|
||||
if [ "$mksrc" ]; then
|
||||
AddConfigure --with-mksrc= "$mksrc"
|
||||
# not all cc's support this
|
||||
CFLAGS_MF= CFLAGS_MD=
|
||||
export CFLAGS_MF CFLAGS_MD
|
||||
fi
|
||||
|
||||
# this makes it easy to run the bmake we just built
|
||||
# the :tA dance is needed because 'pwd' and even /bin/pwd
|
||||
# may not give the same result as realpath().
|
||||
Bmake() {
|
||||
(
|
||||
cd $Mydir &&
|
||||
MAKESYSPATH=$mksrc SRCTOP=$Mydir OBJTOP=$objdir \
|
||||
MAKEOBJDIR='${.CURDIR:S,${SRCTOP:tA},${OBJTOP:tA},}' \
|
||||
${BMAKE:-$objdir/bmake} -f $Mydir/Makefile "$@"
|
||||
)
|
||||
}
|
||||
|
||||
# there is actually a shell where type is not a builtin
|
||||
# if type is missing, which(1) had better exists!
|
||||
if (type cat) > /dev/null 2>&1; then
|
||||
which() {
|
||||
type "$@" | sed 's,[()],,g;s,^[^/][^/]*,,;q'
|
||||
}
|
||||
fi
|
||||
# make sure test below uses the same diff that configure did
|
||||
TOOL_DIFF=`which diff`
|
||||
export TOOL_DIFF
|
||||
|
||||
op_configure() {
|
||||
$srcdir/configure $CONFIGURE_ARGS || exit 1
|
||||
}
|
||||
|
||||
op_build() {
|
||||
[ -s make-bootstrap.sh ] || op_configure
|
||||
chmod 755 make-bootstrap.sh || exit 1
|
||||
./make-bootstrap.sh || exit 1
|
||||
case "$op" in
|
||||
build) op_test;;
|
||||
esac
|
||||
}
|
||||
|
||||
op_test() {
|
||||
[ -x bmake ] || op_build
|
||||
Bmake test || exit 1
|
||||
}
|
||||
|
||||
op_clean() {
|
||||
if [ -x bmake ]; then
|
||||
ln bmake bmake$$
|
||||
BMAKE=$objdir/bmake$$ Bmake clean
|
||||
rm -f bmake$$
|
||||
elif [ $objdir != $srcdir ]; then
|
||||
rm -rf *
|
||||
fi
|
||||
}
|
||||
|
||||
op_install() {
|
||||
op_test
|
||||
case "$INSTALL_PREFIX,$INSTALL_BIN,$prefix" in
|
||||
,$HOST_TARGET/bin,*/$HOST_TARGET)
|
||||
INSTALL_PREFIX=`dirname $prefix`
|
||||
;;
|
||||
esac
|
||||
INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix}
|
||||
Bmake install prefix=$INSTALL_PREFIX BINDIR=$INSTALL_PREFIX/${INSTALL_BIN:-bin} ${INSTALL_DESTDIR:+DESTDIR=$INSTALL_DESTDIR} $INSTALL_ARGS || exit 1
|
||||
}
|
||||
|
||||
op_all() {
|
||||
rm -f make-bootstrap.sh bmake *.o
|
||||
if [ -n "$INSTALL_PREFIX" ]; then
|
||||
op_install
|
||||
else
|
||||
op_test
|
||||
MAKE_VERSION=`sed -n '/^_MAKE_VERSION/ { s,.*= *,,;p; }' $srcdir/Makefile`
|
||||
echo You can install by running:
|
||||
echo
|
||||
echo $0 $cmd_args op=install
|
||||
echo
|
||||
echo "Use --install-prefix=/something to install somewhere other than $prefix"
|
||||
echo "Use --install-destdir=/somewhere to set DESTDIR during install"
|
||||
echo "Use --install-host-target to use INSTALL_BIN=$HOST_TARGET/bin"
|
||||
echo "Use -DWITH_PROG_VERSION to install as bmake-$MAKE_VERSION"
|
||||
echo "Use -DWITHOUT_PROG_LINK to suppress bmake -> bmake-$MAKE_VERSION symlink"
|
||||
echo "Use -DWITHOUT_INSTALL_MK to skip installing files to $prefix/share/mk"
|
||||
fi
|
||||
}
|
||||
|
||||
op_$op
|
||||
exit 0
|
126
20200902/bsd.after-import.mk
Normal file
126
20200902/bsd.after-import.mk
Normal file
@ -0,0 +1,126 @@
|
||||
# $Id: bsd.after-import.mk,v 1.16 2020/07/12 03:39:01 sjg Exp $
|
||||
|
||||
# This makefile is for use when integrating bmake into a BSD build
|
||||
# system. Use this makefile after importing bmake.
|
||||
# It will bootstrap the new version,
|
||||
# capture the generated files we need, and add an after-import
|
||||
# target to allow the process to be easily repeated.
|
||||
|
||||
# The goal is to allow the benefits of autoconf without
|
||||
# the overhead of running configure.
|
||||
|
||||
all: _makefile _utmakefile
|
||||
all: after-import
|
||||
|
||||
# we rely on bmake
|
||||
.if !defined(.PARSEDIR)
|
||||
.error this makefile requires bmake
|
||||
.endif
|
||||
|
||||
_this := ${MAKEFILE:tA}
|
||||
BMAKE_SRC := ${.PARSEDIR}
|
||||
|
||||
# it helps to know where the top of the tree is.
|
||||
.if !defined(SRCTOP)
|
||||
srctop := ${.MAKE.MAKEFILES:M*src/share/mk/sys.mk:H:H:H}
|
||||
.if empty(srctop)
|
||||
# likely locations?
|
||||
.for d in contrib/bmake external/bsd/bmake/dist
|
||||
.if ${BMAKE_SRC:M*/$d} != ""
|
||||
srctop := ${BMAKE_SRC:tA:S,/$d,,}
|
||||
.endif
|
||||
.endfor
|
||||
.endif
|
||||
.if !empty(srctop)
|
||||
SRCTOP := ${srctop}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# This lets us match what boot-strap does
|
||||
.if defined(.MAKE.OS)
|
||||
HOST_OS:= ${.MAKE.OS}
|
||||
.elif !defined(HOST_OS)
|
||||
HOST_OS!= uname
|
||||
.endif
|
||||
|
||||
BOOTSTRAP_ARGS = \
|
||||
--prefix /usr \
|
||||
--share /usr/share
|
||||
|
||||
.if !empty(DEFAULT_SYS_PATH)
|
||||
BOOTSTRAP_ARGS += --with-default-sys-path='${DEFAULT_SYS_PATH}'
|
||||
.endif
|
||||
|
||||
# run boot-strap with minimal influence
|
||||
bootstrap: ${BMAKE_SRC}/boot-strap ${MAKEFILE}
|
||||
HOME=/ ${BMAKE_SRC}/boot-strap -o ${HOST_OS} ${BOOTSTRAP_ARGS} ${BOOTSTRAP_XTRAS}
|
||||
touch ${.TARGET}
|
||||
|
||||
# Makefiles need a little more tweaking than say config.h
|
||||
MAKEFILE_SED = sed -e '/^MACHINE/d' \
|
||||
-e '/include.*VERSION/d' \
|
||||
-e '/^PROG/ { s,=,?=,;s,bmake,$${.CURDIR:T},; }' \
|
||||
-e 's,^.-include,.sinclude,' \
|
||||
-e '/^\..*include *</ { s,<,<bsd.,;/autoconf/d; }' \
|
||||
-e 's,${SRCTOP},$${SRCTOP},g'
|
||||
|
||||
# These are the simple files we want to capture
|
||||
configured_files= config.h Makefile.config unit-tests/Makefile.config
|
||||
|
||||
after-import: bootstrap ${MAKEFILE}
|
||||
.for f in ${configured_files:M*.[ch]}
|
||||
@echo Capturing $f
|
||||
@mkdir -p ${${.CURDIR}/$f:L:H}
|
||||
@(echo '/* $$${HOST_OS}$$ */'; cat ${HOST_OS}/$f) > ${.CURDIR}/$f
|
||||
.endfor
|
||||
.for f in ${configured_files:M*Makefile*}
|
||||
@echo Capturing $f
|
||||
@mkdir -p ${${.CURDIR}/$f:L:H}
|
||||
@(echo '# This is a generated file, do NOT edit!'; \
|
||||
echo '# See ${_this:S,${SRCTOP}/,,}'; \
|
||||
echo '#'; echo '# $$${HOST_OS}$$'; echo; \
|
||||
echo 'SRCTOP?= $${.CURDIR:${${.CURDIR}/$f:L:H:S,${SRCTOP}/,,:C,[^/]+,H,g:S,/,:,g}}'; echo; \
|
||||
${MAKEFILE_SED} ${HOST_OS}/$f ) > ${.CURDIR}/$f
|
||||
.endfor
|
||||
|
||||
# this needs the most work
|
||||
_makefile: bootstrap ${MAKEFILE}
|
||||
@echo Generating ${.CURDIR}/Makefile
|
||||
@(echo '# This is a generated file, do NOT edit!'; \
|
||||
echo '# See ${_this:S,${SRCTOP}/,,}'; \
|
||||
echo '#'; echo '# $$${HOST_OS}$$'; \
|
||||
echo; echo 'SRCTOP?= $${.CURDIR:${.CURDIR:S,${SRCTOP}/,,:C,[^/]+,H,g:S,/,:,g}}'; \
|
||||
echo; echo '# look here first for config.h'; \
|
||||
echo 'CFLAGS+= -I$${.CURDIR}'; echo; \
|
||||
echo '# for after-import'; \
|
||||
echo 'CLEANDIRS+= ${HOST_OS}'; \
|
||||
echo 'CLEANFILES+= bootstrap'; echo; \
|
||||
${MAKEFILE_SED} \
|
||||
${1 2:L:@n@-e '/start-delete$n/,/end-delete$n/d'@} \
|
||||
${BMAKE_SRC}/Makefile; \
|
||||
echo; echo '# override some simple things'; \
|
||||
echo 'BINDIR= /usr/bin'; \
|
||||
echo 'MANDIR= ${MANDIR:U/usr/share/man}'; \
|
||||
echo; echo '# make sure we get this'; \
|
||||
echo 'CFLAGS+= $${COPTS.$${.IMPSRC:T}}'; \
|
||||
echo; echo 'after-import: ${_this:S,${SRCTOP},\${SRCTOP},}'; \
|
||||
echo ' cd $${.CURDIR} && $${.MAKE} -f ${_this:S,${SRCTOP},\${SRCTOP},}'; \
|
||||
echo ) > ${.TARGET}
|
||||
@cmp -s ${.TARGET} ${.CURDIR}/Makefile || \
|
||||
mv ${.TARGET} ${.CURDIR}/Makefile
|
||||
|
||||
_utmakefile: bootstrap ${MAKEFILE}
|
||||
@echo Generating ${.CURDIR}/unit-tests/Makefile
|
||||
@mkdir -p ${.CURDIR}/unit-tests
|
||||
@(echo '# This is a generated file, do NOT edit!'; \
|
||||
echo '# See ${_this:S,${SRCTOP}/,,}'; \
|
||||
echo '#'; echo '# $$${HOST_OS}$$'; \
|
||||
${MAKEFILE_SED} \
|
||||
-e '/^UNIT_TESTS/s,=.*,= $${srcdir},' \
|
||||
${BMAKE_SRC}/unit-tests/Makefile ) > ${.TARGET}
|
||||
@cmp -s ${.TARGET} ${.CURDIR}/unit-tests/Makefile || \
|
||||
mv ${.TARGET} ${.CURDIR}/unit-tests/Makefile
|
||||
|
||||
|
||||
.include <bsd.obj.mk>
|
||||
|
223
20200902/buf.c
Normal file
223
20200902/buf.c
Normal file
@ -0,0 +1,223 @@
|
||||
/* $NetBSD: buf.c,v 1.37 2020/08/23 08:21:50 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989 by Adam de Boor
|
||||
* Copyright (c) 1989 by Berkeley Softworks
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: buf.c,v 1.37 2020/08/23 08:21:50 rillig Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: buf.c,v 1.37 2020/08/23 08:21:50 rillig Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
/* Functions for automatically-expanded null-terminated buffers. */
|
||||
|
||||
#include <limits.h>
|
||||
#include "make.h"
|
||||
|
||||
/* Extend the buffer for adding a single byte. */
|
||||
void
|
||||
Buf_Expand_1(Buffer *bp)
|
||||
{
|
||||
bp->size += MAX(bp->size, 16);
|
||||
bp->buffer = bmake_realloc(bp->buffer, bp->size);
|
||||
}
|
||||
|
||||
/* Add the given bytes to the buffer. */
|
||||
void
|
||||
Buf_AddBytes(Buffer *bp, const char *bytesPtr, size_t numBytes)
|
||||
{
|
||||
size_t count = bp->count;
|
||||
char *ptr;
|
||||
|
||||
if (__predict_false(count + numBytes >= bp->size)) {
|
||||
bp->size += MAX(bp->size, numBytes + 16);
|
||||
bp->buffer = bmake_realloc(bp->buffer, bp->size);
|
||||
}
|
||||
|
||||
ptr = bp->buffer + count;
|
||||
bp->count = count + numBytes;
|
||||
memcpy(ptr, bytesPtr, numBytes);
|
||||
ptr[numBytes] = '\0';
|
||||
}
|
||||
|
||||
/* Add the bytes between start and end to the buffer. */
|
||||
void
|
||||
Buf_AddBytesBetween(Buffer *bp, const char *start, const char *end)
|
||||
{
|
||||
Buf_AddBytes(bp, start, (size_t)(end - start));
|
||||
}
|
||||
|
||||
/* Add the given string to the buffer. */
|
||||
void
|
||||
Buf_AddStr(Buffer *bp, const char *str)
|
||||
{
|
||||
Buf_AddBytes(bp, str, strlen(str));
|
||||
}
|
||||
|
||||
/* Add the given number to the buffer. */
|
||||
void
|
||||
Buf_AddInt(Buffer *bp, int n)
|
||||
{
|
||||
enum {
|
||||
bits = sizeof(int) * CHAR_BIT,
|
||||
max_octal_digits = (bits + 2) / 3,
|
||||
max_decimal_digits = /* at most */ max_octal_digits,
|
||||
max_sign_chars = 1,
|
||||
buf_size = max_sign_chars + max_decimal_digits + 1
|
||||
};
|
||||
char buf[buf_size];
|
||||
|
||||
size_t len = (size_t)snprintf(buf, sizeof buf, "%d", n);
|
||||
Buf_AddBytes(bp, buf, len);
|
||||
}
|
||||
|
||||
/* Get the data (usually a string) from the buffer.
|
||||
* The returned data is valid until the next modifying operation
|
||||
* on the buffer.
|
||||
*
|
||||
* Returns the pointer to the data and optionally the length of the
|
||||
* data in the buffer. */
|
||||
char *
|
||||
Buf_GetAll(Buffer *bp, size_t *numBytesPtr)
|
||||
{
|
||||
if (numBytesPtr != NULL)
|
||||
*numBytesPtr = bp->count;
|
||||
return bp->buffer;
|
||||
}
|
||||
|
||||
/* Mark the buffer as empty, so it can be filled with data again. */
|
||||
void
|
||||
Buf_Empty(Buffer *bp)
|
||||
{
|
||||
bp->count = 0;
|
||||
bp->buffer[0] = '\0';
|
||||
}
|
||||
|
||||
/* Initialize a buffer.
|
||||
* If the given initial size is 0, a reasonable default is used. */
|
||||
void
|
||||
Buf_Init(Buffer *bp, size_t size)
|
||||
{
|
||||
if (size <= 0) {
|
||||
size = 256;
|
||||
}
|
||||
bp->size = size;
|
||||
bp->count = 0;
|
||||
bp->buffer = bmake_malloc(size);
|
||||
bp->buffer[0] = '\0';
|
||||
}
|
||||
|
||||
/* Reset the buffer.
|
||||
* If freeData is TRUE, the data from the buffer is freed as well.
|
||||
* Otherwise it is kept and returned. */
|
||||
char *
|
||||
Buf_Destroy(Buffer *buf, Boolean freeData)
|
||||
{
|
||||
char *data = buf->buffer;
|
||||
if (freeData) {
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
buf->size = 0;
|
||||
buf->count = 0;
|
||||
buf->buffer = NULL;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
#ifndef BUF_COMPACT_LIMIT
|
||||
# define BUF_COMPACT_LIMIT 128 /* worthwhile saving */
|
||||
#endif
|
||||
|
||||
/* Reset the buffer and return its data.
|
||||
*
|
||||
* If the buffer size is much greater than its content,
|
||||
* a new buffer will be allocated and the old one freed. */
|
||||
char *
|
||||
Buf_DestroyCompact(Buffer *buf)
|
||||
{
|
||||
#if BUF_COMPACT_LIMIT > 0
|
||||
if (buf->size - buf->count >= BUF_COMPACT_LIMIT) {
|
||||
/* We trust realloc to be smart */
|
||||
char *data = bmake_realloc(buf->buffer, buf->count + 1);
|
||||
data[buf->count] = '\0';
|
||||
Buf_Destroy(buf, FALSE);
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
return Buf_Destroy(buf, FALSE);
|
||||
}
|
125
20200902/buf.h
Normal file
125
20200902/buf.h
Normal file
@ -0,0 +1,125 @@
|
||||
/* $NetBSD: buf.h,v 1.28 2020/09/01 17:38:26 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)buf.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989 by Adam de Boor
|
||||
* Copyright (c) 1989 by Berkeley Softworks
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)buf.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/* Automatically growing null-terminated buffers of characters. */
|
||||
|
||||
#ifndef MAKE_BUF_H
|
||||
#define MAKE_BUF_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* An automatically growing null-terminated buffer of characters. */
|
||||
typedef struct Buffer {
|
||||
size_t size; /* Allocated size of the buffer, including the null */
|
||||
size_t count; /* Number of bytes in buffer, excluding the null */
|
||||
char *buffer; /* The buffer itself (always null-terminated) */
|
||||
} Buffer;
|
||||
|
||||
/* If we aren't on NetBSD, __predict_false() might not be defined. */
|
||||
#ifndef __predict_false
|
||||
#define __predict_false(x) (x)
|
||||
#endif
|
||||
|
||||
void Buf_Expand_1(Buffer *);
|
||||
|
||||
/* Buf_AddByte adds a single byte to a buffer. */
|
||||
static inline void MAKE_ATTR_UNUSED
|
||||
Buf_AddByte(Buffer *bp, char byte)
|
||||
{
|
||||
size_t count = ++bp->count;
|
||||
char *ptr;
|
||||
if (__predict_false(count >= bp->size))
|
||||
Buf_Expand_1(bp);
|
||||
ptr = bp->buffer + count;
|
||||
ptr[-1] = byte;
|
||||
ptr[0] = 0;
|
||||
}
|
||||
|
||||
static inline size_t MAKE_ATTR_UNUSED
|
||||
Buf_Size(const Buffer *bp)
|
||||
{
|
||||
return bp->count;
|
||||
}
|
||||
|
||||
void Buf_AddBytes(Buffer *, const char *, size_t);
|
||||
void Buf_AddBytesBetween(Buffer *, const char *, const char *);
|
||||
void Buf_AddStr(Buffer *, const char *);
|
||||
void Buf_AddInt(Buffer *, int);
|
||||
char *Buf_GetAll(Buffer *, size_t *);
|
||||
void Buf_Empty(Buffer *);
|
||||
void Buf_Init(Buffer *, size_t);
|
||||
char *Buf_Destroy(Buffer *, Boolean);
|
||||
char *Buf_DestroyCompact(Buffer *);
|
||||
|
||||
#endif /* MAKE_BUF_H */
|
751
20200902/compat.c
Normal file
751
20200902/compat.c
Normal file
@ -0,0 +1,751 @@
|
||||
/* $NetBSD: compat.c,v 1.139 2020/08/30 20:08:47 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989 by Adam de Boor
|
||||
* Copyright (c) 1989 by Berkeley Softworks
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: compat.c,v 1.139 2020/08/30 20:08:47 rillig Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: compat.c,v 1.139 2020/08/30 20:08:47 rillig Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
/*-
|
||||
* compat.c --
|
||||
* The routines in this file implement the full-compatibility
|
||||
* mode of PMake. Most of the special functionality of PMake
|
||||
* is available in this mode. Things not supported:
|
||||
* - different shells.
|
||||
* - friendly variable substitution.
|
||||
*
|
||||
* Interface:
|
||||
* Compat_Run Initialize things for this module and recreate
|
||||
* thems as need creatin'
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "wait.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "make.h"
|
||||
#include "hash.h"
|
||||
#include "dir.h"
|
||||
#include "job.h"
|
||||
#include "metachar.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
|
||||
static GNode *curTarg = NULL;
|
||||
static GNode *ENDNode;
|
||||
static void CompatInterrupt(int);
|
||||
static pid_t compatChild;
|
||||
static int compatSigno;
|
||||
|
||||
/*
|
||||
* CompatDeleteTarget -- delete a failed, interrupted, or otherwise
|
||||
* duffed target if not inhibited by .PRECIOUS.
|
||||
*/
|
||||
static void
|
||||
CompatDeleteTarget(GNode *gn)
|
||||
{
|
||||
if ((gn != NULL) && !Targ_Precious (gn)) {
|
||||
char *p1;
|
||||
const char *file = Var_Value(TARGET, gn, &p1);
|
||||
|
||||
if (!noExecute && eunlink(file) != -1) {
|
||||
Error("*** %s removed", file);
|
||||
}
|
||||
|
||||
bmake_free(p1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Interrupt the creation of the current target and remove it if it ain't
|
||||
* precious. Then exit.
|
||||
*
|
||||
* If .INTERRUPT exists, its commands are run first WITH INTERRUPTS IGNORED.
|
||||
*
|
||||
* XXX: is .PRECIOUS supposed to inhibit .INTERRUPT? I doubt it, but I've
|
||||
* left the logic alone for now. - dholland 20160826
|
||||
*/
|
||||
static void
|
||||
CompatInterrupt(int signo)
|
||||
{
|
||||
GNode *gn;
|
||||
|
||||
CompatDeleteTarget(curTarg);
|
||||
|
||||
if ((curTarg != NULL) && !Targ_Precious (curTarg)) {
|
||||
/*
|
||||
* Run .INTERRUPT only if hit with interrupt signal
|
||||
*/
|
||||
if (signo == SIGINT) {
|
||||
gn = Targ_FindNode(".INTERRUPT", TARG_NOCREATE);
|
||||
if (gn != NULL) {
|
||||
Compat_Make(gn, gn);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (signo == SIGQUIT)
|
||||
_exit(signo);
|
||||
/*
|
||||
* If there is a child running, pass the signal on
|
||||
* we will exist after it has exited.
|
||||
*/
|
||||
compatSigno = signo;
|
||||
if (compatChild > 0) {
|
||||
KILLPG(compatChild, signo);
|
||||
} else {
|
||||
bmake_signal(signo, SIG_DFL);
|
||||
kill(myPid, signo);
|
||||
}
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* CompatRunCommand --
|
||||
* Execute the next command for a target. If the command returns an
|
||||
* error, the node's made field is set to ERROR and creation stops.
|
||||
*
|
||||
* Input:
|
||||
* cmdp Command to execute
|
||||
* gnp Node from which the command came
|
||||
*
|
||||
* Results:
|
||||
* 0 if the command succeeded, 1 if an error occurred.
|
||||
*
|
||||
* Side Effects:
|
||||
* The node's 'made' field may be set to ERROR.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
CompatRunCommand(void *cmdp, void *gnp)
|
||||
{
|
||||
char *cmdStart; /* Start of expanded command */
|
||||
char *cp, *bp;
|
||||
Boolean silent, /* Don't print command */
|
||||
doIt; /* Execute even if -n */
|
||||
volatile Boolean errCheck; /* Check errors */
|
||||
WAIT_T reason; /* Reason for child's death */
|
||||
int status; /* Description of child's death */
|
||||
pid_t cpid; /* Child actually found */
|
||||
pid_t retstat; /* Result of wait */
|
||||
LstNode cmdNode; /* Node where current command is located */
|
||||
const char ** volatile av; /* Argument vector for thing to exec */
|
||||
char ** volatile mav;/* Copy of the argument vector for freeing */
|
||||
Boolean useShell; /* TRUE if command should be executed
|
||||
* using a shell */
|
||||
char * volatile cmd = (char *)cmdp;
|
||||
GNode *gn = (GNode *)gnp;
|
||||
|
||||
silent = (gn->type & OP_SILENT) != 0;
|
||||
errCheck = !(gn->type & OP_IGNORE);
|
||||
doIt = FALSE;
|
||||
|
||||
cmdNode = Lst_FindDatum(gn->commands, cmd);
|
||||
cmdStart = Var_Subst(cmd, gn, VARE_WANTRES);
|
||||
|
||||
/*
|
||||
* brk_string will return an argv with a NULL in av[0], thus causing
|
||||
* execvp to choke and die horribly. Besides, how can we execute a null
|
||||
* command? In any case, we warn the user that the command expanded to
|
||||
* nothing (is this the right thing to do?).
|
||||
*/
|
||||
|
||||
if (*cmdStart == '\0') {
|
||||
free(cmdStart);
|
||||
return 0;
|
||||
}
|
||||
cmd = cmdStart;
|
||||
LstNode_Set(cmdNode, cmdStart);
|
||||
|
||||
if ((gn->type & OP_SAVE_CMDS) && (gn != ENDNode)) {
|
||||
assert(ENDNode != NULL);
|
||||
Lst_Append(ENDNode->commands, cmdStart);
|
||||
return 0;
|
||||
}
|
||||
if (strcmp(cmdStart, "...") == 0) {
|
||||
gn->type |= OP_SAVE_CMDS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((*cmd == '@') || (*cmd == '-') || (*cmd == '+')) {
|
||||
switch (*cmd) {
|
||||
case '@':
|
||||
silent = !DEBUG(LOUD);
|
||||
break;
|
||||
case '-':
|
||||
errCheck = FALSE;
|
||||
break;
|
||||
case '+':
|
||||
doIt = TRUE;
|
||||
if (!shellName) /* we came here from jobs */
|
||||
Shell_Init();
|
||||
break;
|
||||
}
|
||||
cmd++;
|
||||
}
|
||||
|
||||
while (isspace((unsigned char)*cmd))
|
||||
cmd++;
|
||||
|
||||
/*
|
||||
* If we did not end up with a command, just skip it.
|
||||
*/
|
||||
if (!*cmd)
|
||||
return 0;
|
||||
|
||||
#if !defined(MAKE_NATIVE)
|
||||
/*
|
||||
* In a non-native build, the host environment might be weird enough
|
||||
* that it's necessary to go through a shell to get the correct
|
||||
* behaviour. Or perhaps the shell has been replaced with something
|
||||
* that does extra logging, and that should not be bypassed.
|
||||
*/
|
||||
useShell = TRUE;
|
||||
#else
|
||||
/*
|
||||
* Search for meta characters in the command. If there are no meta
|
||||
* characters, there's no need to execute a shell to execute the
|
||||
* command.
|
||||
*
|
||||
* Additionally variable assignments and empty commands
|
||||
* go to the shell. Therefore treat '=' and ':' like shell
|
||||
* meta characters as documented in make(1).
|
||||
*/
|
||||
|
||||
useShell = needshell(cmd, FALSE);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Print the command before echoing if we're not supposed to be quiet for
|
||||
* this one. We also print the command if -n given.
|
||||
*/
|
||||
if (!silent || NoExecute(gn)) {
|
||||
printf("%s\n", cmd);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're not supposed to execute any commands, this is as far as
|
||||
* we go...
|
||||
*/
|
||||
if (!doIt && NoExecute(gn)) {
|
||||
return 0;
|
||||
}
|
||||
if (DEBUG(JOB))
|
||||
fprintf(debug_file, "Execute: '%s'\n", cmd);
|
||||
|
||||
if (useShell) {
|
||||
/*
|
||||
* We need to pass the command off to the shell, typically
|
||||
* because the command contains a "meta" character.
|
||||
*/
|
||||
static const char *shargv[5];
|
||||
int shargc;
|
||||
|
||||
shargc = 0;
|
||||
shargv[shargc++] = shellPath;
|
||||
/*
|
||||
* The following work for any of the builtin shell specs.
|
||||
*/
|
||||
if (errCheck && shellErrFlag) {
|
||||
shargv[shargc++] = shellErrFlag;
|
||||
}
|
||||
if (DEBUG(SHELL))
|
||||
shargv[shargc++] = "-xc";
|
||||
else
|
||||
shargv[shargc++] = "-c";
|
||||
shargv[shargc++] = cmd;
|
||||
shargv[shargc] = NULL;
|
||||
av = shargv;
|
||||
bp = NULL;
|
||||
mav = NULL;
|
||||
} else {
|
||||
/*
|
||||
* No meta-characters, so no need to exec a shell. Break the command
|
||||
* into words to form an argument vector we can execute.
|
||||
*/
|
||||
Words words = Str_Words(cmd, FALSE);
|
||||
mav = words.words;
|
||||
bp = words.freeIt;
|
||||
av = (void *)mav;
|
||||
}
|
||||
|
||||
#ifdef USE_META
|
||||
if (useMeta) {
|
||||
meta_compat_start();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Fork and execute the single command. If the fork fails, we abort.
|
||||
*/
|
||||
compatChild = cpid = vFork();
|
||||
if (cpid < 0) {
|
||||
Fatal("Could not fork");
|
||||
}
|
||||
if (cpid == 0) {
|
||||
Var_ExportVars();
|
||||
#ifdef USE_META
|
||||
if (useMeta) {
|
||||
meta_compat_child();
|
||||
}
|
||||
#endif
|
||||
(void)execvp(av[0], (char *const *)UNCONST(av));
|
||||
execError("exec", av[0]);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
free(mav);
|
||||
free(bp);
|
||||
|
||||
/* XXX: Memory management looks suspicious here. */
|
||||
/* XXX: Setting a list item to NULL is unexpected. */
|
||||
LstNode_SetNull(cmdNode);
|
||||
|
||||
#ifdef USE_META
|
||||
if (useMeta) {
|
||||
meta_compat_parent(cpid);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The child is off and running. Now all we can do is wait...
|
||||
*/
|
||||
while (1) {
|
||||
|
||||
while ((retstat = wait(&reason)) != cpid) {
|
||||
if (retstat > 0)
|
||||
JobReapChild(retstat, reason, FALSE); /* not ours? */
|
||||
if (retstat == -1 && errno != EINTR) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (retstat > -1) {
|
||||
if (WIFSTOPPED(reason)) {
|
||||
status = WSTOPSIG(reason); /* stopped */
|
||||
} else if (WIFEXITED(reason)) {
|
||||
status = WEXITSTATUS(reason); /* exited */
|
||||
#if defined(USE_META) && defined(USE_FILEMON_ONCE)
|
||||
if (useMeta) {
|
||||
meta_cmd_finish(NULL);
|
||||
}
|
||||
#endif
|
||||
if (status != 0) {
|
||||
if (DEBUG(ERROR)) {
|
||||
fprintf(debug_file, "\n*** Failed target: %s\n*** Failed command: ",
|
||||
gn->name);
|
||||
for (cp = cmd; *cp; ) {
|
||||
if (isspace((unsigned char)*cp)) {
|
||||
fprintf(debug_file, " ");
|
||||
while (isspace((unsigned char)*cp))
|
||||
cp++;
|
||||
} else {
|
||||
fprintf(debug_file, "%c", *cp);
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
fprintf(debug_file, "\n");
|
||||
}
|
||||
printf("*** Error code %d", status);
|
||||
}
|
||||
} else {
|
||||
status = WTERMSIG(reason); /* signaled */
|
||||
printf("*** Signal %d", status);
|
||||
}
|
||||
|
||||
|
||||
if (!WIFEXITED(reason) || (status != 0)) {
|
||||
if (errCheck) {
|
||||
#ifdef USE_META
|
||||
if (useMeta) {
|
||||
meta_job_error(NULL, gn, 0, status);
|
||||
}
|
||||
#endif
|
||||
gn->made = ERROR;
|
||||
if (keepgoing) {
|
||||
/*
|
||||
* Abort the current target, but let others
|
||||
* continue.
|
||||
*/
|
||||
printf(" (continuing)\n");
|
||||
} else {
|
||||
printf("\n");
|
||||
}
|
||||
if (deleteOnError) {
|
||||
CompatDeleteTarget(gn);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Continue executing commands for this target.
|
||||
* If we return 0, this will happen...
|
||||
*/
|
||||
printf(" (ignored)\n");
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
Fatal("error in wait: %d: %s", retstat, strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
free(cmdStart);
|
||||
compatChild = 0;
|
||||
if (compatSigno) {
|
||||
bmake_signal(compatSigno, SIG_DFL);
|
||||
kill(myPid, compatSigno);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Compat_Make --
|
||||
* Make a target.
|
||||
*
|
||||
* Input:
|
||||
* gnp The node to make
|
||||
* pgnp Parent to abort if necessary
|
||||
*
|
||||
* Results:
|
||||
* 0
|
||||
*
|
||||
* Side Effects:
|
||||
* If an error is detected and not being ignored, the process exits.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
Compat_Make(void *gnp, void *pgnp)
|
||||
{
|
||||
GNode *gn = (GNode *)gnp;
|
||||
GNode *pgn = (GNode *)pgnp;
|
||||
|
||||
if (!shellName) /* we came here from jobs */
|
||||
Shell_Init();
|
||||
if (gn->made == UNMADE && (gn == pgn || (pgn->type & OP_MADE) == 0)) {
|
||||
/*
|
||||
* First mark ourselves to be made, then apply whatever transformations
|
||||
* the suffix module thinks are necessary. Once that's done, we can
|
||||
* descend and make all our children. If any of them has an error
|
||||
* but the -k flag was given, our 'make' field will be set FALSE again.
|
||||
* This is our signal to not attempt to do anything but abort our
|
||||
* parent as well.
|
||||
*/
|
||||
gn->flags |= REMAKE;
|
||||
gn->made = BEINGMADE;
|
||||
if ((gn->type & OP_MADE) == 0)
|
||||
Suff_FindDeps(gn);
|
||||
Lst_ForEach(gn->children, Compat_Make, gn);
|
||||
if ((gn->flags & REMAKE) == 0) {
|
||||
gn->made = ABORTED;
|
||||
pgn->flags &= ~(unsigned)REMAKE;
|
||||
goto cohorts;
|
||||
}
|
||||
|
||||
if (Lst_FindDatum(gn->implicitParents, pgn) != NULL) {
|
||||
char *p1;
|
||||
Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn);
|
||||
bmake_free(p1);
|
||||
}
|
||||
|
||||
/*
|
||||
* All the children were made ok. Now cmgn->mtime contains the
|
||||
* modification time of the newest child, we need to find out if we
|
||||
* exist and when we were modified last. The criteria for datedness
|
||||
* are defined by the Make_OODate function.
|
||||
*/
|
||||
if (DEBUG(MAKE)) {
|
||||
fprintf(debug_file, "Examining %s...", gn->name);
|
||||
}
|
||||
if (! Make_OODate(gn)) {
|
||||
gn->made = UPTODATE;
|
||||
if (DEBUG(MAKE)) {
|
||||
fprintf(debug_file, "up-to-date.\n");
|
||||
}
|
||||
goto cohorts;
|
||||
} else if (DEBUG(MAKE)) {
|
||||
fprintf(debug_file, "out-of-date.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user is just seeing if something is out-of-date, exit now
|
||||
* to tell him/her "yes".
|
||||
*/
|
||||
if (queryFlag) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to be re-made. We also have to make sure we've got a $?
|
||||
* variable. To be nice, we also define the $> variable using
|
||||
* Make_DoAllVar().
|
||||
*/
|
||||
Make_DoAllVar(gn);
|
||||
|
||||
/*
|
||||
* Alter our type to tell if errors should be ignored or things
|
||||
* should not be printed so CompatRunCommand knows what to do.
|
||||
*/
|
||||
if (Targ_Ignore(gn)) {
|
||||
gn->type |= OP_IGNORE;
|
||||
}
|
||||
if (Targ_Silent(gn)) {
|
||||
gn->type |= OP_SILENT;
|
||||
}
|
||||
|
||||
if (Job_CheckCommands(gn, Fatal)) {
|
||||
/*
|
||||
* Our commands are ok, but we still have to worry about the -t
|
||||
* flag...
|
||||
*/
|
||||
if (!touchFlag || (gn->type & OP_MAKE)) {
|
||||
curTarg = gn;
|
||||
#ifdef USE_META
|
||||
if (useMeta && !NoExecute(gn)) {
|
||||
meta_job_start(NULL, gn);
|
||||
}
|
||||
#endif
|
||||
Lst_ForEach(gn->commands, CompatRunCommand, gn);
|
||||
curTarg = NULL;
|
||||
} else {
|
||||
Job_Touch(gn, (gn->type & OP_SILENT) != 0);
|
||||
}
|
||||
} else {
|
||||
gn->made = ERROR;
|
||||
}
|
||||
#ifdef USE_META
|
||||
if (useMeta && !NoExecute(gn)) {
|
||||
if (meta_job_finish(NULL) != 0)
|
||||
gn->made = ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gn->made != ERROR) {
|
||||
/*
|
||||
* If the node was made successfully, mark it so, update
|
||||
* its modification time and timestamp all its parents. Note
|
||||
* that for .ZEROTIME targets, the timestamping isn't done.
|
||||
* This is to keep its state from affecting that of its parent.
|
||||
*/
|
||||
gn->made = MADE;
|
||||
pgn->flags |= Make_Recheck(gn) == 0 ? FORCE : 0;
|
||||
if (!(gn->type & OP_EXEC)) {
|
||||
pgn->flags |= CHILDMADE;
|
||||
Make_TimeStamp(pgn, gn);
|
||||
}
|
||||
} else if (keepgoing) {
|
||||
pgn->flags &= ~(unsigned)REMAKE;
|
||||
} else {
|
||||
PrintOnError(gn, "\nStop.");
|
||||
exit(1);
|
||||
}
|
||||
} else if (gn->made == ERROR) {
|
||||
/*
|
||||
* Already had an error when making this beastie. Tell the parent
|
||||
* to abort.
|
||||
*/
|
||||
pgn->flags &= ~(unsigned)REMAKE;
|
||||
} else {
|
||||
if (Lst_FindDatum(gn->implicitParents, pgn) != NULL) {
|
||||
char *p1;
|
||||
const char *target = Var_Value(TARGET, gn, &p1);
|
||||
Var_Set(IMPSRC, target != NULL ? target : "", pgn);
|
||||
bmake_free(p1);
|
||||
}
|
||||
switch(gn->made) {
|
||||
case BEINGMADE:
|
||||
Error("Graph cycles through %s", gn->name);
|
||||
gn->made = ERROR;
|
||||
pgn->flags &= ~(unsigned)REMAKE;
|
||||
break;
|
||||
case MADE:
|
||||
if ((gn->type & OP_EXEC) == 0) {
|
||||
pgn->flags |= CHILDMADE;
|
||||
Make_TimeStamp(pgn, gn);
|
||||
}
|
||||
break;
|
||||
case UPTODATE:
|
||||
if ((gn->type & OP_EXEC) == 0) {
|
||||
Make_TimeStamp(pgn, gn);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cohorts:
|
||||
Lst_ForEach(gn->cohorts, Compat_Make, pgnp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize this module and start making.
|
||||
*
|
||||
* Input:
|
||||
* targs The target nodes to re-create
|
||||
*/
|
||||
void
|
||||
Compat_Run(Lst targs)
|
||||
{
|
||||
GNode *gn = NULL;/* Current root target */
|
||||
int errors; /* Number of targets not remade due to errors */
|
||||
|
||||
if (!shellName)
|
||||
Shell_Init();
|
||||
|
||||
if (bmake_signal(SIGINT, SIG_IGN) != SIG_IGN) {
|
||||
bmake_signal(SIGINT, CompatInterrupt);
|
||||
}
|
||||
if (bmake_signal(SIGTERM, SIG_IGN) != SIG_IGN) {
|
||||
bmake_signal(SIGTERM, CompatInterrupt);
|
||||
}
|
||||
if (bmake_signal(SIGHUP, SIG_IGN) != SIG_IGN) {
|
||||
bmake_signal(SIGHUP, CompatInterrupt);
|
||||
}
|
||||
if (bmake_signal(SIGQUIT, SIG_IGN) != SIG_IGN) {
|
||||
bmake_signal(SIGQUIT, CompatInterrupt);
|
||||
}
|
||||
|
||||
ENDNode = Targ_FindNode(".END", TARG_CREATE);
|
||||
ENDNode->type = OP_SPECIAL;
|
||||
/*
|
||||
* If the user has defined a .BEGIN target, execute the commands attached
|
||||
* to it.
|
||||
*/
|
||||
if (!queryFlag) {
|
||||
gn = Targ_FindNode(".BEGIN", TARG_NOCREATE);
|
||||
if (gn != NULL) {
|
||||
Compat_Make(gn, gn);
|
||||
if (gn->made == ERROR) {
|
||||
PrintOnError(gn, "\nStop.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Expand .USE nodes right now, because they can modify the structure
|
||||
* of the tree.
|
||||
*/
|
||||
Make_ExpandUse(targs);
|
||||
|
||||
/*
|
||||
* For each entry in the list of targets to create, call Compat_Make on
|
||||
* it to create the thing. Compat_Make will leave the 'made' field of gn
|
||||
* in one of several states:
|
||||
* UPTODATE gn was already up-to-date
|
||||
* MADE gn was recreated successfully
|
||||
* ERROR An error occurred while gn was being created
|
||||
* ABORTED gn was not remade because one of its inferiors
|
||||
* could not be made due to errors.
|
||||
*/
|
||||
errors = 0;
|
||||
while (!Lst_IsEmpty(targs)) {
|
||||
gn = Lst_Dequeue(targs);
|
||||
Compat_Make(gn, gn);
|
||||
|
||||
if (gn->made == UPTODATE) {
|
||||
printf("`%s' is up to date.\n", gn->name);
|
||||
} else if (gn->made == ABORTED) {
|
||||
printf("`%s' not remade because of errors.\n", gn->name);
|
||||
errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user has defined a .END target, run its commands.
|
||||
*/
|
||||
if (errors == 0) {
|
||||
Compat_Make(ENDNode, ENDNode);
|
||||
if (gn->made == ERROR) {
|
||||
PrintOnError(gn, "\nStop.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
1282
20200902/cond.c
Normal file
1282
20200902/cond.c
Normal file
File diff suppressed because it is too large
Load Diff
344
20200902/config.h.in
Normal file
344
20200902/config.h.in
Normal file
@ -0,0 +1,344 @@
|
||||
/* config.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
#undef AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
/* Path of default shell */
|
||||
#undef DEFSHELL_CUSTOM
|
||||
|
||||
/* Shell spec to use by default */
|
||||
#undef DEFSHELL_INDEX
|
||||
|
||||
/* Define to 1 if you have the <ar.h> header file. */
|
||||
#undef HAVE_AR_H
|
||||
|
||||
/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_SYS_SIGLIST
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/* Define to 1 if you have the `dirname' function. */
|
||||
#undef HAVE_DIRNAME
|
||||
|
||||
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
|
||||
#undef HAVE_DOPRNT
|
||||
|
||||
/* Define to 1 if you have the `err' function. */
|
||||
#undef HAVE_ERR
|
||||
|
||||
/* Define to 1 if you have the `errx' function. */
|
||||
#undef HAVE_ERRX
|
||||
|
||||
/* Define to 1 if you have the <err.h> header file. */
|
||||
#undef HAVE_ERR_H
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define to 1 if you have the `fork' function. */
|
||||
#undef HAVE_FORK
|
||||
|
||||
/* Define to 1 if you have the `getcwd' function. */
|
||||
#undef HAVE_GETCWD
|
||||
|
||||
/* Define to 1 if you have the `getenv' function. */
|
||||
#undef HAVE_GETENV
|
||||
|
||||
/* Define to 1 if you have the `getopt' function. */
|
||||
#undef HAVE_GETOPT
|
||||
|
||||
/* Define to 1 if you have the `getwd' function. */
|
||||
#undef HAVE_GETWD
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `killpg' function. */
|
||||
#undef HAVE_KILLPG
|
||||
|
||||
/* Define to 1 if you have the <libgen.h> header file. */
|
||||
#undef HAVE_LIBGEN_H
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
#undef HAVE_NDIR_H
|
||||
|
||||
/* Define to 1 if you have the <paths.h> header file. */
|
||||
#undef HAVE_PATHS_H
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#undef HAVE_POLL_H
|
||||
|
||||
/* Define to 1 if you have the `putenv' function. */
|
||||
#undef HAVE_PUTENV
|
||||
|
||||
/* Define to 1 if you have the <ranlib.h> header file. */
|
||||
#undef HAVE_RANLIB_H
|
||||
|
||||
/* Define to 1 if you have the `realpath' function. */
|
||||
#undef HAVE_REALPATH
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#undef HAVE_SELECT
|
||||
|
||||
/* Define to 1 if you have the `setenv' function. */
|
||||
#undef HAVE_SETENV
|
||||
|
||||
/* Define to 1 if you have the `setpgid' function. */
|
||||
#undef HAVE_SETPGID
|
||||
|
||||
/* Define to 1 if you have the `setsid' function. */
|
||||
#undef HAVE_SETSID
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#undef HAVE_SIGACTION
|
||||
|
||||
/* Define to 1 if you have the `sigvec' function. */
|
||||
#undef HAVE_SIGVEC
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#undef HAVE_SNPRINTF
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the `stresep' function. */
|
||||
#undef HAVE_STRESEP
|
||||
|
||||
/* Define to 1 if you have the `strftime' function. */
|
||||
#undef HAVE_STRFTIME
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#undef HAVE_STRLCPY
|
||||
|
||||
/* Define to 1 if you have the `strsep' function. */
|
||||
#undef HAVE_STRSEP
|
||||
|
||||
/* Define to 1 if you have the `strtod' function. */
|
||||
#undef HAVE_STRTOD
|
||||
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#undef HAVE_STRTOL
|
||||
|
||||
/* Define to 1 if `st_rdev' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_RDEV
|
||||
|
||||
/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
|
||||
`HAVE_STRUCT_STAT_ST_RDEV' instead. */
|
||||
#undef HAVE_ST_RDEV
|
||||
|
||||
/* Define to 1 if you have the `sysctl' function. */
|
||||
#undef HAVE_SYSCTL
|
||||
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#undef HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sysctl.h> header file. */
|
||||
#undef HAVE_SYS_SYSCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
#undef HAVE_SYS_UIO_H
|
||||
|
||||
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `unsetenv' function. */
|
||||
#undef HAVE_UNSETENV
|
||||
|
||||
/* Define to 1 if you have the <utime.h> header file. */
|
||||
#undef HAVE_UTIME_H
|
||||
|
||||
/* Define to 1 if you have the `vfork' function. */
|
||||
#undef HAVE_VFORK
|
||||
|
||||
/* Define to 1 if you have the <vfork.h> header file. */
|
||||
#undef HAVE_VFORK_H
|
||||
|
||||
/* Define to 1 if you have the `vprintf' function. */
|
||||
#undef HAVE_VPRINTF
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#undef HAVE_VSNPRINTF
|
||||
|
||||
/* Define to 1 if you have the `wait3' function. */
|
||||
#undef HAVE_WAIT3
|
||||
|
||||
/* Define to 1 if you have the `wait4' function. */
|
||||
#undef HAVE_WAIT4
|
||||
|
||||
/* Define to 1 if you have the `waitpid' function. */
|
||||
#undef HAVE_WAITPID
|
||||
|
||||
/* Define to 1 if you have the `warn' function. */
|
||||
#undef HAVE_WARN
|
||||
|
||||
/* Define to 1 if you have the `warnx' function. */
|
||||
#undef HAVE_WARNX
|
||||
|
||||
/* Define to 1 if `fork' works. */
|
||||
#undef HAVE_WORKING_FORK
|
||||
|
||||
/* Define to 1 if `vfork' works. */
|
||||
#undef HAVE_WORKING_VFORK
|
||||
|
||||
/* define if your compiler has __attribute__ */
|
||||
#undef HAVE___ATTRIBUTE__
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
#undef STAT_MACROS_BROKEN
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#undef TIME_WITH_SYS_TIME
|
||||
|
||||
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
|
||||
#undef TM_IN_SYS_TIME
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
# undef WORDS_BIGENDIAN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
#undef _UINT32_T
|
||||
|
||||
/* C99 function name */
|
||||
#undef __func__
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef mode_t
|
||||
|
||||
/* Define to `long int' if <sys/types.h> does not define. */
|
||||
#undef off_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef pid_t
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 32 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#undef uint32_t
|
||||
|
||||
/* Define as `fork' if `vfork' does not work. */
|
||||
#undef vfork
|
7448
20200902/configure
vendored
Executable file
7448
20200902/configure
vendored
Executable file
File diff suppressed because it is too large
Load Diff
433
20200902/configure.in
Normal file
433
20200902/configure.in
Normal file
@ -0,0 +1,433 @@
|
||||
dnl
|
||||
dnl RCSid:
|
||||
dnl $Id: configure.in,v 1.66 2020/07/10 16:34:38 sjg Exp $
|
||||
dnl
|
||||
dnl Process this file with autoconf to produce a configure script
|
||||
dnl
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT([bmake], [20200710], [sjg@NetBSD.org])
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
|
||||
dnl make srcdir absolute
|
||||
case "$srcdir" in
|
||||
/*) ;;
|
||||
*) srcdir=`cd $srcdir && pwd`;;
|
||||
esac
|
||||
|
||||
dnl get _MAKE_VERSION
|
||||
. $srcdir/VERSION
|
||||
OS=`uname -s`
|
||||
|
||||
dnl
|
||||
AC_ARG_WITH(defshell,
|
||||
[ --with-defshell=SHELL use SHELL by default - must be sh compatible, use sh or ksh to pick the internal definitions],
|
||||
[case "${withval}" in
|
||||
yes) AC_MSG_ERROR(bad value ${withval} given for bmake DEFSHELL) ;;
|
||||
no) ;;
|
||||
*) case "$with_defshell" in
|
||||
sh) DEFSHELL_INDEX=DEFSHELL_INDEX_SH;; # it's the default anyway
|
||||
ksh) DEFSHELL_INDEX=DEFSHELL_INDEX_KSH;;
|
||||
csh) DEFSHELL_INDEX=DEFSHELL_INDEX_CSH;; # kidding right?
|
||||
*) defshell_path=$with_defshell;; # better be sh compatible!
|
||||
esac
|
||||
;;
|
||||
esac])
|
||||
dnl
|
||||
case "$OS" in
|
||||
CYGWIN*|MINGW*) use_makefile=no;;
|
||||
*) use_makefile=yes;;
|
||||
esac
|
||||
AC_ARG_WITH(makefile,
|
||||
[ --without-makefile dissable use of generated makefile],
|
||||
[case "${withval}" in
|
||||
yes|no) use_makefile=${withval};;
|
||||
*) AC_MSG_ERROR(bad value ${withval} given for makefile) ;;
|
||||
esac])
|
||||
dnl
|
||||
use_meta=yes
|
||||
AC_ARG_WITH(meta,
|
||||
[ --without-meta dissable use of meta-mode],
|
||||
[case "${withval}" in
|
||||
yes|no) use_meta=${withval};;
|
||||
*) AC_MSG_ERROR(bad value ${withval} given for meta) ;;
|
||||
esac])
|
||||
dnl
|
||||
AC_ARG_WITH(filemon,
|
||||
[ --with-filemon={no,dev,ktrace,path/filemon.h} indicate filemon method for meta-mode. Path to filemon.h implies dev],
|
||||
[ case "/${withval}" in
|
||||
/no) use_filemon=no;;
|
||||
/*trace) filemon_h=no use_filemon="${withval}";;
|
||||
*/filemon.h) filemon_h="${withval}";;
|
||||
*/filemon*) filemon_h="${withval}/filemon.h";;
|
||||
*) AC_MSG_ERROR(bad value ${withval} given for filemon) ;;
|
||||
esac
|
||||
case "$use_filemon,$filemon_h" in
|
||||
,*.h) use_filemon=dev;;
|
||||
esac
|
||||
],
|
||||
[
|
||||
case "$OS" in
|
||||
NetBSD) filemon_h=no use_filemon=ktrace;;
|
||||
*)
|
||||
for d in "/usr/include/dev/filemon" "$prefix/include/dev/filemon" "$srcdir/../../sys/dev/filemon"
|
||||
do
|
||||
for x in "/$OS" ""
|
||||
do
|
||||
filemon_h="$d$x/filemon.h"
|
||||
test -s "$filemon_h" && break
|
||||
done
|
||||
test -s "$filemon_h" && { use_filemon=dev; break; }
|
||||
done
|
||||
;;
|
||||
esac
|
||||
use_filemon=${use_filemon:-no}
|
||||
case "$use_filemon" in
|
||||
dev) ;;
|
||||
*) filemon_h=no;;
|
||||
esac
|
||||
])
|
||||
dnl echo "Note: use_meta=$use_meta use_filemon=$use_filemon filemon_h=$filemon_h" >&6
|
||||
case "$use_meta" in
|
||||
yes)
|
||||
case "$use_filemon" in
|
||||
no) ;;
|
||||
*) echo "Using: filemon_${use_filemon}.c" >&6;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
dnl
|
||||
dnl Check for OS problems
|
||||
dnl Solaris's signal.h only privides sigset_t etc if one of
|
||||
dnl _EXTENSIONS_ _POSIX_C_SOURCE or _XOPEN_SOURCE are defined.
|
||||
dnl The later two seem to cause more problems than they solve so if we
|
||||
dnl see _EXTENSIONS_ we use it.
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CC_C99
|
||||
dnl AC_PROG_GCC_TRADITIONAL
|
||||
AC_PROG_INSTALL
|
||||
dnl Executable suffix - normally empty; .exe on os2.
|
||||
AC_SUBST(ac_exe_suffix)dnl
|
||||
dnl
|
||||
dnl Hurd refuses to define PATH_MAX or MAXPATHLEN
|
||||
if test -x /usr/bin/getconf; then
|
||||
bmake_path_max=`getconf PATH_MAX / 2> /dev/null`
|
||||
# only a numeric response is useful
|
||||
test ${bmake_path_max:-0} -gt 0 2> /dev/null || bmake_path_max=
|
||||
fi
|
||||
bmake_path_max=${bmake_path_max:-1024}
|
||||
if test $bmake_path_max -gt 1024; then
|
||||
# this is all we expect
|
||||
bmake_path_max=1024
|
||||
fi
|
||||
echo "Using: BMAKE_PATH_MAX=$bmake_path_max" >&6
|
||||
AC_SUBST(bmake_path_max)dnl
|
||||
dnl
|
||||
dnl AC_C_CROSS
|
||||
dnl
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_INCLUDES_DEFAULT
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_HEADER_DIRENT
|
||||
dnl Keep this list sorted
|
||||
AC_CHECK_HEADERS(sys/param.h)
|
||||
dnl On BSDi at least we really need sys/param.h for sys/sysctl.h
|
||||
AC_CHECK_HEADERS([sys/sysctl.h], [], [],
|
||||
[#ifdef HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
])
|
||||
|
||||
AC_CHECK_HEADERS( \
|
||||
ar.h \
|
||||
err.h \
|
||||
fcntl.h \
|
||||
libgen.h \
|
||||
limits.h \
|
||||
paths.h \
|
||||
poll.h \
|
||||
ranlib.h \
|
||||
sys/mman.h \
|
||||
sys/select.h \
|
||||
sys/socket.h \
|
||||
sys/time.h \
|
||||
sys/uio.h \
|
||||
utime.h \
|
||||
)
|
||||
|
||||
dnl Both *BSD and Linux have sys/cdefs.h, most do not.
|
||||
dnl If it is missing, we add -I${srcdir}/missing to CFLAGS
|
||||
dnl also if sys/cdefs.h does not have __RCSID we need to use ours
|
||||
dnl but we need to include the host's one too *sigh*
|
||||
AC_CHECK_HEADER(sys/cdefs.h,
|
||||
echo $ECHO_N "checking whether sys/cdefs.h is compatible... $ECHO_C" >&6
|
||||
AC_EGREP_CPP(yes,
|
||||
[#include <sys/cdefs.h>
|
||||
#ifdef __RCSID
|
||||
yes
|
||||
#endif
|
||||
],
|
||||
echo yes >&6,
|
||||
echo no >&6; CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd` -DNEED_HOST_CDEFS_H"),
|
||||
CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd`")
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C___ATTRIBUTE__
|
||||
AC_C_BIGENDIAN
|
||||
AC_C_CONST
|
||||
AC_TYPE_MODE_T
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_UINT32_T
|
||||
AC_DECL_SYS_SIGLIST
|
||||
AC_HEADER_TIME
|
||||
AC_STRUCT_TM
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_VFORK
|
||||
AC_FUNC_VPRINTF
|
||||
AC_FUNC_WAIT3
|
||||
dnl Keep this list sorted
|
||||
AC_CHECK_FUNCS( \
|
||||
err \
|
||||
errx \
|
||||
getcwd \
|
||||
getenv \
|
||||
getopt \
|
||||
getwd \
|
||||
killpg \
|
||||
mmap \
|
||||
putenv \
|
||||
select \
|
||||
setenv \
|
||||
setpgid \
|
||||
setsid \
|
||||
sigaction \
|
||||
sigvec \
|
||||
snprintf \
|
||||
strerror \
|
||||
strftime \
|
||||
strsep \
|
||||
strtod \
|
||||
strtol \
|
||||
sysctl \
|
||||
unsetenv \
|
||||
vsnprintf \
|
||||
wait3 \
|
||||
wait4 \
|
||||
waitpid \
|
||||
warn \
|
||||
warnx \
|
||||
)
|
||||
|
||||
dnl functions which we may need to provide
|
||||
AC_REPLACE_FUNCS( \
|
||||
realpath \
|
||||
dirname \
|
||||
stresep \
|
||||
strlcpy \
|
||||
)
|
||||
|
||||
AC_CHECK_LIB([util], [emalloc],
|
||||
[ AC_CHECK_LIB([util], [erealloc],
|
||||
[ AC_CHECK_LIB([util], [estrdup],
|
||||
[ AC_CHECK_LIB([util], [estrndup],
|
||||
[ LIBS="$LIBS -lutil"
|
||||
CPPFLAGS="$CPPFLAGS -DUSE_EMALLOC" ])])])])
|
||||
|
||||
dnl
|
||||
dnl Structures
|
||||
dnl
|
||||
AC_HEADER_STAT
|
||||
AC_STRUCT_ST_RDEV
|
||||
dnl
|
||||
echo "checking if compiler supports __func__" >&6
|
||||
AC_LANG(C)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[[const char *func = __func__;]])],,
|
||||
AC_DEFINE(__func__, __FUNCTION__, C99 function name))
|
||||
dnl
|
||||
dnl we want this for unit-tests/Makefile
|
||||
echo $ECHO_N "checking if diff -u works... $ECHO_C" >&6
|
||||
if diff -u /dev/null /dev/null > /dev/null 2>&1; then
|
||||
diff_u=-u
|
||||
echo yes >&6
|
||||
else
|
||||
diff_u=
|
||||
echo no >&6
|
||||
fi
|
||||
dnl
|
||||
dnl AC_* don't quite cut it.
|
||||
dnl
|
||||
echo "checking for MACHINE & MACHINE_ARCH..." >&6
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#include "confdefs.h"
|
||||
#include <sys/param.h>
|
||||
#ifdef MACHINE
|
||||
machine=MACHINE
|
||||
#endif
|
||||
#ifdef MACHINE_ARCH
|
||||
machine_arch=MACHINE_ARCH
|
||||
#endif
|
||||
EOF
|
||||
|
||||
default_machine=`(eval "$ac_cpp conftest.$ac_ext") 2>&5 |
|
||||
egrep machine= | tr -d ' "'`
|
||||
rm -rf conftest*
|
||||
if test "$default_machine"; then
|
||||
eval "$default_machine"
|
||||
fi
|
||||
machine=${machine:-`$srcdir/machine.sh`}
|
||||
machine_arch=${machine_arch:-`$srcdir/machine.sh arch`}
|
||||
echo "defaults: MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6
|
||||
dnl
|
||||
dnl now allow overrides
|
||||
dnl
|
||||
AC_ARG_WITH(machine,
|
||||
[ --with-machine=MACHINE explicitly set MACHINE],
|
||||
[case "${withval}" in
|
||||
yes) AC_MSG_ERROR(bad value ${withval} given for bmake MACHINE) ;;
|
||||
no) ;;
|
||||
generic) machine=`$srcdir/machine.sh`;;
|
||||
*) machine=$with_machine;;
|
||||
esac])
|
||||
force_machine=
|
||||
AC_ARG_WITH(force_machine,
|
||||
[ --with-force-machine=MACHINE set FORCE_MACHINE],
|
||||
[case "${withval}" in
|
||||
yes) force_machine=FORCE_;;
|
||||
no) ;;
|
||||
*) force_machine=FORCE_; machine=$with_force_machine;;
|
||||
esac])
|
||||
dnl
|
||||
force_machine_arch=
|
||||
AC_ARG_WITH(force_machine_arch,
|
||||
[ --with-force-machine-arch=MACHINE set FORCE_MACHINE_ARCH],
|
||||
[case "${withval}" in
|
||||
yes) force_machine_arch=FORCE_;;
|
||||
no) ;;
|
||||
*) force_machine_arch=FORCE_; machine_arch=$with_force_machine;;
|
||||
esac])
|
||||
dnl
|
||||
AC_ARG_WITH(machine_arch,
|
||||
[ --with-machine_arch=MACHINE_ARCH explicitly set MACHINE_ARCH],
|
||||
[case "${withval}" in
|
||||
yes) AC_MSG_ERROR(bad value ${withval} given for bmake MACHINE_ARCH) ;;
|
||||
no) ;;
|
||||
*) machine_arch=$with_machine_arch;;
|
||||
esac])
|
||||
dnl
|
||||
dnl Tell them what we ended up with
|
||||
dnl
|
||||
echo "Using: ${force_machine}MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6
|
||||
dnl
|
||||
dnl Allow folk to control _PATH_DEFSYSPATH
|
||||
dnl
|
||||
default_sys_path=\${prefix}/share/mk
|
||||
AC_ARG_WITH(default-sys-path,
|
||||
[ --with-default-sys-path=PATH:DIR:LIST use an explicit _PATH_DEFSYSPATH
|
||||
MAKESYSPATH is a ':' separated list of directories
|
||||
that bmake will search for system .mk files.
|
||||
_PATH_DEFSYSPATH is its default value.],
|
||||
[case "${withval}" in
|
||||
yes) AC_MSG_ERROR(bad value ${withval} given for bmake _PATH_DEFSYSPATH) ;;
|
||||
no) ;;
|
||||
*) default_sys_path="$with_default_sys_path"
|
||||
;;
|
||||
esac])
|
||||
dnl
|
||||
dnl Some folk don't like this one
|
||||
dnl
|
||||
AC_ARG_WITH(path-objdirprefix,
|
||||
[ --with-path-objdirprefix=PATH override _PATH_OBJDIRPREFIX],
|
||||
[case "${withval}" in
|
||||
yes) AC_MSG_ERROR(bad value ${withval} given for bmake _PATH_OBJDIRPREFIX) ;;
|
||||
no) CPPFLAGS="$CPPFLAGS -DNO_PATH_OBJDIRPREFIX" ;;
|
||||
*) CPPFLAGS="$CPPFLAGS \"-D_PATH_OBJDIRPREFIX=\\\"$with_path-objdir\\\"\"" ;;
|
||||
esac])
|
||||
dnl
|
||||
dnl And this can be handy to do with out.
|
||||
dnl
|
||||
AC_ARG_ENABLE(pwd-override,
|
||||
[ --disable-pwd-override disable \$PWD overriding getcwd()],
|
||||
[case "${enableval}" in
|
||||
yes) ;;
|
||||
no) CPPFLAGS="$CPPFLAGS -DNO_PWD_OVERRIDE" ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} given for pwd-override option) ;;
|
||||
esac])
|
||||
dnl
|
||||
dnl Just for grins
|
||||
dnl
|
||||
AC_ARG_ENABLE(check-make-chdir,
|
||||
[ --disable-check-make-chdir disable make trying to guess
|
||||
when it should automatically cd \${.CURDIR}],
|
||||
[case "${enableval}" in
|
||||
yes) ;;
|
||||
no) CPPFLAGS="$CPPFLAGS -DNO_CHECK_MAKE_CHDIR" ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} given for check-make-chdir option) ;;
|
||||
esac])
|
||||
dnl
|
||||
dnl On non-BSD systems, bootstrap won't work without mk
|
||||
dnl
|
||||
AC_ARG_WITH(mksrc,
|
||||
[ --with-mksrc=PATH tell makefile.boot where to find mk src],
|
||||
[case "${withval}" in
|
||||
""|yes|no) ;;
|
||||
*) test -s $withval/install-mk && mksrc=$withval ||
|
||||
AC_MSG_ERROR(bad value ${withval} given for mksrc cannot find install-mk)
|
||||
;;
|
||||
esac
|
||||
])
|
||||
dnl
|
||||
dnl Now make sure we have a value
|
||||
dnl
|
||||
srcdir=`cd $srcdir && pwd`
|
||||
for mksrc in $mksrc $srcdir/mk $srcdir/../mk mk
|
||||
do
|
||||
test -s $mksrc/install-mk || continue
|
||||
mksrc=`cd $mksrc && pwd`
|
||||
break
|
||||
done
|
||||
mksrc=`echo $mksrc | sed "s,$srcdir,\\\${srcdir},"`
|
||||
echo "Using: MKSRC=$mksrc" 1>&6
|
||||
dnl On some systems we want a different default shell by default
|
||||
if test -x /usr/xpg4/bin/sh; then
|
||||
defshell_path=${defshell_path:-/usr/xpg4/bin/sh}
|
||||
fi
|
||||
if test -n "$defshell_path"; then
|
||||
echo "Using: SHELL=$defshell_path" >&6
|
||||
AC_DEFINE_UNQUOTED(DEFSHELL_CUSTOM, "$defshell_path", Path of default shell)
|
||||
fi
|
||||
if test -n "$DEFSHELL_INDEX"; then
|
||||
AC_DEFINE_UNQUOTED(DEFSHELL_INDEX, $DEFSHELL_INDEX, Shell spec to use by default)
|
||||
fi
|
||||
dnl
|
||||
AC_SUBST(machine)
|
||||
AC_SUBST(force_machine)
|
||||
AC_SUBST(machine_arch)
|
||||
AC_SUBST(mksrc)
|
||||
AC_SUBST(default_sys_path)
|
||||
AC_SUBST(INSTALL)
|
||||
AC_SUBST(GCC)
|
||||
AC_SUBST(diff_u)
|
||||
AC_SUBST(use_meta)
|
||||
AC_SUBST(use_filemon)
|
||||
AC_SUBST(filemon_h)
|
||||
AC_SUBST(_MAKE_VERSION)
|
||||
bm_outfiles="Makefile.config unit-tests/Makefile.config make-bootstrap.sh"
|
||||
if test $use_makefile = yes; then
|
||||
bm_outfiles="makefile $bm_outfiles"
|
||||
fi
|
||||
AC_OUTPUT($bm_outfiles)
|
||||
cat <<EOF
|
||||
|
||||
You can now run
|
||||
|
||||
sh ./make-bootstrap.sh
|
||||
|
||||
to produce a fully functional bmake.
|
||||
|
||||
EOF
|
1770
20200902/dir.c
Normal file
1770
20200902/dir.c
Normal file
File diff suppressed because it is too large
Load Diff
116
20200902/dir.h
Normal file
116
20200902/dir.h
Normal file
@ -0,0 +1,116 @@
|
||||
/* $NetBSD: dir.h,v 1.23 2020/09/02 04:08:54 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)dir.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989 by Adam de Boor
|
||||
* Copyright (c) 1989 by Berkeley Softworks
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)dir.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
#ifndef MAKE_DIR_H
|
||||
#define MAKE_DIR_H
|
||||
|
||||
/* A cache of a directory, remembering all the files that exist in that
|
||||
* directory. */
|
||||
typedef struct {
|
||||
char *name; /* Name of directory */
|
||||
int refCount; /* Number of paths with this directory */
|
||||
int hits; /* the number of times a file in this
|
||||
* directory has been found */
|
||||
Hash_Table files; /* Hash set of files in directory */
|
||||
} Path;
|
||||
|
||||
struct make_stat {
|
||||
time_t mst_mtime;
|
||||
mode_t mst_mode;
|
||||
};
|
||||
|
||||
void Dir_Init(void);
|
||||
void Dir_InitDir(const char *);
|
||||
void Dir_InitCur(const char *);
|
||||
void Dir_InitDot(void);
|
||||
void Dir_End(void);
|
||||
void Dir_SetPATH(void);
|
||||
Boolean Dir_HasWildcards(const char *);
|
||||
void Dir_Expand(const char *, Lst, Lst);
|
||||
char *Dir_FindFile(const char *, Lst);
|
||||
Boolean Dir_FindHereOrAbove(const char *, const char *, char *, int);
|
||||
int Dir_MTime(GNode *, Boolean);
|
||||
Path *Dir_AddDir(Lst, const char *);
|
||||
char *Dir_MakeFlags(const char *, Lst);
|
||||
void Dir_ClearPath(Lst);
|
||||
void Dir_Concat(Lst, Lst);
|
||||
void Dir_PrintDirectories(void);
|
||||
void Dir_PrintPath(Lst);
|
||||
void Dir_Destroy(void *);
|
||||
void *Dir_CopyDir(void *);
|
||||
|
||||
int cached_lstat(const char *, struct make_stat *);
|
||||
int cached_stat(const char *, struct make_stat *);
|
||||
|
||||
#endif /* MAKE_DIR_H */
|
125
20200902/dirname.c
Normal file
125
20200902/dirname.c
Normal file
@ -0,0 +1,125 @@
|
||||
/* $NetBSD: dirname.c,v 1.14 2018/09/27 00:45:34 kre Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Klaus Klein and Jason R. Thorpe.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#ifndef HAVE_DIRNAME
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: dirname.c,v 1.14 2018/09/27 00:45:34 kre Exp $");
|
||||
#endif /* !LIBC_SCCS && !lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#ifdef HAVE_LIBGEN_H
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifndef PATH_MAX
|
||||
# define PATH_MAX 1024
|
||||
#endif
|
||||
#ifndef MIN
|
||||
# define MIN(a, b) ((a < b) ? a : b)
|
||||
#endif
|
||||
|
||||
|
||||
static size_t
|
||||
xdirname_r(const char *path, char *buf, size_t buflen)
|
||||
{
|
||||
const char *endp;
|
||||
size_t len;
|
||||
|
||||
/*
|
||||
* If `path' is a null pointer or points to an empty string,
|
||||
* return a pointer to the string ".".
|
||||
*/
|
||||
if (path == NULL || *path == '\0') {
|
||||
path = ".";
|
||||
len = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Strip trailing slashes, if any. */
|
||||
endp = path + strlen(path) - 1;
|
||||
while (endp != path && *endp == '/')
|
||||
endp--;
|
||||
|
||||
/* Find the start of the dir */
|
||||
while (endp > path && *endp != '/')
|
||||
endp--;
|
||||
|
||||
if (endp == path) {
|
||||
path = *endp == '/' ? "/" : ".";
|
||||
len = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
do
|
||||
endp--;
|
||||
while (endp > path && *endp == '/');
|
||||
|
||||
len = endp - path + 1;
|
||||
out:
|
||||
if (buf != NULL && buflen != 0) {
|
||||
buflen = MIN(len, buflen - 1);
|
||||
if (buf != path)
|
||||
memcpy(buf, path, buflen);
|
||||
buf[buflen] = '\0';
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
char *
|
||||
dirname(char *path)
|
||||
{
|
||||
static char result[PATH_MAX];
|
||||
(void)xdirname_r(path, result, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef MAIN
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
printf("%s\n", dirname(argv[1]));
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
100
20200902/enum.c
Executable file
100
20200902/enum.c
Executable file
@ -0,0 +1,100 @@
|
||||
/* $NetBSD: enum.c,v 1.6 2020/09/01 20:34:51 rillig Exp $ */
|
||||
|
||||
/*
|
||||
Copyright (c) 2020 Roland Illig <rillig@NetBSD.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: enum.c,v 1.6 2020/09/01 20:34:51 rillig Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: enum.c,v 1.6 2020/09/01 20:34:51 rillig Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "enum.h"
|
||||
|
||||
/* Convert a bitset into a string representation, showing the names of the
|
||||
* individual bits.
|
||||
*
|
||||
* Optionally, shortcuts for groups of bits can be added. To have an effect,
|
||||
* they need to be listed before their individual bits. */
|
||||
const char *
|
||||
Enum_FlagsToString(char *buf, size_t buf_size,
|
||||
int value, const EnumToStringSpec *spec)
|
||||
{
|
||||
const char *buf_start = buf;
|
||||
const char *sep = "";
|
||||
size_t sep_len = 0;
|
||||
|
||||
for (; spec->es_value != 0; spec++) {
|
||||
size_t name_len;
|
||||
|
||||
if ((value & spec->es_value) != spec->es_value)
|
||||
continue;
|
||||
value &= ~spec->es_value;
|
||||
|
||||
assert(buf_size >= sep_len + 1);
|
||||
memcpy(buf, sep, sep_len);
|
||||
buf += sep_len;
|
||||
buf_size -= sep_len;
|
||||
|
||||
name_len = strlen(spec->es_name);
|
||||
assert(buf_size >= name_len + 1);
|
||||
memcpy(buf, spec->es_name, name_len);
|
||||
buf += name_len;
|
||||
buf_size -= name_len;
|
||||
|
||||
sep = ENUM__SEP;
|
||||
sep_len = sizeof ENUM__SEP - 1;
|
||||
}
|
||||
|
||||
/* If this assertion fails, the listed enum values are incomplete. */
|
||||
assert(value == 0);
|
||||
|
||||
if (buf == buf_start)
|
||||
return "none";
|
||||
|
||||
assert(buf_size >= 1);
|
||||
buf[0] = '\0';
|
||||
return buf_start;
|
||||
}
|
||||
|
||||
/* Convert a fixed-value enum into a string representation. */
|
||||
const char *
|
||||
Enum_ValueToString(int value, const EnumToStringSpec *spec)
|
||||
{
|
||||
for (; spec->es_name[0] != '\0'; spec++) {
|
||||
if (value == spec->es_value)
|
||||
return spec->es_name;
|
||||
}
|
||||
abort(/* unknown enum value */);
|
||||
}
|
193
20200902/enum.h
Executable file
193
20200902/enum.h
Executable file
@ -0,0 +1,193 @@
|
||||
/* $NetBSD: enum.h,v 1.9 2020/09/01 20:34:51 rillig Exp $ */
|
||||
|
||||
/*
|
||||
Copyright (c) 2020 Roland Illig <rillig@NetBSD.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MAKE_ENUM_H
|
||||
#define MAKE_ENUM_H
|
||||
|
||||
/* Generate string representations for bitmasks and simple enums. */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
int es_value;
|
||||
const char *es_name;
|
||||
} EnumToStringSpec;
|
||||
|
||||
const char *Enum_FlagsToString(char *, size_t, int, const EnumToStringSpec *);
|
||||
const char *Enum_ValueToString(int, const EnumToStringSpec *);
|
||||
|
||||
/* For Enum_FlagsToString, the separator between flags. */
|
||||
#define ENUM__SEP "|"
|
||||
|
||||
/* Generate the string that joins all possible flags, to see how large the
|
||||
* buffer must be. */
|
||||
#define ENUM__JOIN_STR_1(v1) \
|
||||
#v1
|
||||
#define ENUM__JOIN_STR_2(v1, v2) \
|
||||
ENUM__JOIN_STR_1(v1) ENUM__SEP \
|
||||
ENUM__JOIN_STR_1(v2)
|
||||
#define ENUM__JOIN_STR_4(v1, v2, v3, v4) \
|
||||
ENUM__JOIN_STR_2(v1, v2) ENUM__SEP \
|
||||
ENUM__JOIN_STR_2(v3, v4)
|
||||
#define ENUM__JOIN_STR_8(v1, v2, v3, v4, v5, v6, v7, v8) \
|
||||
ENUM__JOIN_STR_4(v1, v2, v3, v4) ENUM__SEP \
|
||||
ENUM__JOIN_STR_4(v5, v6, v7, v8)
|
||||
#define ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16) \
|
||||
ENUM__JOIN_STR_8(v01, v02, v03, v04, v05, v06, v07, v08) ENUM__SEP \
|
||||
ENUM__JOIN_STR_8(v09, v10, v11, v12, v13, v14, v15, v16)
|
||||
|
||||
#define ENUM__JOIN_2(part1, part2) \
|
||||
part1 ENUM__SEP part2
|
||||
#define ENUM__JOIN_3(part1, part2, part3) \
|
||||
part1 ENUM__SEP part2 ENUM__SEP part3
|
||||
#define ENUM__JOIN_4(part1, part2, part3, part4) \
|
||||
part1 ENUM__SEP part2 ENUM__SEP part3 ENUM__SEP part4
|
||||
#define ENUM__JOIN_5(part1, part2, part3, part4, part5) \
|
||||
part1 ENUM__SEP part2 ENUM__SEP part3 ENUM__SEP part4 ENUM__SEP part5
|
||||
|
||||
/* List the pairs of enum value and corresponding name. */
|
||||
#define ENUM__SPEC_1(v1) \
|
||||
{ v1, #v1 }
|
||||
#define ENUM__SPEC_2(v1, v2) \
|
||||
ENUM__SPEC_1(v1), \
|
||||
ENUM__SPEC_1(v2)
|
||||
#define ENUM__SPEC_4(v1, v2, v3, v4) \
|
||||
ENUM__SPEC_2(v1, v2), \
|
||||
ENUM__SPEC_2(v3, v4)
|
||||
#define ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8) \
|
||||
ENUM__SPEC_4(v1, v2, v3, v4), \
|
||||
ENUM__SPEC_4(v5, v6, v7, v8)
|
||||
#define ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16) \
|
||||
ENUM__SPEC_8(v01, v02, v03, v04, v05, v06, v07, v08), \
|
||||
ENUM__SPEC_8(v09, v10, v11, v12, v13, v14, v15, v16)
|
||||
|
||||
#define ENUM__SPECS_2(part1, part2) \
|
||||
{ part1, part2, { 0, "" } }
|
||||
#define ENUM__SPECS_3(part1, part2, part3) \
|
||||
{ part1, part2, part3, { 0, "" } }
|
||||
#define ENUM__SPECS_4(part1, part2, part3, part4) \
|
||||
{ part1, part2, part3, part4, { 0, "" } }
|
||||
#define ENUM__SPECS_5(part1, part2, part3, part4, part5) \
|
||||
{ part1, part2, part3, part4, part5, { 0, "" } }
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_ValueToString. */
|
||||
#define ENUM__VALUE_RTTI(typnam, specs) \
|
||||
static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_FlagsToString. */
|
||||
#define ENUM__FLAGS_RTTI(typnam, specs, joined) \
|
||||
static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs; \
|
||||
enum { typnam ## _ ## ToStringSize = sizeof joined }
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 3 flags. */
|
||||
#define ENUM_FLAGS_RTTI_3(typnam, v1, v2, v3) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_2(v1, v2), \
|
||||
ENUM__SPEC_1(v3)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_2(v1, v2), \
|
||||
ENUM__JOIN_STR_1(v3)))
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 8 flags. */
|
||||
#define ENUM_FLAGS_RTTI_8(typnam, v1, v2, v3, v4, v5, v6, v7, v8) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_4(v1, v2, v3, v4), \
|
||||
ENUM__SPEC_4(v5, v6, v7, v8)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_4(v1, v2, v3, v4), \
|
||||
ENUM__JOIN_STR_4(v5, v6, v7, v8)))
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_ValueToString
|
||||
* for an enum with 8 constants. */
|
||||
#define ENUM_VALUE_RTTI_8(typnam, v1, v2, v3, v4, v5, v6, v7, v8) \
|
||||
ENUM__VALUE_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_4(v1, v2, v3, v4), \
|
||||
ENUM__SPEC_4(v5, v6, v7, v8)))
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 10 flags. */
|
||||
#define ENUM_FLAGS_RTTI_10(typnam, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8), \
|
||||
ENUM__SPEC_2(v9, v10)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_8(v1, v2, v3, v4, v5, v6, v7, v8), \
|
||||
ENUM__JOIN_STR_2(v9, v10)))
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 31 flags. */
|
||||
#define ENUM_FLAGS_RTTI_31(typnam, \
|
||||
v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16, \
|
||||
v17, v18, v19, v20, v21, v22, v23, v24, \
|
||||
v25, v26, v27, v28, v29, v30, v31) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_5( \
|
||||
ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16), \
|
||||
ENUM__SPEC_8(v17, v18, v19, v20, v21, v22, v23, v24), \
|
||||
ENUM__SPEC_4(v25, v26, v27, v28), \
|
||||
ENUM__SPEC_2(v29, v30), \
|
||||
ENUM__SPEC_1(v31)), \
|
||||
ENUM__JOIN_5( \
|
||||
ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16), \
|
||||
ENUM__JOIN_STR_8(v17, v18, v19, v20, v21, v22, v23, v24), \
|
||||
ENUM__JOIN_STR_4(v25, v26, v27, v28), \
|
||||
ENUM__JOIN_STR_2(v29, v30), \
|
||||
ENUM__JOIN_STR_1(v31)))
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 32 flags. */
|
||||
#define ENUM_FLAGS_RTTI_32(typnam, \
|
||||
v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16, \
|
||||
v17, v18, v19, v20, v21, v22, v23, v24, \
|
||||
v25, v26, v27, v28, v29, v30, v31, v32) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16), \
|
||||
ENUM__SPEC_16(v17, v18, v19, v20, v21, v22, v23, v24, \
|
||||
v25, v26, v27, v28, v29, v30, v31, v32)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16), \
|
||||
ENUM__JOIN_STR_16(v17, v18, v19, v20, v21, v22, v23, v24, \
|
||||
v25, v26, v27, v28, v29, v30, v31, v32)))
|
||||
|
||||
#endif
|
53
20200902/filemon/filemon.h
Normal file
53
20200902/filemon/filemon.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* $NetBSD: filemon.h,v 1.2 2020/01/22 22:10:36 sjg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Taylor R. Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FILEMON_H_
|
||||
#define FILEMON_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
struct filemon;
|
||||
|
||||
const char *
|
||||
filemon_path(void);
|
||||
|
||||
struct filemon *
|
||||
filemon_open(void);
|
||||
int filemon_close(struct filemon *);
|
||||
|
||||
int filemon_setfd(struct filemon *, int);
|
||||
void filemon_setpid_parent(struct filemon *, pid_t);
|
||||
int filemon_setpid_child(const struct filemon *, pid_t);
|
||||
|
||||
int filemon_readfd(const struct filemon *);
|
||||
int filemon_process(struct filemon *);
|
||||
|
||||
#endif /* FILEMON_H_ */
|
151
20200902/filemon/filemon_dev.c
Normal file
151
20200902/filemon/filemon_dev.c
Normal file
@ -0,0 +1,151 @@
|
||||
/* $NetBSD: filemon_dev.c,v 1.3 2020/07/10 15:53:30 sjg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2020 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Taylor R. Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "filemon.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_FILEMON_H
|
||||
# include <filemon.h>
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_FILEMON
|
||||
#define _PATH_FILEMON "/dev/filemon"
|
||||
#endif
|
||||
|
||||
struct filemon {
|
||||
int fd;
|
||||
};
|
||||
|
||||
const char *
|
||||
filemon_path(void)
|
||||
{
|
||||
|
||||
return _PATH_FILEMON;
|
||||
}
|
||||
|
||||
struct filemon *
|
||||
filemon_open(void)
|
||||
{
|
||||
struct filemon *F;
|
||||
unsigned i;
|
||||
int error;
|
||||
|
||||
/* Allocate and zero a struct filemon object. */
|
||||
F = calloc(1, sizeof(*F));
|
||||
if (F == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Try opening /dev/filemon, up to six times (cargo cult!). */
|
||||
for (i = 0; (F->fd = open(_PATH_FILEMON, O_RDWR|O_CLOEXEC)) == -1; i++) {
|
||||
if (i == 5) {
|
||||
error = errno;
|
||||
goto fail0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Success! */
|
||||
return F;
|
||||
|
||||
fail0: free(F);
|
||||
errno = error;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
filemon_setfd(struct filemon *F, int fd)
|
||||
{
|
||||
|
||||
/* Point the kernel at this file descriptor. */
|
||||
if (ioctl(F->fd, FILEMON_SET_FD, &fd) == -1)
|
||||
return -1;
|
||||
|
||||
/* No need for it in userland any more; close it. */
|
||||
(void)close(fd);
|
||||
|
||||
/* Success! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
filemon_setpid_parent(struct filemon *F, pid_t pid)
|
||||
{
|
||||
/* Nothing to do! */
|
||||
}
|
||||
|
||||
int
|
||||
filemon_setpid_child(const struct filemon *F, pid_t pid)
|
||||
{
|
||||
|
||||
/* Just pass it on to the kernel. */
|
||||
return ioctl(F->fd, FILEMON_SET_PID, &pid);
|
||||
}
|
||||
|
||||
int
|
||||
filemon_close(struct filemon *F)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
/* Close the filemon device fd. */
|
||||
if (close(F->fd) == -1 && error == 0)
|
||||
error = errno;
|
||||
|
||||
/* Free the filemon descriptor. */
|
||||
free(F);
|
||||
|
||||
/* Set errno and return -1 if anything went wrong. */
|
||||
if (error) {
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Success! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
filemon_readfd(const struct filemon *F)
|
||||
{
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
filemon_process(struct filemon *F)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
878
20200902/filemon/filemon_ktrace.c
Normal file
878
20200902/filemon/filemon_ktrace.c
Normal file
@ -0,0 +1,878 @@
|
||||
/* $NetBSD: filemon_ktrace.c,v 1.2 2020/01/19 20:22:57 riastradh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Taylor R. Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define _KERNTYPES /* register_t */
|
||||
|
||||
#include "filemon.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/rbtree.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <sys/ktrace.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef AT_CWD
|
||||
#define AT_CWD -1
|
||||
#endif
|
||||
|
||||
struct filemon;
|
||||
struct filemon_key;
|
||||
struct filemon_state;
|
||||
|
||||
typedef struct filemon_state *filemon_syscall_t(struct filemon *,
|
||||
const struct filemon_key *, const struct ktr_syscall *);
|
||||
|
||||
static filemon_syscall_t filemon_sys_chdir;
|
||||
static filemon_syscall_t filemon_sys_execve;
|
||||
static filemon_syscall_t filemon_sys_exit;
|
||||
static filemon_syscall_t filemon_sys_fork;
|
||||
static filemon_syscall_t filemon_sys_link;
|
||||
static filemon_syscall_t filemon_sys_open;
|
||||
static filemon_syscall_t filemon_sys_openat;
|
||||
static filemon_syscall_t filemon_sys_symlink;
|
||||
static filemon_syscall_t filemon_sys_unlink;
|
||||
static filemon_syscall_t filemon_sys_rename;
|
||||
|
||||
static filemon_syscall_t *const filemon_syscalls[] = {
|
||||
[SYS_chdir] = &filemon_sys_chdir,
|
||||
[SYS_execve] = &filemon_sys_execve,
|
||||
[SYS_exit] = &filemon_sys_exit,
|
||||
[SYS_fork] = &filemon_sys_fork,
|
||||
[SYS_link] = &filemon_sys_link,
|
||||
[SYS_open] = &filemon_sys_open,
|
||||
[SYS_openat] = &filemon_sys_openat,
|
||||
[SYS_symlink] = &filemon_sys_symlink,
|
||||
[SYS_unlink] = &filemon_sys_unlink,
|
||||
[SYS_rename] = &filemon_sys_rename,
|
||||
};
|
||||
|
||||
struct filemon {
|
||||
int ktrfd; /* kernel writes ktrace events here */
|
||||
FILE *in; /* we read ktrace events from here */
|
||||
FILE *out; /* we write filemon events to here */
|
||||
rb_tree_t active;
|
||||
pid_t child;
|
||||
|
||||
/* I/O state machine. */
|
||||
enum {
|
||||
FILEMON_START = 0,
|
||||
FILEMON_HEADER,
|
||||
FILEMON_PAYLOAD,
|
||||
FILEMON_ERROR,
|
||||
} state;
|
||||
unsigned char *p;
|
||||
size_t resid;
|
||||
|
||||
/* I/O buffer. */
|
||||
struct ktr_header hdr;
|
||||
union {
|
||||
struct ktr_syscall syscall;
|
||||
struct ktr_sysret sysret;
|
||||
char namei[PATH_MAX];
|
||||
unsigned char buf[4096];
|
||||
} payload;
|
||||
};
|
||||
|
||||
struct filemon_state {
|
||||
struct filemon_key {
|
||||
pid_t pid;
|
||||
lwpid_t lid;
|
||||
} key;
|
||||
struct rb_node node;
|
||||
int syscode;
|
||||
void (*show)(struct filemon *, const struct filemon_state *,
|
||||
const struct ktr_sysret *);
|
||||
unsigned i;
|
||||
unsigned npath;
|
||||
char *path[/*npath*/];
|
||||
};
|
||||
|
||||
static int
|
||||
compare_filemon_states(void *cookie, const void *na, const void *nb)
|
||||
{
|
||||
const struct filemon_state *Sa = na;
|
||||
const struct filemon_state *Sb = nb;
|
||||
|
||||
if (Sa->key.pid < Sb->key.pid)
|
||||
return -1;
|
||||
if (Sa->key.pid > Sb->key.pid)
|
||||
return +1;
|
||||
if (Sa->key.lid < Sb->key.lid)
|
||||
return -1;
|
||||
if (Sa->key.lid > Sb->key.lid)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
compare_filemon_key(void *cookie, const void *n, const void *k)
|
||||
{
|
||||
const struct filemon_state *S = n;
|
||||
const struct filemon_key *key = k;
|
||||
|
||||
if (S->key.pid < key->pid)
|
||||
return -1;
|
||||
if (S->key.pid > key->pid)
|
||||
return +1;
|
||||
if (S->key.lid < key->lid)
|
||||
return -1;
|
||||
if (S->key.lid > key->lid)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const rb_tree_ops_t filemon_rb_ops = {
|
||||
.rbto_compare_nodes = &compare_filemon_states,
|
||||
.rbto_compare_key = &compare_filemon_key,
|
||||
.rbto_node_offset = offsetof(struct filemon_state, node),
|
||||
.rbto_context = NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* filemon_path()
|
||||
*
|
||||
* Return a pointer to a constant string denoting the `path' of
|
||||
* the filemon.
|
||||
*/
|
||||
const char *
|
||||
filemon_path(void)
|
||||
{
|
||||
|
||||
return "ktrace";
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_open()
|
||||
*
|
||||
* Allocate a filemon descriptor. Returns NULL and sets errno on
|
||||
* failure.
|
||||
*/
|
||||
struct filemon *
|
||||
filemon_open(void)
|
||||
{
|
||||
struct filemon *F;
|
||||
int ktrpipe[2];
|
||||
int error;
|
||||
|
||||
/* Allocate and zero a struct filemon object. */
|
||||
F = calloc(1, sizeof(*F));
|
||||
if (F == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Create a pipe for ktrace events. */
|
||||
if (pipe2(ktrpipe, O_CLOEXEC|O_NONBLOCK) == -1) {
|
||||
error = errno;
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
/* Create a file stream for reading the ktrace events. */
|
||||
if ((F->in = fdopen(ktrpipe[0], "r")) == NULL) {
|
||||
error = errno;
|
||||
goto fail1;
|
||||
}
|
||||
ktrpipe[0] = -1; /* claimed by fdopen */
|
||||
|
||||
/*
|
||||
* Set the fd for writing ktrace events and initialize the
|
||||
* rbtree. The rest can be safely initialized to zero.
|
||||
*/
|
||||
F->ktrfd = ktrpipe[1];
|
||||
rb_tree_init(&F->active, &filemon_rb_ops);
|
||||
|
||||
/* Success! */
|
||||
return F;
|
||||
|
||||
fail2: __unused
|
||||
(void)fclose(F->in);
|
||||
fail1: (void)close(ktrpipe[0]);
|
||||
(void)close(ktrpipe[1]);
|
||||
fail0: free(F);
|
||||
errno = error;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_closefd(F)
|
||||
*
|
||||
* Internal subroutine to try to flush and close the output file.
|
||||
* If F is not open for output, do nothing. Never leaves F open
|
||||
* for output even on failure. Returns 0 on success; sets errno
|
||||
* and return -1 on failure.
|
||||
*/
|
||||
static int
|
||||
filemon_closefd(struct filemon *F)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
/* If we're not open, nothing to do. */
|
||||
if (F->out == NULL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Flush it, close it, and null it unconditionally, but be
|
||||
* careful to return the earliest error in errno.
|
||||
*/
|
||||
if (fflush(F->out) == EOF && error == 0)
|
||||
error = errno;
|
||||
if (fclose(F->out) == EOF && error == 0)
|
||||
error = errno;
|
||||
F->out = NULL;
|
||||
|
||||
/* Set errno and return -1 if anything went wrong. */
|
||||
if (error) {
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Success! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_setfd(F, fd)
|
||||
*
|
||||
* Cause filemon activity on F to be sent to fd. Claims ownership
|
||||
* of fd; caller should not use fd afterward, and any duplicates
|
||||
* of fd may see their file positions changed.
|
||||
*/
|
||||
int
|
||||
filemon_setfd(struct filemon *F, int fd)
|
||||
{
|
||||
|
||||
/*
|
||||
* Close an existing output file if done. Fail now if there's
|
||||
* an error closing.
|
||||
*/
|
||||
if ((filemon_closefd(F)) == -1)
|
||||
return -1;
|
||||
assert(F->out == NULL);
|
||||
|
||||
/* Open a file stream and claim ownership of the fd. */
|
||||
if ((F->out = fdopen(fd, "a")) == NULL)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Print the opening output. Any failure will be deferred
|
||||
* until closing. For hysterical raisins, we show the parent
|
||||
* pid, not the child pid.
|
||||
*/
|
||||
fprintf(F->out, "# filemon version 4\n");
|
||||
fprintf(F->out, "# Target pid %jd\n", (intmax_t)getpid());
|
||||
fprintf(F->out, "V 4\n");
|
||||
|
||||
/* Success! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_setpid_parent(F, pid)
|
||||
*
|
||||
* Set the traced pid, from the parent. Never fails.
|
||||
*/
|
||||
void
|
||||
filemon_setpid_parent(struct filemon *F, pid_t pid)
|
||||
{
|
||||
|
||||
F->child = pid;
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_setpid_child(F, pid)
|
||||
*
|
||||
* Set the traced pid, from the child. Returns 0 on success; sets
|
||||
* errno and returns -1 on failure.
|
||||
*/
|
||||
int
|
||||
filemon_setpid_child(const struct filemon *F, pid_t pid)
|
||||
{
|
||||
int ops, trpoints;
|
||||
|
||||
ops = KTROP_SET|KTRFLAG_DESCEND;
|
||||
trpoints = KTRFACv2;
|
||||
trpoints |= KTRFAC_SYSCALL|KTRFAC_NAMEI|KTRFAC_SYSRET;
|
||||
trpoints |= KTRFAC_INHERIT;
|
||||
if (fktrace(F->ktrfd, ops, trpoints, pid) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_close(F)
|
||||
*
|
||||
* Close F for output if necessary, and free a filemon descriptor.
|
||||
* Returns 0 on success; sets errno and returns -1 on failure, but
|
||||
* frees the filemon descriptor either way;
|
||||
*/
|
||||
int
|
||||
filemon_close(struct filemon *F)
|
||||
{
|
||||
struct filemon_state *S;
|
||||
int error = 0;
|
||||
|
||||
/* Close for output. */
|
||||
if (filemon_closefd(F) == -1 && error == 0)
|
||||
error = errno;
|
||||
|
||||
/* Close the ktrace pipe. */
|
||||
if (fclose(F->in) == EOF && error == 0)
|
||||
error = errno;
|
||||
if (close(F->ktrfd) == -1 && error == 0)
|
||||
error = errno;
|
||||
|
||||
/* Free any active records. */
|
||||
while ((S = RB_TREE_MIN(&F->active)) != NULL) {
|
||||
rb_tree_remove_node(&F->active, S);
|
||||
free(S);
|
||||
}
|
||||
|
||||
/* Free the filemon descriptor. */
|
||||
free(F);
|
||||
|
||||
/* Set errno and return -1 if anything went wrong. */
|
||||
if (error) {
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Success! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_readfd(F)
|
||||
*
|
||||
* Returns a file descriptor which will select/poll ready for read
|
||||
* when there are filemon events to be processed by
|
||||
* filemon_process, or -1 if anything has gone wrong.
|
||||
*/
|
||||
int
|
||||
filemon_readfd(const struct filemon *F)
|
||||
{
|
||||
|
||||
if (F->state == FILEMON_ERROR)
|
||||
return -1;
|
||||
return fileno(F->in);
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_dispatch(F)
|
||||
*
|
||||
* Internal subroutine to dispatch a filemon ktrace event.
|
||||
* Silently ignore events that we don't recognize.
|
||||
*/
|
||||
static void
|
||||
filemon_dispatch(struct filemon *F)
|
||||
{
|
||||
const struct filemon_key key = {
|
||||
.pid = F->hdr.ktr_pid,
|
||||
.lid = F->hdr.ktr_lid,
|
||||
};
|
||||
struct filemon_state *S;
|
||||
|
||||
switch (F->hdr.ktr_type) {
|
||||
case KTR_SYSCALL: {
|
||||
struct ktr_syscall *call = &F->payload.syscall;
|
||||
struct filemon_state *S1;
|
||||
|
||||
/* Validate the syscall code. */
|
||||
if (call->ktr_code < 0 ||
|
||||
(size_t)call->ktr_code >= __arraycount(filemon_syscalls) ||
|
||||
filemon_syscalls[call->ktr_code] == NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Invoke the syscall-specific logic to create a new
|
||||
* active state.
|
||||
*/
|
||||
S = (*filemon_syscalls[call->ktr_code])(F, &key, call);
|
||||
if (S == NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Insert the active state, or ignore it if there
|
||||
* already is one.
|
||||
*
|
||||
* Collisions shouldn't happen because the states are
|
||||
* keyed by <pid,lid>, in which syscalls should happen
|
||||
* sequentially in CALL/RET pairs, but let's be
|
||||
* defensive.
|
||||
*/
|
||||
S1 = rb_tree_insert_node(&F->active, S);
|
||||
if (S1 != S) {
|
||||
/* XXX Which one to drop? */
|
||||
free(S);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KTR_NAMEI:
|
||||
/* Find an active syscall state, or drop it. */
|
||||
S = rb_tree_find_node(&F->active, &key);
|
||||
if (S == NULL)
|
||||
break;
|
||||
/* Find the position of the next path, or drop it. */
|
||||
if (S->i >= S->npath)
|
||||
break;
|
||||
/* Record the path. */
|
||||
S->path[S->i++] = strndup(F->payload.namei,
|
||||
sizeof F->payload.namei);
|
||||
break;
|
||||
case KTR_SYSRET: {
|
||||
struct ktr_sysret *ret = &F->payload.sysret;
|
||||
unsigned i;
|
||||
|
||||
/* Find and remove an active syscall state, or drop it. */
|
||||
S = rb_tree_find_node(&F->active, &key);
|
||||
if (S == NULL)
|
||||
break;
|
||||
rb_tree_remove_node(&F->active, S);
|
||||
|
||||
/*
|
||||
* If the active syscall state matches this return,
|
||||
* invoke the syscall-specific logic to show a filemon
|
||||
* event.
|
||||
*/
|
||||
/* XXX What to do if syscall code doesn't match? */
|
||||
if (S->i == S->npath && S->syscode == ret->ktr_code)
|
||||
(*S->show)(F, S, ret);
|
||||
|
||||
/* Free the state now that it is no longer active. */
|
||||
for (i = 0; i < S->i; i++)
|
||||
free(S->path[i]);
|
||||
free(S);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* Ignore all other ktrace events. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* filemon_process(F)
|
||||
*
|
||||
* Process all pending events after filemon_readfd(F) has
|
||||
* selected/polled ready for read.
|
||||
*
|
||||
* Returns -1 on failure, 0 on end of events, and anything else if
|
||||
* there may be more events.
|
||||
*
|
||||
* XXX What about fairness to other activities in the event loop?
|
||||
* If we stop while there's events buffered in F->in, then select
|
||||
* or poll may not return ready even though there's work queued up
|
||||
* in the buffer of F->in, but if we don't stop then ktrace events
|
||||
* may overwhelm all other activity in the event loop.
|
||||
*/
|
||||
int
|
||||
filemon_process(struct filemon *F)
|
||||
{
|
||||
size_t nread;
|
||||
|
||||
top: /* If the child has exited, nothing to do. */
|
||||
/* XXX What if one thread calls exit while another is running? */
|
||||
if (F->child == 0)
|
||||
return 0;
|
||||
|
||||
/* If we're waiting for input, read some. */
|
||||
if (F->resid) {
|
||||
nread = fread(F->p, 1, F->resid, F->in);
|
||||
if (nread == 0) {
|
||||
if (feof(F->in))
|
||||
return 0;
|
||||
assert(ferror(F->in));
|
||||
/*
|
||||
* If interrupted or would block, there may be
|
||||
* more events. Otherwise fail.
|
||||
*/
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
return 1;
|
||||
F->state = FILEMON_ERROR;
|
||||
F->p = NULL;
|
||||
F->resid = 0;
|
||||
return -1;
|
||||
}
|
||||
assert(nread <= F->resid);
|
||||
F->p += nread;
|
||||
F->resid -= nread;
|
||||
if (F->resid) /* may be more events */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Process a state transition now that we've read a buffer. */
|
||||
switch (F->state) {
|
||||
case FILEMON_START: /* just started filemon; read header next */
|
||||
F->state = FILEMON_HEADER;
|
||||
F->p = (void *)&F->hdr;
|
||||
F->resid = sizeof F->hdr;
|
||||
goto top;
|
||||
case FILEMON_HEADER: /* read header */
|
||||
/* Sanity-check ktrace header; then read payload. */
|
||||
if (F->hdr.ktr_len < 0 ||
|
||||
(size_t)F->hdr.ktr_len > sizeof F->payload) {
|
||||
F->state = FILEMON_ERROR;
|
||||
F->p = NULL;
|
||||
F->resid = 0;
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
F->state = FILEMON_PAYLOAD;
|
||||
F->p = (void *)&F->payload;
|
||||
F->resid = (size_t)F->hdr.ktr_len;
|
||||
goto top;
|
||||
case FILEMON_PAYLOAD: /* read header and payload */
|
||||
/* Dispatch ktrace event; then read next header. */
|
||||
filemon_dispatch(F);
|
||||
F->state = FILEMON_HEADER;
|
||||
F->p = (void *)&F->hdr;
|
||||
F->resid = sizeof F->hdr;
|
||||
goto top;
|
||||
default: /* paranoia */
|
||||
F->state = FILEMON_ERROR;
|
||||
/*FALLTHROUGH*/
|
||||
case FILEMON_ERROR: /* persistent error indicator */
|
||||
F->p = NULL;
|
||||
F->resid = 0;
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
syscall_enter(struct filemon *F,
|
||||
const struct filemon_key *key, const struct ktr_syscall *call,
|
||||
unsigned npath,
|
||||
void (*show)(struct filemon *, const struct filemon_state *,
|
||||
const struct ktr_sysret *))
|
||||
{
|
||||
struct filemon_state *S;
|
||||
unsigned i;
|
||||
|
||||
S = calloc(1, offsetof(struct filemon_state, path[npath]));
|
||||
if (S == NULL)
|
||||
return NULL;
|
||||
S->key = *key;
|
||||
S->show = show;
|
||||
S->syscode = call->ktr_code;
|
||||
S->i = 0;
|
||||
S->npath = npath;
|
||||
for (i = 0; i < npath; i++)
|
||||
S->path[i] = NULL; /* paranoia */
|
||||
|
||||
return S;
|
||||
}
|
||||
|
||||
static void
|
||||
show_paths(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret, const char *prefix)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* Caller must ensure all paths have been specified. */
|
||||
assert(S->i == S->npath);
|
||||
|
||||
/*
|
||||
* Ignore it if it failed or yielded EJUSTRETURN (-2), or if
|
||||
* we're not producing output.
|
||||
*/
|
||||
if (ret->ktr_error && ret->ktr_error != -2)
|
||||
return;
|
||||
if (F->out == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Print the prefix, pid, and paths -- with the paths quoted if
|
||||
* there's more than one.
|
||||
*/
|
||||
fprintf(F->out, "%s %jd", prefix, (intmax_t)S->key.pid);
|
||||
for (i = 0; i < S->npath; i++) {
|
||||
const char *q = S->npath > 1 ? "'" : "";
|
||||
fprintf(F->out, " %s%s%s", q, S->path[i], q);
|
||||
}
|
||||
fprintf(F->out, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
show_retval(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret, const char *prefix)
|
||||
{
|
||||
|
||||
/*
|
||||
* Ignore it if it failed or yielded EJUSTRETURN (-2), or if
|
||||
* we're not producing output.
|
||||
*/
|
||||
if (ret->ktr_error && ret->ktr_error != -2)
|
||||
return;
|
||||
if (F->out == NULL)
|
||||
return;
|
||||
|
||||
fprintf(F->out, "%s %jd %jd\n", prefix, (intmax_t)S->key.pid,
|
||||
(intmax_t)ret->ktr_retval);
|
||||
}
|
||||
|
||||
static void
|
||||
show_chdir(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "C");
|
||||
}
|
||||
|
||||
static void
|
||||
show_execve(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
return show_paths(F, S, ret, "E");
|
||||
}
|
||||
|
||||
static void
|
||||
show_fork(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_retval(F, S, ret, "F");
|
||||
}
|
||||
|
||||
static void
|
||||
show_link(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "L"); /* XXX same as symlink */
|
||||
}
|
||||
|
||||
static void
|
||||
show_open_read(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "R");
|
||||
}
|
||||
|
||||
static void
|
||||
show_open_write(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "W");
|
||||
}
|
||||
|
||||
static void
|
||||
show_open_readwrite(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "R");
|
||||
show_paths(F, S, ret, "W");
|
||||
}
|
||||
|
||||
static void
|
||||
show_openat_read(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
if (S->path[0][0] != '/')
|
||||
show_paths(F, S, ret, "A");
|
||||
show_paths(F, S, ret, "R");
|
||||
}
|
||||
|
||||
static void
|
||||
show_openat_write(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
if (S->path[0][0] != '/')
|
||||
show_paths(F, S, ret, "A");
|
||||
show_paths(F, S, ret, "W");
|
||||
}
|
||||
|
||||
static void
|
||||
show_openat_readwrite(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
if (S->path[0][0] != '/')
|
||||
show_paths(F, S, ret, "A");
|
||||
show_paths(F, S, ret, "R");
|
||||
show_paths(F, S, ret, "W");
|
||||
}
|
||||
|
||||
static void
|
||||
show_symlink(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "L"); /* XXX same as link */
|
||||
}
|
||||
|
||||
static void
|
||||
show_unlink(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "D");
|
||||
}
|
||||
|
||||
static void
|
||||
show_rename(struct filemon *F, const struct filemon_state *S,
|
||||
const struct ktr_sysret *ret)
|
||||
{
|
||||
show_paths(F, S, ret, "M");
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_chdir(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 1, &show_chdir);
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_execve(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 1, &show_execve);
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_exit(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
const register_t *args = (const void *)&call[1];
|
||||
int status = args[0];
|
||||
|
||||
if (F->out) {
|
||||
fprintf(F->out, "X %jd %d\n", (intmax_t)key->pid, status);
|
||||
if (key->pid == F->child) {
|
||||
fprintf(F->out, "# Bye bye\n");
|
||||
F->child = 0;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_fork(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 0, &show_fork);
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_link(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 2, &show_link);
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_open(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
const register_t *args = (const void *)&call[1];
|
||||
int flags;
|
||||
|
||||
if (call->ktr_argsize < 2)
|
||||
return NULL;
|
||||
flags = args[1];
|
||||
|
||||
if ((flags & O_RDWR) == O_RDWR)
|
||||
return syscall_enter(F, key, call, 1, &show_open_readwrite);
|
||||
else if ((flags & O_WRONLY) == O_WRONLY)
|
||||
return syscall_enter(F, key, call, 1, &show_open_write);
|
||||
else if ((flags & O_RDONLY) == O_RDONLY)
|
||||
return syscall_enter(F, key, call, 1, &show_open_read);
|
||||
else
|
||||
return NULL; /* XXX Do we care if no read or write? */
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_openat(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
const register_t *args = (const void *)&call[1];
|
||||
int flags, fd;
|
||||
|
||||
if (call->ktr_argsize < 3)
|
||||
return NULL;
|
||||
fd = args[0];
|
||||
flags = args[2];
|
||||
|
||||
if (fd == AT_CWD) {
|
||||
if ((flags & O_RDWR) == O_RDWR)
|
||||
return syscall_enter(F, key, call, 1,
|
||||
&show_open_readwrite);
|
||||
else if ((flags & O_WRONLY) == O_WRONLY)
|
||||
return syscall_enter(F, key, call, 1,
|
||||
&show_open_write);
|
||||
else if ((flags & O_RDONLY) == O_RDONLY)
|
||||
return syscall_enter(F, key, call, 1, &show_open_read);
|
||||
else
|
||||
return NULL;
|
||||
} else {
|
||||
if ((flags & O_RDWR) == O_RDWR)
|
||||
return syscall_enter(F, key, call, 1,
|
||||
&show_openat_readwrite);
|
||||
else if ((flags & O_WRONLY) == O_WRONLY)
|
||||
return syscall_enter(F, key, call, 1,
|
||||
&show_openat_write);
|
||||
else if ((flags & O_RDONLY) == O_RDONLY)
|
||||
return syscall_enter(F, key, call, 1,
|
||||
&show_openat_read);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_symlink(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 2, &show_symlink);
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_unlink(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 1, &show_unlink);
|
||||
}
|
||||
|
||||
static struct filemon_state *
|
||||
filemon_sys_rename(struct filemon *F, const struct filemon_key *key,
|
||||
const struct ktr_syscall *call)
|
||||
{
|
||||
return syscall_enter(F, key, call, 2, &show_rename);
|
||||
}
|
13
20200902/find_lib.sh
Executable file
13
20200902/find_lib.sh
Executable file
@ -0,0 +1,13 @@
|
||||
:
|
||||
re=$1; shift
|
||||
|
||||
for lib in $*
|
||||
do
|
||||
found=`nm $lib | egrep "$re"`
|
||||
case "$found" in
|
||||
"") ;;
|
||||
*) echo "$lib: $found";;
|
||||
esac
|
||||
done
|
||||
|
||||
|
467
20200902/for.c
Normal file
467
20200902/for.c
Normal file
@ -0,0 +1,467 @@
|
||||
/* $NetBSD: for.c,v 1.67 2020/08/30 19:56:02 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: for.c,v 1.67 2020/08/30 19:56:02 rillig Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: for.c,v 1.67 2020/08/30 19:56:02 rillig Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
/*-
|
||||
* for.c --
|
||||
* Functions to handle loops in a makefile.
|
||||
*
|
||||
* Interface:
|
||||
* For_Eval Evaluate the loop in the passed line.
|
||||
* For_Run Run accumulated loop
|
||||
*
|
||||
*/
|
||||
|
||||
#include "make.h"
|
||||
#include "strlist.h"
|
||||
|
||||
#define FOR_SUB_ESCAPE_CHAR 1
|
||||
#define FOR_SUB_ESCAPE_BRACE 2
|
||||
#define FOR_SUB_ESCAPE_PAREN 4
|
||||
|
||||
/*
|
||||
* For statements are of the form:
|
||||
*
|
||||
* .for <variable> in <varlist>
|
||||
* ...
|
||||
* .endfor
|
||||
*
|
||||
* The trick is to look for the matching end inside for for loop
|
||||
* To do that, we count the current nesting level of the for loops.
|
||||
* and the .endfor statements, accumulating all the statements between
|
||||
* the initial .for loop and the matching .endfor;
|
||||
* then we evaluate the for loop for each variable in the varlist.
|
||||
*
|
||||
* Note that any nested fors are just passed through; they get handled
|
||||
* recursively in For_Eval when we're expanding the enclosing for in
|
||||
* For_Run.
|
||||
*/
|
||||
|
||||
static int forLevel = 0; /* Nesting level */
|
||||
|
||||
/*
|
||||
* State of a for loop.
|
||||
*/
|
||||
typedef struct {
|
||||
Buffer buf; /* Body of loop */
|
||||
strlist_t vars; /* Iteration variables */
|
||||
strlist_t items; /* Substitution items */
|
||||
char *parse_buf;
|
||||
int short_var;
|
||||
int sub_next;
|
||||
} For;
|
||||
|
||||
static For *accumFor; /* Loop being accumulated */
|
||||
|
||||
|
||||
static void
|
||||
For_Free(For *arg)
|
||||
{
|
||||
Buf_Destroy(&arg->buf, TRUE);
|
||||
strlist_clean(&arg->vars);
|
||||
strlist_clean(&arg->items);
|
||||
free(arg->parse_buf);
|
||||
|
||||
free(arg);
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* For_Eval --
|
||||
* Evaluate the for loop in the passed line. The line
|
||||
* looks like this:
|
||||
* .for <variable> in <varlist>
|
||||
*
|
||||
* Input:
|
||||
* line Line to parse
|
||||
*
|
||||
* Results:
|
||||
* 0: Not a .for statement, parse the line
|
||||
* 1: We found a for loop
|
||||
* -1: A .for statement with a bad syntax error, discard.
|
||||
*
|
||||
* Side Effects:
|
||||
* None.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
For_Eval(char *line)
|
||||
{
|
||||
For *new_for;
|
||||
char *ptr = line, *sub;
|
||||
size_t len;
|
||||
int escapes;
|
||||
unsigned char ch;
|
||||
Words words;
|
||||
|
||||
/* Skip the '.' and any following whitespace */
|
||||
for (ptr++; *ptr && isspace((unsigned char)*ptr); ptr++)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If we are not in a for loop quickly determine if the statement is
|
||||
* a for.
|
||||
*/
|
||||
if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' ||
|
||||
!isspace((unsigned char)ptr[3])) {
|
||||
if (ptr[0] == 'e' && strncmp(ptr + 1, "ndfor", 5) == 0) {
|
||||
Parse_Error(PARSE_FATAL, "for-less endfor");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
ptr += 3;
|
||||
|
||||
/*
|
||||
* we found a for loop, and now we are going to parse it.
|
||||
*/
|
||||
|
||||
new_for = bmake_malloc(sizeof *new_for);
|
||||
memset(new_for, 0, sizeof *new_for);
|
||||
|
||||
/* Grab the variables. Terminate on "in". */
|
||||
for (;; ptr += len) {
|
||||
while (*ptr && isspace((unsigned char)*ptr))
|
||||
ptr++;
|
||||
if (*ptr == '\0') {
|
||||
Parse_Error(PARSE_FATAL, "missing `in' in for");
|
||||
For_Free(new_for);
|
||||
return -1;
|
||||
}
|
||||
for (len = 1; ptr[len] && !isspace((unsigned char)ptr[len]); len++)
|
||||
continue;
|
||||
if (len == 2 && ptr[0] == 'i' && ptr[1] == 'n') {
|
||||
ptr += 2;
|
||||
break;
|
||||
}
|
||||
if (len == 1)
|
||||
new_for->short_var = 1;
|
||||
strlist_add_str(&new_for->vars, bmake_strldup(ptr, len), len);
|
||||
}
|
||||
|
||||
if (strlist_num(&new_for->vars) == 0) {
|
||||
Parse_Error(PARSE_FATAL, "no iteration variables in for");
|
||||
For_Free(new_for);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (*ptr && isspace((unsigned char)*ptr))
|
||||
ptr++;
|
||||
|
||||
/*
|
||||
* Make a list with the remaining words
|
||||
* The values are substituted as ${:U<value>...} so we must \ escape
|
||||
* characters that break that syntax.
|
||||
* Variables are fully expanded - so it is safe for escape $.
|
||||
* We can't do the escapes here - because we don't know whether
|
||||
* we are substuting into ${...} or $(...).
|
||||
*/
|
||||
sub = Var_Subst(ptr, VAR_GLOBAL, VARE_WANTRES);
|
||||
|
||||
/*
|
||||
* Split into words allowing for quoted strings.
|
||||
*/
|
||||
words = Str_Words(sub, FALSE);
|
||||
|
||||
free(sub);
|
||||
|
||||
{
|
||||
size_t n;
|
||||
|
||||
for (n = 0; n < words.len; n++) {
|
||||
ptr = words.words[n];
|
||||
if (!*ptr)
|
||||
continue;
|
||||
escapes = 0;
|
||||
while ((ch = *ptr++)) {
|
||||
switch (ch) {
|
||||
case ':':
|
||||
case '$':
|
||||
case '\\':
|
||||
escapes |= FOR_SUB_ESCAPE_CHAR;
|
||||
break;
|
||||
case ')':
|
||||
escapes |= FOR_SUB_ESCAPE_PAREN;
|
||||
break;
|
||||
case /*{*/ '}':
|
||||
escapes |= FOR_SUB_ESCAPE_BRACE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* We have to dup words[n] to maintain the semantics of
|
||||
* strlist.
|
||||
*/
|
||||
strlist_add_str(&new_for->items, bmake_strdup(words.words[n]),
|
||||
escapes);
|
||||
}
|
||||
|
||||
Words_Free(words);
|
||||
|
||||
if ((len = strlist_num(&new_for->items)) > 0 &&
|
||||
len % (n = strlist_num(&new_for->vars))) {
|
||||
Parse_Error(PARSE_FATAL,
|
||||
"Wrong number of words (%zu) in .for substitution list"
|
||||
" with %zu vars", len, n);
|
||||
/*
|
||||
* Return 'success' so that the body of the .for loop is
|
||||
* accumulated.
|
||||
* Remove all items so that the loop doesn't iterate.
|
||||
*/
|
||||
strlist_clean(&new_for->items);
|
||||
}
|
||||
}
|
||||
|
||||
Buf_Init(&new_for->buf, 0);
|
||||
accumFor = new_for;
|
||||
forLevel = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add another line to a .for loop.
|
||||
* Returns 0 when the matching .endfor is reached.
|
||||
*/
|
||||
|
||||
int
|
||||
For_Accum(char *line)
|
||||
{
|
||||
char *ptr = line;
|
||||
|
||||
if (*ptr == '.') {
|
||||
|
||||
for (ptr++; *ptr && isspace((unsigned char)*ptr); ptr++)
|
||||
continue;
|
||||
|
||||
if (strncmp(ptr, "endfor", 6) == 0 &&
|
||||
(isspace((unsigned char)ptr[6]) || !ptr[6])) {
|
||||
if (DEBUG(FOR))
|
||||
(void)fprintf(debug_file, "For: end for %d\n", forLevel);
|
||||
if (--forLevel <= 0)
|
||||
return 0;
|
||||
} else if (strncmp(ptr, "for", 3) == 0 &&
|
||||
isspace((unsigned char)ptr[3])) {
|
||||
forLevel++;
|
||||
if (DEBUG(FOR))
|
||||
(void)fprintf(debug_file, "For: new loop %d\n", forLevel);
|
||||
}
|
||||
}
|
||||
|
||||
Buf_AddStr(&accumFor->buf, line);
|
||||
Buf_AddByte(&accumFor->buf, '\n');
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
for_var_len(const char *var)
|
||||
{
|
||||
char ch, var_start, var_end;
|
||||
int depth;
|
||||
size_t len;
|
||||
|
||||
var_start = *var;
|
||||
if (var_start == 0)
|
||||
/* just escape the $ */
|
||||
return 0;
|
||||
|
||||
if (var_start == '(')
|
||||
var_end = ')';
|
||||
else if (var_start == '{')
|
||||
var_end = '}';
|
||||
else
|
||||
/* Single char variable */
|
||||
return 1;
|
||||
|
||||
depth = 1;
|
||||
for (len = 1; (ch = var[len++]) != 0;) {
|
||||
if (ch == var_start)
|
||||
depth++;
|
||||
else if (ch == var_end && --depth == 0)
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Variable end not found, escape the $ */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
for_substitute(Buffer *cmds, strlist_t *items, unsigned int item_no, char ech)
|
||||
{
|
||||
char ch;
|
||||
|
||||
const char *item = strlist_str(items, item_no);
|
||||
|
||||
/* If there were no escapes, or the only escape is the other variable
|
||||
* terminator, then just substitute the full string */
|
||||
if (!(strlist_info(items, item_no) &
|
||||
(ech == ')' ? ~FOR_SUB_ESCAPE_BRACE : ~FOR_SUB_ESCAPE_PAREN))) {
|
||||
Buf_AddStr(cmds, item);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Escape ':', '$', '\\' and 'ech' - removed by :U processing */
|
||||
while ((ch = *item++) != 0) {
|
||||
if (ch == '$') {
|
||||
size_t len = for_var_len(item);
|
||||
if (len != 0) {
|
||||
Buf_AddBytes(cmds, item - 1, len + 1);
|
||||
item += len;
|
||||
continue;
|
||||
}
|
||||
Buf_AddByte(cmds, '\\');
|
||||
} else if (ch == ':' || ch == '\\' || ch == ech)
|
||||
Buf_AddByte(cmds, '\\');
|
||||
Buf_AddByte(cmds, ch);
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
For_Iterate(void *v_arg, size_t *ret_len)
|
||||
{
|
||||
For *arg = v_arg;
|
||||
int i;
|
||||
char *var;
|
||||
char *cp;
|
||||
char *cmd_cp;
|
||||
char *body_end;
|
||||
char ch;
|
||||
Buffer cmds;
|
||||
size_t cmd_len;
|
||||
|
||||
if (arg->sub_next + strlist_num(&arg->vars) > strlist_num(&arg->items)) {
|
||||
/* No more iterations */
|
||||
For_Free(arg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(arg->parse_buf);
|
||||
arg->parse_buf = NULL;
|
||||
|
||||
/*
|
||||
* Scan the for loop body and replace references to the loop variables
|
||||
* with variable references that expand to the required text.
|
||||
* Using variable expansions ensures that the .for loop can't generate
|
||||
* syntax, and that the later parsing will still see a variable.
|
||||
* We assume that the null variable will never be defined.
|
||||
*
|
||||
* The detection of substitions of the loop control variable is naive.
|
||||
* Many of the modifiers use \ to escape $ (not $) so it is possible
|
||||
* to contrive a makefile where an unwanted substitution happens.
|
||||
*/
|
||||
|
||||
cmd_cp = Buf_GetAll(&arg->buf, &cmd_len);
|
||||
body_end = cmd_cp + cmd_len;
|
||||
Buf_Init(&cmds, cmd_len + 256);
|
||||
for (cp = cmd_cp; (cp = strchr(cp, '$')) != NULL;) {
|
||||
char ech;
|
||||
ch = *++cp;
|
||||
if ((ch == '(' && (ech = ')', 1)) || (ch == '{' && (ech = '}', 1))) {
|
||||
cp++;
|
||||
/* Check variable name against the .for loop variables */
|
||||
STRLIST_FOREACH(var, &arg->vars, i) {
|
||||
size_t vlen = strlist_info(&arg->vars, i);
|
||||
if (memcmp(cp, var, vlen) != 0)
|
||||
continue;
|
||||
if (cp[vlen] != ':' && cp[vlen] != ech && cp[vlen] != '\\')
|
||||
continue;
|
||||
/* Found a variable match. Replace with :U<value> */
|
||||
Buf_AddBytesBetween(&cmds, cmd_cp, cp);
|
||||
Buf_AddStr(&cmds, ":U");
|
||||
cp += vlen;
|
||||
cmd_cp = cp;
|
||||
for_substitute(&cmds, &arg->items, arg->sub_next + i, ech);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (ch == 0)
|
||||
break;
|
||||
/* Probably a single character name, ignore $$ and stupid ones. {*/
|
||||
if (!arg->short_var || strchr("}):$", ch) != NULL) {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
STRLIST_FOREACH(var, &arg->vars, i) {
|
||||
if (var[0] != ch || var[1] != 0)
|
||||
continue;
|
||||
/* Found a variable match. Replace with ${:U<value>} */
|
||||
Buf_AddBytesBetween(&cmds, cmd_cp, cp);
|
||||
Buf_AddStr(&cmds, "{:U");
|
||||
cmd_cp = ++cp;
|
||||
for_substitute(&cmds, &arg->items, arg->sub_next + i, /*{*/ '}');
|
||||
Buf_AddByte(&cmds, '}');
|
||||
break;
|
||||
}
|
||||
}
|
||||
Buf_AddBytesBetween(&cmds, cmd_cp, body_end);
|
||||
|
||||
cp = Buf_Destroy(&cmds, FALSE);
|
||||
if (DEBUG(FOR))
|
||||
(void)fprintf(debug_file, "For: loop body:\n%s", cp);
|
||||
|
||||
arg->sub_next += strlist_num(&arg->vars);
|
||||
|
||||
arg->parse_buf = cp;
|
||||
*ret_len = strlen(cp);
|
||||
return cp;
|
||||
}
|
||||
|
||||
/* Run the for loop, imitating the actions of an include file. */
|
||||
void
|
||||
For_Run(int lineno)
|
||||
{
|
||||
For *arg;
|
||||
|
||||
arg = accumFor;
|
||||
accumFor = NULL;
|
||||
|
||||
if (strlist_num(&arg->items) == 0) {
|
||||
/* Nothing to expand - possibly due to an earlier syntax error. */
|
||||
For_Free(arg);
|
||||
return;
|
||||
}
|
||||
|
||||
Parse_SetInput(NULL, lineno, -1, For_Iterate, arg);
|
||||
}
|
188
20200902/getopt.c
Normal file
188
20200902/getopt.c
Normal file
@ -0,0 +1,188 @@
|
||||
/* $NetBSD: getopt.c,v 1.29 2014/06/05 22:00:22 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#if !defined(HAVE_GETOPT) || defined(WANT_GETOPT_LONG) || defined(BROKEN_GETOPT)
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define BADCH (int)'?'
|
||||
#define BADARG (int)':'
|
||||
#define EMSG ""
|
||||
|
||||
int opterr = 1, /* if error message should be printed */
|
||||
optind = 1, /* index into parent argv vector */
|
||||
optopt = BADCH, /* character checked for validity */
|
||||
optreset; /* reset getopt */
|
||||
char *optarg; /* argument associated with option */
|
||||
|
||||
/*
|
||||
* getopt --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt(int nargc, char * const nargv[], const char *ostr)
|
||||
{
|
||||
extern char *__progname;
|
||||
static const char *place = EMSG; /* option letter processing */
|
||||
char *oli; /* option letter list index */
|
||||
|
||||
#ifndef BSD4_4
|
||||
if (!__progname) {
|
||||
if (__progname = strrchr(nargv[0], '/'))
|
||||
++__progname;
|
||||
else
|
||||
__progname = nargv[0];
|
||||
}
|
||||
#endif
|
||||
|
||||
if (optreset || *place == 0) { /* update scanning pointer */
|
||||
optreset = 0;
|
||||
place = nargv[optind];
|
||||
if (optind >= nargc || *place++ != '-') {
|
||||
/* Argument is absent or is not an option */
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
optopt = *place++;
|
||||
if (optopt == '-' && *place == 0) {
|
||||
/* "--" => end of options */
|
||||
++optind;
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
if (optopt == 0) {
|
||||
/* Solitary '-', treat as a '-' option
|
||||
if the program (eg su) is looking for it. */
|
||||
place = EMSG;
|
||||
if (strchr(ostr, '-') == NULL)
|
||||
return -1;
|
||||
optopt = '-';
|
||||
}
|
||||
} else
|
||||
optopt = *place++;
|
||||
|
||||
/* See if option letter is one the caller wanted... */
|
||||
if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
|
||||
if (*place == 0)
|
||||
++optind;
|
||||
if (opterr && *ostr != ':')
|
||||
(void)fprintf(stderr,
|
||||
"%s: unknown option -- %c\n", __progname, optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
|
||||
/* Does this option need an argument? */
|
||||
if (oli[1] != ':') {
|
||||
/* don't need argument */
|
||||
optarg = NULL;
|
||||
if (*place == 0)
|
||||
++optind;
|
||||
} else {
|
||||
/* Option-argument is either the rest of this argument or the
|
||||
entire next argument. */
|
||||
if (*place)
|
||||
optarg = __UNCONST(place);
|
||||
else if (oli[2] == ':')
|
||||
/*
|
||||
* GNU Extension, for optional arguments if the rest of
|
||||
* the argument is empty, we return NULL
|
||||
*/
|
||||
optarg = NULL;
|
||||
else if (nargc > ++optind)
|
||||
optarg = nargv[optind];
|
||||
else {
|
||||
/* option-argument absent */
|
||||
place = EMSG;
|
||||
if (*ostr == ':')
|
||||
return (BADARG);
|
||||
if (opterr)
|
||||
(void)fprintf(stderr,
|
||||
"%s: option requires an argument -- %c\n",
|
||||
__progname, optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
place = EMSG;
|
||||
++optind;
|
||||
}
|
||||
return (optopt); /* return option letter */
|
||||
}
|
||||
#endif
|
||||
#ifdef MAIN
|
||||
#ifndef BSD4_4
|
||||
char *__progname;
|
||||
#endif
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int c;
|
||||
char *opts = argv[1];
|
||||
|
||||
--argc;
|
||||
++argv;
|
||||
|
||||
while ((c = getopt(argc, argv, opts)) != EOF) {
|
||||
switch (c) {
|
||||
case '-':
|
||||
if (optarg)
|
||||
printf("--%s ", optarg);
|
||||
break;
|
||||
case '?':
|
||||
exit(1);
|
||||
break;
|
||||
default:
|
||||
if (optarg)
|
||||
printf("-%c %s ", c, optarg);
|
||||
else
|
||||
printf("-%c ", c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
printf("-- ");
|
||||
for (; optind < argc; ++optind) {
|
||||
printf("%s ", argv[optind]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
404
20200902/hash.c
Normal file
404
20200902/hash.c
Normal file
@ -0,0 +1,404 @@
|
||||
/* $NetBSD: hash.c,v 1.29 2020/09/01 21:11:31 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989 by Adam de Boor
|
||||
* Copyright (c) 1989 by Berkeley Softworks
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: hash.c,v 1.29 2020/09/01 21:11:31 rillig Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: hash.c,v 1.29 2020/09/01 21:11:31 rillig Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
/* hash.c --
|
||||
*
|
||||
* This module contains routines to manipulate a hash table.
|
||||
* See hash.h for a definition of the structure of the hash
|
||||
* table. Hash tables grow automatically as the amount of
|
||||
* information increases.
|
||||
*/
|
||||
#include "make.h"
|
||||
|
||||
/*
|
||||
* Forward references to local procedures that are used before they're
|
||||
* defined:
|
||||
*/
|
||||
|
||||
static void RebuildTable(Hash_Table *);
|
||||
|
||||
/*
|
||||
* The following defines the ratio of # entries to # buckets
|
||||
* at which we rebuild the table to make it larger.
|
||||
*/
|
||||
|
||||
#define rebuildLimit 3
|
||||
|
||||
/* The hash function(s) */
|
||||
|
||||
#ifndef HASH
|
||||
/* The default: this one matches Gosling's emacs */
|
||||
#define HASH(h, key, p) do { \
|
||||
for (h = 0, p = key; *p;) \
|
||||
h = (h << 5) - h + *p++; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
/* Sets up the hash table.
|
||||
*
|
||||
* Input:
|
||||
* t Structure to to hold the table.
|
||||
* numBuckets How many buckets to create for starters. This
|
||||
* number is rounded up to a power of two. If
|
||||
* <= 0, a reasonable default is chosen. The
|
||||
* table will grow in size later as needed.
|
||||
*/
|
||||
void
|
||||
Hash_InitTable(Hash_Table *t, int numBuckets)
|
||||
{
|
||||
int i;
|
||||
struct Hash_Entry **hp;
|
||||
|
||||
/*
|
||||
* Round up the size to a power of two.
|
||||
*/
|
||||
if (numBuckets <= 0)
|
||||
i = 16;
|
||||
else {
|
||||
for (i = 2; i < numBuckets; i <<= 1)
|
||||
continue;
|
||||
}
|
||||
t->numEntries = 0;
|
||||
t->maxchain = 0;
|
||||
t->bucketsSize = i;
|
||||
t->bucketsMask = i - 1;
|
||||
t->buckets = hp = bmake_malloc(sizeof(*hp) * i);
|
||||
while (--i >= 0)
|
||||
*hp++ = NULL;
|
||||
}
|
||||
|
||||
/* Removes everything from the hash table and frees up the memory space it
|
||||
* occupied (except for the space in the Hash_Table structure). */
|
||||
void
|
||||
Hash_DeleteTable(Hash_Table *t)
|
||||
{
|
||||
struct Hash_Entry **hp, *h, *nexth = NULL;
|
||||
int i;
|
||||
|
||||
for (hp = t->buckets, i = t->bucketsSize; --i >= 0;) {
|
||||
for (h = *hp++; h != NULL; h = nexth) {
|
||||
nexth = h->next;
|
||||
free(h);
|
||||
}
|
||||
}
|
||||
free(t->buckets);
|
||||
|
||||
/*
|
||||
* Set up the hash table to cause memory faults on any future access
|
||||
* attempts until re-initialization.
|
||||
*/
|
||||
t->buckets = NULL;
|
||||
}
|
||||
|
||||
/* Searches the hash table for an entry corresponding to the key.
|
||||
*
|
||||
* Input:
|
||||
* t Hash table to search.
|
||||
* key A hash key.
|
||||
*
|
||||
* Results:
|
||||
* Returns a pointer to the entry for key, or NULL if the table contains
|
||||
* no entry for the key.
|
||||
*/
|
||||
Hash_Entry *
|
||||
Hash_FindEntry(Hash_Table *t, const char *key)
|
||||
{
|
||||
Hash_Entry *e;
|
||||
unsigned h;
|
||||
const char *p;
|
||||
int chainlen;
|
||||
|
||||
if (t == NULL || t->buckets == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
HASH(h, key, p);
|
||||
p = key;
|
||||
chainlen = 0;
|
||||
#ifdef DEBUG_HASH_LOOKUP
|
||||
if (DEBUG(HASH))
|
||||
fprintf(debug_file, "%s: %p h=%x key=%s\n", __func__,
|
||||
t, h, key);
|
||||
#endif
|
||||
for (e = t->buckets[h & t->bucketsMask]; e != NULL; e = e->next) {
|
||||
chainlen++;
|
||||
if (e->namehash == h && strcmp(e->name, p) == 0)
|
||||
break;
|
||||
}
|
||||
if (chainlen > t->maxchain)
|
||||
t->maxchain = chainlen;
|
||||
return e;
|
||||
}
|
||||
|
||||
/* Searches the hash table for an entry corresponding to the key.
|
||||
* If no entry is found, then one is created.
|
||||
*
|
||||
* Input:
|
||||
* t Hash table to search.
|
||||
* key A hash key.
|
||||
* newPtr Filled with TRUE if new entry created,
|
||||
* FALSE otherwise.
|
||||
*/
|
||||
Hash_Entry *
|
||||
Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr)
|
||||
{
|
||||
Hash_Entry *e;
|
||||
unsigned h;
|
||||
const char *p;
|
||||
int keylen;
|
||||
int chainlen;
|
||||
struct Hash_Entry **hp;
|
||||
|
||||
/*
|
||||
* Hash the key. As a side effect, save the length (strlen) of the
|
||||
* key in case we need to create the entry.
|
||||
*/
|
||||
HASH(h, key, p);
|
||||
keylen = p - key;
|
||||
p = key;
|
||||
chainlen = 0;
|
||||
#ifdef DEBUG_HASH_LOOKUP
|
||||
if (DEBUG(HASH))
|
||||
fprintf(debug_file, "%s: %p h=%x key=%s\n", __func__,
|
||||
t, h, key);
|
||||
#endif
|
||||
for (e = t->buckets[h & t->bucketsMask]; e != NULL; e = e->next) {
|
||||
chainlen++;
|
||||
if (e->namehash == h && strcmp(e->name, p) == 0) {
|
||||
if (newPtr != NULL)
|
||||
*newPtr = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (chainlen > t->maxchain)
|
||||
t->maxchain = chainlen;
|
||||
if (e)
|
||||
return e;
|
||||
|
||||
/*
|
||||
* The desired entry isn't there. Before allocating a new entry,
|
||||
* expand the table if necessary (and this changes the resulting
|
||||
* bucket chain).
|
||||
*/
|
||||
if (t->numEntries >= rebuildLimit * t->bucketsSize)
|
||||
RebuildTable(t);
|
||||
e = bmake_malloc(sizeof(*e) + keylen);
|
||||
hp = &t->buckets[h & t->bucketsMask];
|
||||
e->next = *hp;
|
||||
*hp = e;
|
||||
Hash_SetValue(e, NULL);
|
||||
e->namehash = h;
|
||||
(void)strcpy(e->name, p);
|
||||
t->numEntries++;
|
||||
|
||||
if (newPtr != NULL)
|
||||
*newPtr = TRUE;
|
||||
return e;
|
||||
}
|
||||
|
||||
/* Delete the given hash table entry and free memory associated with it. */
|
||||
void
|
||||
Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e)
|
||||
{
|
||||
Hash_Entry **hp, *p;
|
||||
|
||||
if (e == NULL)
|
||||
return;
|
||||
for (hp = &t->buckets[e->namehash & t->bucketsMask];
|
||||
(p = *hp) != NULL; hp = &p->next) {
|
||||
if (p == e) {
|
||||
*hp = p->next;
|
||||
free(p);
|
||||
t->numEntries--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
(void)write(2, "bad call to Hash_DeleteEntry\n", 29);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Sets things up for enumerating all entries in the hash table.
|
||||
*
|
||||
* Input:
|
||||
* t Table to be searched.
|
||||
* searchPtr Area in which to keep state about search.
|
||||
*
|
||||
* Results:
|
||||
* The return value is the address of the first entry in
|
||||
* the hash table, or NULL if the table is empty.
|
||||
*/
|
||||
Hash_Entry *
|
||||
Hash_EnumFirst(Hash_Table *t, Hash_Search *searchPtr)
|
||||
{
|
||||
searchPtr->table = t;
|
||||
searchPtr->nextBucket = 0;
|
||||
searchPtr->entry = NULL;
|
||||
return Hash_EnumNext(searchPtr);
|
||||
}
|
||||
|
||||
/* Returns the next entry in the hash table, or NULL if the end of the table
|
||||
* is reached.
|
||||
*
|
||||
* Input:
|
||||
* searchPtr Area used to keep state about search.
|
||||
*/
|
||||
Hash_Entry *
|
||||
Hash_EnumNext(Hash_Search *searchPtr)
|
||||
{
|
||||
Hash_Entry *e;
|
||||
Hash_Table *t = searchPtr->table;
|
||||
|
||||
/*
|
||||
* The entry field points to the most recently returned
|
||||
* entry, or is NULL if we are starting up. If not NULL, we have
|
||||
* to start at the next one in the chain.
|
||||
*/
|
||||
e = searchPtr->entry;
|
||||
if (e != NULL)
|
||||
e = e->next;
|
||||
/*
|
||||
* If the chain ran out, or if we are starting up, we need to
|
||||
* find the next nonempty chain.
|
||||
*/
|
||||
while (e == NULL) {
|
||||
if (searchPtr->nextBucket >= t->bucketsSize)
|
||||
return NULL;
|
||||
e = t->buckets[searchPtr->nextBucket++];
|
||||
}
|
||||
searchPtr->entry = e;
|
||||
return e;
|
||||
}
|
||||
|
||||
/* Makes a new hash table that is larger than the old one. The entire hash
|
||||
* table is moved, so any bucket numbers from the old table become invalid. */
|
||||
static void
|
||||
RebuildTable(Hash_Table *t)
|
||||
{
|
||||
Hash_Entry *e, *next = NULL, **hp, **xp;
|
||||
int i, mask;
|
||||
Hash_Entry **oldhp;
|
||||
int oldsize;
|
||||
|
||||
oldhp = t->buckets;
|
||||
oldsize = i = t->bucketsSize;
|
||||
i <<= 1;
|
||||
t->bucketsSize = i;
|
||||
t->bucketsMask = mask = i - 1;
|
||||
t->buckets = hp = bmake_malloc(sizeof(*hp) * i);
|
||||
while (--i >= 0)
|
||||
*hp++ = NULL;
|
||||
for (hp = oldhp, i = oldsize; --i >= 0;) {
|
||||
for (e = *hp++; e != NULL; e = next) {
|
||||
next = e->next;
|
||||
xp = &t->buckets[e->namehash & mask];
|
||||
e->next = *xp;
|
||||
*xp = e;
|
||||
}
|
||||
}
|
||||
free(oldhp);
|
||||
if (DEBUG(HASH))
|
||||
fprintf(debug_file, "%s: %p size=%d entries=%d maxchain=%d\n",
|
||||
__func__, t, t->bucketsSize, t->numEntries, t->maxchain);
|
||||
t->maxchain = 0;
|
||||
}
|
||||
|
||||
void
|
||||
Hash_ForEach(Hash_Table *t, void (*action)(void *, void *), void *data)
|
||||
{
|
||||
Hash_Search search;
|
||||
Hash_Entry *e;
|
||||
|
||||
for (e = Hash_EnumFirst(t, &search);
|
||||
e != NULL;
|
||||
e = Hash_EnumNext(&search))
|
||||
action(Hash_GetValue(e), data);
|
||||
}
|
||||
|
||||
void
|
||||
Hash_DebugStats(Hash_Table *t, const char *name)
|
||||
{
|
||||
if (DEBUG(HASH))
|
||||
fprintf(debug_file, "Hash_Table %s: size=%d numEntries=%d maxchain=%d\n",
|
||||
name, t->bucketsSize, t->numEntries, t->maxchain);
|
||||
}
|
131
20200902/hash.h
Normal file
131
20200902/hash.h
Normal file
@ -0,0 +1,131 @@
|
||||
/* $NetBSD: hash.h,v 1.21 2020/09/01 21:11:31 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)hash.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989 by Adam de Boor
|
||||
* Copyright (c) 1989 by Berkeley Softworks
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)hash.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/* Hash tables with strings as keys and arbitrary pointers as values. */
|
||||
|
||||
#ifndef MAKE_HASH_H
|
||||
#define MAKE_HASH_H
|
||||
|
||||
/* A single key-value entry in the hash table. */
|
||||
typedef struct Hash_Entry {
|
||||
struct Hash_Entry *next; /* Used to link together all the entries
|
||||
* associated with the same bucket. */
|
||||
void *value;
|
||||
unsigned namehash; /* hash value of key */
|
||||
char name[1]; /* key string, variable length */
|
||||
} Hash_Entry;
|
||||
|
||||
/* The hash table containing the entries. */
|
||||
typedef struct Hash_Table {
|
||||
Hash_Entry **buckets; /* Pointers to Hash_Entry, one
|
||||
* for each bucket in the table. */
|
||||
int bucketsSize;
|
||||
int numEntries; /* Number of entries in the table. */
|
||||
int bucketsMask; /* Used to select the bucket for a hash. */
|
||||
int maxchain; /* max length of chain detected */
|
||||
} Hash_Table;
|
||||
|
||||
/*
|
||||
* The following structure is used by the searching routines
|
||||
* to record where we are in the search.
|
||||
*/
|
||||
typedef struct Hash_Search {
|
||||
Hash_Table *table; /* Table being searched. */
|
||||
int nextBucket; /* Next bucket to check (after current). */
|
||||
Hash_Entry *entry; /* Next entry to check in current bucket. */
|
||||
} Hash_Search;
|
||||
|
||||
static inline void * MAKE_ATTR_UNUSED
|
||||
Hash_GetValue(Hash_Entry *h)
|
||||
{
|
||||
return h->value;
|
||||
}
|
||||
|
||||
static inline void MAKE_ATTR_UNUSED
|
||||
Hash_SetValue(Hash_Entry *h, void *datum)
|
||||
{
|
||||
h->value = datum;
|
||||
}
|
||||
|
||||
void Hash_InitTable(Hash_Table *, int);
|
||||
void Hash_DeleteTable(Hash_Table *);
|
||||
Hash_Entry *Hash_FindEntry(Hash_Table *, const char *);
|
||||
Hash_Entry *Hash_CreateEntry(Hash_Table *, const char *, Boolean *);
|
||||
void Hash_DeleteEntry(Hash_Table *, Hash_Entry *);
|
||||
Hash_Entry *Hash_EnumFirst(Hash_Table *, Hash_Search *);
|
||||
Hash_Entry *Hash_EnumNext(Hash_Search *);
|
||||
void Hash_ForEach(Hash_Table *, void (*)(void *, void *), void *);
|
||||
void Hash_DebugStats(Hash_Table *, const char *);
|
||||
|
||||
#endif /* MAKE_HASH_H */
|
201
20200902/install-sh
Executable file
201
20200902/install-sh
Executable file
@ -0,0 +1,201 @@
|
||||
:
|
||||
# NAME:
|
||||
# install.sh - portable version of install(1)
|
||||
#
|
||||
# SYNOPSIS:
|
||||
# install [-CNcs] [-f flags] [-i errs] [-o owner] [-g group] [-m mode] file1 file2 ...
|
||||
# install -d [-i errs] [-o owner] [-g group] [-m mode] directory ...
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Compatible with BSD install(1). Except that '-c' is always
|
||||
# true and we always move an already installed target aside as
|
||||
# this is important on many systems. Recent BSD install(1)
|
||||
# versions have a '-b' option for this.
|
||||
#
|
||||
#
|
||||
# OPTIONS:
|
||||
# -b move previous target file aside (always true).
|
||||
#
|
||||
# -B "suffix"
|
||||
# use "suffix" instead of .old for saving existing target.
|
||||
#
|
||||
# -c copy rather than move the file into place (always true).
|
||||
#
|
||||
# -C compare. Only install if target is missing or
|
||||
# different.
|
||||
#
|
||||
# -N newer. Only install if target is missing or older.
|
||||
#
|
||||
# -s strip target
|
||||
#
|
||||
# -o "owner"
|
||||
# make target owned by "owner"
|
||||
#
|
||||
# -g "group"
|
||||
# make target group owned by "group"
|
||||
#
|
||||
# -m "mode"
|
||||
# set permissions to "mode"
|
||||
#
|
||||
# -f "flags"
|
||||
# Pass "flags" onto chflags(1)
|
||||
#
|
||||
# -i "errs"
|
||||
# Ignore errors from steps indicated by "errs" (``s,o,g,m'').
|
||||
#
|
||||
# BUGS:
|
||||
# The '-i' option is to save your sanity when 'bsd.prog.mk'
|
||||
# insists on haveing a '-o' "owner" option which is doomed to
|
||||
# fail on many systems. We ignore '-b', '-B' and '-c' options.
|
||||
#
|
||||
# AUTHOR:
|
||||
# Simon J. Gerraty <sjg@quick.com.au>
|
||||
#
|
||||
|
||||
# RCSid:
|
||||
# $Id: install-sh,v 1.18 2001/03/16 17:33:02 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1993 Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@quick.com.au
|
||||
#
|
||||
|
||||
set -- `getopt B:bpxCNcsdo:g:m:i:f: $*`
|
||||
|
||||
Mydir=`dirname $0`
|
||||
[ -s $Mydir/.installrc ] && . $Mydir/.installrc
|
||||
|
||||
owner=:
|
||||
group=:
|
||||
mode=:
|
||||
strip=:
|
||||
mkdirs=
|
||||
compare=:
|
||||
newer=:
|
||||
chflags=:
|
||||
LS1=
|
||||
CP_P=
|
||||
|
||||
while [ $# -gt 1 ]
|
||||
do
|
||||
case $1 in
|
||||
--) shift; break;;
|
||||
-p) CP_P=-p;;
|
||||
-x) set -x;;
|
||||
-B) OLD_EXT=$2; shift;;
|
||||
-C) compare=Different;;
|
||||
-N) newer=Newer;
|
||||
# check if /bin/ls supports -1
|
||||
/bin/ls -1 $0 >/dev/null 2>&1 && LS1=1
|
||||
;;
|
||||
-o) owner="${CHOWN:-chown} $2 "; shift;;
|
||||
-g) group="${CHGRP:-chgrp} $2 "; shift;;
|
||||
-m) mode="${CHMOD:-chmod} $2 "; shift;;
|
||||
-s) strip=${STRIP:-strip};;
|
||||
-d) mkdirs="mkdir -p";;
|
||||
-i) ignore_err="$ignore_err$2"; shift;;
|
||||
-f) chflags="${CHFLAGS:-chflags} $2 "; shift;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
Newer() {
|
||||
n=`/bin/ls -t$LS1 $* 2>/dev/null | head -1`
|
||||
[ $1 = $n ]
|
||||
}
|
||||
|
||||
Different() {
|
||||
cmp -s $*
|
||||
[ $? != 0 ]
|
||||
}
|
||||
|
||||
Err() {
|
||||
case "$ignore_err" in
|
||||
*$1*) ;;
|
||||
*) exit 1;;
|
||||
esac
|
||||
}
|
||||
|
||||
Setem() {
|
||||
# the order is important
|
||||
if [ ! -d $1 ]; then
|
||||
$strip $1 || Err s
|
||||
fi
|
||||
$group $1 || Err g
|
||||
$owner $1 || Err o
|
||||
$mode $1 || Err m
|
||||
$chflags $1 || Err f
|
||||
return 0
|
||||
}
|
||||
|
||||
# a bug in HP-UX's /bin/sh, means we need to re-set $*
|
||||
# after any calls to add_path()
|
||||
args="$*"
|
||||
|
||||
# all this just for chown!
|
||||
add_path () { [ -d $1 ] && eval ${2:-PATH}="\$${2:-PATH}:$1"; }
|
||||
add_path /etc
|
||||
add_path /usr/etc
|
||||
add_path /sbin
|
||||
add_path /usr/sbin
|
||||
|
||||
# restore saved $*
|
||||
set -- $args
|
||||
|
||||
# make directories if needed
|
||||
# and ensure mode etc are as desired
|
||||
if [ "$mkdirs" ]; then
|
||||
for d in $*
|
||||
do
|
||||
[ ! -d $d ] && $mkdirs $d
|
||||
Setem $d
|
||||
done
|
||||
exit 0 # that's all we do
|
||||
fi
|
||||
|
||||
# install files
|
||||
if [ $# -gt 2 ]; then
|
||||
dest_dir=yes
|
||||
elif [ $# -eq 1 ]; then
|
||||
echo "what should I do with $*?" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# get list of files
|
||||
while [ $# -gt 1 ]
|
||||
do
|
||||
files="$files $1"
|
||||
shift
|
||||
done
|
||||
# last one is dest
|
||||
dest=$1
|
||||
shift
|
||||
|
||||
|
||||
if [ "$dest_dir" = yes -a ! -d $dest ]; then
|
||||
echo "no directory $dest" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for f in $files
|
||||
do
|
||||
b=`basename $f`
|
||||
if [ -d $dest ]; then
|
||||
t=$dest/$b
|
||||
else
|
||||
t=$dest
|
||||
fi
|
||||
$newer $f $t || continue
|
||||
$compare $f $t || continue
|
||||
[ -f $t ] && { mv -f $t $t.old || exit 1; }
|
||||
{ cp $CP_P $f $t && Setem $t; } || exit 1
|
||||
done
|
||||
exit 0
|
3118
20200902/job.c
Normal file
3118
20200902/job.c
Normal file
File diff suppressed because it is too large
Load Diff
269
20200902/job.h
Normal file
269
20200902/job.h
Normal file
@ -0,0 +1,269 @@
|
||||
/* $NetBSD: job.h,v 1.47 2020/08/29 12:20:17 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)job.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989 by Adam de Boor
|
||||
* Copyright (c) 1989 by Berkeley Softworks
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)job.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*-
|
||||
* job.h --
|
||||
* Definitions pertaining to the running of jobs in parallel mode.
|
||||
*/
|
||||
#ifndef MAKE_JOB_H
|
||||
#define MAKE_JOB_H
|
||||
|
||||
#define TMPPAT "makeXXXXXX" /* relative to tmpdir */
|
||||
|
||||
#ifdef USE_SELECT
|
||||
/*
|
||||
* Emulate poll() in terms of select(). This is not a complete
|
||||
* emulation but it is sufficient for make's purposes.
|
||||
*/
|
||||
|
||||
#define poll emul_poll
|
||||
#define pollfd emul_pollfd
|
||||
|
||||
struct emul_pollfd {
|
||||
int fd;
|
||||
short events;
|
||||
short revents;
|
||||
};
|
||||
|
||||
#define POLLIN 0x0001
|
||||
#define POLLOUT 0x0004
|
||||
|
||||
int
|
||||
emul_poll(struct pollfd *fd, int nfd, int timeout);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The POLL_MSEC constant determines the maximum number of milliseconds spent
|
||||
* in poll before coming out to see if a child has finished.
|
||||
*/
|
||||
#define POLL_MSEC 5000
|
||||
|
||||
/*-
|
||||
* Job Table definitions.
|
||||
*
|
||||
* Each job has several things associated with it:
|
||||
* 1) The process id of the child shell
|
||||
* 2) The graph node describing the target being made by this job
|
||||
* 3) A LstNode for the first command to be saved after the job
|
||||
* completes. This is NULL if there was no "..." in the job's
|
||||
* commands.
|
||||
* 4) An FILE* for writing out the commands. This is only
|
||||
* used before the job is actually started.
|
||||
* 5) The output is being caught via a pipe and
|
||||
* the descriptors of our pipe, an array in which output is line
|
||||
* buffered and the current position in that buffer are all
|
||||
* maintained for each job.
|
||||
* 6) A word of flags which determine how the module handles errors,
|
||||
* echoing, etc. for the job
|
||||
*
|
||||
* When a job is finished, the Make_Update function is called on each of the
|
||||
* parents of the node which was just remade. This takes care of the upward
|
||||
* traversal of the dependency graph.
|
||||
*/
|
||||
struct pollfd;
|
||||
|
||||
|
||||
#ifdef USE_META
|
||||
# include "meta.h"
|
||||
#endif
|
||||
|
||||
#define JOB_BUFSIZE 1024
|
||||
typedef struct Job {
|
||||
int pid; /* The child's process ID */
|
||||
GNode *node; /* The target the child is making */
|
||||
LstNode tailCmds; /* The node of the first command to be
|
||||
* saved when the job has been run */
|
||||
FILE *cmdFILE; /* When creating the shell script, this is
|
||||
* where the commands go */
|
||||
int exit_status; /* from wait4() in signal handler */
|
||||
char job_state; /* status of the job entry */
|
||||
#define JOB_ST_FREE 0 /* Job is available */
|
||||
#define JOB_ST_SETUP 1 /* Job is allocated but otherwise invalid */
|
||||
#define JOB_ST_RUNNING 3 /* Job is running, pid valid */
|
||||
#define JOB_ST_FINISHED 4 /* Job is done (ie after SIGCHILD) */
|
||||
char job_suspended;
|
||||
short flags; /* Flags to control treatment of job */
|
||||
#define JOB_IGNERR 0x001 /* Ignore non-zero exits */
|
||||
#define JOB_SILENT 0x002 /* no output */
|
||||
#define JOB_SPECIAL 0x004 /* Target is a special one. i.e. run it locally
|
||||
* if we can't export it and maxLocal is 0 */
|
||||
#define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing
|
||||
* commands */
|
||||
#define JOB_TRACED 0x400 /* we've sent 'set -x' */
|
||||
|
||||
int jobPipe[2]; /* Pipe for reading output from job */
|
||||
struct pollfd *inPollfd; /* pollfd associated with inPipe */
|
||||
char outBuf[JOB_BUFSIZE + 1];
|
||||
/* Buffer for storing the output of the
|
||||
* job, line by line */
|
||||
int curPos; /* Current position in op_outBuf */
|
||||
|
||||
#ifdef USE_META
|
||||
struct BuildMon bm;
|
||||
#endif
|
||||
} Job;
|
||||
|
||||
#define inPipe jobPipe[0]
|
||||
#define outPipe jobPipe[1]
|
||||
|
||||
/*-
|
||||
* Shell Specifications:
|
||||
* Each shell type has associated with it the following information:
|
||||
* 1) The string which must match the last character of the shell name
|
||||
* for the shell to be considered of this type. The longest match
|
||||
* wins.
|
||||
* 2) A command to issue to turn off echoing of command lines
|
||||
* 3) A command to issue to turn echoing back on again
|
||||
* 4) What the shell prints, and its length, when given the echo-off
|
||||
* command. This line will not be printed when received from the shell
|
||||
* 5) A boolean to tell if the shell has the ability to control
|
||||
* error checking for individual commands.
|
||||
* 6) The string to turn this checking on.
|
||||
* 7) The string to turn it off.
|
||||
* 8) The command-flag to give to cause the shell to start echoing
|
||||
* commands right away.
|
||||
* 9) The command-flag to cause the shell to Lib_Exit when an error is
|
||||
* detected in one of the commands.
|
||||
*
|
||||
* Some special stuff goes on if a shell doesn't have error control. In such
|
||||
* a case, errCheck becomes a printf template for echoing the command,
|
||||
* should echoing be on and ignErr becomes another printf template for
|
||||
* executing the command while ignoring the return status. Finally errOut
|
||||
* is a printf template for running the command and causing the shell to
|
||||
* exit on error. If any of these strings are empty when hasErrCtl is FALSE,
|
||||
* the command will be executed anyway as is and if it causes an error, so be
|
||||
* it. Any templates setup to echo the command will escape any '$ ` \ "'i
|
||||
* characters in the command string to avoid common problems with
|
||||
* echo "%s\n" as a template.
|
||||
*/
|
||||
typedef struct Shell {
|
||||
const char *name; /* the name of the shell. For Bourne and C
|
||||
* shells, this is used only to find the
|
||||
* shell description when used as the single
|
||||
* source of a .SHELL target. For user-defined
|
||||
* shells, this is the full path of the shell.
|
||||
*/
|
||||
Boolean hasEchoCtl; /* True if both echoOff and echoOn defined */
|
||||
const char *echoOff; /* command to turn off echo */
|
||||
const char *echoOn; /* command to turn it back on again */
|
||||
const char *noPrint; /* command to skip when printing output from
|
||||
* shell. This is usually the command which
|
||||
* was executed to turn off echoing */
|
||||
int noPLen; /* length of noPrint command */
|
||||
Boolean hasErrCtl; /* set if can control error checking for
|
||||
* individual commands */
|
||||
const char *errCheck; /* string to turn error checking on */
|
||||
const char *ignErr; /* string to turn off error checking */
|
||||
const char *errOut; /* string to use for testing exit code */
|
||||
const char *newline; /* string literal that results in a newline
|
||||
* character when it appears outside of any
|
||||
* 'quote' or "quote" characters */
|
||||
char commentChar; /* character used by shell for comment lines */
|
||||
|
||||
/*
|
||||
* command-line flags
|
||||
*/
|
||||
const char *echo; /* echo commands */
|
||||
const char *exit; /* exit on error */
|
||||
} Shell;
|
||||
|
||||
extern const char *shellPath;
|
||||
extern const char *shellName;
|
||||
extern char *shellErrFlag;
|
||||
|
||||
extern int jobTokensRunning; /* tokens currently "out" */
|
||||
extern int maxJobs; /* Max jobs we can run */
|
||||
|
||||
void Shell_Init(void);
|
||||
const char *Shell_GetNewline(void);
|
||||
void Job_Touch(GNode *, Boolean);
|
||||
Boolean Job_CheckCommands(GNode *, void (*abortProc )(const char *, ...));
|
||||
void Job_CatchChildren(void);
|
||||
void Job_CatchOutput(void);
|
||||
void Job_Make(GNode *);
|
||||
void Job_Init(void);
|
||||
Boolean Job_Empty(void);
|
||||
Boolean Job_ParseShell(char *);
|
||||
int Job_Finish(void);
|
||||
void Job_End(void);
|
||||
void Job_Wait(void);
|
||||
void Job_AbortAll(void);
|
||||
void Job_TokenReturn(void);
|
||||
Boolean Job_TokenWithdraw(void);
|
||||
void Job_ServerStart(int, int, int);
|
||||
void Job_SetPrefix(void);
|
||||
Boolean Job_RunTarget(const char *, const char *);
|
||||
|
||||
#endif /* MAKE_JOB_H */
|
641
20200902/lst.c
Normal file
641
20200902/lst.c
Normal file
@ -0,0 +1,641 @@
|
||||
/* $NetBSD: lst.c,v 1.60 2020/08/31 05:56:02 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#elif defined(HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "make.h"
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: lst.c,v 1.60 2020/08/31 05:56:02 rillig Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: lst.c,v 1.60 2020/08/31 05:56:02 rillig Exp $");
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
struct ListNode {
|
||||
struct ListNode *prev; /* previous element in list */
|
||||
struct ListNode *next; /* next in list */
|
||||
uint8_t useCount; /* Count of functions using the node.
|
||||
* node may not be deleted until count
|
||||
* goes to 0 */
|
||||
Boolean deleted; /* List node should be removed when done */
|
||||
union {
|
||||
void *datum; /* datum associated with this element */
|
||||
const GNode *gnode; /* alias, just for debugging */
|
||||
const char *str; /* alias, just for debugging */
|
||||
};
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
Head, Middle, Tail, Unknown
|
||||
} Where;
|
||||
|
||||
struct List {
|
||||
LstNode first; /* first node in list */
|
||||
LstNode last; /* last node in list */
|
||||
|
||||
/* fields for sequential access */
|
||||
Boolean isOpen; /* true if list has been Lst_Open'ed */
|
||||
Where lastAccess; /* Where in the list the last access was */
|
||||
LstNode curr; /* current node, if open. NULL if
|
||||
* *just* opened */
|
||||
LstNode prev; /* Previous node, if open. Used by Lst_Remove */
|
||||
};
|
||||
|
||||
/* Allocate and initialize a list node.
|
||||
*
|
||||
* The fields 'prev' and 'next' must be initialized by the caller.
|
||||
*/
|
||||
static LstNode
|
||||
LstNodeNew(void *datum)
|
||||
{
|
||||
LstNode node = bmake_malloc(sizeof *node);
|
||||
node->useCount = 0;
|
||||
node->deleted = FALSE;
|
||||
node->datum = datum;
|
||||
return node;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
LstIsEmpty(Lst list)
|
||||
{
|
||||
return list->first == NULL;
|
||||
}
|
||||
|
||||
/* Create and initialize a new, empty list. */
|
||||
Lst
|
||||
Lst_Init(void)
|
||||
{
|
||||
Lst list = bmake_malloc(sizeof *list);
|
||||
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
list->isOpen = FALSE;
|
||||
list->lastAccess = Unknown;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/* Duplicate an entire list, usually by copying the datum pointers.
|
||||
* If copyProc is given, that function is used to create the new datum from the
|
||||
* old datum, usually by creating a copy of it. */
|
||||
Lst
|
||||
Lst_Copy(Lst list, LstCopyProc copyProc)
|
||||
{
|
||||
Lst newList;
|
||||
LstNode node;
|
||||
|
||||
assert(list != NULL);
|
||||
|
||||
newList = Lst_Init();
|
||||
|
||||
for (node = list->first; node != NULL; node = node->next) {
|
||||
void *datum = copyProc != NULL ? copyProc(node->datum) : node->datum;
|
||||
Lst_Append(newList, datum);
|
||||
}
|
||||
|
||||
return newList;
|
||||
}
|
||||
|
||||
/* Free a list and all its nodes. The list data itself are not freed though. */
|
||||
void
|
||||
Lst_Free(Lst list)
|
||||
{
|
||||
LstNode node;
|
||||
LstNode next;
|
||||
|
||||
assert(list != NULL);
|
||||
|
||||
for (node = list->first; node != NULL; node = next) {
|
||||
next = node->next;
|
||||
free(node);
|
||||
}
|
||||
|
||||
free(list);
|
||||
}
|
||||
|
||||
/* Destroy a list and free all its resources. The freeProc is called with the
|
||||
* datum from each node in turn before the node is freed. */
|
||||
void
|
||||
Lst_Destroy(Lst list, LstFreeProc freeProc)
|
||||
{
|
||||
LstNode node;
|
||||
LstNode next;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(freeProc != NULL);
|
||||
|
||||
for (node = list->first; node != NULL; node = next) {
|
||||
next = node->next;
|
||||
freeProc(node->datum);
|
||||
free(node);
|
||||
}
|
||||
|
||||
free(list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions to modify a list
|
||||
*/
|
||||
|
||||
/* Insert a new node with the given piece of data before the given node in the
|
||||
* given list. */
|
||||
void
|
||||
Lst_InsertBefore(Lst list, LstNode node, void *datum)
|
||||
{
|
||||
LstNode newNode;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(!LstIsEmpty(list));
|
||||
assert(node != NULL);
|
||||
assert(datum != NULL);
|
||||
|
||||
newNode = LstNodeNew(datum);
|
||||
newNode->prev = node->prev;
|
||||
newNode->next = node;
|
||||
|
||||
if (node->prev != NULL) {
|
||||
node->prev->next = newNode;
|
||||
}
|
||||
node->prev = newNode;
|
||||
|
||||
if (node == list->first) {
|
||||
list->first = newNode;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a piece of data at the start of the given list. */
|
||||
void
|
||||
Lst_Prepend(Lst list, void *datum)
|
||||
{
|
||||
LstNode node;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(datum != NULL);
|
||||
|
||||
node = LstNodeNew(datum);
|
||||
node->prev = NULL;
|
||||
node->next = list->first;
|
||||
|
||||
if (list->first == NULL) {
|
||||
list->first = node;
|
||||
list->last = node;
|
||||
} else {
|
||||
list->first->prev = node;
|
||||
list->first = node;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a piece of data at the end of the given list. */
|
||||
void
|
||||
Lst_Append(Lst list, void *datum)
|
||||
{
|
||||
LstNode node;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(datum != NULL);
|
||||
|
||||
node = LstNodeNew(datum);
|
||||
node->prev = list->last;
|
||||
node->next = NULL;
|
||||
|
||||
if (list->last == NULL) {
|
||||
list->first = node;
|
||||
list->last = node;
|
||||
} else {
|
||||
list->last->next = node;
|
||||
list->last = node;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove the given node from the given list.
|
||||
* The datum stored in the node must be freed by the caller, if necessary. */
|
||||
void
|
||||
Lst_Remove(Lst list, LstNode node)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(node != NULL);
|
||||
|
||||
/*
|
||||
* unlink it from the list
|
||||
*/
|
||||
if (node->next != NULL) {
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
if (node->prev != NULL) {
|
||||
node->prev->next = node->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* if either the first or last of the list point to this node,
|
||||
* adjust them accordingly
|
||||
*/
|
||||
if (list->first == node) {
|
||||
list->first = node->next;
|
||||
}
|
||||
if (list->last == node) {
|
||||
list->last = node->prev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sequential access stuff. If the node we're removing is the current
|
||||
* node in the list, reset the current node to the previous one. If the
|
||||
* previous one was non-existent (prev == NULL), we set the
|
||||
* end to be Unknown, since it is.
|
||||
*/
|
||||
if (list->isOpen && list->curr == node) {
|
||||
list->curr = list->prev;
|
||||
if (list->curr == NULL) {
|
||||
list->lastAccess = Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* note that the datum is unmolested. The caller must free it as
|
||||
* necessary and as expected.
|
||||
*/
|
||||
if (node->useCount == 0) {
|
||||
free(node);
|
||||
} else {
|
||||
node->deleted = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Replace the datum in the given node with the new datum. */
|
||||
void
|
||||
LstNode_Set(LstNode node, void *datum)
|
||||
{
|
||||
assert(node != NULL);
|
||||
assert(datum != NULL);
|
||||
|
||||
node->datum = datum;
|
||||
}
|
||||
|
||||
/* Replace the datum in the given node to NULL. */
|
||||
void
|
||||
LstNode_SetNull(LstNode node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
|
||||
node->datum = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Node-specific functions
|
||||
*/
|
||||
|
||||
/* Return the first node from the given list, or NULL if the list is empty. */
|
||||
LstNode
|
||||
Lst_First(Lst list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
|
||||
return list->first;
|
||||
}
|
||||
|
||||
/* Return the last node from the given list, or NULL if the list is empty. */
|
||||
LstNode
|
||||
Lst_Last(Lst list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
|
||||
return list->last;
|
||||
}
|
||||
|
||||
/* Return the successor to the given node on its list, or NULL. */
|
||||
LstNode
|
||||
LstNode_Next(LstNode node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
|
||||
return node->next;
|
||||
}
|
||||
|
||||
/* Return the predecessor to the given node on its list, or NULL. */
|
||||
LstNode
|
||||
LstNode_Prev(LstNode node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
return node->prev;
|
||||
}
|
||||
|
||||
/* Return the datum stored in the given node. */
|
||||
void *
|
||||
LstNode_Datum(LstNode node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
return node->datum;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Functions for entire lists
|
||||
*/
|
||||
|
||||
/* Return TRUE if the given list is empty. */
|
||||
Boolean
|
||||
Lst_IsEmpty(Lst list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
|
||||
return LstIsEmpty(list);
|
||||
}
|
||||
|
||||
/* Return the first node from the list for which the match function returns
|
||||
* TRUE, or NULL if none of the nodes matched. */
|
||||
LstNode
|
||||
Lst_Find(Lst list, LstFindProc match, const void *matchArgs)
|
||||
{
|
||||
return Lst_FindFrom(list, Lst_First(list), match, matchArgs);
|
||||
}
|
||||
|
||||
/* Return the first node from the list, starting at the given node, for which
|
||||
* the match function returns TRUE, or NULL if none of the nodes matches.
|
||||
*
|
||||
* The start node may be NULL, in which case nothing is found. This allows
|
||||
* for passing Lst_First or LstNode_Next as the start node. */
|
||||
LstNode
|
||||
Lst_FindFrom(Lst list, LstNode node, LstFindProc match, const void *matchArgs)
|
||||
{
|
||||
LstNode tln;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(match != NULL);
|
||||
|
||||
for (tln = node; tln != NULL; tln = tln->next) {
|
||||
if (match(tln->datum, matchArgs))
|
||||
return tln;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the first node that contains the given datum, or NULL. */
|
||||
LstNode
|
||||
Lst_FindDatum(Lst list, const void *datum)
|
||||
{
|
||||
LstNode node;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(datum != NULL);
|
||||
|
||||
for (node = list->first; node != NULL; node = node->next) {
|
||||
if (node->datum == datum) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Apply the given function to each element of the given list. The function
|
||||
* should return 0 if traversal should continue and non-zero if it should
|
||||
* abort. */
|
||||
int
|
||||
Lst_ForEach(Lst list, LstActionProc proc, void *procData)
|
||||
{
|
||||
if (LstIsEmpty(list))
|
||||
return 0; /* XXX: Document what this value means. */
|
||||
return Lst_ForEachFrom(list, Lst_First(list), proc, procData);
|
||||
}
|
||||
|
||||
/* Apply the given function to each element of the given list, starting from
|
||||
* the given node. The function should return 0 if traversal should continue,
|
||||
* and non-zero if it should abort. */
|
||||
int
|
||||
Lst_ForEachFrom(Lst list, LstNode node,
|
||||
LstActionProc proc, void *procData)
|
||||
{
|
||||
LstNode tln = node;
|
||||
LstNode next;
|
||||
Boolean done;
|
||||
int result;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(node != NULL);
|
||||
assert(proc != NULL);
|
||||
|
||||
do {
|
||||
/*
|
||||
* Take care of having the current element deleted out from under
|
||||
* us.
|
||||
*/
|
||||
|
||||
next = tln->next;
|
||||
|
||||
/*
|
||||
* We're done with the traversal if
|
||||
* - the next node to examine doesn't exist and
|
||||
* - nothing's been added after the current node (check this
|
||||
* after proc() has been called).
|
||||
*/
|
||||
done = next == NULL;
|
||||
|
||||
tln->useCount++;
|
||||
result = (*proc)(tln->datum, procData);
|
||||
tln->useCount--;
|
||||
|
||||
/*
|
||||
* Now check whether a node has been added.
|
||||
* Note: this doesn't work if this node was deleted before
|
||||
* the new node was added.
|
||||
*/
|
||||
if (next != tln->next) {
|
||||
next = tln->next;
|
||||
done = 0;
|
||||
}
|
||||
|
||||
if (tln->deleted) {
|
||||
free((char *)tln);
|
||||
}
|
||||
tln = next;
|
||||
} while (!result && !LstIsEmpty(list) && !done);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Move all nodes from list2 to the end of list1.
|
||||
* List2 is destroyed and freed. */
|
||||
void
|
||||
Lst_MoveAll(Lst list1, Lst list2)
|
||||
{
|
||||
assert(list1 != NULL);
|
||||
assert(list2 != NULL);
|
||||
|
||||
if (list2->first != NULL) {
|
||||
list2->first->prev = list1->last;
|
||||
if (list1->last != NULL) {
|
||||
list1->last->next = list2->first;
|
||||
} else {
|
||||
list1->first = list2->first;
|
||||
}
|
||||
list1->last = list2->last;
|
||||
}
|
||||
free(list2);
|
||||
}
|
||||
|
||||
/* Copy the element data from src to the start of dst. */
|
||||
void
|
||||
Lst_PrependAll(Lst dst, Lst src)
|
||||
{
|
||||
LstNode node;
|
||||
for (node = src->last; node != NULL; node = node->prev)
|
||||
Lst_Prepend(dst, node->datum);
|
||||
}
|
||||
|
||||
/* Copy the element data from src to the end of dst. */
|
||||
void
|
||||
Lst_AppendAll(Lst dst, Lst src)
|
||||
{
|
||||
LstNode node;
|
||||
for (node = src->first; node != NULL; node = node->next)
|
||||
Lst_Append(dst, node->datum);
|
||||
}
|
||||
|
||||
/*
|
||||
* these functions are for dealing with a list as a table, of sorts.
|
||||
* An idea of the "current element" is kept and used by all the functions
|
||||
* between Lst_Open() and Lst_Close().
|
||||
*
|
||||
* The sequential functions access the list in a slightly different way.
|
||||
* CurPtr points to their idea of the current node in the list and they
|
||||
* access the list based on it.
|
||||
*/
|
||||
|
||||
/* Open a list for sequential access. A list can still be searched, etc.,
|
||||
* without confusing these functions. */
|
||||
void
|
||||
Lst_Open(Lst list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(!list->isOpen);
|
||||
|
||||
list->isOpen = TRUE;
|
||||
list->lastAccess = LstIsEmpty(list) ? Head : Unknown;
|
||||
list->curr = NULL;
|
||||
}
|
||||
|
||||
/* Return the next node for the given list, or NULL if the end has been
|
||||
* reached. */
|
||||
LstNode
|
||||
Lst_Next(Lst list)
|
||||
{
|
||||
LstNode node;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(list->isOpen);
|
||||
|
||||
list->prev = list->curr;
|
||||
|
||||
if (list->curr == NULL) {
|
||||
if (list->lastAccess == Unknown) {
|
||||
/*
|
||||
* If we're just starting out, lastAccess will be Unknown.
|
||||
* Then we want to start this thing off in the right
|
||||
* direction -- at the start with lastAccess being Middle.
|
||||
*/
|
||||
list->curr = node = list->first;
|
||||
list->lastAccess = Middle;
|
||||
} else {
|
||||
node = NULL;
|
||||
list->lastAccess = Tail;
|
||||
}
|
||||
} else {
|
||||
node = list->curr->next;
|
||||
list->curr = node;
|
||||
|
||||
if (node == list->first || node == NULL) {
|
||||
/*
|
||||
* If back at the front, then we've hit the end...
|
||||
*/
|
||||
list->lastAccess = Tail;
|
||||
} else {
|
||||
/*
|
||||
* Reset to Middle if gone past first.
|
||||
*/
|
||||
list->lastAccess = Middle;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Close a list which was opened for sequential access. */
|
||||
void
|
||||
Lst_Close(Lst list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(list->isOpen);
|
||||
|
||||
list->isOpen = FALSE;
|
||||
list->lastAccess = Unknown;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* for using the list as a queue
|
||||
*/
|
||||
|
||||
/* Add the datum to the tail of the given list. */
|
||||
void
|
||||
Lst_Enqueue(Lst list, void *datum)
|
||||
{
|
||||
Lst_Append(list, datum);
|
||||
}
|
||||
|
||||
/* Remove and return the datum at the head of the given list. */
|
||||
void *
|
||||
Lst_Dequeue(Lst list)
|
||||
{
|
||||
void *datum;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(!LstIsEmpty(list));
|
||||
|
||||
datum = list->first->datum;
|
||||
Lst_Remove(list, list->first);
|
||||
assert(datum != NULL);
|
||||
return datum;
|
||||
}
|
179
20200902/lst.h
Normal file
179
20200902/lst.h
Normal file
@ -0,0 +1,179 @@
|
||||
/* $NetBSD: lst.h,v 1.60 2020/09/02 23:33:13 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)lst.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989 by Adam de Boor
|
||||
* Copyright (c) 1989 by Berkeley Softworks
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)lst.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/* Doubly-linked lists of arbitrary pointers. */
|
||||
|
||||
#ifndef MAKE_LST_H
|
||||
#define MAKE_LST_H
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* A doubly-linked list of pointers. */
|
||||
typedef struct List *Lst;
|
||||
/* A single node in the doubly-linked list. */
|
||||
typedef struct ListNode *LstNode;
|
||||
|
||||
/* Copy a node, usually by allocating a copy of the given object.
|
||||
* For reference-counted objects, the original object may need to be
|
||||
* modified, therefore the parameter is not const. */
|
||||
typedef void *LstCopyProc(void *);
|
||||
/* Free the datum of a node, called before freeing the node itself. */
|
||||
typedef void LstFreeProc(void *);
|
||||
/* Return TRUE if the datum matches the args, for Lst_Find. */
|
||||
typedef Boolean LstFindProc(const void *datum, const void *args);
|
||||
/* An action for Lst_ForEach. */
|
||||
typedef int LstActionProc(void *datum, void *args);
|
||||
|
||||
/* Create or destroy a list */
|
||||
|
||||
/* Create a new list. */
|
||||
Lst Lst_Init(void);
|
||||
/* Duplicate an existing list. */
|
||||
Lst Lst_Copy(Lst, LstCopyProc);
|
||||
/* Free the list, leaving the node data unmodified. */
|
||||
void Lst_Free(Lst);
|
||||
/* Free the list, freeing the node data using the given function. */
|
||||
void Lst_Destroy(Lst, LstFreeProc);
|
||||
|
||||
/* Get information about a list */
|
||||
|
||||
Boolean Lst_IsEmpty(Lst);
|
||||
/* Return the first node of the list, or NULL. */
|
||||
LstNode Lst_First(Lst);
|
||||
/* Return the last node of the list, or NULL. */
|
||||
LstNode Lst_Last(Lst);
|
||||
/* Find the first node for which the function returns TRUE, or NULL. */
|
||||
LstNode Lst_Find(Lst, LstFindProc, const void *);
|
||||
/* Find the first node for which the function returns TRUE, or NULL.
|
||||
* The search starts at the given node, towards the end of the list. */
|
||||
LstNode Lst_FindFrom(Lst, LstNode, LstFindProc, const void *);
|
||||
/* Find the first node that contains the given datum, or NULL. */
|
||||
LstNode Lst_FindDatum(Lst, const void *);
|
||||
|
||||
/* Modify a list */
|
||||
|
||||
/* Insert a datum before the given node. */
|
||||
void Lst_InsertBefore(Lst, LstNode, void *);
|
||||
/* Place a datum at the front of the list. */
|
||||
void Lst_Prepend(Lst, void *);
|
||||
/* Place a datum at the end of the list. */
|
||||
void Lst_Append(Lst, void *);
|
||||
/* Remove the node from the list. */
|
||||
void Lst_Remove(Lst, LstNode);
|
||||
void Lst_PrependAll(Lst, Lst);
|
||||
void Lst_AppendAll(Lst, Lst);
|
||||
void Lst_MoveAll(Lst, Lst);
|
||||
|
||||
/* Node-specific functions */
|
||||
|
||||
/* Return the successor of the node, or NULL. */
|
||||
LstNode LstNode_Next(LstNode);
|
||||
/* Return the predecessor of the node, or NULL. */
|
||||
LstNode LstNode_Prev(LstNode);
|
||||
/* Return the datum of the node. Usually not NULL. */
|
||||
void *LstNode_Datum(LstNode);
|
||||
/* Replace the value of the node. */
|
||||
void LstNode_Set(LstNode, void *);
|
||||
/* Set the value of the node to NULL. Having NULL in a list is unusual. */
|
||||
void LstNode_SetNull(LstNode);
|
||||
|
||||
/* Iterating over a list, using a callback function */
|
||||
|
||||
/* Apply a function to each datum of the list, until the callback function
|
||||
* returns non-zero. */
|
||||
int Lst_ForEach(Lst, LstActionProc, void *);
|
||||
/* Apply a function to each datum of the list, starting at the node,
|
||||
* until the callback function returns non-zero. */
|
||||
int Lst_ForEachFrom(Lst, LstNode, LstActionProc, void *);
|
||||
|
||||
/* Iterating over a list while keeping track of the current node and possible
|
||||
* concurrent modifications */
|
||||
|
||||
/* Start iterating the list. */
|
||||
void Lst_Open(Lst);
|
||||
/* Return the next node, or NULL. */
|
||||
LstNode Lst_Next(Lst);
|
||||
/* Finish iterating the list. */
|
||||
void Lst_Close(Lst);
|
||||
|
||||
/* Using the list as a queue */
|
||||
|
||||
/* Add a datum at the tail of the queue. */
|
||||
void Lst_Enqueue(Lst, void *);
|
||||
/* Remove the head node of the queue and return its datum. */
|
||||
void *Lst_Dequeue(Lst);
|
||||
|
||||
#endif /* MAKE_LST_H */
|
106
20200902/machine.sh
Executable file
106
20200902/machine.sh
Executable file
@ -0,0 +1,106 @@
|
||||
:
|
||||
# derrived from /etc/rc_d/os.sh
|
||||
|
||||
# RCSid:
|
||||
# $Id: machine.sh,v 1.18 2017/08/13 19:11:28 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1994-2002 Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
OS=`uname`
|
||||
OSREL=`uname -r`
|
||||
OSMAJOR=`IFS=.; set $OSREL; echo $1`
|
||||
machine=`uname -p 2>/dev/null || uname -m`
|
||||
MACHINE=
|
||||
|
||||
# there is at least one case of `uname -p` outputting
|
||||
# a bunch of usless drivel
|
||||
case "$machine" in
|
||||
unknown|*[!A-Za-z0-9_-]*)
|
||||
machine=`uname -m`
|
||||
;;
|
||||
esac
|
||||
|
||||
# Great! Solaris keeps moving arch(1)
|
||||
# we need this here, and it is not always available...
|
||||
Which() {
|
||||
# some shells cannot correctly handle `IFS`
|
||||
# in conjunction with the for loop.
|
||||
_dirs=`IFS=:; echo ${2:-$PATH}`
|
||||
for d in $_dirs
|
||||
do
|
||||
test -x $d/$1 && { echo $d/$1; break; }
|
||||
done
|
||||
}
|
||||
|
||||
case $OS in
|
||||
AIX) # from http://gnats.netbsd.org/29386
|
||||
OSMAJOR=`uname -v`
|
||||
OSMINOR=`uname -r`
|
||||
MACHINE=$OS$OSMAJOR.$OSMINOR
|
||||
MACHINE_ARCH=`bootinfo -T`
|
||||
;;
|
||||
OpenBSD)
|
||||
MACHINE=$OS$OSMAJOR.$machine
|
||||
arch=`Which arch /usr/bin:/usr/ucb:$PATH`
|
||||
MACHINE_ARCH=`$arch -s`;
|
||||
;;
|
||||
Bitrig)
|
||||
MACHINE=$OS$OSMAJOR.$machine
|
||||
MACHINE_ARCH=`uname -m`;
|
||||
;;
|
||||
*BSD)
|
||||
MACHINE=$OS$OSMAJOR.$machine
|
||||
;;
|
||||
SunOS)
|
||||
arch=`Which arch /usr/bin:/usr/ucb:$PATH`
|
||||
test "$arch" && machine_arch=`$arch`
|
||||
|
||||
case "$OSREL" in
|
||||
4.0*) MACHINE_ARCH=$machine_arch MACHINE=$machine_arch;;
|
||||
4*) MACHINE_ARCH=$machine_arch;;
|
||||
esac
|
||||
;;
|
||||
HP-UX)
|
||||
MACHINE_ARCH=`IFS="/-."; set $machine; echo $1`
|
||||
;;
|
||||
Interix)
|
||||
MACHINE=i386
|
||||
MACHINE_ARCH=i386
|
||||
;;
|
||||
UnixWare)
|
||||
OSREL=`uname -v`
|
||||
OSMAJOR=`IFS=.; set $OSREL; echo $1`
|
||||
MACHINE_ARCH=`uname -m`
|
||||
;;
|
||||
Linux)
|
||||
case "$machine" in
|
||||
i?86) MACHINE_ARCH=i386;;# does anyone really care about 686 vs 586?
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
MACHINE=${MACHINE:-$OS$OSMAJOR}
|
||||
MACHINE_ARCH=${MACHINE_ARCH:-$machine}
|
||||
|
||||
(
|
||||
case "$0" in
|
||||
arch*) echo $MACHINE_ARCH;;
|
||||
*)
|
||||
case "$1" in
|
||||
"") echo $MACHINE;;
|
||||
*) echo $MACHINE_ARCH;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
) | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz
|
2220
20200902/main.c
Normal file
2220
20200902/main.c
Normal file
File diff suppressed because it is too large
Load Diff
101
20200902/make-bootstrap.sh.in
Executable file
101
20200902/make-bootstrap.sh.in
Executable file
@ -0,0 +1,101 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
srcdir=@srcdir@
|
||||
|
||||
DEFAULT_SYS_PATH="@default_sys_path@"
|
||||
|
||||
case "@use_meta@" in
|
||||
yes) XDEFS="-DUSE_META ${XDEFS}";;
|
||||
esac
|
||||
|
||||
CC="@CC@"
|
||||
CFLAGS="@CFLAGS@ -I. -I${srcdir} @DEFS@ @CPPFLAGS@ -DMAKE_NATIVE ${XDEFS} -DBMAKE_PATH_MAX=@bmake_path_max@"
|
||||
|
||||
MAKE_VERSION=@_MAKE_VERSION@
|
||||
|
||||
MDEFS="-DMAKE_VERSION=\"$MAKE_VERSION\" \
|
||||
-D@force_machine@MACHINE=\"@machine@\" -DMACHINE_ARCH=\"@machine_arch@\" \
|
||||
-D_PATH_DEFSYSPATH=\"${DEFAULT_SYS_PATH}\""
|
||||
|
||||
|
||||
LDFLAGS="@LDFLAGS@"
|
||||
LIBS="@LIBS@"
|
||||
|
||||
toUpper() {
|
||||
${TR:-tr} abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
}
|
||||
|
||||
do_compile2() {
|
||||
obj="$1"; shift
|
||||
src="$1"; shift
|
||||
echo ${CC} -c ${CFLAGS} "$@" -o "$obj" "$src"
|
||||
${CC} -c ${CFLAGS} "$@" -o "$obj" "$src"
|
||||
}
|
||||
|
||||
do_compile() {
|
||||
obj="$1"; shift
|
||||
case "$1" in
|
||||
*.c) src=$1; shift;;
|
||||
*) src=`basename "$obj" .o`.c;;
|
||||
esac
|
||||
|
||||
for d in "$srcdir" "$srcdir/lst.lib"
|
||||
do
|
||||
test -s "$d/$src" || continue
|
||||
|
||||
do_compile2 "$obj" "$d/$src" "$@" || exit 1
|
||||
return
|
||||
done
|
||||
echo "Unknown object file '$obj'" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
do_link() {
|
||||
output="$1"; shift
|
||||
echo ${CC} ${LDSTATIC} ${LDFLAGS} -o "$output" "$@" ${LIBS}
|
||||
${CC} ${LDSTATIC} ${LDFLAGS} -o "$output" "$@" ${LIBS}
|
||||
}
|
||||
|
||||
BASE_OBJECTS="arch.o buf.o compat.o cond.o dir.o for.o getopt hash.o \
|
||||
make.o make_malloc.o metachar.o parse.o sigcompat.o str.o strlist.o \
|
||||
suff.o targ.o trace.o var.o util.o"
|
||||
|
||||
LST_OBJECTS="lstAppend.o lstDupl.o lstInit.o lstOpen.o \
|
||||
lstAtEnd.o lstEnQueue.o lstInsert.o lstAtFront.o lstIsAtEnd.o \
|
||||
lstClose.o lstFind.o lstIsEmpty.o lstRemove.o lstConcat.o \
|
||||
lstFindFrom.o lstLast.o lstReplace.o lstFirst.o lstDatum.o \
|
||||
lstForEach.o lstMember.o lstSucc.o lstDeQueue.o lstForEachFrom.o \
|
||||
lstDestroy.o lstNext.o lstPrev.o"
|
||||
|
||||
LIB_OBJECTS="@LIBOBJS@"
|
||||
|
||||
do_compile main.o ${MDEFS}
|
||||
|
||||
for o in ${BASE_OBJECTS} ${LST_OBJECTS} ${LIB_OBJECTS}
|
||||
do
|
||||
do_compile "$o"
|
||||
done
|
||||
|
||||
case "@use_meta@" in
|
||||
yes)
|
||||
case "@use_filemon@" in
|
||||
no) MDEFS=;;
|
||||
*)
|
||||
MDEFS="-DUSE_FILEMON -DUSE_FILEMON_`echo @use_filemon@ | toUpper`"
|
||||
case "@use_filemon@,@filemon_h@" in
|
||||
dev,*/filemon.h) FDEFS="-DHAVE_FILEMON_H -I`dirname @filemon_h@`";;
|
||||
*) FDEFS=;;
|
||||
esac
|
||||
do_compile filemon_@use_filemon@.o filemon/filemon_@use_filemon@.c ${FDEFS}
|
||||
BASE_OBJECTS="filemon_@use_filemon@.o $BASE_OBJECTS"
|
||||
;;
|
||||
esac
|
||||
do_compile meta.o ${MDEFS}
|
||||
BASE_OBJECTS="meta.o ${BASE_OBJECTS}"
|
||||
;;
|
||||
esac
|
||||
do_compile job.o ${MDEFS}
|
||||
|
||||
do_link bmake main.o job.o ${BASE_OBJECTS} ${LST_OBJECTS} ${LIB_OBJECTS}
|
164
20200902/make-conf.h
Normal file
164
20200902/make-conf.h
Normal file
@ -0,0 +1,164 @@
|
||||
/* $NetBSD: config.h,v 1.22 2020/09/01 17:40:34 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)config.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989 by Adam de Boor
|
||||
* Copyright (c) 1989 by Berkeley Softworks
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)config.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* DEFMAXJOBS
|
||||
* DEFMAXLOCAL
|
||||
* These control the default concurrency. On no occasion will more
|
||||
* than DEFMAXJOBS targets be created at once (locally or remotely)
|
||||
* DEFMAXLOCAL is the highest number of targets which will be
|
||||
* created on the local machine at once. Note that if you set this
|
||||
* to 0, nothing will ever happen...
|
||||
*/
|
||||
#define DEFMAXJOBS 4
|
||||
#define DEFMAXLOCAL 1
|
||||
|
||||
/*
|
||||
* INCLUDES
|
||||
* LIBRARIES
|
||||
* These control the handling of the .INCLUDES and .LIBS variables.
|
||||
* If INCLUDES is defined, the .INCLUDES variable will be filled
|
||||
* from the search paths of those suffixes which are marked by
|
||||
* .INCLUDES dependency lines. Similarly for LIBRARIES and .LIBS
|
||||
* See suff.c for more details.
|
||||
*/
|
||||
#define INCLUDES
|
||||
#define LIBRARIES
|
||||
|
||||
/*
|
||||
* LIBSUFF
|
||||
* Is the suffix used to denote libraries and is used by the Suff module
|
||||
* to find the search path on which to seek any -l<xx> targets.
|
||||
*/
|
||||
#define LIBSUFF ".a"
|
||||
|
||||
/*
|
||||
* RECHECK
|
||||
* If defined, Make_Update will check a target for its current
|
||||
* modification time after it has been re-made, setting it to the
|
||||
* starting time of the make only if the target still doesn't exist.
|
||||
* Unfortunately, under NFS the modification time often doesn't
|
||||
* get updated in time, so a target will appear to not have been
|
||||
* re-made, causing later targets to appear up-to-date. On systems
|
||||
* that don't have this problem, you should define this. Under
|
||||
* NFS you probably should not, unless you aren't exporting jobs.
|
||||
*/
|
||||
#define RECHECK
|
||||
|
||||
/*
|
||||
* POSIX
|
||||
* Adhere to the POSIX 1003.2 draft for the make(1) program.
|
||||
* - Use MAKEFLAGS instead of MAKE to pick arguments from the
|
||||
* environment.
|
||||
* - Allow empty command lines if starting with tab.
|
||||
*/
|
||||
#define POSIX
|
||||
|
||||
/*
|
||||
* SYSVINCLUDE
|
||||
* Recognize system V like include directives [include "filename"]
|
||||
* SYSVVARSUB
|
||||
* Recognize system V like ${VAR:x=y} variable substitutions
|
||||
*/
|
||||
#define SYSVINCLUDE
|
||||
#define SYSVVARSUB
|
||||
|
||||
/*
|
||||
* GMAKEEXPORT
|
||||
* Recognize gmake like variable export directives [export <VAR>=<VALUE>]
|
||||
*/
|
||||
#define GMAKEEXPORT
|
||||
|
||||
/*
|
||||
* SUNSHCMD
|
||||
* Recognize SunOS and Solaris:
|
||||
* VAR :sh= CMD # Assign VAR to the command substitution of CMD
|
||||
* ${VAR:sh} # Return the command substitution of the value
|
||||
* # of ${VAR}
|
||||
*/
|
||||
#define SUNSHCMD
|
||||
|
||||
/*
|
||||
* USE_IOVEC
|
||||
* We have writev(2)
|
||||
*/
|
||||
#ifdef HAVE_SYS_UIO_H
|
||||
# define USE_IOVEC
|
||||
#endif
|
||||
|
||||
#if defined(MAKE_NATIVE) && !defined(__ELF__)
|
||||
# ifndef RANLIBMAG
|
||||
# define RANLIBMAG "__.SYMDEF"
|
||||
# endif
|
||||
#endif
|
2450
20200902/make.1
Normal file
2450
20200902/make.1
Normal file
File diff suppressed because it is too large
Load Diff
1561
20200902/make.c
Normal file
1561
20200902/make.c
Normal file
File diff suppressed because it is too large
Load Diff
595
20200902/make.h
Normal file
595
20200902/make.h
Normal file
@ -0,0 +1,595 @@
|
||||
/* $NetBSD: make.h,v 1.137 2020/09/02 23:42:58 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)make.h 8.3 (Berkeley) 6/13/95
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989 by Berkeley Softworks
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Adam de Boor.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)make.h 8.3 (Berkeley) 6/13/95
|
||||
*/
|
||||
|
||||
/*-
|
||||
* make.h --
|
||||
* The global definitions for pmake
|
||||
*/
|
||||
|
||||
#ifndef MAKE_MAKE_H
|
||||
#define MAKE_MAKE_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#ifndef FD_CLOEXEC
|
||||
#define FD_CLOEXEC 1
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define MAKE_GNUC_PREREQ(x, y) \
|
||||
((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
|
||||
(__GNUC__ > (x)))
|
||||
#else /* defined(__GNUC__) */
|
||||
#define MAKE_GNUC_PREREQ(x, y) 0
|
||||
#endif /* defined(__GNUC__) */
|
||||
|
||||
#if MAKE_GNUC_PREREQ(2, 7)
|
||||
#define MAKE_ATTR_UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
#define MAKE_ATTR_UNUSED /* delete */
|
||||
#endif
|
||||
|
||||
#if MAKE_GNUC_PREREQ(2, 5)
|
||||
#define MAKE_ATTR_DEAD __attribute__((__noreturn__))
|
||||
#elif defined(__GNUC__)
|
||||
#define MAKE_ATTR_DEAD __volatile
|
||||
#else
|
||||
#define MAKE_ATTR_DEAD /* delete */
|
||||
#endif
|
||||
|
||||
#if MAKE_GNUC_PREREQ(2, 7)
|
||||
#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) \
|
||||
__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
|
||||
#else
|
||||
#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) /* delete */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A boolean type is defined as an integer, not an enum, for historic reasons.
|
||||
* The only allowed values are the constants TRUE and FALSE (1 and 0).
|
||||
*/
|
||||
|
||||
#ifdef USE_DOUBLE_BOOLEAN
|
||||
/* During development, to find type mismatches in function declarations. */
|
||||
typedef double Boolean;
|
||||
#elif defined(USE_UCHAR_BOOLEAN)
|
||||
/* During development, to find code that depends on the exact value of TRUE or
|
||||
* that stores other values in Boolean variables. */
|
||||
typedef unsigned char Boolean;
|
||||
#define TRUE ((unsigned char)0xFF)
|
||||
#define FALSE ((unsigned char)0x00)
|
||||
#elif defined(USE_ENUM_BOOLEAN)
|
||||
typedef enum { FALSE, TRUE} Boolean;
|
||||
#else
|
||||
typedef int Boolean;
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif /* TRUE */
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif /* FALSE */
|
||||
|
||||
#include "lst.h"
|
||||
#include "enum.h"
|
||||
#include "hash.h"
|
||||
#include "make-conf.h"
|
||||
#include "buf.h"
|
||||
#include "make_malloc.h"
|
||||
|
||||
/*
|
||||
* some vendors don't have this --sjg
|
||||
*/
|
||||
#if defined(S_IFDIR) && !defined(S_ISDIR)
|
||||
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#if defined(sun) && (defined(__svr4__) || defined(__SVR4))
|
||||
#define POSIX_SIGNALS
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
UNMADE, /* Not examined yet */
|
||||
DEFERRED, /* Examined once (building child) */
|
||||
REQUESTED, /* on toBeMade list */
|
||||
BEINGMADE, /* Target is already being made.
|
||||
* Indicates a cycle in the graph. */
|
||||
MADE, /* Was out-of-date and has been made */
|
||||
UPTODATE, /* Was already up-to-date */
|
||||
ERROR, /* An error occurred while it was being
|
||||
* made (used only in compat mode) */
|
||||
ABORTED /* The target was aborted due to an error
|
||||
* making an inferior (compat). */
|
||||
} GNodeMade;
|
||||
|
||||
/* The OP_ constants are used when parsing a dependency line as a way of
|
||||
* communicating to other parts of the program the way in which a target
|
||||
* should be made.
|
||||
*
|
||||
* These constants are bitwise-OR'ed together and placed in the 'type' field
|
||||
* of each node. Any node that has a 'type' field which satisfies the OP_NOP
|
||||
* function was never never on the left-hand side of an operator, though it
|
||||
* may have been on the right-hand side... */
|
||||
typedef enum {
|
||||
/* Execution of commands depends on children (:) */
|
||||
OP_DEPENDS = 1 << 0,
|
||||
/* Always execute commands (!) */
|
||||
OP_FORCE = 1 << 1,
|
||||
/* Execution of commands depends on children per line (::) */
|
||||
OP_DOUBLEDEP = 1 << 2,
|
||||
|
||||
OP_OPMASK = OP_DEPENDS|OP_FORCE|OP_DOUBLEDEP,
|
||||
|
||||
/* Don't care if the target doesn't exist and can't be created */
|
||||
OP_OPTIONAL = 1 << 3,
|
||||
/* Use associated commands for parents */
|
||||
OP_USE = 1 << 4,
|
||||
/* Target is never out of date, but always execute commands anyway.
|
||||
* Its time doesn't matter, so it has none...sort of */
|
||||
OP_EXEC = 1 << 5,
|
||||
/* Ignore errors when creating the node */
|
||||
OP_IGNORE = 1 << 6,
|
||||
/* Don't remove the target when interrupted */
|
||||
OP_PRECIOUS = 1 << 7,
|
||||
/* Don't echo commands when executed */
|
||||
OP_SILENT = 1 << 8,
|
||||
/* Target is a recursive make so its commands should always be executed
|
||||
* when it is out of date, regardless of the state of the -n or -t flags */
|
||||
OP_MAKE = 1 << 9,
|
||||
/* Target is out-of-date only if any of its children was out-of-date */
|
||||
OP_JOIN = 1 << 10,
|
||||
/* Assume the children of the node have been already made */
|
||||
OP_MADE = 1 << 11,
|
||||
/* Special .BEGIN, .END, .INTERRUPT */
|
||||
OP_SPECIAL = 1 << 12,
|
||||
/* Like .USE, only prepend commands */
|
||||
OP_USEBEFORE = 1 << 13,
|
||||
/* The node is invisible to its parents. I.e. it doesn't show up in the
|
||||
* parents' local variables. */
|
||||
OP_INVISIBLE = 1 << 14,
|
||||
/* The node is exempt from normal 'main target' processing in parse.c */
|
||||
OP_NOTMAIN = 1 << 15,
|
||||
/* Not a file target; run always */
|
||||
OP_PHONY = 1 << 16,
|
||||
/* Don't search for file in the path */
|
||||
OP_NOPATH = 1 << 17,
|
||||
/* .WAIT phony node */
|
||||
OP_WAIT = 1 << 18,
|
||||
/* .NOMETA do not create a .meta file */
|
||||
OP_NOMETA = 1 << 19,
|
||||
/* .META we _do_ want a .meta file */
|
||||
OP_META = 1 << 20,
|
||||
/* Do not compare commands in .meta file */
|
||||
OP_NOMETA_CMP = 1 << 21,
|
||||
/* Possibly a submake node */
|
||||
OP_SUBMAKE = 1 << 22,
|
||||
|
||||
/* Attributes applied by PMake */
|
||||
|
||||
/* The node is a transformation rule */
|
||||
OP_TRANSFORM = 1 << 31,
|
||||
/* Target is a member of an archive */
|
||||
OP_MEMBER = 1 << 30,
|
||||
/* Target is a library */
|
||||
OP_LIB = 1 << 29,
|
||||
/* Target is an archive construct */
|
||||
OP_ARCHV = 1 << 28,
|
||||
/* Target has all the commands it should. Used when parsing to catch
|
||||
* multiple commands for a target. */
|
||||
OP_HAS_COMMANDS = 1 << 27,
|
||||
/* Saving commands on .END (Compat) */
|
||||
OP_SAVE_CMDS = 1 << 26,
|
||||
/* Already processed by Suff_FindDeps */
|
||||
OP_DEPS_FOUND = 1 << 25,
|
||||
/* Node found while expanding .ALLSRC */
|
||||
OP_MARK = 1 << 24
|
||||
} GNodeType;
|
||||
|
||||
typedef enum {
|
||||
REMAKE = 0x0001, /* this target needs to be (re)made */
|
||||
CHILDMADE = 0x0002, /* children of this target were made */
|
||||
FORCE = 0x0004, /* children don't exist, and we pretend made */
|
||||
DONE_WAIT = 0x0008, /* Set by Make_ProcessWait() */
|
||||
DONE_ORDER = 0x0010, /* Build requested by .ORDER processing */
|
||||
FROM_DEPEND = 0x0020, /* Node created from .depend */
|
||||
DONE_ALLSRC = 0x0040, /* We do it once only */
|
||||
CYCLE = 0x1000, /* Used by MakePrintStatus */
|
||||
DONECYCLE = 0x2000, /* Used by MakePrintStatus */
|
||||
INTERNAL = 0x4000 /* Internal use only */
|
||||
} GNodeFlags;
|
||||
|
||||
/* A graph node represents a target that can possibly be made, including its
|
||||
* relation to other targets and a lot of other details. */
|
||||
typedef struct GNode {
|
||||
/* The target's name, such as "clean" or "make.c" */
|
||||
char *name;
|
||||
/* The unexpanded name of a .USE node */
|
||||
char *uname;
|
||||
/* The full pathname of the file belonging to the target.
|
||||
* XXX: What about .PHONY targets? These don't have an associated path. */
|
||||
char *path;
|
||||
|
||||
/* The type of operator used to define the sources (see the OP flags below).
|
||||
* XXX: This looks like a wild mixture of type and flags. */
|
||||
GNodeType type;
|
||||
/* whether it is involved in this invocation of make */
|
||||
GNodeFlags flags;
|
||||
|
||||
/* The state of processing on this node */
|
||||
GNodeMade made;
|
||||
int unmade; /* The number of unmade children */
|
||||
|
||||
time_t mtime; /* Its modification time */
|
||||
struct GNode *cmgn; /* The youngest child */
|
||||
|
||||
/* The GNodes for which this node is an implied source. May be empty.
|
||||
* For example, when there is an inference rule for .c.o, the node for
|
||||
* file.c has the node for file.o in this list. */
|
||||
Lst implicitParents;
|
||||
|
||||
/* Other nodes of the same name for the :: operator. */
|
||||
Lst cohorts;
|
||||
|
||||
/* The nodes that depend on this one, or in other words, the nodes for
|
||||
* which this is a source. */
|
||||
Lst parents;
|
||||
/* The nodes on which this one depends. */
|
||||
Lst children;
|
||||
|
||||
/* .ORDER nodes we need made. The nodes that must be made (if they're
|
||||
* made) before this node can be made, but that do not enter into the
|
||||
* datedness of this node. */
|
||||
Lst order_pred;
|
||||
/* .ORDER nodes who need us. The nodes that must be made (if they're made
|
||||
* at all) after this node is made, but that do not depend on this node,
|
||||
* in the normal sense. */
|
||||
Lst order_succ;
|
||||
|
||||
/* #n for this cohort */
|
||||
char cohort_num[8];
|
||||
/* The number of unmade instances on the cohorts list */
|
||||
int unmade_cohorts;
|
||||
/* Pointer to the first instance of a '::' node; only set when on a
|
||||
* cohorts list */
|
||||
struct GNode *centurion;
|
||||
|
||||
/* Last time (sequence number) we tried to make this node */
|
||||
unsigned int checked;
|
||||
|
||||
/* The "local" variables that are specific to this target and this target
|
||||
* only, such as $@, $<, $?. */
|
||||
Hash_Table context;
|
||||
|
||||
/* The commands to be given to a shell to create this target. */
|
||||
Lst commands;
|
||||
|
||||
/* Suffix for the node (determined by Suff_FindDeps and opaque to everyone
|
||||
* but the Suff module) */
|
||||
struct Suff *suffix;
|
||||
|
||||
/* filename where the GNode got defined */
|
||||
const char *fname;
|
||||
/* line number where the GNode got defined */
|
||||
int lineno;
|
||||
} GNode;
|
||||
|
||||
#define NoExecute(gn) ((gn->type & OP_MAKE) ? noRecursiveExecute : noExecute)
|
||||
/*
|
||||
* OP_NOP will return TRUE if the node with the given type was not the
|
||||
* object of a dependency operator
|
||||
*/
|
||||
#define OP_NOP(t) (((t) & OP_OPMASK) == 0x00000000)
|
||||
|
||||
#define OP_NOTARGET (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM)
|
||||
|
||||
/*
|
||||
* The TARG_ constants are used when calling the Targ_FindNode and
|
||||
* Targ_FindList functions in targ.c. They simply tell the functions what to
|
||||
* do if the desired node(s) is (are) not found. If the TARG_CREATE constant
|
||||
* is given, a new, empty node will be created for the target, placed in the
|
||||
* table of all targets and its address returned. If TARG_NOCREATE is given,
|
||||
* a NULL pointer will be returned.
|
||||
*/
|
||||
#define TARG_NOCREATE 0x00 /* don't create it */
|
||||
#define TARG_CREATE 0x01 /* create node if not found */
|
||||
#define TARG_NOHASH 0x02 /* don't look in/add to hash table */
|
||||
|
||||
/*
|
||||
* Error levels for parsing. PARSE_FATAL means the process cannot continue
|
||||
* once the makefile has been parsed. PARSE_WARNING means it can. Passed
|
||||
* as the first argument to Parse_Error.
|
||||
*/
|
||||
#define PARSE_INFO 3
|
||||
#define PARSE_WARNING 2
|
||||
#define PARSE_FATAL 1
|
||||
|
||||
/*
|
||||
* Values returned by Cond_Eval.
|
||||
*/
|
||||
typedef enum {
|
||||
COND_PARSE, /* Parse the next lines */
|
||||
COND_SKIP, /* Skip the next lines */
|
||||
COND_INVALID /* Not a conditional statement */
|
||||
} CondEvalResult;
|
||||
|
||||
/*
|
||||
* Definitions for the "local" variables. Used only for clarity.
|
||||
*/
|
||||
#define TARGET "@" /* Target of dependency */
|
||||
#define OODATE "?" /* All out-of-date sources */
|
||||
#define ALLSRC ">" /* All sources */
|
||||
#define IMPSRC "<" /* Source implied by transformation */
|
||||
#define PREFIX "*" /* Common prefix */
|
||||
#define ARCHIVE "!" /* Archive in "archive(member)" syntax */
|
||||
#define MEMBER "%" /* Member in "archive(member)" syntax */
|
||||
|
||||
#define FTARGET "@F" /* file part of TARGET */
|
||||
#define DTARGET "@D" /* directory part of TARGET */
|
||||
#define FIMPSRC "<F" /* file part of IMPSRC */
|
||||
#define DIMPSRC "<D" /* directory part of IMPSRC */
|
||||
#define FPREFIX "*F" /* file part of PREFIX */
|
||||
#define DPREFIX "*D" /* directory part of PREFIX */
|
||||
|
||||
/*
|
||||
* Global Variables
|
||||
*/
|
||||
extern Lst create; /* The list of target names specified on the
|
||||
* command line. used to resolve #if
|
||||
* make(...) statements */
|
||||
extern Lst dirSearchPath; /* The list of directories to search when
|
||||
* looking for targets */
|
||||
|
||||
extern Boolean compatMake; /* True if we are make compatible */
|
||||
extern Boolean ignoreErrors; /* True if should ignore all errors */
|
||||
extern Boolean beSilent; /* True if should print no commands */
|
||||
extern Boolean noExecute; /* True if should execute nothing */
|
||||
extern Boolean noRecursiveExecute; /* True if should execute nothing */
|
||||
extern Boolean allPrecious; /* True if every target is precious */
|
||||
extern Boolean deleteOnError; /* True if failed targets should be deleted */
|
||||
extern Boolean keepgoing; /* True if should continue on unaffected
|
||||
* portions of the graph when have an error
|
||||
* in one portion */
|
||||
extern Boolean touchFlag; /* TRUE if targets should just be 'touched'
|
||||
* if out of date. Set by the -t flag */
|
||||
extern Boolean queryFlag; /* TRUE if we aren't supposed to really make
|
||||
* anything, just see if the targets are out-
|
||||
* of-date */
|
||||
extern Boolean doing_depend; /* TRUE if processing .depend */
|
||||
|
||||
extern Boolean checkEnvFirst; /* TRUE if environment should be searched for
|
||||
* variables before the global context */
|
||||
|
||||
extern Boolean parseWarnFatal; /* TRUE if makefile parsing warnings are
|
||||
* treated as errors */
|
||||
|
||||
extern Boolean varNoExportEnv; /* TRUE if we should not export variables
|
||||
* set on the command line to the env. */
|
||||
|
||||
extern GNode *DEFAULT; /* .DEFAULT rule */
|
||||
|
||||
extern GNode *VAR_INTERNAL; /* Variables defined internally by make
|
||||
* which should not override those set by
|
||||
* makefiles.
|
||||
*/
|
||||
extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g
|
||||
* in the Makefile itself */
|
||||
extern GNode *VAR_CMD; /* Variables defined on the command line */
|
||||
extern char var_Error[]; /* Value returned by Var_Parse when an error
|
||||
* is encountered. It actually points to
|
||||
* an empty string, so naive callers needn't
|
||||
* worry about it. */
|
||||
|
||||
extern time_t now; /* The time at the start of this whole
|
||||
* process */
|
||||
|
||||
extern Boolean oldVars; /* Do old-style variable substitution */
|
||||
|
||||
extern Lst sysIncPath; /* The system include path. */
|
||||
extern Lst defIncPath; /* The default include path. */
|
||||
|
||||
extern char curdir[]; /* Startup directory */
|
||||
extern char *progname; /* The program name */
|
||||
extern char *makeDependfile; /* .depend */
|
||||
extern char **savedEnv; /* if we replaced environ this will be non-NULL */
|
||||
|
||||
extern int makelevel;
|
||||
|
||||
/*
|
||||
* We cannot vfork() in a child of vfork().
|
||||
* Most systems do not enforce this but some do.
|
||||
*/
|
||||
#define vFork() ((getpid() == myPid) ? vfork() : fork())
|
||||
extern pid_t myPid;
|
||||
|
||||
#define MAKEFLAGS ".MAKEFLAGS"
|
||||
#define MAKEOVERRIDES ".MAKEOVERRIDES"
|
||||
#define MAKE_JOB_PREFIX ".MAKE.JOB.PREFIX" /* prefix for job target output */
|
||||
#define MAKE_EXPORTED ".MAKE.EXPORTED" /* variables we export */
|
||||
#define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all the makefiles we read */
|
||||
#define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */
|
||||
#define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE"
|
||||
#define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */
|
||||
#define MAKE_MODE ".MAKE.MODE"
|
||||
#ifndef MAKE_LEVEL_ENV
|
||||
# define MAKE_LEVEL_ENV "MAKELEVEL"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* debug control:
|
||||
* There is one bit per module. It is up to the module what debug
|
||||
* information to print.
|
||||
*/
|
||||
extern FILE *debug_file; /* Output is written here - default stderr */
|
||||
extern int debug;
|
||||
#define DEBUG_ARCH 0x00001
|
||||
#define DEBUG_COND 0x00002
|
||||
#define DEBUG_DIR 0x00004
|
||||
#define DEBUG_GRAPH1 0x00008
|
||||
#define DEBUG_GRAPH2 0x00010
|
||||
#define DEBUG_JOB 0x00020
|
||||
#define DEBUG_MAKE 0x00040
|
||||
#define DEBUG_SUFF 0x00080
|
||||
#define DEBUG_TARG 0x00100
|
||||
#define DEBUG_VAR 0x00200
|
||||
#define DEBUG_FOR 0x00400
|
||||
#define DEBUG_SHELL 0x00800
|
||||
#define DEBUG_ERROR 0x01000
|
||||
#define DEBUG_LOUD 0x02000
|
||||
#define DEBUG_META 0x04000
|
||||
#define DEBUG_HASH 0x08000
|
||||
|
||||
#define DEBUG_GRAPH3 0x10000
|
||||
#define DEBUG_SCRIPT 0x20000
|
||||
#define DEBUG_PARSE 0x40000
|
||||
#define DEBUG_CWD 0x80000
|
||||
|
||||
#define DEBUG_LINT 0x100000
|
||||
|
||||
#define CONCAT(a,b) a##b
|
||||
|
||||
#define DEBUG(module) (debug & CONCAT(DEBUG_,module))
|
||||
|
||||
#include "nonints.h"
|
||||
|
||||
int Make_TimeStamp(GNode *, GNode *);
|
||||
Boolean Make_OODate(GNode *);
|
||||
void Make_ExpandUse(Lst);
|
||||
time_t Make_Recheck(GNode *);
|
||||
void Make_HandleUse(GNode *, GNode *);
|
||||
void Make_Update(GNode *);
|
||||
void Make_DoAllVar(GNode *);
|
||||
Boolean Make_Run(Lst);
|
||||
int dieQuietly(GNode *, int);
|
||||
void PrintOnError(GNode *, const char *);
|
||||
void Main_ExportMAKEFLAGS(Boolean);
|
||||
Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
|
||||
int mkTempFile(const char *, char **);
|
||||
int str2Lst_Append(Lst, char *, const char *);
|
||||
void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *);
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define UNCONST(ptr) ({ \
|
||||
union __unconst { \
|
||||
const void *__cp; \
|
||||
void *__p; \
|
||||
} __d; \
|
||||
__d.__cp = ptr, __d.__p; })
|
||||
#else
|
||||
#define UNCONST(ptr) (void *)(ptr)
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/* At least GNU/Hurd systems lack hardcoded MAXPATHLEN/PATH_MAX */
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifndef MAXPATHLEN
|
||||
#define MAXPATHLEN BMAKE_PATH_MAX
|
||||
#endif
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX MAXPATHLEN
|
||||
#endif
|
||||
|
||||
#if defined(SYSV)
|
||||
#define KILLPG(pid, sig) kill(-(pid), (sig))
|
||||
#else
|
||||
#define KILLPG(pid, sig) killpg((pid), (sig))
|
||||
#endif
|
||||
|
||||
#endif /* MAKE_MAKE_H */
|
101
20200902/make_malloc.c
Normal file
101
20200902/make_malloc.c
Normal file
@ -0,0 +1,101 @@
|
||||
/* $NetBSD: make_malloc.c,v 1.18 2020/09/02 06:10:44 rillig Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef MAKE_NATIVE
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: make_malloc.c,v 1.18 2020/09/02 06:10:44 rillig Exp $");
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "make.h"
|
||||
|
||||
#ifndef USE_EMALLOC
|
||||
static MAKE_ATTR_DEAD void enomem(void);
|
||||
|
||||
/* die when out of memory. */
|
||||
static MAKE_ATTR_DEAD void
|
||||
enomem(void)
|
||||
{
|
||||
(void)fprintf(stderr, "%s: %s.\n", progname, strerror(ENOMEM));
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/* malloc, but die on error. */
|
||||
void *
|
||||
bmake_malloc(size_t len)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if ((p = malloc(len)) == NULL)
|
||||
enomem();
|
||||
return p;
|
||||
}
|
||||
|
||||
/* strdup, but die on error. */
|
||||
char *
|
||||
bmake_strdup(const char *str)
|
||||
{
|
||||
size_t len;
|
||||
char *p;
|
||||
|
||||
len = strlen(str) + 1;
|
||||
if ((p = malloc(len)) == NULL)
|
||||
enomem();
|
||||
return memcpy(p, str, len);
|
||||
}
|
||||
|
||||
/* Allocate a string starting from str with exactly len characters. */
|
||||
char *
|
||||
bmake_strldup(const char *str, size_t len)
|
||||
{
|
||||
char *p = bmake_malloc(len + 1);
|
||||
memcpy(p, str, len);
|
||||
p[len] = '\0';
|
||||
return p;
|
||||
}
|
||||
|
||||
/* realloc, but die on error. */
|
||||
void *
|
||||
bmake_realloc(void *ptr, size_t size)
|
||||
{
|
||||
if ((ptr = realloc(ptr, size)) == NULL)
|
||||
enomem();
|
||||
return ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate a string from start up to but excluding end. */
|
||||
char *
|
||||
bmake_strsedup(const char *start, const char *end)
|
||||
{
|
||||
return bmake_strldup(start, (size_t)(end - start));
|
||||
}
|
54
20200902/make_malloc.h
Normal file
54
20200902/make_malloc.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* $NetBSD: make_malloc.h,v 1.10 2020/08/29 16:47:45 rillig Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef USE_EMALLOC
|
||||
void *bmake_malloc(size_t);
|
||||
void *bmake_realloc(void *, size_t);
|
||||
char *bmake_strdup(const char *);
|
||||
char *bmake_strldup(const char *, size_t);
|
||||
#else
|
||||
#include <util.h>
|
||||
#define bmake_malloc(x) emalloc(x)
|
||||
#define bmake_realloc(x,y) erealloc(x,y)
|
||||
#define bmake_strdup(x) estrdup(x)
|
||||
#define bmake_strldup(x,y) estrndup(x,y)
|
||||
#endif
|
||||
char *bmake_strsedup(const char *, const char *);
|
||||
|
||||
/* Thin wrapper around free(3) to avoid the extra function call in case
|
||||
* p is NULL, which on x86_64 costs about 12 machine instructions.
|
||||
* Other platforms are similarly affected.
|
||||
*
|
||||
* The case of a NULL pointer happens especially often after Var_Value,
|
||||
* since only environment variables need to be freed, but not others. */
|
||||
static inline void MAKE_ATTR_UNUSED
|
||||
bmake_free(void *p)
|
||||
{
|
||||
if (p != NULL)
|
||||
free(p);
|
||||
}
|
14
20200902/makefile.in
Normal file
14
20200902/makefile.in
Normal file
@ -0,0 +1,14 @@
|
||||
# $Id: makefile.in,v 1.1 2012/12/28 21:28:19 sjg Exp $
|
||||
|
||||
# a simple makefile for those who don't like anything beyond:
|
||||
# ./configure; make; make install
|
||||
|
||||
prefix= @prefix@
|
||||
srcdir= @srcdir@
|
||||
|
||||
all: build
|
||||
|
||||
build clean install test:
|
||||
${srcdir}/boot-strap --prefix=${prefix} -o . op=$@
|
||||
|
||||
|
1730
20200902/meta.c
Normal file
1730
20200902/meta.c
Normal file
File diff suppressed because it is too large
Load Diff
59
20200902/meta.h
Normal file
59
20200902/meta.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* $NetBSD: meta.h,v 1.7 2020/07/03 08:13:23 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Things needed for 'meta' mode.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2009-2010, Juniper Networks, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
typedef struct BuildMon {
|
||||
char meta_fname[MAXPATHLEN];
|
||||
struct filemon *filemon;
|
||||
int mon_fd;
|
||||
FILE *mfp;
|
||||
} BuildMon;
|
||||
|
||||
extern Boolean useMeta;
|
||||
|
||||
struct Job; /* not defined yet */
|
||||
void meta_init(void);
|
||||
void meta_finish(void);
|
||||
void meta_mode_init(const char *);
|
||||
void meta_job_start(struct Job *, GNode *);
|
||||
void meta_job_child(struct Job *);
|
||||
void meta_job_parent(struct Job *, pid_t);
|
||||
int meta_job_fd(struct Job *);
|
||||
int meta_job_event(struct Job *);
|
||||
void meta_job_error(struct Job *, GNode *, int, int);
|
||||
void meta_job_output(struct Job *, char *, const char *);
|
||||
int meta_cmd_finish(void *);
|
||||
int meta_job_finish(struct Job *);
|
||||
Boolean meta_oodate(GNode *, Boolean);
|
||||
void meta_compat_start(void);
|
||||
void meta_compat_child(void);
|
||||
void meta_compat_parent(pid_t);
|
88
20200902/metachar.c
Normal file
88
20200902/metachar.c
Normal file
@ -0,0 +1,88 @@
|
||||
/* $NetBSD: metachar.c,v 1.6 2020/08/03 20:43:41 rillig Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#if defined(MAKE_NATIVE) || defined(HAVE_NBTOOL_CONFIG_H)
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
__RCSID("$NetBSD: metachar.c,v 1.6 2020/08/03 20:43:41 rillig Exp $");
|
||||
#endif
|
||||
|
||||
#include "metachar.h"
|
||||
/*
|
||||
* The following array is used to make a fast determination of which
|
||||
* characters are interpreted specially by the shell. If a command
|
||||
* contains any of these characters, it is executed by the shell, not
|
||||
* directly by us.
|
||||
*
|
||||
* perhaps move it to ctype?
|
||||
*/
|
||||
|
||||
unsigned char _metachar[128] = {
|
||||
/* nul soh stx etx eot enq ack bel */
|
||||
1, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* bs ht nl vt np cr so si */
|
||||
0, 0, 1, 0, 0, 0, 0, 0,
|
||||
/* dle dc1 dc2 dc3 dc4 nak syn etb */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* can em sub esc fs gs rs us */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* sp ! " # $ % & ' */
|
||||
0, 1, 1, 1, 1, 0, 1, 1,
|
||||
/* ( ) * + , - . / */
|
||||
1, 1, 1, 0, 0, 0, 0, 0,
|
||||
/* 0 1 2 3 4 5 6 7 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 8 9 : ; < = > ? */
|
||||
0, 0, 0, 1, 1, 0, 1, 1,
|
||||
/* @ A B C D E F G */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* H I J K L M N O */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* P Q R S T U V W */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* X Y Z [ \ ] ^ _ */
|
||||
0, 0, 0, 1, 1, 1, 1, 0,
|
||||
/* ` a b c d e f g */
|
||||
1, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* h i j k l m n o */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* p q r s t u v w */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* x y z { | } ~ del */
|
||||
0, 0, 0, 1, 1, 1, 1, 0,
|
||||
};
|
||||
|
52
20200902/metachar.h
Normal file
52
20200902/metachar.h
Normal file
@ -0,0 +1,52 @@
|
||||
/* $NetBSD: metachar.h,v 1.7 2020/08/25 17:37:09 rillig Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef MAKE_METACHAR_H
|
||||
#define MAKE_METACHAR_H
|
||||
|
||||
#include "make.h"
|
||||
|
||||
extern unsigned char _metachar[];
|
||||
|
||||
#define ismeta(c) _metachar[(c) & 0x7f]
|
||||
|
||||
static inline int MAKE_ATTR_UNUSED
|
||||
needshell(const char *cmd, int white)
|
||||
{
|
||||
while (!ismeta(*cmd) && *cmd != ':' && *cmd != '=') {
|
||||
if (white && isspace((unsigned char)*cmd))
|
||||
break;
|
||||
cmd++;
|
||||
}
|
||||
|
||||
return *cmd != '\0';
|
||||
}
|
||||
|
||||
#endif /* MAKE_METACHAR_H */
|
1681
20200902/mk/ChangeLog
Normal file
1681
20200902/mk/ChangeLog
Normal file
File diff suppressed because it is too large
Load Diff
74
20200902/mk/FILES
Normal file
74
20200902/mk/FILES
Normal file
@ -0,0 +1,74 @@
|
||||
ChangeLog
|
||||
FILES
|
||||
LICENSE
|
||||
README
|
||||
auto.obj.mk
|
||||
autoconf.mk
|
||||
autodep.mk
|
||||
auto.dep.mk
|
||||
compiler.mk
|
||||
cython.mk
|
||||
dep.mk
|
||||
doc.mk
|
||||
dpadd.mk
|
||||
files.mk
|
||||
final.mk
|
||||
host-target.mk
|
||||
host.libnames.mk
|
||||
inc.mk
|
||||
init.mk
|
||||
install-mk
|
||||
java.mk
|
||||
ldorder.mk
|
||||
lib.mk
|
||||
libnames.mk
|
||||
libs.mk
|
||||
links.mk
|
||||
man.mk
|
||||
manifest.mk
|
||||
mk-files.txt
|
||||
mkopt.sh
|
||||
nls.mk
|
||||
obj.mk
|
||||
options.mk
|
||||
own.mk
|
||||
prlist.mk
|
||||
prog.mk
|
||||
progs.mk
|
||||
rst2htm.mk
|
||||
scripts.mk
|
||||
srctop.mk
|
||||
stage-install.sh
|
||||
subdir.mk
|
||||
sys.mk
|
||||
sys.clean-env.mk
|
||||
sys.debug.mk
|
||||
sys.dependfile.mk
|
||||
sys.vars.mk
|
||||
sys/AIX.mk
|
||||
sys/Darwin.mk
|
||||
sys/Generic.mk
|
||||
sys/HP-UX.mk
|
||||
sys/IRIX.mk
|
||||
sys/Linux.mk
|
||||
sys/NetBSD.mk
|
||||
sys/OSF1.mk
|
||||
sys/OpenBSD.mk
|
||||
sys/SunOS.mk
|
||||
sys/UnixWare.mk
|
||||
target-flags.mk
|
||||
warnings.mk
|
||||
whats.mk
|
||||
yacc.mk
|
||||
dirdeps.mk
|
||||
dirdeps-cache-update.mk
|
||||
dirdeps-options.mk
|
||||
dirdeps-targets.mk
|
||||
gendirdeps.mk
|
||||
install-new.mk
|
||||
meta2deps.py
|
||||
meta2deps.sh
|
||||
meta.sys.mk
|
||||
meta.autodep.mk
|
||||
meta.stage.mk
|
||||
meta.subdir.mk
|
401
20200902/mk/README
Normal file
401
20200902/mk/README
Normal file
@ -0,0 +1,401 @@
|
||||
# $Id: README,v 1.2 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
This directory contains some macro's derrived from the NetBSD bsd.*.mk
|
||||
macros. They have the same names but without the bsd., separate macro
|
||||
files are needed to ensure we can make them do what we want for
|
||||
builing things outside of /usr/src. Nearly all the comments below
|
||||
apply.
|
||||
|
||||
# $NetBSD: bsd.README,v 1.18 1997/01/13 00:54:23 mark Exp $
|
||||
# @(#)bsd.README 5.1 (Berkeley) 5/11/90
|
||||
|
||||
This is the README file for the new make "include" files for the BSD
|
||||
source tree. The files are installed in /usr/share/mk, and are, by
|
||||
convention, named with the suffix ".mk".
|
||||
|
||||
Note, this file is not intended to replace reading through the .mk
|
||||
files for anything tricky.
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
RANDOM THINGS WORTH KNOWING:
|
||||
|
||||
The files are simply C-style #include files, and pretty much behave like
|
||||
you'd expect. The syntax is slightly different in that a single '.' is
|
||||
used instead of the hash mark, i.e. ".include <bsd.prog.mk>".
|
||||
|
||||
One difference that will save you lots of debugging time is that inclusion
|
||||
of the file is normally done at the *end* of the Makefile. The reason for
|
||||
this is because .mk files often modify variables and behavior based on the
|
||||
values of variables set in the Makefile. To make this work, remember that
|
||||
the FIRST target found is the target that is used, i.e. if the Makefile has:
|
||||
|
||||
a:
|
||||
echo a
|
||||
a:
|
||||
echo a number two
|
||||
|
||||
the command "make a" will echo "a". To make things confusing, the SECOND
|
||||
variable assignment is the overriding one, i.e. if the Makefile has:
|
||||
|
||||
a= foo
|
||||
a= bar
|
||||
|
||||
b:
|
||||
echo ${a}
|
||||
|
||||
the command "make b" will echo "bar". This is for compatibility with the
|
||||
way the V7 make behaved.
|
||||
|
||||
It's fairly difficult to make the BSD .mk files work when you're building
|
||||
multiple programs in a single directory. It's a lot easier split up the
|
||||
programs than to deal with the problem. Most of the agony comes from making
|
||||
the "obj" directory stuff work right, not because we switch to a new version
|
||||
of make. So, don't get mad at us, figure out a better way to handle multiple
|
||||
architectures so we can quit using the symbolic link stuff. (Imake doesn't
|
||||
count.)
|
||||
|
||||
The file .depend in the source directory is expected to contain dependencies
|
||||
for the source files. This file is read automatically by make after reading
|
||||
the Makefile.
|
||||
|
||||
The variable DESTDIR works as before. It's not set anywhere but will change
|
||||
the tree where the file gets installed.
|
||||
|
||||
The profiled libraries are no longer built in a different directory than
|
||||
the regular libraries. A new suffix, ".po", is used to denote a profiled
|
||||
object.
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
The include file <sys.mk> has the default rules for all makes, in the BSD
|
||||
environment or otherwise. You probably don't want to touch this file.
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
The include file <bsd.man.mk> handles installing manual pages and their
|
||||
links.
|
||||
|
||||
It has a single target:
|
||||
|
||||
maninstall:
|
||||
Install the manual pages and their links.
|
||||
|
||||
It sets/uses the following variables:
|
||||
|
||||
MANDIR Base path for manual installation.
|
||||
|
||||
MANGRP Manual group.
|
||||
|
||||
MANOWN Manual owner.
|
||||
|
||||
MANMODE Manual mode.
|
||||
|
||||
MANSUBDIR Subdirectory under the manual page section, i.e. "/vax"
|
||||
or "/tahoe" for machine specific manual pages.
|
||||
|
||||
MAN The manual pages to be installed (use a .1 - .9 suffix).
|
||||
|
||||
MLINKS List of manual page links (using a .1 - .9 suffix). The
|
||||
linked-to file must come first, the linked file second,
|
||||
and there may be multiple pairs. The files are soft-linked.
|
||||
|
||||
The include file <bsd.man.mk> includes a file named "../Makefile.inc" if
|
||||
it exists.
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
The include file <bsd.own.mk> contains source tree configuration parameters,
|
||||
such as the owners, groups, etc. for both manual pages and binaries, and
|
||||
a few global "feature configuration" parameters.
|
||||
|
||||
It has no targets.
|
||||
|
||||
To get system-specific configuration parameters, bsd.own.mk will try to
|
||||
include the file specified by the "MAKECONF" variable. If MAKECONF is not
|
||||
set, or no such file exists, the system make configuration file, /etc/mk.conf
|
||||
is included. These files may define any of the variables described below.
|
||||
|
||||
bsd.own.mk sets the following variables, if they are not already defined
|
||||
(defaults are in brackets):
|
||||
|
||||
BSDSRCDIR The real path to the system sources, so that 'make obj'
|
||||
will work correctly. [/usr/src]
|
||||
|
||||
BSDOBJDIR The real path to the system 'obj' tree, so that 'make obj'
|
||||
will work correctly. [/usr/obj]
|
||||
|
||||
BINGRP Binary group. [bin]
|
||||
|
||||
BINOWN Binary owner. [bin]
|
||||
|
||||
BINMODE Binary mode. [555]
|
||||
|
||||
NONBINMODE Mode for non-executable files. [444]
|
||||
|
||||
MANDIR Base path for manual installation. [/usr/share/man/cat]
|
||||
|
||||
MANGRP Manual group. [bin]
|
||||
|
||||
MANOWN Manual owner. [bin]
|
||||
|
||||
MANMODE Manual mode. [${NONBINMODE}]
|
||||
|
||||
LIBDIR Base path for library installation. [/usr/lib]
|
||||
|
||||
LINTLIBDIR Base path for lint(1) library installation. [/usr/libdata/lint]
|
||||
|
||||
LIBGRP Library group. [${BINGRP}]
|
||||
|
||||
LIBOWN Library owner. [${BINOWN}]
|
||||
|
||||
LIBMODE Library mode. [${NONBINMODE}]
|
||||
|
||||
DOCDIR Base path for system documentation (e.g. PSD, USD, etc.)
|
||||
installation. [/usr/share/doc]
|
||||
|
||||
DOCGRP Documentation group. [bin]
|
||||
|
||||
DOCOWN Documentation owner. [bin]
|
||||
|
||||
DOCMODE Documentation mode. [${NONBINMODE}]
|
||||
|
||||
NLSDIR Base path for National Language Support files installation.
|
||||
[/usr/share/nls]
|
||||
|
||||
NLSGRP National Language Support files group. [bin]
|
||||
|
||||
NLSOWN National Language Support files owner. [bin]
|
||||
|
||||
NLSMODE National Language Support files mode. [${NONBINMODE}]
|
||||
|
||||
STRIP The flag passed to the install program to cause the binary
|
||||
to be stripped. This is to be used when building your
|
||||
own install script so that the entire system can be made
|
||||
stripped/not-stripped using a single knob. [-s]
|
||||
|
||||
COPY The flag passed to the install program to cause the binary
|
||||
to be copied rather than moved. This is to be used when
|
||||
building our own install script so that the entire system
|
||||
can either be installed with copies, or with moves using
|
||||
a single knob. [-c]
|
||||
|
||||
Additionally, the following variables may be set by bsd.own.mk or in a
|
||||
make configuration file to modify the behaviour of the system build
|
||||
process (default values are in brackets along with comments, if set by
|
||||
bsd.own.mk):
|
||||
|
||||
EXPORTABLE_SYSTEM
|
||||
Do not build /usr/src/domestic, even if it is present.
|
||||
|
||||
SKEY Compile in support for S/key authentication. [yes, set
|
||||
unconditionally]
|
||||
|
||||
KERBEROS Compile in support for Kerberos 4 authentication.
|
||||
|
||||
KERBEROS5 Compile in support for Kerberos 5 authentication.
|
||||
|
||||
MANZ Compress manual pages at installation time.
|
||||
|
||||
SYS_INCLUDE Copy or symlink kernel include files into /usr/include.
|
||||
Possible values are "symlinks" or "copies" (which is
|
||||
the same as the variable being unset).
|
||||
|
||||
NOPROFILE Do not build profiled versions of system libraries
|
||||
|
||||
NOPIC Do not build PIC versions of system libraries, and
|
||||
do not build shared libraries. [set if ${MACHINE_ARCH}
|
||||
is "mips", "vax", "alpha" or "arm32", unset otherwise.]
|
||||
|
||||
NOLINT Do not build lint libraries. [set, set unconditionally]
|
||||
|
||||
bsd.own.mk is generally useful when building your own Makefiles so that
|
||||
they use the same default owners etc. as the rest of the tree.
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
The include file <bsd.prog.mk> handles building programs from one or
|
||||
more source files, along with their manual pages. It has a limited number
|
||||
of suffixes, consistent with the current needs of the BSD tree.
|
||||
|
||||
It has eight targets:
|
||||
|
||||
all:
|
||||
build the program and its manual page
|
||||
clean:
|
||||
remove the program, any object files and the files a.out,
|
||||
Errs, errs, mklog, and core.
|
||||
cleandir:
|
||||
remove all of the files removed by the target clean, as
|
||||
well as .depend, tags, and any manual pages.
|
||||
depend:
|
||||
make the dependencies for the source files, and store
|
||||
them in the file .depend.
|
||||
includes:
|
||||
install any header files.
|
||||
install:
|
||||
install the program and its manual pages; if the Makefile
|
||||
does not itself define the target install, the targets
|
||||
beforeinstall and afterinstall may also be used to cause
|
||||
actions immediately before and after the install target
|
||||
is executed.
|
||||
lint:
|
||||
run lint on the source files
|
||||
tags:
|
||||
create a tags file for the source files.
|
||||
|
||||
It sets/uses the following variables:
|
||||
|
||||
BINGRP Binary group.
|
||||
|
||||
BINOWN Binary owner.
|
||||
|
||||
BINMODE Binary mode.
|
||||
|
||||
CLEANFILES Additional files to remove for the clean and cleandir targets.
|
||||
|
||||
COPTS Additional flags to the compiler when creating C objects.
|
||||
|
||||
HIDEGAME If HIDEGAME is defined, the binary is installed in
|
||||
/usr/games/hide, and a symbolic link is created to
|
||||
/usr/games/dm.
|
||||
|
||||
LDADD Additional loader objects. Usually used for libraries.
|
||||
For example, to load with the compatibility and utility
|
||||
libraries, use:
|
||||
|
||||
LDADD+=-lutil -lcompat
|
||||
|
||||
LDFLAGS Additional loader flags.
|
||||
|
||||
LINKS The list of binary links; should be full pathnames, the
|
||||
linked-to file coming first, followed by the linked
|
||||
file. The files are hard-linked. For example, to link
|
||||
/bin/test and /bin/[, use:
|
||||
|
||||
LINKS= ${DESTDIR}/bin/test ${DESTDIR}/bin/[
|
||||
|
||||
MAN Manual pages (should end in .1 - .9). If no MAN variable is
|
||||
defined, "MAN=${PROG}.1" is assumed.
|
||||
|
||||
PROG The name of the program to build. If not supplied, nothing
|
||||
is built.
|
||||
|
||||
SRCS List of source files to build the program. If PROG is not
|
||||
defined, it's assumed to be ${PROG}.c.
|
||||
|
||||
DPADD Additional dependencies for the program. Usually used for
|
||||
libraries. For example, to depend on the compatibility and
|
||||
utility libraries use:
|
||||
|
||||
DPADD+=${LIBCOMPAT} ${LIBUTIL}
|
||||
|
||||
The following libraries are predefined for DPADD:
|
||||
|
||||
LIBC /lib/libc.a
|
||||
LIBCOMPAT /usr/lib/libcompat.a
|
||||
LIBCRYPT /usr/lib/libcrypt.a
|
||||
LIBCURSES /usr/lib/libcurses.a
|
||||
LIBDBM /usr/lib/libdbm.a
|
||||
LIBDES /usr/lib/libdes.a
|
||||
LIBL /usr/lib/libl.a
|
||||
LIBKDB /usr/lib/libkdb.a
|
||||
LIBKRB /usr/lib/libkrb.a
|
||||
LIBKVM /usr/lib/libkvm.a
|
||||
LIBM /usr/lib/libm.a
|
||||
LIBMP /usr/lib/libmp.a
|
||||
LIBPC /usr/lib/libpc.a
|
||||
LIBPLOT /usr/lib/libplot.a
|
||||
LIBRPC /usr/lib/sunrpc.a
|
||||
LIBTERM /usr/lib/libterm.a
|
||||
LIBUTIL /usr/lib/libutil.a
|
||||
|
||||
SHAREDSTRINGS If defined, a new .c.o rule is used that results in shared
|
||||
strings, using xstr(1). Note that this will not work with
|
||||
parallel makes.
|
||||
|
||||
STRIP The flag passed to the install program to cause the binary
|
||||
to be stripped.
|
||||
|
||||
SUBDIR A list of subdirectories that should be built as well.
|
||||
Each of the targets will execute the same target in the
|
||||
subdirectories.
|
||||
|
||||
The include file <bsd.prog.mk> includes the file named "../Makefile.inc"
|
||||
if it exists, as well as the include file <bsd.man.mk>.
|
||||
|
||||
Some simple examples:
|
||||
|
||||
To build foo from foo.c with a manual page foo.1, use:
|
||||
|
||||
PROG= foo
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
To build foo from foo.c with a manual page foo.2, add the line:
|
||||
|
||||
MAN= foo.2
|
||||
|
||||
If foo does not have a manual page at all, add the line:
|
||||
|
||||
NOMAN= noman
|
||||
|
||||
If foo has multiple source files, add the line:
|
||||
|
||||
SRCS= a.c b.c c.c d.c
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
The include file <bsd.subdir.mk> contains the default targets for building
|
||||
subdirectories. It has the same eight targets as <bsd.prog.mk>: all,
|
||||
clean, cleandir, depend, includes, install, lint, and tags. For all of
|
||||
the directories listed in the variable SUBDIRS, the specified directory
|
||||
will be visited and the target made. There is also a default target which
|
||||
allows the command "make subdir" where subdir is any directory listed in
|
||||
the variable SUBDIRS.
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
The include file <bsd.sys.mk> is used by <bsd.prog.mk> and
|
||||
<bsd.lib.mk>. It contains overrides that are used when building
|
||||
the NetBSD source tree. For instance, if "PARALLEL" is defined by
|
||||
the program/library Makefile, it includes a set of rules for lex and
|
||||
yacc that allow multiple lex and yacc targets to be built in parallel.
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
The include file <bsd.lib.mk> has support for building libraries. It has
|
||||
the same eight targets as <bsd.prog.mk>: all, clean, cleandir, depend,
|
||||
includes, install, lint, and tags. It has a limited number of suffixes,
|
||||
consistent with the current needs of the BSD tree.
|
||||
|
||||
It sets/uses the following variables:
|
||||
|
||||
LIB The name of the library to build.
|
||||
|
||||
LIBDIR Target directory for libraries.
|
||||
|
||||
LINTLIBDIR Target directory for lint libraries.
|
||||
|
||||
LIBGRP Library group.
|
||||
|
||||
LIBOWN Library owner.
|
||||
|
||||
LIBMODE Library mode.
|
||||
|
||||
LDADD Additional loader objects.
|
||||
|
||||
MAN The manual pages to be installed (use a .1 - .9 suffix).
|
||||
|
||||
SRCS List of source files to build the library. Suffix types
|
||||
.s, .c, and .f are supported. Note, .s files are preferred
|
||||
to .c files of the same name. (This is not the default for
|
||||
versions of make.)
|
||||
|
||||
The include file <bsd.lib.mk> includes the file named "../Makefile.inc"
|
||||
if it exists, as well as the include file <bsd.man.mk>.
|
||||
|
||||
It has rules for building profiled objects; profiled libraries are
|
||||
built by default.
|
||||
|
||||
Libraries are ranlib'd when made.
|
74
20200902/mk/auto.dep.mk
Normal file
74
20200902/mk/auto.dep.mk
Normal file
@ -0,0 +1,74 @@
|
||||
#
|
||||
# RCSid:
|
||||
# $Id: auto.dep.mk,v 1.6 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2010, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
# This module provides automagic dependency generation along the
|
||||
# lines suggested in the GNU make.info
|
||||
|
||||
# set MKDEP_MK=auto.dep.mk and dep.mk will include us
|
||||
|
||||
# This version differs from autodep.mk, in that
|
||||
# we use ${.TARGET:T}.d rather than ${.TARGET:T:R}.d
|
||||
# this makes it simpler to get the args to -MF and -MT right
|
||||
# and ensure we can simply include all the .d files.
|
||||
#
|
||||
# However suffix rules do not work with something like .o.d so we
|
||||
# don't even try to handle 'make depend' gracefully.
|
||||
# dep.mk will handle that itself.
|
||||
#
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
# this what bmake > 20100401 will look for
|
||||
.MAKE.DEPENDFILE ?= .depend
|
||||
|
||||
# set this to -MMD to ignore /usr/include
|
||||
# actually it ignores <> so may not be a great idea
|
||||
CFLAGS_MD ?= -MD
|
||||
# -MF etc not available on all gcc versions.
|
||||
CFLAGS_MF ?= -MF ${.TARGET:T}.d -MT ${.TARGET:T}
|
||||
CFLAGS += ${CFLAGS_MD} ${CFLAGS_MF}
|
||||
CXXFLAGS += ${CFLAGS_MD} ${CFLAGS_MF}
|
||||
|
||||
CLEANFILES += .depend ${.MAKE.DEPENDFILE} *.d
|
||||
|
||||
.if ${MAKE_VERSION} < 20160218
|
||||
# skip generating dependfile for misc targets
|
||||
.if ${.TARGETS:Uall:M*all} != ""
|
||||
.END: ${.MAKE.DEPENDFILE}
|
||||
.endif
|
||||
|
||||
# doing 'make depend' isn't a big win with this model
|
||||
.if !target(depend)
|
||||
depend: ${.MAKE.DEPENDFILE}
|
||||
.endif
|
||||
|
||||
# this is trivial
|
||||
${.MAKE.DEPENDFILE}: ${OBJS} ${POBJS} ${SOBJS}
|
||||
-@for f in ${.ALLSRC:M*o:T:O:u:%=%.d}; do \
|
||||
echo ".-include \"$$f\""; \
|
||||
done > $@
|
||||
.else
|
||||
# we have .dinclude
|
||||
.if empty(_SKIP_BUILD)
|
||||
_all_objs = ${OBJS} ${POBJS} ${SOBJS}
|
||||
.for d in ${_all_objs:M*o:T:O:u:%=%.d}
|
||||
.dinclude <$d>
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
.endif
|
||||
.endif
|
76
20200902/mk/auto.obj.mk
Normal file
76
20200902/mk/auto.obj.mk
Normal file
@ -0,0 +1,76 @@
|
||||
# $Id: auto.obj.mk,v 1.16 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2004, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
ECHO_TRACE ?= echo
|
||||
|
||||
.ifndef Mkdirs
|
||||
# A race condition in some versions of mkdir, means that it can bail
|
||||
# if another process made a dir that mkdir expected to.
|
||||
# We repeat the mkdir -p a number of times to try and work around this.
|
||||
# We stop looping as soon as the dir exists.
|
||||
# If we get to the end of the loop, a plain mkdir will issue an error.
|
||||
Mkdirs= Mkdirs() { \
|
||||
for d in $$*; do \
|
||||
for i in 1 2 3 4 5 6; do \
|
||||
mkdir -p $$d; \
|
||||
test -d $$d && return 0; \
|
||||
done > /dev/null 2>&1; \
|
||||
mkdir $$d || exit $$?; \
|
||||
done; }
|
||||
.endif
|
||||
|
||||
# if MKOBJDIRS is set to auto (and NOOBJ isn't defined) do some magic...
|
||||
# This will automatically create objdirs as needed.
|
||||
# Skip it if we are just doing 'clean'.
|
||||
.if ${MK_AUTO_OBJ:Uno} == "yes"
|
||||
MKOBJDIRS= auto
|
||||
.endif
|
||||
.if !defined(NOOBJ) && !defined(NO_OBJ) && ${MKOBJDIRS:Uno} == auto
|
||||
# Use __objdir here so it is easier to tweak without impacting
|
||||
# the logic.
|
||||
.if !empty(MAKEOBJDIRPREFIX)
|
||||
.if ${.CURDIR:M${MAKEOBJDIRPREFIX}/*} != ""
|
||||
# we are already in obj tree!
|
||||
__objdir?= ${.CURDIR}
|
||||
.endif
|
||||
__objdir?= ${MAKEOBJDIRPREFIX}${.CURDIR}
|
||||
.endif
|
||||
__objdir?= ${MAKEOBJDIR:Uobj}
|
||||
__objdir:= ${__objdir}
|
||||
.if ${.OBJDIR:tA} != ${__objdir:tA}
|
||||
# We need to chdir, make the directory if needed
|
||||
.if !exists(${__objdir}/) && \
|
||||
(${.TARGETS} == "" || ${.TARGETS:Nclean*:N*clean:Ndestroy*} != "")
|
||||
# This will actually make it...
|
||||
__objdir_made != echo ${__objdir}/; umask ${OBJDIR_UMASK:U002}; \
|
||||
${ECHO_TRACE} "[Creating objdir ${__objdir}...]" >&2; \
|
||||
${Mkdirs}; Mkdirs ${__objdir}
|
||||
.endif
|
||||
# This causes make to use the specified directory as .OBJDIR
|
||||
.OBJDIR: ${__objdir}
|
||||
.if ${.OBJDIR:tA} != ${__objdir:tA}
|
||||
# we did not get what we want - do we care?
|
||||
.if ${__objdir_made:Uno:M${__objdir}/*} != ""
|
||||
# watch out for __objdir being relative path
|
||||
.if !(${__objdir:M/*} == "" && ${.OBJDIR:tA} == ${${.CURDIR}/${__objdir}:L:tA})
|
||||
.error could not use ${__objdir}: .OBJDIR=${.OBJDIR}
|
||||
.endif
|
||||
.endif
|
||||
# apparently we can live with it
|
||||
# make sure we know what we have
|
||||
.OBJDIR: ${.CURDIR}
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
80
20200902/mk/autoconf.mk
Normal file
80
20200902/mk/autoconf.mk
Normal file
@ -0,0 +1,80 @@
|
||||
# $Id: autoconf.mk,v 1.10 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1996-2009, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.NOPATH: config.h config.status
|
||||
|
||||
CONFIGURE_DEPS += ${.CURDIR}/config.h.in ${.CURDIR}/configure
|
||||
|
||||
.if !target(config.h)
|
||||
config.h: ${CONFIGURE_DEPS} config.status
|
||||
./config.status
|
||||
.endif
|
||||
|
||||
.if !target(config.status)
|
||||
# avoid the targets behaving differently
|
||||
.if exists(${.OBJDIR}/config.status)
|
||||
config.status: config.recheck
|
||||
.else
|
||||
config.status: config.gen
|
||||
.endif
|
||||
|
||||
config.recheck: ${CONFIGURE_DEPS}
|
||||
./config.status --recheck
|
||||
@touch $@
|
||||
|
||||
config.gen: ${CONFIGURE_DEPS}
|
||||
CC="${CC} ${CCMODE}" ${.CURDIR}/configure --no-create ${CONFIGURE_ARGS}
|
||||
@touch $@ config.recheck
|
||||
|
||||
CLEANFILES+= config.recheck config.gen config.status *.meta
|
||||
.endif
|
||||
|
||||
# avoid things blowing up if these are not here...
|
||||
# this is not quite per the autoconf manual,
|
||||
# and is extremely convoluted - but all utterly necessary!
|
||||
|
||||
.if make(autoconf-in) || make(configure) || make(config.h.in) || ${AUTO_AUTOCONF:Uno:tl} == "yes"
|
||||
AUTOCONF ?= autoconf
|
||||
AUTOHEADER ?= autoheader
|
||||
|
||||
# expand it to a full path
|
||||
AUTOCONF := ${AUTOCONF:${M_whence}}
|
||||
|
||||
.if exists(${AUTOCONF})
|
||||
|
||||
.PRECIOUS: configure config.h.in config.status
|
||||
|
||||
ACLOCAL =
|
||||
ACCONFIG =
|
||||
|
||||
.if exists(${.CURDIR}/aclocal.m4)
|
||||
ACLOCAL += aclocal.m4
|
||||
.endif
|
||||
# use of acconfig.h is deprecated!
|
||||
.if exists(${.CURDIR}/acconfig.h)
|
||||
ACCONFIG += acconfig.h
|
||||
.endif
|
||||
|
||||
config.h.in: ${.CURDIR}/configure.in ${ACCONFIG}
|
||||
(cd ${.CURDIR} && ${AUTOHEADER})
|
||||
|
||||
configure: ${.CURDIR}/configure.in ${ACLOCAL}
|
||||
(cd ${.CURDIR} && ${AUTOCONF})
|
||||
|
||||
AUTOCONF_INPUTS += configure
|
||||
autoconf-input: ${AUTOCONF_INPUTS}
|
||||
|
||||
.endif
|
||||
.endif
|
219
20200902/mk/autodep.mk
Normal file
219
20200902/mk/autodep.mk
Normal file
@ -0,0 +1,219 @@
|
||||
#
|
||||
# RCSid:
|
||||
# $Id: autodep.mk,v 1.38 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1999-2010, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
|
||||
# This module provides automagic dependency generation along the
|
||||
# lines suggested in the GNU make.info
|
||||
# The depend target is mainly for backwards compatibility,
|
||||
# dependencies are normally updated as part of compilation.
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
DEPENDFILE?= .depend
|
||||
.for d in ${DEPENDFILE:N.depend}
|
||||
# bmake only groks .depend
|
||||
.if ${MAKE_VERSION} < 20160218
|
||||
.-include <$d>
|
||||
.else
|
||||
.dinclude <$d>
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
# it does nothing if SRCS is not defined or is empty
|
||||
.if defined(SRCS) && !empty(SRCS)
|
||||
DEPSRCS?=${SRCS}
|
||||
__depsrcs=${DEPSRCS:M*.c}
|
||||
__depsrcs+=${DEPSRCS:M*.y}
|
||||
__depsrcs+=${DEPSRCS:M*.l}
|
||||
__depsrcs+=${DEPSRCS:M*.s}
|
||||
__depsrcs+=${DEPSRCS:M*.S}
|
||||
__depsrcs+=${DEPSRCS:M*.cc}
|
||||
__depsrcs+=${DEPSRCS:M*.cpp}
|
||||
__depsrcs+=${DEPSRCS:M*.C}
|
||||
__depsrcs+=${DEPSRCS:M*.cxx}
|
||||
__depsrcs+=${DEPSRCS:M*.pc}
|
||||
|
||||
.for s in ${__depsrcs}
|
||||
${s:T:R}.d: $s
|
||||
.endfor
|
||||
|
||||
__depsrcs:=${__depsrcs:T:R:S/$/.d/g}
|
||||
# we also need to handle makefiles where the .d's from __depsrcs
|
||||
# don't match those from OBJS
|
||||
# we avoid using := here, since the modifier applied to OBJS
|
||||
# can cause trouble if there are any undefined vars in OBJS.
|
||||
__dependsrcsx?= ${__depsrcs} ${OBJS:S/.o/.d/}
|
||||
__dependsrcs= ${__dependsrcsx:O:u}
|
||||
|
||||
# clean up any .c files we may have generated
|
||||
#__gensrcs:= ${DEPSRCS:M*.y} ${DEPSRCS:M*.l}
|
||||
#CLEANFILES+= ${__gensrcs:T:R:S/$/.c/g}
|
||||
|
||||
# set this to -MMD to ignore /usr/include
|
||||
# actually it ignores <> so may not be a great idea
|
||||
CFLAGS_MD?=-MD
|
||||
# -MF etc not available on all gcc versions.
|
||||
# we "fix" the .o later
|
||||
CFLAGS_MF?=-MF ${.TARGET:T:R}.d -MT ${.TARGET:T:R}.o
|
||||
CFLAGS+= ${CFLAGS_MD} ${CFLAGS_MF}
|
||||
RM?= rm
|
||||
MAKE_SHELL?= sh
|
||||
|
||||
# watch out for people who don't use CPPFLAGS
|
||||
CPPFLAGS_MD=${CFLAGS:M-[IUD]*} ${CPPFLAGS}
|
||||
CXXFLAGS_MD=${CXXFLAGS:M-[IUD]*} ${CPPFLAGS}
|
||||
|
||||
# just in case these need to be different
|
||||
CC_MD?=${CC}
|
||||
CXX_MD?=${CXX}
|
||||
|
||||
# should have been set by sys.mk
|
||||
CXX_SUFFIXES?= .cc .cpp .cxx .C
|
||||
|
||||
# so we can do an explicit make depend, but not otherwise
|
||||
.if make(depend)
|
||||
.SUFFIXES: .d
|
||||
|
||||
.if empty(CFLAGS_MD)
|
||||
.y.d:
|
||||
@echo updating dependencies for $<
|
||||
@${YACC} ${YFLAGS} $<
|
||||
@${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} y.tab.c | sed '/:/s/^/$@ /' > $@" || { ${RM} -f y.tab.c $@; false; }
|
||||
@${RM} -f y.tab.c
|
||||
|
||||
.l.d:
|
||||
@echo updating dependencies for $<
|
||||
${LEX} ${LFLAGS} $<
|
||||
@${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} lex.yy.c | sed '/:/s/^/$@ /' > $@" || { ${RM} -f lex.yy.c $@; false; }
|
||||
@${RM} -f lex.yy.c
|
||||
|
||||
.c.d:
|
||||
@echo updating dependencies for $<
|
||||
@${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
|
||||
|
||||
.s.d .S.d:
|
||||
@echo updating dependencies for $<
|
||||
@${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} ${AINC} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
|
||||
|
||||
${CXX_SUFFIXES:%=%.d}:
|
||||
@echo updating dependencies for $<
|
||||
@${MAKE_SHELL} -ec "${CXX_MD} -M ${CXXFLAGS_MD} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
|
||||
.else
|
||||
.y.d:
|
||||
${YACC} ${YFLAGS} $<
|
||||
${CC_MD} ${CFLAGS_MD:S/D//} ${CPPFLAGS_MD} y.tab.c > $@ || { ${RM} -f y.tab.c $@; false; }
|
||||
${RM} -f y.tab.c
|
||||
|
||||
.l.d:
|
||||
${LEX} ${LFLAGS} $<
|
||||
${CC_MD} ${CFLAGS_MD:S/D//} ${CPPFLAGS_MD} lex.yy.c > $@ || { ${RM} -f lex.yy.c $@; false; }
|
||||
${RM} -f lex.yy.c
|
||||
|
||||
.c.d:
|
||||
${CC_MD} ${CFLAGS_MD:S/D//} ${CPPFLAGS_MD} $< > $@ || { ${RM} -f $@; false; }
|
||||
|
||||
.s.d .S.d:
|
||||
${CC_MD} ${CFLAGS_MD:S/D//} ${CPPFLAGS_MD} ${AINC} $< > $@ || { ${RM} -f $@; false; }
|
||||
|
||||
${CXX_SUFFIXES:%=%.d}:
|
||||
${CXX_MD} ${CFLAGS_MD:S/D//} ${CXXFLAGS_MD} $< > $@ || { ${RM} -f $@; false; }
|
||||
.endif
|
||||
|
||||
.if !target(depend)
|
||||
depend: beforedepend ${DEPENDFILE} afterdepend _SUBDIRUSE
|
||||
|
||||
${DEPENDFILE}: ${DEPSRCS} ${__dependsrcs}
|
||||
.NOPATH: ${__dependsrcs}
|
||||
.OPTIONAL: ${__dependsrcs}
|
||||
.endif
|
||||
.endif # make(depend)
|
||||
|
||||
.if empty(CFLAGS_MD)
|
||||
# make sure the .d's are generated/updated
|
||||
${PROG} ${_LIBS}: ${DEPENDFILE}
|
||||
.endif
|
||||
|
||||
.ORDER: beforedepend ${DEPENDFILE} afterdepend
|
||||
|
||||
.if ${.OBJDIR} != ${.CURDIR}
|
||||
__depfiles= *.d
|
||||
.else
|
||||
__depfiles= ${__dependsrcs}
|
||||
.endif
|
||||
|
||||
DEPCLEANFILES= ${DEPENDFILE} ${__depfiles} y.tab.d *.tmp.d
|
||||
|
||||
cleandir: cleanautodepend
|
||||
cleanautodepend:
|
||||
${RM} -f ${DEPCLEANFILES}
|
||||
|
||||
CLEANFILES+= ${DEPCLEANFILES}
|
||||
|
||||
.if defined(__dependsrcs) && !empty(__dependsrcs)
|
||||
.if make(depend) || !(make(clean*) || make(destroy*) || make(obj) || make(*install) || make(install-*))
|
||||
# this ensures we do the right thing if only building a shared or
|
||||
# profiled lib
|
||||
OBJ_EXTENSIONS?=.o .po .so .So
|
||||
MDLIB_SED= -e '/:/s,^\([^\.:]*\)\.[psS]*o,${OBJ_EXTENSIONS:S,^,\1,},'
|
||||
.ifdef NOMD_SED
|
||||
.ifdef LIB
|
||||
MD_SED=sed ${MDLIB_SED}
|
||||
.else
|
||||
MD_SED=cat
|
||||
.endif
|
||||
.else
|
||||
# arrange to put some variable names into ${DEPENDFILE}
|
||||
.ifdef LIB
|
||||
MD_SED=sed ${MDLIB_SED}
|
||||
.else
|
||||
MD_SED=sed
|
||||
.endif
|
||||
SUBST_DEPVARS+= SB TOP BACKING SRC SRCDIR BASE BASEDIR
|
||||
.for v in ${SUBST_DEPVARS}
|
||||
.if defined(${v}) && !empty(${v})
|
||||
MD_SED+= -e 's,${$v},$${$v},'
|
||||
.endif
|
||||
.endfor
|
||||
.endif
|
||||
.if (${MD_SED} == "sed")
|
||||
MD_SED=cat
|
||||
.endif
|
||||
|
||||
# this will be done whenever make finishes successfully
|
||||
.if ${MAKE_VERSION:U0:[1]:C/.*-//} < 20050530
|
||||
.END:
|
||||
.else
|
||||
.END: ${DEPENDFILE}
|
||||
# we do not want to trigger building .d's just use them if they exist
|
||||
${DEPENDFILE}: ${__dependsrcs:@d@${exists($d):?$d:}@}
|
||||
.endif
|
||||
-@${MD_SED} ${__depfiles} > ${DEPENDFILE}.new 2> /dev/null && \
|
||||
test -s ${DEPENDFILE}.new && mv ${DEPENDFILE}.new ${DEPENDFILE}; \
|
||||
${RM} -f ${DEPENDFILE}.new
|
||||
.endif
|
||||
.endif
|
||||
.else
|
||||
depend: beforedepend afterdepend _SUBDIRUSE
|
||||
.endif
|
||||
|
||||
.if !target(beforedepend)
|
||||
beforedepend:
|
||||
.endif
|
||||
.if !target(afterdepend)
|
||||
afterdepend:
|
||||
.endif
|
||||
|
||||
.endif
|
43
20200902/mk/compiler.mk
Normal file
43
20200902/mk/compiler.mk
Normal file
@ -0,0 +1,43 @@
|
||||
# $Id: compiler.mk,v 1.7 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2019, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
.if ${MACHINE} == "common"
|
||||
COMPILER_TYPE = none
|
||||
COMPILER_VERSION = 0
|
||||
.endif
|
||||
.if empty(COMPILER_TYPE) || empty(COMPILER_VERSION)
|
||||
# gcc does not always say gcc
|
||||
_v != ${CC} --version 2> /dev/null | \
|
||||
egrep -i 'clang|cc|[1-9]\.[0-9]|Free Software Foundation'
|
||||
.if empty(COMPILER_TYPE)
|
||||
.if ${_v:Mclang} != ""
|
||||
COMPILER_TYPE = clang
|
||||
.elif ${_v:M[Gg][Cc][Cc]} != "" || ${_v:MFoundation*} != ""
|
||||
COMPILER_TYPE = gcc
|
||||
.endif
|
||||
.endif
|
||||
.if empty(COMPILER_VERSION)
|
||||
COMPILER_VERSION != echo "${_v:M[1-9].[0-9]*}:[1]" | \
|
||||
awk -F. '{print $$1 * 10000 + $$2 * 100 + $$3;}'
|
||||
.endif
|
||||
.undef _v
|
||||
.endif
|
||||
# just in case we don't recognize compiler
|
||||
COMPILER_TYPE ?= unknown
|
||||
COMPILER_VERSION ?= 0
|
||||
.endif
|
101
20200902/mk/cython.mk
Normal file
101
20200902/mk/cython.mk
Normal file
@ -0,0 +1,101 @@
|
||||
# RCSid:
|
||||
# $Id: cython.mk,v 1.8 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2014, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
# pyprefix is where python bits are
|
||||
# which may not be where we want to put ours (prefix)
|
||||
.if exists(/usr/pkg/include)
|
||||
pyprefix?= /usr/pkg
|
||||
.endif
|
||||
pyprefix?= /usr/local
|
||||
|
||||
PYTHON_VERSION?= 2.7
|
||||
PYTHON_H?= ${pyprefix}/include/python${PYTHON_VERSION}/Python.h
|
||||
PYVERSION:= ${PYTHON_VERSION:C,\..*,,}
|
||||
|
||||
CFLAGS+= -I${PYTHON_H:H}
|
||||
|
||||
# conf.host_target() is limited to uname -m rather than uname -p
|
||||
_HOST_MACHINE!= uname -m
|
||||
.if ${HOST_TARGET:M*${_HOST_MACHINE}} == ""
|
||||
PY_HOST_TARGET:= ${HOST_TARGET:S,${_HOST_ARCH:U${uname -p:L:sh}}$,${_HOST_MACHINE},}
|
||||
.endif
|
||||
|
||||
COMPILE.c?= ${CC} -c ${CFLAGS}
|
||||
PICO?= .pico
|
||||
|
||||
.SUFFIXES: ${PICO} .c
|
||||
|
||||
.c${PICO}:
|
||||
${COMPILE.c} ${PICFLAG} ${CC_PIC} ${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
# this is what we build
|
||||
.if !empty(CYTHON_MODULE_NAME)
|
||||
CYTHON_MODULE = ${CYTHON_MODULE_NAME}${CYTHON_PYVERSION}.so
|
||||
|
||||
CYTHON_SRCS?= ${CYTHON_MODULE_NAME}.pyx
|
||||
|
||||
# this is where we save generated src
|
||||
CYTHON_SAVEGENDIR?= ${.CURDIR}/gen
|
||||
|
||||
# set this empty if you don't want to handle multiple versions
|
||||
.if !defined(CYTHON_PYVERSION)
|
||||
CYTHON_PYVERSION:= ${PYVERSION}
|
||||
.endif
|
||||
|
||||
CYTHON_GENSRCS= ${CYTHON_SRCS:R:S,$,${CYTHON_PYVERSION}.c,}
|
||||
SRCS+= ${CYTHON_GENSRCS}
|
||||
|
||||
.SUFFIXES: .pyx .c .So
|
||||
|
||||
CYTHON?= ${pyprefix}/bin/cython
|
||||
|
||||
# if we don't have cython we can use pre-generated srcs
|
||||
.if ${type ${CYTHON} 2> /dev/null || echo:L:sh:M/*} == ""
|
||||
.PATH: ${CYTHON_SAVEGENDIR}
|
||||
.else
|
||||
|
||||
.if !empty(CYTHON_PYVERSION)
|
||||
.for c in ${CYTHON_SRCS}
|
||||
${c:R}${CYTHON_PYVERSION}.${c:E}: $c
|
||||
ln -sf ${.ALLSRC:M*pyx} ${.TARGET}
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
.pyx.c:
|
||||
${CYTHON} ${CYTHON_FLAGS} -${PYVERSION} -o ${.TARGET} ${.IMPSRC}
|
||||
|
||||
|
||||
save-gen: ${CYTHON_GENSRCS}
|
||||
mkdir -p ${CYTHON_SAVEGENDIR}
|
||||
cp -p ${.ALLSRC} ${CYTHON_SAVEGENDIR}
|
||||
|
||||
.endif
|
||||
|
||||
${CYTHON_MODULE}: ${SRCS:S,.c,${PICO},}
|
||||
${CC} ${CC_SHARED:U-shared} -o ${.TARGET} ${.ALLSRC:M*${PICO}} ${LDADD}
|
||||
|
||||
MODULE_BINDIR?= ${.CURDIR:H}/${PY_HOST_TARGET:U${HOST_TARGET}}
|
||||
|
||||
build-cython-module: ${CYTHON_MODULE}
|
||||
|
||||
install-cython-module: ${CYTHON_MODULE}
|
||||
test -d ${DESTDIR}${MODULE_BINDIR} || \
|
||||
${INSTALL} -d ${DESTDIR}${MODULE_BINDIR}
|
||||
${INSTALL} -m 755 ${.ALLSRC} ${DESTDIR}${MODULE_BINDIR}
|
||||
|
||||
CLEANFILES+= *${PICO} ${CYTHON_MODULE}
|
||||
|
||||
.endif
|
127
20200902/mk/dep.mk
Normal file
127
20200902/mk/dep.mk
Normal file
@ -0,0 +1,127 @@
|
||||
# $Id: dep.mk,v 1.17 2014/08/04 05:12:27 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
# handle Proc*C as well...
|
||||
.if defined(SRCS)
|
||||
.if !empty(SRCS:M*.pc)
|
||||
.include <proc.mk>
|
||||
.endif
|
||||
|
||||
# it would be nice to be able to query .SUFFIXES
|
||||
OBJ_EXTENSIONS+= .o .po .lo .So
|
||||
|
||||
# explicit dependencies help short-circuit .SUFFIX searches
|
||||
SRCS_DEP_FILTER+= N*.[hly]
|
||||
.for s in ${SRCS:${SRCS_DEP_FILTER:O:u:ts:}}
|
||||
.for e in ${OBJ_EXTENSIONS:O:u}
|
||||
.if !target(${s:T:R}$e)
|
||||
${s:T:R}$e: $s
|
||||
.endif
|
||||
.endfor
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
.if exists(/usr/bin/mkdep)
|
||||
MKDEP_CMD?= mkdep
|
||||
.elif exists(/usr/local/share/bin/mkdeps.sh)
|
||||
MKDEP_CMD?= /usr/local/share/bin/mkdeps.sh -N
|
||||
.endif
|
||||
MKDEP_CMD?= mkdep
|
||||
|
||||
MKDEP ?= ${MKDEP_CMD}
|
||||
|
||||
.NOPATH: .depend
|
||||
|
||||
.if ${MKDEP_MK:Uno} == "auto.dep.mk" && make(depend)
|
||||
# auto.dep.mk does not "do" depend
|
||||
MK_AUTODEP= no
|
||||
.endif
|
||||
|
||||
.if ${MK_AUTODEP} == yes
|
||||
MKDEP_MK ?= autodep.mk
|
||||
.include <${MKDEP_MK}>
|
||||
.else
|
||||
MKDEP_ENV_VARS += CC CXX
|
||||
.for v in ${MKDEP_ENV_VARS:O:u}
|
||||
.if !empty($v)
|
||||
MKDEP_ENV += $v='${$v}'
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
_MKDEP = ${MKDEP_ENV} ${MKDEP}
|
||||
|
||||
# some of the rules involve .h sources, so remove them from mkdep line
|
||||
.if !target(depend)
|
||||
depend: beforedepend .depend _SUBDIRUSE afterdepend
|
||||
|
||||
.if defined(SRCS)
|
||||
# libs can have too many SRCS for a single command line
|
||||
# so do them one at a time.
|
||||
.depend: ${SRCS} ${.PARSEDIR}/${.PASEFILE}
|
||||
@rm -f .depend
|
||||
.ifdef LIB
|
||||
@files="${.ALLSRC:M*.[sS]}"; \
|
||||
set -x; for f in $$files; do ${_MKDEP} -a ${MKDEPFLAGS} \
|
||||
${CFLAGS:M-[ID]*} ${CPPFLAGS} ${AINC} $$f; done
|
||||
@files="${.ALLSRC:M*.c} ${.ALLSRC:M*.pc:T:.pc=.c}"; \
|
||||
set -x; for f in $$files; do ${_MKDEP} -a ${MKDEPFLAGS} \
|
||||
${CFLAGS:M-[ID]*} ${CPPFLAGS} $$f; done
|
||||
@files="${.ALLSRC:M*.cc} ${.ALLSRC:M*.C} ${.ALLSRC:M*.cxx}"; \
|
||||
set -x; for f in $$files; do ${_MKDEP} -a ${MKDEPFLAGS} \
|
||||
${CXXFLAGS:M-[ID]*} ${CPPFLAGS} $$f; done
|
||||
.else
|
||||
@files="${.ALLSRC:M*.[Ss]}"; \
|
||||
case "$$files" in *.[Ss]*) \
|
||||
echo ${_MKDEP} -a ${MKDEPFLAGS} \
|
||||
${CFLAGS:M-[ID]*} ${CPPFLAGS} ${AINC} $$files; \
|
||||
${_MKDEP} -a ${MKDEPFLAGS} \
|
||||
${CFLAGS:M-[ID]*} ${CPPFLAGS} ${AINC} $$files;; \
|
||||
esac
|
||||
@files="${.ALLSRC:M*.c} ${.ALLSRC:M*.pc:T:.pc=.c}"; \
|
||||
case "$$files" in *.c*) \
|
||||
echo ${_MKDEP} -a ${MKDEPFLAGS} \
|
||||
${CFLAGS:M-[ID]*} ${CPPFLAGS} $$files; \
|
||||
${_MKDEP} -a ${MKDEPFLAGS} \
|
||||
${CFLAGS:M-[ID]*} ${CPPFLAGS} $$files;; \
|
||||
esac
|
||||
@files="${.ALLSRC:M*.cc} ${.ALLSRC:M*.C} ${.ALLSRC:M*.cxx}"; \
|
||||
case "$$files" in *.[Cc]*) \
|
||||
echo ${_MKDEP} -a ${MKDEPFLAGS} \
|
||||
${CXXFLAGS:M-[ID]*} ${CPPFLAGS} $$files; \
|
||||
${_MKDEP} -a ${MKDEPFLAGS} \
|
||||
${CXXFLAGS:M-[ID]*} ${CPPFLAGS} $$files;; \
|
||||
esac
|
||||
.endif
|
||||
.else
|
||||
.depend:
|
||||
.endif
|
||||
.if !target(beforedepend)
|
||||
beforedepend:
|
||||
.endif
|
||||
.if !target(afterdepend)
|
||||
afterdepend:
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if !target(tags)
|
||||
.if defined(SRCS)
|
||||
tags: ${SRCS} _SUBDIRUSE
|
||||
-cd ${.CURDIR}; ctags -f /dev/stdout ${.ALLSRC:N*.h} | \
|
||||
sed "s;\${.CURDIR}/;;" > tags
|
||||
.else
|
||||
tags:
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if defined(SRCS)
|
||||
cleandir: cleandepend
|
||||
.if !target(cleandepend)
|
||||
cleandepend:
|
||||
rm -f .depend ${.CURDIR}/tags
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.endif
|
179
20200902/mk/dirdeps-cache-update.mk
Normal file
179
20200902/mk/dirdeps-cache-update.mk
Normal file
@ -0,0 +1,179 @@
|
||||
# $Id: dirdeps-cache-update.mk,v 1.21 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2020, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
##
|
||||
#
|
||||
# This makefile deals with the updating of STATIC_DIRDEPS_CACHE.
|
||||
# Some targets are so huge that computing dirdeps takes a significant
|
||||
# amount of time. For such targets a STATIC_DIRDEPS_CACHE can make
|
||||
# sense.
|
||||
#
|
||||
# If the target is represented by targets/pseudo/production
|
||||
# it's normal DIRDEPS would be in
|
||||
# targets/pseudo/production/Makefile.depend
|
||||
# and STATIC_DIRDEPS_CACHE would be
|
||||
# targets/pseudo/production/Makefile.dirdeps.cache
|
||||
# which is simply initialized by copying dirdeps.cache.production
|
||||
# from $OBJTOP
|
||||
#
|
||||
# When dirdeps-targets.mk is initializing DIRDEPS it will look for
|
||||
# Makefile.dirdeps.cache and unless told not to
|
||||
# (MK_STATIC_DIRDEPS_CACHE=no) will use it as DIRDEPS_CACHE.
|
||||
#
|
||||
# If MK_STATIC_DIRDEPS_CACHE_UPDATE is "yes", then this makefile
|
||||
# comes into play.
|
||||
#
|
||||
# We usually get included from local.dirdeps.mk
|
||||
# as well as Makefile.depend of RELDIR with a static Makefile.dirdeps.cache
|
||||
#
|
||||
# If we see that STATIC_DIRDEPS_CACHE is in use, we need to hook a
|
||||
# cache-update target into the build to regenerate dirdeps.cache
|
||||
# in parallel with the rest of the build.
|
||||
# If MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE is "yes" we update
|
||||
# STATIC_DIRDEPS_CACHE as soon as the update is ready,
|
||||
# otherwise it will be done at the end of the build.
|
||||
#
|
||||
# If STATIC_DIRDEPS_CACHE is not in use, but a DIRDEPS_CACHE is,
|
||||
# then we need do nothing except export STATIC_DIRDEPS_CACHE and
|
||||
# DYNAMIC_DIRDEPS_CACHE for use when we are include during the visit
|
||||
# to the ultimate target (targets/pseudo/production).
|
||||
#
|
||||
# Regardless of which happens, when included at .MAKE.LEVEL > 0
|
||||
# for a target other than cache-update we simply copy
|
||||
# DYNAMIC_DIRDEPS_CACHE to STATIC_DIRDEPS_CACHE with some optional
|
||||
# filtering.
|
||||
#
|
||||
# If we are included for the target cache-update we take care of
|
||||
# running dirdeps.mk again to generate the DYNAMIC_DIRDEPS_CACHE.
|
||||
#
|
||||
|
||||
.if !target(_${.PARSEFILE}_)
|
||||
_${.PARSEFILE}_: .NOTMAIN
|
||||
|
||||
STATIC_CACHE_SED += \
|
||||
-e '/Autogenerated/s,-.*,- edit with care!,' \
|
||||
-e '/cache-update/d'
|
||||
|
||||
STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT ?= \
|
||||
{ echo Saving ${DYNAMIC_DIRDEPS_CACHE} as ${STATIC_DIRDEPS_CACHE}; \
|
||||
sed ${STATIC_CACHE_SED} ${DYNAMIC_DIRDEPS_CACHE} > ${STATIC_DIRDEPS_CACHE}; }
|
||||
.endif
|
||||
|
||||
.if ${MK_DIRDEPS_CACHE:Uno} == "yes"
|
||||
.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE:Uno} == "yes"
|
||||
.if ${_debug_reldir:U0} || ${DEBUG_DIRDEPS:U:Mcache*} != ""
|
||||
_debug_cache = 1
|
||||
.else
|
||||
_debug_cache = 0
|
||||
.endif
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0 && !make(cache-update)
|
||||
|
||||
.if ${_debug_cache}
|
||||
.info ${MK_STATIC_DIRDEPS_CACHE_UPDATE MK_STATIC_DIRDEPS_CACHE MK_DIRDEPS_CACHE DIRDEPS_CACHE STATIC_DIRDEPS_CACHE:L:@v@$v=${$v}@}
|
||||
.endif
|
||||
|
||||
.if ${MK_STATIC_DIRDEPS_CACHE} == "yes" && defined(STATIC_DIRDEPS_CACHE) && exists(${STATIC_DIRDEPS_CACHE})
|
||||
.if !make(dirdeps)
|
||||
# We are using static cache and this is the only look we will get.
|
||||
# We want to generate an updated cache while we build
|
||||
# so need to hook cache-update to dirdeps now.
|
||||
# Note: we are running as a sibling to dirdeps-cached,
|
||||
# attempting to do this in that context is problematic.
|
||||
|
||||
# One of these should exist - to actually kick off the cache generation
|
||||
.for d in ${STATIC_DIRDEPS_CACHE:H}/cache-update ${STATIC_DIRDEPS_CACHE:H:H}/cache-update ${STATIC_DIRDEPS_CACHE:H:H:H}/cache-update
|
||||
.if exists($d)
|
||||
cache_update_dirdep ?= $d.${TARGET_SPEC}
|
||||
.endif
|
||||
.endfor
|
||||
.if !target(${cache_update_dirdep})
|
||||
dirdeps: ${cache_update_dirdep}
|
||||
${cache_update_dirdep}: _DIRDEP_USE
|
||||
DYNAMIC_DIRDEPS_CACHE := ${OBJTOP}/dirdeps.cache.${STATIC_DIRDEPS_CACHE:H:T}-update
|
||||
.export DYNAMIC_DIRDEPS_CACHE STATIC_DIRDEPS_CACHE
|
||||
.endif
|
||||
.endif # make(dirdeps)
|
||||
.endif # MK_*
|
||||
|
||||
.endif # .MAKE.LEVEL 0
|
||||
|
||||
.if ${.MAKE.LEVEL} > 0 && ${.CURDIR:T} == "cache-update"
|
||||
# we are the background update shim
|
||||
|
||||
.if ${_debug_cache}
|
||||
.info level ${.MAKE.LEVEL}: ${MK_DIRDEPS_CACHE DYNAMIC_DIRDEPS_CACHE STATIC_DIRDEPS_CACHE:L:@v@$v=${$v}@}
|
||||
.endif
|
||||
|
||||
all: cache-build
|
||||
cache-build: .META
|
||||
@set -x; MAKELEVEL=0 \
|
||||
${.MAKE} -C ${SRCTOP} -f ${RELDIR}/Makefile cache-update \
|
||||
-DWITHOUT_STATIC_DIRDEPS_CACHE_UPDATE
|
||||
|
||||
.endif # cache-update
|
||||
|
||||
.elif ${.MAKE.LEVEL} == 0 && make(cache-update) && !target(cache-update)
|
||||
# we were invoked above
|
||||
# we just leverage dirdeps.mk
|
||||
BUILD_DIRDEPS_TARGETS := ${STATIC_DIRDEPS_CACHE:H:T}
|
||||
DIRDEPS := ${STATIC_DIRDEPS_CACHE:H:S,^${SRCTOP}/,,}.${TARGET_SPEC}
|
||||
DIRDEPS_CACHE := ${DYNAMIC_DIRDEPS_CACHE}
|
||||
|
||||
.if ${DEBUG_DIRDEPS:U:Mcache*} != ""
|
||||
.info level 0: ${MK_DIRDEPS_CACHE DIRDEPS_CACHE DIRDEPS:L:@v@$v=${$v}@}
|
||||
.endif
|
||||
|
||||
# so cache-built below can check on us
|
||||
x!= echo; echo ${.MAKE.PID} > ${DIRDEPS_CACHE}.new.pid
|
||||
|
||||
cache-update: ${DIRDEPS_CACHE}
|
||||
@rm -f ${DIRDEPS_CACHE}.new.pid
|
||||
.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE:Uno} == "yes"
|
||||
${STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT}
|
||||
.endif
|
||||
|
||||
all:
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.endif # MK_STATIC_DIRDEPS_CACHE_UPDATE
|
||||
.endif # MK_DIRDEPS_CACHE
|
||||
|
||||
.if ${.MAKE.LEVEL} > 0 && ${MK_STATIC_DIRDEPS_CACHE_UPDATE:Uno} == "yes" && \
|
||||
${STATIC_DIRDEPS_CACHE:Uno:H} == "${SRCTOP}/${RELDIR}"
|
||||
.if !defined(DYNAMIC_DIRDEPS_CACHE)
|
||||
all:
|
||||
.else
|
||||
# This is the easy bit, time to save the cache
|
||||
|
||||
all: cache-update
|
||||
|
||||
# ensure the cache update is completed
|
||||
cache-built:
|
||||
@test -s ${DYNAMIC_DIRDEPS_CACHE}.new || exit 0; \
|
||||
pid=`cat ${DYNAMIC_DIRDEPS_CACHE}.new.pid 2> /dev/null`; \
|
||||
test $${pid:-0} -gt 1 || exit 0; \
|
||||
echo "Waiting for $$pid to finish ${DYNAMIC_DIRDEPS_CACHE} ..."; \
|
||||
while 'kill' -0 $$pid; do sleep 30; done > /dev/null 2>&1
|
||||
|
||||
cache-update: cache-built
|
||||
.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE:Uno} == "no"
|
||||
@test ! -s ${DYNAMIC_DIRDEPS_CACHE} || \
|
||||
${STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT}
|
||||
.endif
|
||||
|
||||
.endif
|
||||
.endif
|
100
20200902/mk/dirdeps-options.mk
Normal file
100
20200902/mk/dirdeps-options.mk
Normal file
@ -0,0 +1,100 @@
|
||||
# $Id: dirdeps-options.mk,v 1.17 2020/08/07 01:57:38 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2018-2020, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
##
|
||||
#
|
||||
# This makefile is used to deal with optional DIRDEPS.
|
||||
#
|
||||
# It is to be included by Makefile.depend.options in a
|
||||
# directory which has DIRDEPS affected by optional features.
|
||||
# Makefile.depend.options should set DIRDEPS_OPTIONS and
|
||||
# may also set specific DIRDEPS.* for those options.
|
||||
#
|
||||
# If a Makefile.depend.options file exists, it will be included by
|
||||
# dirdeps.mk and meta.autodep.mk
|
||||
#
|
||||
# We include local.dirdeps-options.mk which may also define DIRDEPS.*
|
||||
# for options.
|
||||
#
|
||||
# Thus a directory, that is affected by an option FOO would have
|
||||
# a Makefile.depend.options that sets
|
||||
# DIRDEPS_OPTIONS= FOO
|
||||
# It can also set either/both of
|
||||
# DIRDEPS.FOO.yes
|
||||
# DIRDEPS.FOO.no
|
||||
# to whatever applies for that dir, or it can rely on globals
|
||||
# set in local.dirdeps-options.mk
|
||||
# Either way, we will .undef DIRDEPS.* when done.
|
||||
#
|
||||
# In some cases the value of MK_FOO might depend on TARGET_SPEC
|
||||
# so we qualify MK_FOO with .${TARGET_SPEC} and each component
|
||||
# TARGET_SPEC_VAR (in reverse order) before using MK_FOO.
|
||||
#
|
||||
|
||||
# This should have been set by Makefile.depend.options
|
||||
# before including us
|
||||
DIRDEPS_OPTIONS ?=
|
||||
|
||||
# pickup any DIRDEPS.* we need
|
||||
.-include <local.dirdeps-options.mk>
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0
|
||||
# :U below avoids potential errors when we :=
|
||||
# some options can depend on TARGET_SPEC!
|
||||
DIRDEPS_OPTIONS_QUALIFIER_LIST ?= \
|
||||
${DEP_TARGET_SPEC:U${TARGET_SPEC}} \
|
||||
${TARGET_SPEC_VARSr:U${TARGET_SPEC_VARS}:@v@${DEP_$v:U${$v}}@}
|
||||
# note that we need to include $o in the variable _o$o
|
||||
# to ensure correct evaluation.
|
||||
.for o in ${DIRDEPS_OPTIONS}
|
||||
.undef _o$o _v$o
|
||||
.for x in ${DIRDEPS_OPTIONS_QUALIFIER_LIST}
|
||||
.if defined(MK_$o.$x)
|
||||
_o$o ?= MK_$o.$x
|
||||
_v$o ?= ${MK_$o.$x}
|
||||
.endif
|
||||
.endfor
|
||||
_v$o ?= ${MK_$o}
|
||||
.if ${_debug_reldir:U0}
|
||||
.info ${DEP_RELDIR:U${RELDIR}}.${DEP_TARGET_SPEC:U${TARGET_SPEC}}: o=$o ${_o$o:UMK_$o}=${_v$o:U} DIRDEPS += ${DIRDEPS.$o.${_v$o:U}:U}
|
||||
.endif
|
||||
DIRDEPS += ${DIRDEPS.$o.${_v$o:U}:U}
|
||||
.endfor
|
||||
DIRDEPS := ${DIRDEPS:O:u}
|
||||
.if ${_debug_reldir:U0}
|
||||
.info ${DEP_RELDIR:U${RELDIR}}: DIRDEPS=${DIRDEPS}
|
||||
.endif
|
||||
# avoid cross contamination
|
||||
.for o in ${DIRDEPS_OPTIONS}
|
||||
.undef DIRDEPS.$o.yes
|
||||
.undef DIRDEPS.$o.no
|
||||
.undef _o$o
|
||||
.undef _v$o
|
||||
.endfor
|
||||
.else
|
||||
# whether options are enabled or not,
|
||||
# we want to filter out the relevant DIRDEPS.*
|
||||
# we should only be included by meta.autodep.mk
|
||||
# if dependencies are to be updated
|
||||
.for o in ${DIRDEPS_OPTIONS}
|
||||
.for d in ${DIRDEPS.$o.yes} ${DIRDEPS.$o.no}
|
||||
.if exists(${SRCTOP}/$d)
|
||||
GENDIRDEPS_FILTER += N$d*
|
||||
.elif exists(${SRCTOP}/${d:R})
|
||||
GENDIRDEPS_FILTER += N${d:R}*
|
||||
.endif
|
||||
.endfor
|
||||
.endfor
|
||||
.endif
|
171
20200902/mk/dirdeps-targets.mk
Normal file
171
20200902/mk/dirdeps-targets.mk
Normal file
@ -0,0 +1,171 @@
|
||||
# RCSid:
|
||||
# $Id: dirdeps-targets.mk,v 1.22 2020/08/15 18:00:11 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2019-2020 Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
##
|
||||
# This makefile is used to set initial DIRDEPS for top-level build
|
||||
# targets.
|
||||
#
|
||||
# The basic idea is that we have a list of directories in
|
||||
# DIRDEPS_TARGETS_DIRS which are relative to SRCTOP.
|
||||
# When asked to make 'foo' we look for any directory named 'foo'
|
||||
# under DIRDEPS_TARGETS_DIRS.
|
||||
# We then search those dirs for any Makefile.depend*
|
||||
# Finally we select any that match conditions like REQUESTED_MACHINE
|
||||
# or TARGET_SPEC and initialize DIRDEPS accordingly.
|
||||
#
|
||||
# We will check each of the initial DIRDEPS for Makefile.dirdeps.options
|
||||
# and include any found.
|
||||
# This makes it feasible to tweak options like MK_DIRDEPS_CACHE
|
||||
# for a specific target.
|
||||
#
|
||||
# If MK_STATIC_DIRDEPS_CACHE is defined we will check if the
|
||||
# initial DIRDEPS has a static cache (Makefile.dirdeps.cache).
|
||||
# This only makes sense for seriously expensive targets.
|
||||
#
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0
|
||||
# pickup customizations
|
||||
.-include <local.dirdeps-targets.mk>
|
||||
|
||||
# for DIRDEPS_BUILD this is how we prime the pump
|
||||
DIRDEPS_TARGETS_DIRS ?= targets targets/pseudo
|
||||
# these prefixes can modify how we behave
|
||||
# they need to be stripped when looking for target dirs
|
||||
DIRDEPS_TARGETS_PREFIX_LIST ?= pkg- build-
|
||||
|
||||
# some .TARGETS need filtering
|
||||
DIRDEPS_TARGETS_FILTER += Nall
|
||||
|
||||
# matching target dirs if any
|
||||
tdirs := ${.TARGETS:${DIRDEPS_TARGETS_FILTER:ts:}:${DIRDEPS_TARGETS_PREFIX_LIST:@p@S,^$p,,@:ts:}:@t@${DIRDEPS_TARGETS_DIRS:@d@$d/$t@}@:@d@${exists(${SRCTOP}/$d):?$d:}@}
|
||||
|
||||
.if !empty(DEBUG_DIRDEPS_TARGETS)
|
||||
.info tdirs=${tdirs}
|
||||
.endif
|
||||
|
||||
.if !empty(tdirs)
|
||||
# some things we know we want to ignore
|
||||
DIRDEPS_TARGETS_SKIP_LIST += \
|
||||
*~ \
|
||||
*.bak \
|
||||
*.inc \
|
||||
*.old \
|
||||
*.options \
|
||||
*.orig \
|
||||
*.rej \
|
||||
|
||||
# the list of MACHINEs we consider
|
||||
DIRDEPS_TARGETS_MACHINE_LIST += \
|
||||
${ALL_MACHINE_LIST:U} \
|
||||
${PSEUDO_MACHINE_LIST:Ucommon host host32} \
|
||||
${TARGET_MACHINE_LIST}
|
||||
|
||||
DIRDEPS_TARGETS_MACHINE_LIST := ${DIRDEPS_TARGETS_MACHINE_LIST:O:u}
|
||||
|
||||
# raw Makefile.depend* list
|
||||
tdeps != 'cd' ${SRCTOP} && 'ls' -1 ${tdirs:O:u:@d@$d/${.MAKE.DEPENDFILE_PREFIX}*@} 2> /dev/null; echo
|
||||
.if ${DEBUG_DIRDEPS_TARGETS:U:Mdep*} != ""
|
||||
.info tdeps=${tdeps}
|
||||
.endif
|
||||
# remove things we know we don't want
|
||||
tdeps := ${tdeps:${DIRDEPS_TARGETS_SKIP_LIST:${M_ListToSkip}}}
|
||||
.if ${DEBUG_DIRDEPS_TARGETS:U:Mdep*} != ""
|
||||
.info tdeps=${tdeps}
|
||||
.endif
|
||||
|
||||
# plain entries (no qualifiers) these apply to any TARGET_SPEC
|
||||
ptdeps := ${tdeps:M*${.MAKE.DEPENDFILE_PREFIX}:S,/${.MAKE.DEPENDFILE_PREFIX},,}
|
||||
|
||||
# MACHINE qualified entries
|
||||
mqtdeps := ${DIRDEPS_TARGETS_MACHINE_LIST:@m@${tdeps:M*.$m}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
|
||||
|
||||
tqtdeps =
|
||||
.if ${TARGET_SPEC_VARS:[#]} > 1
|
||||
# TARGET_SPEC qualified entries
|
||||
.if !empty(TARGET_SPEC_LIST)
|
||||
# we have a list of valid TARGET_SPECS; use it
|
||||
tqtdeps := ${TARGET_SPEC_LIST:U:O:u:@t@${tdeps:M*.$t}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
|
||||
.else
|
||||
# do we have a list of valid tuple members for at least
|
||||
# the last tupple element? if so match on that
|
||||
TARGET_SPEC_LAST_LIST ?= ${${TARGET_SPEC_VARS:[-1]}_LIST}
|
||||
.if !empty(TARGET_SPEC_LAST_LIST)
|
||||
tqtdeps := ${TARGET_SPEC_LAST_LIST:U:O:u:@t@${tdeps:M*,$t}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
|
||||
.else
|
||||
# this is sub-optimal match MACHINE,
|
||||
tqtdeps := ${DIRDEPS_TARGETS_MACHINE_LIST:@m@${tdeps:M*.$m,*}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# now work out what we want in DIRDEPS
|
||||
.if empty(REQUESTED_MACHINE)
|
||||
# we want them all just as found
|
||||
DIRDEPS = ${ptdeps} ${mqtdeps} ${tqtdeps}
|
||||
.else
|
||||
# we only want those that match REQUESTED_MACHINE/REQUESTED_TARGET_SPEC
|
||||
# or REQUESTED_TARGET_SPEC (TARGET_SPEC)
|
||||
DIRDEPS = \
|
||||
${ptdeps:@d@$d.${REQUESTED_TARGET_SPEC:U${TARGET_SPEC:U${REQUESTED_MACHINE}}}@} \
|
||||
${mqtdeps:M*.${REQUESTED_MACHINE}} \
|
||||
${tqtdeps:M*.${REQUESTED_TARGET_SPEC:U${TARGET_SPEC}}}
|
||||
.endif
|
||||
# clean up
|
||||
DIRDEPS := ${DIRDEPS:O:u}
|
||||
|
||||
.if !empty(DEBUG_DIRDEPS_TARGETS)
|
||||
.for x in tdeps ptdeps mqtdeps tqtdeps DIRDEPS
|
||||
.info $x=${$x}
|
||||
.endfor
|
||||
.endif
|
||||
.endif
|
||||
# if we got DIRDEPS get to work
|
||||
.if !empty(DIRDEPS)
|
||||
DIRDEPS.dirs := ${DIRDEPS:S,^,${SRCTOP}/,:@d@${exists($d):?$d:${d:R}}@}
|
||||
# some targets what to tweak options we might want to process now
|
||||
.for m in ${DIRDEPS.dirs:S,$,/Makefile.dirdeps.options,}
|
||||
.-include <$m>
|
||||
.endfor
|
||||
.if defined(MK_STATIC_DIRDEPS_CACHE)
|
||||
# some targets are very expensive to compute dirdeps for
|
||||
# so we may have a static cache
|
||||
.for c in ${DIRDEPS.dirs:S,$,/Makefile.dirdeps.cache,}
|
||||
.if exists($c)
|
||||
STATIC_DIRDEPS_CACHE ?= $c
|
||||
.if ${MK_STATIC_DIRDEPS_CACHE} == "yes"
|
||||
DIRDEPS_CACHE ?= $c
|
||||
MK_DIRDEPS_CACHE = yes
|
||||
.endif
|
||||
.endif
|
||||
.endfor
|
||||
.if defined(STATIC_DIRDEPS_CACHE)
|
||||
.export STATIC_DIRDEPS_CACHE
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# allow a top-level makefile to do other stuff
|
||||
# before including dirdeps.mk
|
||||
.if ${MK_DIRDEPS_TARGETS_INCLUDE_DIRDEPS:Uyes} == "yes"
|
||||
.include <dirdeps.mk>
|
||||
.endif
|
||||
|
||||
DIRDEPS_TARGETS_SKIP += all clean* destroy*
|
||||
|
||||
.for t in ${.TARGETS:${DIRDEPS_TARGETS_SKIP:${M_ListToSkip}}}
|
||||
$t: dirdeps
|
||||
.endfor
|
||||
.endif
|
||||
.endif
|
867
20200902/mk/dirdeps.mk
Normal file
867
20200902/mk/dirdeps.mk
Normal file
@ -0,0 +1,867 @@
|
||||
# $Id: dirdeps.mk,v 1.125 2020/08/26 21:49:45 sjg Exp $
|
||||
|
||||
# Copyright (c) 2010-2020, Simon J. Gerraty
|
||||
# Copyright (c) 2010-2018, Juniper Networks, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Much of the complexity here is for supporting cross-building.
|
||||
# If a tree does not support that, simply using plain Makefile.depend
|
||||
# should provide sufficient clue.
|
||||
# Otherwise the recommendation is to use Makefile.depend.${MACHINE}
|
||||
# as expected below.
|
||||
|
||||
# Note: this file gets multiply included.
|
||||
# This is what we do with DIRDEPS
|
||||
|
||||
# DIRDEPS:
|
||||
# This is a list of directories - relative to SRCTOP, it is
|
||||
# normally only of interest to .MAKE.LEVEL 0.
|
||||
# In some cases the entry may be qualified with a .<machine>
|
||||
# or .<target_spec> suffix (see TARGET_SPEC_VARS below),
|
||||
# for example to force building something for the pseudo
|
||||
# machines "host" or "common" regardless of current ${MACHINE}.
|
||||
#
|
||||
# All unqualified entries end up being qualified with .${TARGET_SPEC}
|
||||
# and partially qualified (if TARGET_SPEC_VARS has multiple
|
||||
# entries) are also expanded to a full .<target_spec>.
|
||||
# The _DIRDEP_USE target uses the suffix to set TARGET_SPEC
|
||||
# correctly when visiting each entry.
|
||||
#
|
||||
# The fully qualified directory entries are used to construct a
|
||||
# dependency graph that will drive the build later.
|
||||
#
|
||||
# Also, for each fully qualified directory target, we will search
|
||||
# using ${.MAKE.DEPENDFILE_PREFERENCE} to find additional
|
||||
# dependencies. We use Makefile.depend (default value for
|
||||
# .MAKE.DEPENDFILE_PREFIX) to refer to these makefiles to
|
||||
# distinguish them from others.
|
||||
#
|
||||
# Before each Makefile.depend file is read, we set
|
||||
# DEP_RELDIR to be the RELDIR (path relative to SRCTOP) for
|
||||
# its directory, and DEP_MACHINE etc according to the .<target_spec>
|
||||
# represented by the suffix of the corresponding target.
|
||||
#
|
||||
# Since each Makefile.depend file includes dirdeps.mk, this
|
||||
# processing is recursive and results in .MAKE.LEVEL 0 learning the
|
||||
# dependencies of the tree wrt the initial directory (_DEP_RELDIR).
|
||||
#
|
||||
# TARGET_SPEC_VARS
|
||||
# The default value is just MACHINE, and for most environments
|
||||
# this is sufficient. The _DIRDEP_USE target actually sets
|
||||
# both MACHINE and TARGET_SPEC to the suffix of the current
|
||||
# target so that in the general case TARGET_SPEC can be ignored.
|
||||
#
|
||||
# If more than MACHINE is needed then sys.mk needs to decompose
|
||||
# TARGET_SPEC and set the relevant variables accordingly.
|
||||
# It is important that MACHINE be included in and actually be
|
||||
# the first member of TARGET_SPEC_VARS. This allows other
|
||||
# variables to be considered optional, and some of the treatment
|
||||
# below relies on MACHINE being the first entry.
|
||||
# Note: TARGET_SPEC cannot contain any '.'s so the target
|
||||
# triple used by compiler folk won't work (directly anyway).
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# # Always list MACHINE first,
|
||||
# # other variables might be optional.
|
||||
# TARGET_SPEC_VARS = MACHINE TARGET_OS
|
||||
# .if ${TARGET_SPEC:Uno:M*,*} != ""
|
||||
# _tspec := ${TARGET_SPEC:S/,/ /g}
|
||||
# MACHINE := ${_tspec:[1]}
|
||||
# TARGET_OS := ${_tspec:[2]}
|
||||
# # etc.
|
||||
# # We need to stop that TARGET_SPEC affecting any submakes
|
||||
# # and deal with MACHINE=${TARGET_SPEC} in the environment.
|
||||
# TARGET_SPEC =
|
||||
# # export but do not track
|
||||
# .export-env TARGET_SPEC
|
||||
# .export ${TARGET_SPEC_VARS}
|
||||
# .for v in ${TARGET_SPEC_VARS:O:u}
|
||||
# .if empty($v)
|
||||
# .undef $v
|
||||
# .endif
|
||||
# .endfor
|
||||
# .endif
|
||||
# # make sure we know what TARGET_SPEC is
|
||||
# # as we may need it to find Makefile.depend*
|
||||
# TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
|
||||
#
|
||||
# The following variables can influence the initial DIRDEPS
|
||||
# computation with regard to the TARGET_SPECs that will be
|
||||
# built.
|
||||
# Most should also be considered by init.mk
|
||||
#
|
||||
# ONLY_TARGET_SPEC_LIST
|
||||
# Defines a list of TARGET_SPECs for which the current
|
||||
# directory can be built.
|
||||
# If ALL_MACHINES is defined, we build for all the
|
||||
# TARGET_SPECs listed.
|
||||
#
|
||||
# ONLY_MACHINE_LIST
|
||||
# As for ONLY_TARGET_SPEC_LIST but only specifies
|
||||
# MACHINEs.
|
||||
#
|
||||
# NOT_TARGET_SPEC_LIST
|
||||
# A list of TARGET_SPECs for which the current
|
||||
# directory should not be built.
|
||||
#
|
||||
# NOT_MACHINE_LIST
|
||||
# A list of MACHINEs the current directory should not be
|
||||
# built for.
|
||||
#
|
||||
# _build_xtra_dirs
|
||||
# local.dirdeps.mk can add targets to this variable.
|
||||
# They will be hooked into the build, but independent of
|
||||
# any other DIRDEP.
|
||||
#
|
||||
# This allows for adding TESTS to the build, such that the build
|
||||
# if any test fails, but without the risk of introducing
|
||||
# circular dependencies.
|
||||
|
||||
now_utc ?= ${%s:L:gmtime}
|
||||
.if !defined(start_utc)
|
||||
start_utc := ${now_utc}
|
||||
.endif
|
||||
|
||||
.if !target(bootstrap) && (make(bootstrap) || \
|
||||
make(bootstrap-this) || \
|
||||
make(bootstrap-recurse) || \
|
||||
make(bootstrap-empty))
|
||||
# disable most of below
|
||||
.MAKE.LEVEL = 1
|
||||
.endif
|
||||
|
||||
# touch this at your peril
|
||||
_DIRDEP_USE_LEVEL?= 0
|
||||
.if ${.MAKE.LEVEL} == ${_DIRDEP_USE_LEVEL}
|
||||
# only the first instance is interested in all this
|
||||
|
||||
.if !target(_DIRDEP_USE)
|
||||
|
||||
# do some setup we only need once
|
||||
_CURDIR ?= ${.CURDIR}
|
||||
_OBJDIR ?= ${.OBJDIR}
|
||||
|
||||
.if ${MAKEFILE:T} == ${.PARSEFILE} && empty(DIRDEPS) && ${.TARGETS:Uall:M*/*} != ""
|
||||
# This little trick let's us do
|
||||
#
|
||||
# mk -f dirdeps.mk some/dir.${TARGET_SPEC}
|
||||
#
|
||||
all:
|
||||
${.TARGETS:Nall}: all
|
||||
DIRDEPS := ${.TARGETS:M*[/.]*}
|
||||
# so that -DNO_DIRDEPS works
|
||||
DEP_RELDIR := ${DIRDEPS:[1]:R}
|
||||
# this will become DEP_MACHINE below
|
||||
TARGET_MACHINE := ${DIRDEPS:[1]:E:C/,.*//}
|
||||
.if ${TARGET_MACHINE:N*/*} == ""
|
||||
TARGET_MACHINE := ${MACHINE}
|
||||
.endif
|
||||
# disable DIRDEPS_CACHE as it does not like this trick
|
||||
MK_DIRDEPS_CACHE = no
|
||||
.endif
|
||||
|
||||
# make sure we get the behavior we expect
|
||||
.MAKE.SAVE_DOLLARS = no
|
||||
|
||||
# make sure these are empty to start with
|
||||
_DEP_TARGET_SPEC =
|
||||
|
||||
# If TARGET_SPEC_VARS is other than just MACHINE
|
||||
# it should be set by sys.mk or similar by now.
|
||||
# TARGET_SPEC must not contain any '.'s.
|
||||
TARGET_SPEC_VARS ?= MACHINE
|
||||
# this is what we started with
|
||||
TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
|
||||
# this is what we mostly use below
|
||||
DEP_TARGET_SPEC = ${TARGET_SPEC_VARS:S,^,DEP_,:@v@${$v:U}@:ts,}
|
||||
# make sure we have defaults
|
||||
.for v in ${TARGET_SPEC_VARS}
|
||||
DEP_$v ?= ${$v}
|
||||
.endfor
|
||||
|
||||
.if ${TARGET_SPEC_VARS:[#]} > 1
|
||||
# Ok, this gets more complex (putting it mildly).
|
||||
# In order to stay sane, we need to ensure that all the build_dirs
|
||||
# we compute below are fully qualified wrt DEP_TARGET_SPEC.
|
||||
# The makefiles may only partially specify (eg. MACHINE only),
|
||||
# so we need to construct a set of modifiers to fill in the gaps.
|
||||
.if ${MAKE_VERSION} >= 20170130
|
||||
_tspec_x := ${TARGET_SPEC_VARS:range}
|
||||
.elif ${TARGET_SPEC_VARS:[#]} > 10
|
||||
# seriously? better have jot(1) or equivalent to produce suitable sequence
|
||||
_tspec_x := ${${JOT:Ujot} ${TARGET_SPEC_VARS:[#]}:L:sh}
|
||||
.else
|
||||
# we can provide the sequence ourselves
|
||||
_tspec_x := ${1 2 3 4 5 6 7 8 9 10:L:[1..${TARGET_SPEC_VARS:[#]}]}
|
||||
.endif
|
||||
# this handles unqualified entries
|
||||
M_dep_qual_fixes = C;(/[^/.,]+)$$;\1.$${DEP_TARGET_SPEC};
|
||||
# there needs to be at least one item missing for these to make sense
|
||||
.for i in ${_tspec_x:[2..-1]}
|
||||
_tspec_m$i := ${TARGET_SPEC_VARS:[2..$i]:@w@[^,]+@:ts,}
|
||||
_tspec_a$i := ,${TARGET_SPEC_VARS:[$i..-1]:@v@$$$${DEP_$v}@:ts,}
|
||||
M_dep_qual_fixes += C;(\.${_tspec_m$i})$$;\1${_tspec_a$i};
|
||||
.endfor
|
||||
TARGET_SPEC_VARSr := ${TARGET_SPEC_VARS:[-1..1]}
|
||||
.else
|
||||
# A harmless? default.
|
||||
M_dep_qual_fixes = U
|
||||
.endif
|
||||
|
||||
.if !defined(.MAKE.DEPENDFILE_PREFERENCE)
|
||||
# .MAKE.DEPENDFILE_PREFERENCE makes the logic below neater?
|
||||
# you really want this set by sys.mk or similar
|
||||
.MAKE.DEPENDFILE_PREFERENCE = ${_CURDIR}/${.MAKE.DEPENDFILE:T}
|
||||
.if ${.MAKE.DEPENDFILE:E} == "${TARGET_SPEC}"
|
||||
.if ${TARGET_SPEC} != ${MACHINE}
|
||||
.MAKE.DEPENDFILE_PREFERENCE += ${_CURDIR}/${.MAKE.DEPENDFILE:T:R}.$${MACHINE}
|
||||
.endif
|
||||
.MAKE.DEPENDFILE_PREFERENCE += ${_CURDIR}/${.MAKE.DEPENDFILE:T:R}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
_default_dependfile := ${.MAKE.DEPENDFILE_PREFERENCE:[1]:T}
|
||||
_machine_dependfiles := ${.MAKE.DEPENDFILE_PREFERENCE:T:M*${MACHINE}*}
|
||||
|
||||
# for machine specific dependfiles we require ${MACHINE} to be at the end
|
||||
# also for the sake of sanity we require a common prefix
|
||||
.if !defined(.MAKE.DEPENDFILE_PREFIX)
|
||||
# knowing .MAKE.DEPENDFILE_PREFIX helps
|
||||
.if !empty(_machine_dependfiles)
|
||||
.MAKE.DEPENDFILE_PREFIX := ${_machine_dependfiles:[1]:T:R}
|
||||
.else
|
||||
.MAKE.DEPENDFILE_PREFIX := ${_default_dependfile:T}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
|
||||
# this is how we identify non-machine specific dependfiles
|
||||
N_notmachine := ${.MAKE.DEPENDFILE_PREFERENCE:E:N*${MACHINE}*:${M_ListToSkip}}
|
||||
|
||||
.endif # !target(_DIRDEP_USE)
|
||||
|
||||
# First off, we want to know what ${MACHINE} to build for.
|
||||
# This can be complicated if we are using a mixture of ${MACHINE} specific
|
||||
# and non-specific Makefile.depend*
|
||||
|
||||
# if we were included recursively _DEP_TARGET_SPEC should be valid.
|
||||
.if empty(_DEP_TARGET_SPEC)
|
||||
# we may or may not have included a dependfile yet
|
||||
.if defined(.INCLUDEDFROMFILE)
|
||||
_last_dependfile := ${.INCLUDEDFROMFILE:M${.MAKE.DEPENDFILE_PREFIX}*}
|
||||
.else
|
||||
_last_dependfile := ${.MAKE.MAKEFILES:M*/${.MAKE.DEPENDFILE_PREFIX}*:[-1]}
|
||||
.endif
|
||||
.if ${_debug_reldir:U0}
|
||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _last_dependfile='${_last_dependfile}'
|
||||
.endif
|
||||
|
||||
.if empty(_last_dependfile) || ${_last_dependfile:E:${N_notmachine}} == ""
|
||||
# this is all we have to work with
|
||||
DEP_MACHINE = ${TARGET_MACHINE:U${MACHINE}}
|
||||
_DEP_TARGET_SPEC := ${DEP_TARGET_SPEC}
|
||||
.else
|
||||
_DEP_TARGET_SPEC = ${_last_dependfile:${M_dep_qual_fixes:ts:}:E}
|
||||
.endif
|
||||
.if !empty(_last_dependfile)
|
||||
# record that we've read dependfile for this
|
||||
_dirdeps_checked.${_CURDIR}.${TARGET_SPEC}:
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# by now _DEP_TARGET_SPEC should be set, parse it.
|
||||
.if ${TARGET_SPEC_VARS:[#]} > 1
|
||||
# we need to parse DEP_MACHINE may or may not contain more info
|
||||
_tspec := ${_DEP_TARGET_SPEC:S/,/ /g}
|
||||
.for i in ${_tspec_x}
|
||||
DEP_${TARGET_SPEC_VARS:[$i]} := ${_tspec:[$i]}
|
||||
.endfor
|
||||
.for v in ${TARGET_SPEC_VARS:O:u}
|
||||
.if empty(DEP_$v)
|
||||
.undef DEP_$v
|
||||
.endif
|
||||
.endfor
|
||||
.else
|
||||
DEP_MACHINE := ${_DEP_TARGET_SPEC}
|
||||
.endif
|
||||
|
||||
# reset each time through
|
||||
_build_all_dirs =
|
||||
_build_xtra_dirs =
|
||||
|
||||
# the first time we are included the _DIRDEP_USE target will not be defined
|
||||
# we can use this as a clue to do initialization and other one time things.
|
||||
.if !target(_DIRDEP_USE)
|
||||
# make sure this target exists
|
||||
dirdeps: beforedirdeps .WAIT
|
||||
beforedirdeps:
|
||||
|
||||
# We normally expect to be included by Makefile.depend.*
|
||||
# which sets the DEP_* macros below.
|
||||
DEP_RELDIR ?= ${RELDIR}
|
||||
|
||||
# this can cause lots of output!
|
||||
# set to a set of glob expressions that might match RELDIR
|
||||
DEBUG_DIRDEPS ?= no
|
||||
|
||||
# remember the initial value of DEP_RELDIR - we test for it below.
|
||||
_DEP_RELDIR := ${DEP_RELDIR}
|
||||
|
||||
.endif
|
||||
|
||||
# DIRDEPS_CACHE can be very handy for debugging.
|
||||
# Also if repeatedly building the same target,
|
||||
# we can avoid the overhead of re-computing the tree dependencies.
|
||||
MK_DIRDEPS_CACHE ?= no
|
||||
BUILD_DIRDEPS_CACHE ?= no
|
||||
BUILD_DIRDEPS ?= yes
|
||||
|
||||
.if ${MK_DIRDEPS_CACHE} == "yes"
|
||||
# this is where we will cache all our work
|
||||
DIRDEPS_CACHE ?= ${_OBJDIR:tA}/dirdeps.cache${_TARGETS:U${.TARGETS}:Nall:O:u:ts-:S,/,_,g:S,^,.,:N.}
|
||||
.endif
|
||||
|
||||
.if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.${DEP_MACHINE}:L:M$x}@} != ""
|
||||
_debug_reldir = 1
|
||||
.else
|
||||
_debug_reldir = 0
|
||||
.endif
|
||||
.if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.depend:L:M$x}@} != ""
|
||||
_debug_search = 1
|
||||
.else
|
||||
_debug_search = 0
|
||||
.endif
|
||||
|
||||
# pickup customizations
|
||||
# as below you can use !target(_DIRDEP_USE) to protect things
|
||||
# which should only be done once.
|
||||
.-include <local.dirdeps.mk>
|
||||
|
||||
.if !target(_DIRDEP_USE)
|
||||
# things we skip for host tools
|
||||
SKIP_HOSTDIR ?=
|
||||
|
||||
NSkipHostDir = ${SKIP_HOSTDIR:N*.host*:S,$,.host*,:N.host*:S,^,${SRCTOP}/,:${M_ListToSkip}}
|
||||
|
||||
# things we always skip
|
||||
# SKIP_DIRDEPS allows for adding entries on command line.
|
||||
SKIP_DIR += .host *.WAIT ${SKIP_DIRDEPS}
|
||||
SKIP_DIR.host += ${SKIP_HOSTDIR}
|
||||
|
||||
DEP_SKIP_DIR = ${SKIP_DIR} \
|
||||
${SKIP_DIR.${DEP_TARGET_SPEC}:U} \
|
||||
${TARGET_SPEC_VARS:@v@${SKIP_DIR.${DEP_$v}:U}@} \
|
||||
${SKIP_DIRDEPS.${DEP_TARGET_SPEC}:U} \
|
||||
${TARGET_SPEC_VARS:@v@${SKIP_DIRDEPS.${DEP_$v}:U}@}
|
||||
|
||||
|
||||
NSkipDir = ${DEP_SKIP_DIR:${M_ListToSkip}}
|
||||
|
||||
.if defined(NODIRDEPS) || defined(WITHOUT_DIRDEPS)
|
||||
NO_DIRDEPS =
|
||||
.elif defined(WITHOUT_DIRDEPS_BELOW)
|
||||
NO_DIRDEPS_BELOW =
|
||||
.endif
|
||||
|
||||
.if defined(NO_DIRDEPS)
|
||||
# confine ourselves to the original dir and below.
|
||||
DIRDEPS_FILTER += M${_DEP_RELDIR}*
|
||||
.elif defined(NO_DIRDEPS_BELOW)
|
||||
DIRDEPS_FILTER += M${_DEP_RELDIR}
|
||||
.endif
|
||||
|
||||
# this is what we run below
|
||||
DIRDEP_MAKE ?= ${.MAKE}
|
||||
DIRDEP_DIR ?= ${.TARGET:R}
|
||||
|
||||
# if you want us to report load averages during build
|
||||
# DIRDEP_USE_PRELUDE += ${DIRDEP_LOADAVG_REPORT};
|
||||
|
||||
DIRDEP_LOADAVG_CMD ?= ${UPTIME:Uuptime} | sed 's,.*\(load\),\1,'
|
||||
DIRDEP_LOADAVG_LAST = 0
|
||||
# yes the expression here is a bit complicated,
|
||||
# the trick is to only eval ${DIRDEP_LOADAVG_LAST::=${now_utc}}
|
||||
# when we want to report.
|
||||
DIRDEP_LOADAVG_REPORT = \
|
||||
test -z "${"${expr ${now_utc} - ${DIRDEP_LOADAVG_INTEVAL:U60} - ${DIRDEP_LOADAVG_LAST}:L:sh:N-*}":?yes${DIRDEP_LOADAVG_LAST::=${now_utc}}:}" || \
|
||||
echo "${TRACER}`${DIRDEP_LOADAVG_CMD}`"
|
||||
|
||||
# we suppress SUBDIR when visiting the leaves
|
||||
# we assume sys.mk will set MACHINE_ARCH
|
||||
# you can add extras to DIRDEP_USE_ENV
|
||||
# if there is no makefile in the target directory, we skip it.
|
||||
_DIRDEP_USE: .USE .MAKE
|
||||
@for m in ${.MAKE.MAKEFILE_PREFERENCE}; do \
|
||||
test -s ${.TARGET:R}/$$m || continue; \
|
||||
echo "${TRACER}Checking ${.TARGET:S,${SRCTOP}/,,} for ${.TARGET:E} ..."; \
|
||||
${DIRDEP_USE_PRELUDE} \
|
||||
MACHINE_ARCH= NO_SUBDIR=1 ${DIRDEP_USE_ENV} \
|
||||
TARGET_SPEC=${.TARGET:E} \
|
||||
MACHINE=${.TARGET:E} \
|
||||
${DIRDEP_MAKE} -C ${DIRDEP_DIR} || exit 1; \
|
||||
break; \
|
||||
done
|
||||
|
||||
.ifdef ALL_MACHINES
|
||||
# this is how you limit it to only the machines we have been built for
|
||||
# previously.
|
||||
.if empty(ONLY_TARGET_SPEC_LIST) && empty(ONLY_MACHINE_LIST)
|
||||
.if !empty(ALL_MACHINE_LIST)
|
||||
# ALL_MACHINE_LIST is the list of all legal machines - ignore anything else
|
||||
_machine_list != cd ${_CURDIR} && 'ls' -1 ${ALL_MACHINE_LIST:O:u:@m@${.MAKE.DEPENDFILE:T:R}.$m@} 2> /dev/null; echo
|
||||
.else
|
||||
_machine_list != 'ls' -1 ${_CURDIR}/${.MAKE.DEPENDFILE_PREFIX}.* 2> /dev/null; echo
|
||||
.endif
|
||||
_only_machines := ${_machine_list:${NIgnoreFiles:UN*.bak}:E:O:u}
|
||||
.else
|
||||
_only_machines := ${ONLY_TARGET_SPEC_LIST:U} ${ONLY_MACHINE_LIST:U}
|
||||
.endif
|
||||
|
||||
.if empty(_only_machines)
|
||||
# we must be boot-strapping
|
||||
_only_machines := ${TARGET_MACHINE:U${ALL_MACHINE_LIST:U${DEP_MACHINE}}}
|
||||
.endif
|
||||
|
||||
.else # ! ALL_MACHINES
|
||||
# if ONLY_TARGET_SPEC_LIST or ONLY_MACHINE_LIST is set, we are limited to that.
|
||||
# Note that ONLY_TARGET_SPEC_LIST should be fully qualified.
|
||||
# if TARGET_MACHINE is set - it is really the same as ONLY_MACHINE_LIST
|
||||
# otherwise DEP_MACHINE is it - so DEP_MACHINE will match.
|
||||
_only_machines := ${ONLY_TARGET_SPEC_LIST:U:M${DEP_MACHINE},*}
|
||||
.if empty(_only_machines)
|
||||
_only_machines := ${ONLY_MACHINE_LIST:U${TARGET_MACHINE:U${DEP_MACHINE}}:M${DEP_MACHINE}}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if !empty(NOT_MACHINE_LIST)
|
||||
_only_machines := ${_only_machines:${NOT_MACHINE_LIST:${M_ListToSkip}}}
|
||||
.endif
|
||||
.if !empty(NOT_TARGET_SPEC_LIST)
|
||||
# we must first qualify
|
||||
_dm := ${DEP_MACHINE}
|
||||
_only_machines := ${_only_machines:M*,*} ${_only_machines:N*,*:@DEP_MACHINE@${DEP_TARGET_SPEC}@:S,^,.,:${M_dep_qual_fixes:ts:}:O:u:S,^.,,}
|
||||
DEP_MACHINE := ${_dm}
|
||||
_only_machines := ${_only_machines:${NOT_TARGET_SPEC_LIST:${M_ListToSkip}}}
|
||||
.endif
|
||||
# clean up
|
||||
_only_machines := ${_only_machines:O:u}
|
||||
|
||||
# make sure we have a starting place?
|
||||
DIRDEPS ?= ${RELDIR}
|
||||
.endif # target
|
||||
|
||||
.if !defined(NO_DIRDEPS) && !defined(NO_DIRDEPS_BELOW)
|
||||
.if ${MK_DIRDEPS_CACHE} == "yes"
|
||||
|
||||
# just ensure this exists
|
||||
build-dirdeps:
|
||||
|
||||
M_oneperline = @x@\\${.newline} $$x@
|
||||
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "no"
|
||||
.if !target(dirdeps-cached)
|
||||
# we do this via sub-make
|
||||
BUILD_DIRDEPS = no
|
||||
|
||||
# ignore anything but these
|
||||
.MAKE.META.IGNORE_FILTER = M*/${.MAKE.DEPENDFILE_PREFIX}*
|
||||
|
||||
dirdeps: dirdeps-cached
|
||||
dirdeps-cached: ${DIRDEPS_CACHE} .MAKE
|
||||
@echo "${TRACER}Using ${DIRDEPS_CACHE}"
|
||||
@MAKELEVEL=${.MAKE.LEVEL} ${.MAKE} -C ${_CURDIR} -f ${DIRDEPS_CACHE} \
|
||||
dirdeps MK_DIRDEPS_CACHE=no BUILD_DIRDEPS=no
|
||||
|
||||
# these should generally do
|
||||
BUILD_DIRDEPS_MAKEFILE ?=
|
||||
BUILD_DIRDEPS_TARGETS ?= ${.TARGETS}
|
||||
|
||||
.if ${DIRDEPS_CACHE} != ${STATIC_DIRDEPS_CACHE:Uno} && ${DIRDEPS_CACHE:M${SRCTOP}/*} == ""
|
||||
# export this for dirdeps-cache-update.mk
|
||||
DYNAMIC_DIRDEPS_CACHE := ${DIRDEPS_CACHE}
|
||||
.export DYNAMIC_DIRDEPS_CACHE
|
||||
# we need the .meta file to ensure we update if
|
||||
# any of the Makefile.depend* changed.
|
||||
# We do not want to compare the command line though.
|
||||
${DIRDEPS_CACHE}: .META .NOMETA_CMP
|
||||
+@{ echo '# Autogenerated - do NOT edit!'; echo; \
|
||||
echo 'BUILD_DIRDEPS=no'; echo; \
|
||||
echo '.include <dirdeps.mk>'; echo; \
|
||||
} > ${.TARGET}.new
|
||||
+@MAKELEVEL=${.MAKE.LEVEL} DIRDEPS_CACHE=${DIRDEPS_CACHE} \
|
||||
DIRDEPS="${DIRDEPS}" \
|
||||
TARGET_SPEC=${TARGET_SPEC} \
|
||||
MAKEFLAGS= ${DIRDEP_CACHE_MAKE:U${.MAKE}} -C ${_CURDIR} \
|
||||
${BUILD_DIRDEPS_MAKEFILE} \
|
||||
${BUILD_DIRDEPS_TARGETS} BUILD_DIRDEPS_CACHE=yes \
|
||||
.MAKE.DEPENDFILE=.none \
|
||||
${.MAKEFLAGS:tW:S,-D ,-D,g:tw:M*WITH*} \
|
||||
${.MAKEFLAGS:tW:S,-d ,-d,g:tw:M-d*} \
|
||||
3>&1 1>&2 | sed 's,${SRCTOP},$${SRCTOP},g;s,_{,$${,g' >> ${.TARGET}.new && \
|
||||
mv ${.TARGET}.new ${.TARGET}
|
||||
|
||||
.endif
|
||||
.endif
|
||||
.elif !target(_count_dirdeps)
|
||||
# we want to capture the dirdeps count in the cache
|
||||
.END: _count_dirdeps
|
||||
_count_dirdeps: .NOMETA
|
||||
@{ echo; echo '.info $${.newline}$${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]} ${DIRDEP_INFO_XTRAS}'; } >&3
|
||||
|
||||
.endif
|
||||
.elif !make(dirdeps) && !target(_count_dirdeps)
|
||||
beforedirdeps: _count_dirdeps
|
||||
_count_dirdeps: .NOMETA
|
||||
@echo "${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]} ${DIRDEP_INFO_XTRAS} seconds=`expr ${now_utc} - ${start_utc}`"
|
||||
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${BUILD_DIRDEPS} == "yes"
|
||||
|
||||
# the rest is done repeatedly for every Makefile.depend we read.
|
||||
# if we are anything but the original dir we care only about the
|
||||
# machine type we were included for..
|
||||
|
||||
.if ${DEP_RELDIR} == "."
|
||||
_this_dir := ${SRCTOP}
|
||||
.else
|
||||
_this_dir := ${SRCTOP}/${DEP_RELDIR}
|
||||
.endif
|
||||
|
||||
# on rare occasions, there can be a need for extra help
|
||||
_dep_hack := ${_this_dir}/${.MAKE.DEPENDFILE_PREFIX}.inc
|
||||
.-include <${_dep_hack}>
|
||||
.-include <${_dep_hack:R}.options>
|
||||
|
||||
.if ${DEP_RELDIR} != ${_DEP_RELDIR} || ${DEP_TARGET_SPEC} != ${TARGET_SPEC}
|
||||
# this should be all
|
||||
_machines := ${DEP_MACHINE}
|
||||
.else
|
||||
# this is the machine list we actually use below
|
||||
_machines := ${_only_machines}
|
||||
|
||||
.if defined(HOSTPROG) || ${DEP_MACHINE:Nhost*} == ""
|
||||
# we need to build this guy's dependencies for host as well.
|
||||
.if ${DEP_MACHINE:Nhost*} == ""
|
||||
_machines += ${DEP_MACHINE}
|
||||
.else
|
||||
_machines += host
|
||||
.endif
|
||||
.endif
|
||||
|
||||
_machines := ${_machines:O:u}
|
||||
.endif
|
||||
|
||||
.if ${TARGET_SPEC_VARS:[#]} > 1
|
||||
# we need to tweak _machines
|
||||
_dm := ${DEP_MACHINE}
|
||||
# apply the same filtering that we do when qualifying DIRDEPS.
|
||||
# M_dep_qual_fixes expects .${MACHINE}* so add (and remove) '.'
|
||||
# Again we expect that any already qualified machines are fully qualified.
|
||||
_machines := ${_machines:M*,*} ${_machines:N*,*:@DEP_MACHINE@${DEP_TARGET_SPEC}@:S,^,.,:${M_dep_qual_fixes:ts:}:O:u:S,^.,,}
|
||||
DEP_MACHINE := ${_dm}
|
||||
_machines := ${_machines:O:u}
|
||||
.endif
|
||||
|
||||
# reset each time through
|
||||
_build_dirs =
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# pickup other machines for this dir if necessary
|
||||
_build_dirs += ${_machines:@m@${_CURDIR}.$m@}
|
||||
.endif
|
||||
|
||||
.if ${_debug_reldir}
|
||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: DIRDEPS='${DIRDEPS}'
|
||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _machines='${_machines}'
|
||||
.endif
|
||||
|
||||
.if !empty(DIRDEPS)
|
||||
# these we reset each time through as they can depend on DEP_MACHINE
|
||||
DEP_DIRDEPS_FILTER = \
|
||||
${DIRDEPS_FILTER.${DEP_TARGET_SPEC}:U} \
|
||||
${TARGET_SPEC_VARS:@v@${DIRDEPS_FILTER.${DEP_$v}:U}@} \
|
||||
${DIRDEPS_FILTER:U}
|
||||
.if empty(DEP_DIRDEPS_FILTER)
|
||||
# something harmless
|
||||
DEP_DIRDEPS_FILTER = U
|
||||
.endif
|
||||
|
||||
# this is what we start with
|
||||
__depdirs := ${DIRDEPS:${NSkipDir}:${DEP_DIRDEPS_FILTER:ts:}:C,//+,/,g:O:u:@d@${SRCTOP}/$d@}
|
||||
|
||||
# some entries may be qualified with .<machine>
|
||||
# the :M*/*/*.* just tries to limit the dirs we check to likely ones.
|
||||
# the ${d:E:M*/*} ensures we don't consider junos/usr.sbin/mgd
|
||||
__qual_depdirs := ${__depdirs:M*/*/*.*:@d@${exists($d):?:${"${d:E:M*/*}":?:${exists(${d:R}):?$d:}}}@}
|
||||
__unqual_depdirs := ${__depdirs:${__qual_depdirs:Uno:${M_ListToSkip}}}
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# if it was called out - we likely need it.
|
||||
__hostdpadd := ${DPADD:U.:M${HOST_OBJTOP}/*:S,${HOST_OBJTOP}/,,:H:${NSkipDir}:${DIRDEPS_FILTER:ts:}:S,$,.host,:N.*:@d@${SRCTOP}/$d@} \
|
||||
${DPADD:U.:M${HOST_OBJTOP32:Uno}/*:S,${HOST_OBJTOP32:Uno}/,,:H:${NSkipDir}:${DIRDEPS_FILTER:ts:}:S,$,.host32,:N.*:@d@${SRCTOP}/$d@}
|
||||
__qual_depdirs += ${__hostdpadd}
|
||||
.endif
|
||||
|
||||
.if ${_debug_reldir}
|
||||
.info depdirs=${__depdirs}
|
||||
.info qualified=${__qual_depdirs}
|
||||
.info unqualified=${__unqual_depdirs}
|
||||
.endif
|
||||
|
||||
# _build_dirs is what we will feed to _DIRDEP_USE
|
||||
_build_dirs += \
|
||||
${__qual_depdirs:M*.host:${NSkipHostDir}:N.host} \
|
||||
${__qual_depdirs:N*.host} \
|
||||
${_machines:Mhost*:@m@${__unqual_depdirs:@d@$d.$m@}@:${NSkipHostDir}:N.host} \
|
||||
${_machines:Nhost*:@m@${__unqual_depdirs:@d@$d.$m@}@}
|
||||
|
||||
# qualify everything now
|
||||
_build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u}
|
||||
|
||||
.endif # empty DIRDEPS
|
||||
|
||||
_build_all_dirs += ${_build_dirs} ${_build_xtra_dirs}
|
||||
_build_all_dirs := ${_build_all_dirs:O:u}
|
||||
|
||||
# Normally if doing make -V something,
|
||||
# we do not want to waste time chasing DIRDEPS
|
||||
# but if we want to count the number of Makefile.depend* read, we do.
|
||||
.if ${.MAKEFLAGS:M-V${_V_READ_DIRDEPS}} == ""
|
||||
.if !empty(_build_all_dirs)
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes"
|
||||
x!= echo; { echo; echo '\# ${DEP_RELDIR}.${DEP_TARGET_SPEC}'; } >&3
|
||||
# guard against _new_dirdeps being too big for a single command line
|
||||
_new_dirdeps := ${_build_all_dirs:@x@${target($x):?:$x}@}
|
||||
.export _build_xtra_dirs _new_dirdeps
|
||||
.if !empty(DEP_EXPORT_VARS)
|
||||
# Discouraged, but there are always exceptions.
|
||||
# Handle it here rather than explain how.
|
||||
x!= echo; { echo; ${DEP_EXPORT_VARS:@v@echo '$v=${$v}';@} echo '.export ${DEP_EXPORT_VARS}'; echo; } >&3
|
||||
.endif
|
||||
.else
|
||||
# this makes it all happen
|
||||
dirdeps: ${_build_all_dirs}
|
||||
.endif
|
||||
${_build_all_dirs}: _DIRDEP_USE
|
||||
|
||||
.if ${_debug_reldir}
|
||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: needs: ${_build_dirs}
|
||||
.endif
|
||||
|
||||
.if !empty(DEP_EXPORT_VARS)
|
||||
.export ${DEP_EXPORT_VARS}
|
||||
DEP_EXPORT_VARS=
|
||||
.endif
|
||||
|
||||
# this builds the dependency graph
|
||||
.for m in ${_machines}
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes" && !empty(_build_dirs)
|
||||
x!= echo; { echo; echo 'DIRDEPS.${_this_dir}.$m = \'; } >&3
|
||||
_cache_deps =
|
||||
.endif
|
||||
# it would be nice to do :N${.TARGET}
|
||||
.if !empty(__qual_depdirs)
|
||||
.for q in ${__qual_depdirs:${M_dep_qual_fixes:ts:}:E:O:u:N$m}
|
||||
.if ${_debug_reldir} || ${DEBUG_DIRDEPS:@x@${${DEP_RELDIR}.$m:L:M$x}${${DEP_RELDIR}.$q:L:M$x}@} != ""
|
||||
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$q}
|
||||
.endif
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes"
|
||||
_cache_deps += ${_build_dirs:M*.$q}
|
||||
.else
|
||||
${_this_dir}.$m: ${_build_dirs:M*.$q}
|
||||
.endif
|
||||
.endfor
|
||||
.endif
|
||||
.if ${_debug_reldir}
|
||||
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
.endif
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes"
|
||||
.if !empty(_build_dirs)
|
||||
_cache_deps += ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
.if !empty(_cache_deps)
|
||||
.export _cache_deps
|
||||
x!= echo; for x in $$_cache_deps; do echo " $$x \\"; done >&3
|
||||
.endif
|
||||
x!= echo; { echo; echo '${_this_dir}.$m: $${DIRDEPS.${_this_dir}.$m}'; \
|
||||
echo; echo 'dirdeps: ${_this_dir}.$m \'; \
|
||||
for x in $$_build_xtra_dirs; do echo " $$x \\"; done; \
|
||||
echo; for x in $$_new_dirdeps; do echo "$$x: _DIRDEP_USE"; done; } >&3
|
||||
.endif
|
||||
.else
|
||||
${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
.endif
|
||||
|
||||
# Now find more dependencies - and recurse.
|
||||
.for d in ${_build_all_dirs}
|
||||
.if !target(_dirdeps_checked.$d)
|
||||
# once only
|
||||
_dirdeps_checked.$d:
|
||||
.if ${_debug_search}
|
||||
.info checking $d
|
||||
.endif
|
||||
# Note: _build_all_dirs is fully qualifed so d:R is always the directory
|
||||
.if exists(${d:R})
|
||||
# we pass _DEP_TARGET_SPEC to tell the next step what we want
|
||||
_DEP_TARGET_SPEC := ${d:E}
|
||||
# some makefiles may still look at this
|
||||
_DEP_MACHINE := ${d:E:C/,.*//}
|
||||
# set these too in case Makefile.depend* uses them
|
||||
.if ${TARGET_SPEC_VARS:[#]} > 1
|
||||
_dtspec := ${_DEP_TARGET_SPEC:S/,/ /g}
|
||||
.for i in ${_tspec_x}
|
||||
DEP_${TARGET_SPEC_VARS:[$i]} := ${_dtspec:[$i]}
|
||||
.endfor
|
||||
.else
|
||||
DEP_MACHINE := ${_DEP_MACHINE}
|
||||
.endif
|
||||
# Warning: there is an assumption here that MACHINE is always
|
||||
# the first entry in TARGET_SPEC_VARS.
|
||||
# If TARGET_SPEC and MACHINE are insufficient, you have a problem.
|
||||
_m := ${.MAKE.DEPENDFILE_PREFERENCE:T:S;${TARGET_SPEC}$;${d:E};:S;${MACHINE};${d:E:C/,.*//};:@m@${exists(${d:R}/$m):?${d:R}/$m:}@:[1]}
|
||||
.if !empty(_m)
|
||||
# M_dep_qual_fixes isn't geared to Makefile.depend
|
||||
_qm := ${_m:C;(\.depend)$;\1.${d:E};:${M_dep_qual_fixes:ts:}}
|
||||
.if ${_debug_search}
|
||||
.info Looking for ${_qm}
|
||||
.endif
|
||||
# set this "just in case"
|
||||
# we can skip :tA since we computed the path above
|
||||
DEP_RELDIR := ${_m:H:S,${SRCTOP}/,,}
|
||||
# and reset this
|
||||
DIRDEPS =
|
||||
.if ${_debug_reldir} && ${_qm} != ${_m}
|
||||
.info loading ${_m} for ${d:E}
|
||||
.endif
|
||||
.include <${_m}>
|
||||
.else
|
||||
.-include <local.dirdeps-missing.mk>
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
.endif # -V
|
||||
.endif # BUILD_DIRDEPS
|
||||
|
||||
.elif ${.MAKE.LEVEL} > 42
|
||||
.error You should have stopped recursing by now.
|
||||
.else
|
||||
# we are building something
|
||||
DEP_RELDIR := ${RELDIR}
|
||||
_DEP_RELDIR := ${RELDIR}
|
||||
# Since we are/should be included by .MAKE.DEPENDFILE
|
||||
# This is a final opportunity to add/hook global rules.
|
||||
.-include <local.dirdeps-build.mk>
|
||||
|
||||
# skip _reldir_{finish,failed} if not included from Makefile.depend*
|
||||
# or not in meta mode
|
||||
.if !defined(WITHOUT_META_STATS) && ${.INCLUDEDFROMFILE:U:M${.MAKE.DEPENDFILE_PREFIX}*} != "" && ${.MAKE.MODE:Mmeta} != ""
|
||||
|
||||
meta_stats= meta=${empty(.MAKE.META.FILES):?0:${.MAKE.META.FILES:[#]}} \
|
||||
created=${empty(.MAKE.META.CREATED):?0:${.MAKE.META.CREATED:[#]}}
|
||||
|
||||
.if !target(_reldir_finish)
|
||||
.END: _reldir_finish
|
||||
_reldir_finish: .NOMETA
|
||||
@echo "${TRACER}Finished ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}"
|
||||
.endif
|
||||
|
||||
.if !target(_reldir_failed)
|
||||
.ERROR: _reldir_failed
|
||||
_reldir_failed: .NOMETA
|
||||
@echo "${TRACER}Failed ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}"
|
||||
.endif
|
||||
|
||||
.endif
|
||||
|
||||
# pickup local dependencies
|
||||
.if ${MAKE_VERSION} < 20160220
|
||||
.-include <.depend>
|
||||
.else
|
||||
.dinclude <.depend>
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# bootstrapping new dependencies made easy?
|
||||
.if !target(bootstrap) && (make(bootstrap) || \
|
||||
make(bootstrap-this) || \
|
||||
make(bootstrap-recurse) || \
|
||||
make(bootstrap-empty))
|
||||
|
||||
# if we are bootstrapping create the default
|
||||
_want = ${.CURDIR}/${.MAKE.DEPENDFILE_DEFAULT:T}
|
||||
|
||||
.if exists(${_want})
|
||||
# stop here
|
||||
${.TARGETS:Mboot*}:
|
||||
.elif !make(bootstrap-empty)
|
||||
# find a Makefile.depend to use as _src
|
||||
_src != cd ${.CURDIR} && for m in ${.MAKE.DEPENDFILE_PREFERENCE:T:S,${MACHINE},*,}; do test -s $$m || continue; echo $$m; break; done; echo
|
||||
.if empty(_src)
|
||||
.error cannot find any of ${.MAKE.DEPENDFILE_PREFERENCE:T}${.newline}Use: bootstrap-empty
|
||||
.endif
|
||||
|
||||
_src?= ${.MAKE.DEPENDFILE}
|
||||
|
||||
.MAKE.DEPENDFILE_BOOTSTRAP_SED+= -e 's/${_src:E:C/,.*//}/${MACHINE}/g'
|
||||
|
||||
# just create Makefile.depend* for this dir
|
||||
bootstrap-this: .NOTMAIN
|
||||
@echo Bootstrapping ${RELDIR}/${_want:T} from ${_src:T}; \
|
||||
echo You need to build ${RELDIR} to correctly populate it.
|
||||
.if ${_src:T} != ${.MAKE.DEPENDFILE_PREFIX:T}
|
||||
(cd ${.CURDIR} && sed ${.MAKE.DEPENDFILE_BOOTSTRAP_SED} ${_src} > ${_want:T})
|
||||
.else
|
||||
cp ${.CURDIR}/${_src:T} ${_want}
|
||||
.endif
|
||||
|
||||
# create Makefile.depend* for this dir and its dependencies
|
||||
bootstrap: bootstrap-recurse
|
||||
bootstrap-recurse: bootstrap-this
|
||||
|
||||
_mf := ${.PARSEFILE}
|
||||
bootstrap-recurse: .NOTMAIN .MAKE
|
||||
@cd ${SRCTOP} && \
|
||||
for d in `cd ${RELDIR} && ${.MAKE} -B -f ${"${.MAKEFLAGS:M-n}":?${_src}:${.MAKE.DEPENDFILE:T}} -V DIRDEPS`; do \
|
||||
test -d $$d || d=$${d%.*}; \
|
||||
test -d $$d || continue; \
|
||||
echo "Checking $$d for bootstrap ..."; \
|
||||
(cd $$d && ${.MAKE} -f ${_mf} bootstrap-recurse); \
|
||||
done
|
||||
|
||||
.endif
|
||||
|
||||
# create an empty Makefile.depend* to get the ball rolling.
|
||||
bootstrap-empty: .NOTMAIN .NOMETA
|
||||
@echo Creating empty ${RELDIR}/${_want:T}; \
|
||||
echo You need to build ${RELDIR} to correctly populate it.
|
||||
@{ echo DIRDEPS=; echo ".include <dirdeps.mk>"; } > ${_want}
|
||||
|
||||
.endif
|
64
20200902/mk/doc.mk
Normal file
64
20200902/mk/doc.mk
Normal file
@ -0,0 +1,64 @@
|
||||
# $Id: doc.mk,v 1.7 2019/06/09 16:22:08 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
.include <init.mk>
|
||||
|
||||
BIB?= bib
|
||||
EQN?= eqn
|
||||
GREMLIN?= grn
|
||||
GRIND?= vgrind -f
|
||||
INDXBIB?= indxbib
|
||||
PIC?= pic
|
||||
REFER?= refer
|
||||
ROFF?= groff -M/usr/share/tmac ${MACROS} ${PAGES}
|
||||
SOELIM?= soelim
|
||||
TBL?= tbl
|
||||
|
||||
.PATH: ${.CURDIR}
|
||||
|
||||
.if !defined(_SKIP_BUILD)
|
||||
realbuild: paper.ps
|
||||
.endif
|
||||
|
||||
.if !target(paper.ps)
|
||||
paper.ps: ${SRCS}
|
||||
${ROFF} ${SRCS} > ${.TARGET}
|
||||
.endif
|
||||
|
||||
.if !target(print)
|
||||
print: paper.ps
|
||||
lpr -P${PRINTER} paper.ps
|
||||
.endif
|
||||
|
||||
.if !target(manpages)
|
||||
manpages:
|
||||
.endif
|
||||
|
||||
.if !target(obj)
|
||||
obj:
|
||||
.endif
|
||||
|
||||
clean cleandir:
|
||||
rm -f paper.* [eE]rrs mklog ${CLEANFILES}
|
||||
|
||||
.if ${MK_DOC} == "no"
|
||||
install:
|
||||
.else
|
||||
FILES?= ${SRCS}
|
||||
install:
|
||||
test -d ${DESTDIR}${DOCDIR}/${DIR} || \
|
||||
${INSTALL} -d ${DOC_INSTALL_OWN} -m ${DIRMODE} ${DESTDIR}${DOCDIR}/${DIR}
|
||||
${INSTALL} ${COPY} ${DOC_INSTALL_OWN} -m ${DOCMODE} \
|
||||
Makefile ${FILES} ${EXTRA} ${DESTDIR}${DOCDIR}/${DIR}
|
||||
.endif
|
||||
|
||||
spell: ${SRCS}
|
||||
spell ${SRCS} | sort | comm -23 - spell.ok > paper.spell
|
||||
|
||||
.if !empty(DOCOWN)
|
||||
DOC_INSTALL_OWN?= -o ${DOCOWN} -g ${DOCGRP}
|
||||
.endif
|
||||
|
||||
.endif
|
339
20200902/mk/dpadd.mk
Normal file
339
20200902/mk/dpadd.mk
Normal file
@ -0,0 +1,339 @@
|
||||
# $Id: dpadd.mk,v 1.28 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2004, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
##
|
||||
# DESCRIPTION:
|
||||
# This makefile manages a number of variables that simplify
|
||||
# dealing with libs in a build.
|
||||
#
|
||||
# Primary inputs are DPLIBS, DPADD and SRC_LIBS:
|
||||
#
|
||||
# DPLIBS
|
||||
# List of LIB* that we will actually link with
|
||||
# should be in correct link order.
|
||||
# DPLIBS is a short-cut to ensure that DPADD and LDADD are
|
||||
# kept in sync.
|
||||
#
|
||||
# DPADD List of LIB* that should already be built.
|
||||
#
|
||||
# SRC_LIBS
|
||||
# List of LIB* that we want headers from, we do *not*
|
||||
# require that such libs have been built.
|
||||
#
|
||||
# The above all get added to DPMAGIC_LIBS which is what we
|
||||
# process.
|
||||
#
|
||||
# We expect LIB* to be set to absolute path of a library -
|
||||
# suitable for putting in DPADD.
|
||||
# eg.
|
||||
#
|
||||
# LIBC ?= ${OBJTOP}/lib/libc/libc.a
|
||||
#
|
||||
# From such a path we can derrive a number of other variables
|
||||
# for which we can supply sensible default values.
|
||||
# We name all these variables for the basename of the library
|
||||
# (libc in our example above -- ${__lib:T:R} in below):
|
||||
#
|
||||
# LDADD_${__lib:T:R}:
|
||||
# What should be added to LDADD (eg -lc)
|
||||
#
|
||||
# OBJ_${__lib:T:R}:
|
||||
# This is trivial - just the dirname of the built library.
|
||||
#
|
||||
# SRC_${__lib:T:R}:
|
||||
# Where the src for ${__lib} is, if LIB* is set as above
|
||||
# we can simply substitute ${SRCTOP} for ${OBJTOP} in
|
||||
# the dirname.
|
||||
#
|
||||
# INCLUDES_${__lib:T:R}:
|
||||
# What should be added to CFLAGS
|
||||
#
|
||||
# If the directory ${SRC_${__lib:T:R}}/h exists we will
|
||||
# only add -I${SRC_${__lib:T:R}}/h on the basis that
|
||||
# this is where the public api is kept.
|
||||
#
|
||||
# Otherwise default will be -I${OBJ_${__lib:T:R}}
|
||||
# -I${SRC_${__lib:T:R}}
|
||||
#
|
||||
# Note much of the above is skipped for staged libs
|
||||
# eg.
|
||||
# LIBC ?= ${STAGE_OBJTOP}/usr/lib/libc.a
|
||||
#
|
||||
# Since we can safely assume that -I${STAGE_OBJTOP}/usr/include
|
||||
# and -L${STAGE_OBJTOP}/usr/lib are sufficient, and we should
|
||||
# have no need of anything else.
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
# sometimes we play games with .CURDIR etc
|
||||
# _* hold the original values of .*
|
||||
_OBJDIR?= ${.OBJDIR}
|
||||
_CURDIR?= ${.CURDIR}
|
||||
|
||||
.if ${_CURDIR} == ${SRCTOP}
|
||||
RELDIR=.
|
||||
RELTOP=.
|
||||
.else
|
||||
RELDIR?= ${_CURDIR:S,${SRCTOP}/,,}
|
||||
.if ${RELDIR} == ${_CURDIR}
|
||||
RELDIR?= ${_OBJDIR:S,${OBJTOP}/,,}
|
||||
.endif
|
||||
RELTOP?= ${RELDIR:C,[^/]+,..,g}
|
||||
.endif
|
||||
RELOBJTOP?= ${OBJTOP}
|
||||
RELSRCTOP?= ${SRCTOP}
|
||||
|
||||
# we get included just about everywhere so this is handy...
|
||||
# C*DEBUG_XTRA are for defining on cmd line etc
|
||||
# so do not use in makefiles.
|
||||
.ifdef CFLAGS_DEBUG_XTRA
|
||||
CFLAGS_LAST += ${CFLAGS_DEBUG_XTRA}
|
||||
.endif
|
||||
.ifdef CXXFLAGS_DEBUG_XTRA
|
||||
CXXFLAGS_LAST += ${CXXFLAGS_DEBUG_XTRA}
|
||||
.endif
|
||||
|
||||
.-include <local.dpadd.mk>
|
||||
|
||||
# DPLIBS helps us ensure we keep DPADD and LDADD in sync
|
||||
DPLIBS+= ${DPLIBS_LAST}
|
||||
DPADD+= ${DPLIBS:N-*}
|
||||
.for __lib in ${DPLIBS}
|
||||
.if "${__lib:M-*}" != ""
|
||||
LDADD += ${__lib}
|
||||
.else
|
||||
LDADD += ${LDADD_${__lib:T:R}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
# DPADD can contain things other than libs
|
||||
__dpadd_libs := ${DPADD:M*/lib*}
|
||||
|
||||
.if defined(PROG) && ${MK_PROG_LDORDER_MK:Uno} != "no"
|
||||
# some libs have dependencies...
|
||||
# DPLIBS_* allows bsd.libnames.mk to flag libs which must be included
|
||||
# in DPADD for a given library.
|
||||
# Gather all such dependencies into __ldadd_all_xtras
|
||||
# dups will be dealt with later.
|
||||
# Note: libfoo_pic uses DPLIBS_libfoo
|
||||
__ldadd_all_xtras=
|
||||
.for __lib in ${__dpadd_libs:@d@${DPLIBS_${d:T:R:S,_pic,,}}@}
|
||||
__ldadd_all_xtras+= ${LDADD_${__lib}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
|
||||
.if "${DPADD:M${__lib}}" == ""
|
||||
DPADD+= ${__lib}
|
||||
.endif
|
||||
.endfor
|
||||
.endif
|
||||
# Last of all... for libc and libgcc
|
||||
DPADD+= ${DPADD_LAST}
|
||||
|
||||
# de-dupuplicate __ldadd_all_xtras into __ldadd_xtras
|
||||
# in reverse order so that libs end up listed after all that needed them.
|
||||
__ldadd_xtras=
|
||||
.for __lib in ${__ldadd_all_xtras:[-1..1]}
|
||||
.if "${__ldadd_xtras:M${__lib}}" == "" || ${NEED_IMPLICIT_LDADD:tl:Uno} != "no"
|
||||
__ldadd_xtras+= ${__lib}
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
.if !empty(__ldadd_xtras)
|
||||
# now back to the original order
|
||||
__ldadd_xtras:= ${__ldadd_xtras:[-1..1]}
|
||||
LDADD+= ${__ldadd_xtras}
|
||||
.endif
|
||||
|
||||
# Convert DPADD into -I and -L options and add them to CPPFLAGS and LDADD
|
||||
# For the -I's convert the path to a relative one. For separate objdirs
|
||||
# the DPADD paths will be to the obj tree so we need to subst anyway.
|
||||
|
||||
# update this
|
||||
__dpadd_libs := ${DPADD:M*/lib*}
|
||||
|
||||
# Order -L's to search ours first.
|
||||
# Avoids picking up old versions already installed.
|
||||
__dpadd_libdirs := ${__dpadd_libs:R:H:S/^/-L/g:O:u:N-L}
|
||||
LDADD += ${__dpadd_libdirs:M-L${OBJTOP}/*}
|
||||
LDADD += ${__dpadd_libdirs:N-L${OBJTOP}/*:N-L${HOST_LIBDIR:U/usr/lib}}
|
||||
.if defined(HOST_LIBDIR) && ${HOST_LIBDIR} != "/usr/lib"
|
||||
LDADD+= -L${HOST_LIBDIR}
|
||||
.endif
|
||||
|
||||
.if !make(dpadd)
|
||||
.ifdef LIB
|
||||
# Each lib is its own src_lib, we want to include it in SRC_LIBS
|
||||
# so that the correct INCLUDES_* will be picked up automatically.
|
||||
SRC_LIBS+= ${_OBJDIR}/lib${LIB}.a
|
||||
.endif
|
||||
.endif
|
||||
|
||||
#
|
||||
# This little bit of magic, assumes that SRC_libfoo will be
|
||||
# set if it cannot be correctly derrived from ${LIBFOO}
|
||||
# Note that SRC_libfoo and INCLUDES_libfoo should be named for the
|
||||
# actual library name not the variable name that might refer to it.
|
||||
# 99% of the time the two are the same, but the DPADD logic
|
||||
# only has the library name available, so stick to that.
|
||||
#
|
||||
|
||||
SRC_LIBS?=
|
||||
# magic_libs includes those we want to link with
|
||||
# as well as those we might look at
|
||||
__dpadd_magic_libs += ${__dpadd_libs} ${SRC_LIBS}
|
||||
DPMAGIC_LIBS += ${__dpadd_magic_libs} \
|
||||
${__dpadd_magic_libs:@d@${DPMAGIC_LIBS_${d:T:R}}@}
|
||||
|
||||
# we skip this for staged libs
|
||||
.for __lib in ${DPMAGIC_LIBS:O:u:N${STAGE_OBJTOP:Unot}*/lib/*}
|
||||
#
|
||||
# if SRC_libfoo is not set, then we assume that the srcdir corresponding
|
||||
# to where we found the library is correct.
|
||||
#
|
||||
SRC_${__lib:T:R} ?= ${__lib:H:S,${OBJTOP},${RELSRCTOP},}
|
||||
#
|
||||
# This is a no-brainer but just to be complete...
|
||||
#
|
||||
OBJ_${__lib:T:R} ?= ${__lib:H:S,${OBJTOP},${RELOBJTOP},}
|
||||
#
|
||||
# If INCLUDES_libfoo is not set, then we'll use ${SRC_libfoo}/h if it exists,
|
||||
# else just ${SRC_libfoo}.
|
||||
#
|
||||
INCLUDES_${__lib:T:R}?= -I${exists(${SRC_${__lib:T:R}}/h):?${SRC_${__lib:T:R}}/h:${SRC_${__lib:T:R}}}
|
||||
|
||||
.endfor
|
||||
|
||||
# even for staged libs we sometimes
|
||||
# need to allow direct -I to avoid cicular dependencies
|
||||
.for __lib in ${DPMAGIC_LIBS:O:u:T:R}
|
||||
.if !empty(SRC_${__lib}) && empty(INCLUDES_${__lib})
|
||||
# must be a staged lib
|
||||
.if exists(${SRC_${__lib}}/h)
|
||||
INCLUDES_${__lib} = -I${SRC_${__lib}}/h
|
||||
.else
|
||||
INCLUDES_${__lib} = -I${SRC_${__lib}}
|
||||
.endif
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
# when linking a shared lib, avoid non pic libs
|
||||
SHLDADD+= ${LDADD:N-[lL]*}
|
||||
.for __lib in ${__dpadd_libs:u}
|
||||
.if defined(SHLIB_NAME) && ${LDADD:M-l${__lib:T:R:S,lib,,}} != ""
|
||||
.if ${__lib:T:N*_pic.a:N*.so} == "" || exists(${__lib:R}.so)
|
||||
SHLDADD+= -l${__lib:T:R:S,lib,,}
|
||||
.elif exists(${__lib:R}_pic.a)
|
||||
SHLDADD+= -l${__lib:T:R:S,lib,,}_pic
|
||||
.else
|
||||
.warning ${RELDIR}.${TARGET_SPEC} needs ${__lib:T:R}_pic.a
|
||||
SHLDADD+= -l${__lib:T:R:S,lib,,}
|
||||
.endif
|
||||
SHLDADD+= -L${__lib:H}
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
# Now for the bits we actually need
|
||||
__dpadd_incs=
|
||||
.for __lib in ${__dpadd_libs:u}
|
||||
.if (make(${PROG}_p) || defined(NEED_GPROF)) && exists(${__lib:R}_p.a)
|
||||
__ldadd=-l${__lib:T:R:S,lib,,}
|
||||
LDADD := ${LDADD:S,^${__ldadd}$,${__ldadd}_p,g}
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
#
|
||||
# We take care of duplicate suppression later.
|
||||
# don't apply :T:R too early
|
||||
__dpadd_incs += ${__dpadd_magic_libs:u:@x@${INCLUDES_${x:T:R}}@}
|
||||
__dpadd_incs += ${__dpadd_magic_libs:O:u:@s@${SRC_LIBS_${s:T:R}:U}@:@x@${INCLUDES_${x:T:R}}@}
|
||||
|
||||
__dpadd_last_incs += ${__dpadd_magic_libs:u:@x@${INCLUDES_LAST_${x:T:R}}@}
|
||||
__dpadd_last_incs += ${__dpadd_magic_libs:O:u:@s@${SRC_LIBS_${s:T:R}:U}@:@x@${INCLUDES_LAST_${x:T:R}}@}
|
||||
|
||||
.if defined(HOSTPROG) || ${MACHINE:Nhost*} == ""
|
||||
# we want any -I/usr/* last
|
||||
__dpadd_last_incs := \
|
||||
${__dpadd_last_incs:N-I/usr/*} \
|
||||
${__dpadd_incs:M-I/usr/*} \
|
||||
${__dpadd_last_incs:M-I/usr/*}
|
||||
__dpadd_incs := ${__dpadd_incs:N-I/usr/*}
|
||||
.endif
|
||||
|
||||
#
|
||||
# eliminate any duplicates - but don't mess with the order
|
||||
# force evaluation now - to avoid giving make a headache
|
||||
#
|
||||
.for t in CFLAGS CXXFLAGS
|
||||
# avoid duplicates
|
||||
__$t_incs:=${$t:M-I*:O:u}
|
||||
.for i in ${__dpadd_incs}
|
||||
.if "${__$t_incs:M$i}" == ""
|
||||
$t+= $i
|
||||
__$t_incs+= $i
|
||||
.endif
|
||||
.endfor
|
||||
.endfor
|
||||
|
||||
.for t in CFLAGS_LAST CXXFLAGS_LAST
|
||||
# avoid duplicates
|
||||
__$t_incs:=${$t:M-I*:u}
|
||||
.for i in ${__dpadd_last_incs}
|
||||
.if "${__$t_incs:M$i}" == ""
|
||||
$t+= $i
|
||||
__$t_incs+= $i
|
||||
.endif
|
||||
.endfor
|
||||
.endfor
|
||||
|
||||
# This target is used to gather a list of
|
||||
# dir: ${DPADD}
|
||||
# entries
|
||||
.if make(*dpadd*)
|
||||
.if !target(dpadd)
|
||||
dpadd: .NOTMAIN
|
||||
.if defined(DPADD) && ${DPADD} != ""
|
||||
@echo "${RELDIR}: ${DPADD:S,${OBJTOP}/,,}"
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.ifdef SRC_PATHADD
|
||||
# We don't want to assume that we need to .PATH every element of
|
||||
# SRC_LIBS, but the Makefile cannot do
|
||||
# .PATH: ${SRC_libfoo}
|
||||
# since the value of SRC_libfoo must be available at the time .PATH:
|
||||
# is read - and we only just worked it out.
|
||||
# Further, they can't wait until after include of {lib,prog}.mk as
|
||||
# the .PATH is needed before then.
|
||||
# So we let the Makefile do
|
||||
# SRC_PATHADD+= ${SRC_libfoo}
|
||||
# and we defer the .PATH: until now so that SRC_libfoo will be available.
|
||||
.PATH: ${SRC_PATHADD}
|
||||
.endif
|
||||
|
||||
# after all that, if doing -n we don't care
|
||||
.if ${.MAKEFLAGS:Ux:M-n} != ""
|
||||
DPADD =
|
||||
.elif ${.MAKE.MODE:Mmeta*} != "" && exists(${.MAKE.DEPENDFILE})
|
||||
DPADD_CLEAR_DPADD ?= yes
|
||||
.if ${DPADD_CLEAR_DPADD} == "yes"
|
||||
# save this
|
||||
__dpadd_libs := ${__dpadd_libs}
|
||||
# we have made what use of it we can of DPADD
|
||||
DPADD =
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.endif
|
83
20200902/mk/files.mk
Normal file
83
20200902/mk/files.mk
Normal file
@ -0,0 +1,83 @@
|
||||
# $Id: files.mk,v 1.7 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2017, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.include <init.mk>
|
||||
|
||||
FILES_INSTALL_OWN ?= -o ${SHAREOWN} -g ${SHAREGRP}
|
||||
FILESMODE ?= ${SHAREMODE}
|
||||
FILES_COPY ?= -C
|
||||
|
||||
FILESGROUPS ?= FILES
|
||||
FILESGROUPS := ${FILESGROUPS:O:u}
|
||||
|
||||
.if !target(buildfiles)
|
||||
.for group in ${FILESGROUPS}
|
||||
buildfiles: ${${group}}
|
||||
.endfor
|
||||
.endif
|
||||
buildfiles:
|
||||
realbuild: buildfiles
|
||||
|
||||
# there is no default FILESDIR so
|
||||
# ignore group if ${group}DIR is not defined
|
||||
.for group in ${FILESGROUPS}
|
||||
.if !empty(${group}) && defined(${group}DIR)
|
||||
.if ${group} != "FILES"
|
||||
${group}_INSTALL_OWN ?= ${FILES_INSTALL_OWN}
|
||||
.endif
|
||||
# incase we are staging
|
||||
STAGE_DIR.${group} ?= ${STAGE_OBJTOP}${${group}DIR}
|
||||
|
||||
.for file in ${${group}:O:u}
|
||||
${group}_INSTALL_OWN.${file:T} ?= ${${group}_INSTALL_OWN}
|
||||
${group}DIR.${file:T} ?= ${${group}DIR}
|
||||
file_mkdir_list += ${${group}DIR.${file:T}}
|
||||
|
||||
.if defined(${group}NAME.${file:T})
|
||||
STAGE_AS_SETS += ${group}
|
||||
STAGE_AS_${file} = ${${group}NAME.${file:T}}
|
||||
stage_as.${group}: ${file}
|
||||
|
||||
installfiles: installfiles.${group}.${file:T}
|
||||
installfiles.${group}.${file:T}: ${file} file_mkdirs
|
||||
${INSTALL} ${FILES_COPY} ${${group}_INSTALL_OWN.${file:T}} \
|
||||
-m ${FILESMODE} ${.ALLSRC:Nfile_mkdirs} ${DESTDIR}${${group}DIR}/${${group}NAME.${file:T}}
|
||||
|
||||
.else
|
||||
STAGE_SETS += ${group}
|
||||
stage_files.${group}: ${file}
|
||||
installfiles.${group}: ${file}
|
||||
installfiles: installfiles.${group}
|
||||
.endif
|
||||
|
||||
.endfor # file
|
||||
|
||||
installfiles.${group}: file_mkdirs
|
||||
${INSTALL} ${FILES_COPY} ${${group}_INSTALL_OWN} -m ${FILESMODE} \
|
||||
${.ALLSRC:Nfile_mkdirs:O:u} ${DESTDIR}${${group}DIR}
|
||||
|
||||
.endif # !empty
|
||||
.endfor # group
|
||||
|
||||
file_mkdirs:
|
||||
@for d in ${file_mkdir_list:O:u}; do \
|
||||
test -d ${DESTDIR}$$d || \
|
||||
${INSTALL} -d ${FILES_INSTALL_OWN} -m 775 ${DESTDIR}$$d; \
|
||||
done
|
||||
|
||||
beforeinstall:
|
||||
installfiles:
|
||||
realinstall: installfiles
|
||||
.ORDER: beforeinstall installfiles
|
22
20200902/mk/final.mk
Normal file
22
20200902/mk/final.mk
Normal file
@ -0,0 +1,22 @@
|
||||
# $Id: final.mk,v 1.9 2018/01/24 22:57:11 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
# provide a hook for folk who want to do scary stuff
|
||||
.-include <${.CURDIR:H}/Makefile-final.inc>
|
||||
|
||||
.-include <local.final.mk>
|
||||
|
||||
.if ${MK_STAGING} == "yes"
|
||||
.include <meta.stage.mk>
|
||||
.elif !empty(STAGE)
|
||||
.-include <stage.mk>
|
||||
.endif
|
||||
|
||||
.if empty(_SKIP_BUILD)
|
||||
install: realinstall
|
||||
.endif
|
||||
realinstall:
|
||||
|
||||
.endif
|
385
20200902/mk/gendirdeps.mk
Normal file
385
20200902/mk/gendirdeps.mk
Normal file
@ -0,0 +1,385 @@
|
||||
# $Id: gendirdeps.mk,v 1.46 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
# Copyright (c) 2011-2020, Simon J. Gerraty
|
||||
# Copyright (c) 2010-2018, Juniper Networks, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#
|
||||
# This makefile [re]generates ${.MAKE.DEPENDFILE}
|
||||
#
|
||||
|
||||
.include <install-new.mk>
|
||||
|
||||
# Assumptions:
|
||||
# RELDIR is the relative path from ${SRCTOP} to ${_CURDIR}
|
||||
# (SRCTOP is ${SB}/src)
|
||||
# _CURDIR is the absolute version of ${.CURDIR}
|
||||
# _OBJDIR is the absolute version of ${.OBJDIR}
|
||||
# _objroot is realpath of ${_OBJTOP} without ${MACHINE}
|
||||
# this may be different from _OBJROOT if $SB/obj is a
|
||||
# symlink to another filesystem.
|
||||
# _objroot must be a prefix match for _objtop
|
||||
|
||||
.MAIN: all
|
||||
|
||||
# keep this simple
|
||||
.MAKE.MODE = compat
|
||||
|
||||
all:
|
||||
|
||||
_CURDIR ?= ${.CURDIR}
|
||||
_OBJDIR ?= ${.OBJDIR}
|
||||
_OBJTOP ?= ${OBJTOP}
|
||||
_OBJROOT ?= ${OBJROOT:U${_OBJTOP:H}}
|
||||
.if ${_OBJROOT:M*/}
|
||||
_slash=/
|
||||
.else
|
||||
_slash=
|
||||
.endif
|
||||
_objroot ?= ${_OBJROOT:tA}${_slash}
|
||||
|
||||
_this = ${.PARSEDIR}/${.PARSEFILE}
|
||||
|
||||
# remember what to make
|
||||
_DEPENDFILE := ${_CURDIR}/${.MAKE.DEPENDFILE:T}
|
||||
|
||||
# We do _not_ want to read our own output!
|
||||
.MAKE.DEPENDFILE = /dev/null
|
||||
|
||||
# caller should have set this
|
||||
META_FILES ?= ${.MAKE.META.FILES}
|
||||
|
||||
.if !empty(META_FILES)
|
||||
|
||||
.if ${.MAKE.LEVEL} > 0 && !empty(GENDIRDEPS_FILTER)
|
||||
# so we can compare below
|
||||
.-include <${_DEPENDFILE}>
|
||||
# yes, I mean :U with no value
|
||||
_DIRDEPS := ${DIRDEPS:U:O:u}
|
||||
.endif
|
||||
|
||||
META_FILES := ${META_FILES:T:O:u}
|
||||
|
||||
# pickup customizations
|
||||
.-include <local.gendirdeps.mk>
|
||||
|
||||
# these are actually prefixes that we'll skip
|
||||
# they should all be absolute paths
|
||||
SKIP_GENDIRDEPS ?=
|
||||
.if !empty(SKIP_GENDIRDEPS)
|
||||
_skip_gendirdeps = egrep -v '^(${SKIP_GENDIRDEPS:O:u:ts|})' |
|
||||
.else
|
||||
_skip_gendirdeps =
|
||||
.endif
|
||||
|
||||
# Below we will turn _{VAR} into ${VAR} which keeps this simple
|
||||
# GENDIRDEPS_FILTER_DIR_VARS is a list of dirs to be substiuted for.
|
||||
# GENDIRDEPS_FILTER_VARS is more general.
|
||||
# In each case order matters.
|
||||
.if !empty(GENDIRDEPS_FILTER_DIR_VARS)
|
||||
GENDIRDEPS_FILTER += ${GENDIRDEPS_FILTER_DIR_VARS:@v@S,${$v},_{${v}},@}
|
||||
.endif
|
||||
.if !empty(GENDIRDEPS_FILTER_VARS)
|
||||
GENDIRDEPS_FILTER += ${GENDIRDEPS_FILTER_VARS:@v@S,/${$v}/,/_{${v}}/,@:NS,//,*:u}
|
||||
.endif
|
||||
|
||||
# this (*should* be set in meta.sys.mk)
|
||||
# is the script that extracts what we want.
|
||||
META2DEPS ?= ${.PARSEDIR}/meta2deps.sh
|
||||
META2DEPS := ${META2DEPS}
|
||||
|
||||
.if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != "" && ${DEBUG_GENDIRDEPS:Uno:Mmeta2d*} != ""
|
||||
_time = time
|
||||
_sh_x = sh -x
|
||||
_py_d = -ddd
|
||||
.else
|
||||
_time =
|
||||
_sh_x =
|
||||
_py_d =
|
||||
.endif
|
||||
|
||||
.if ${META2DEPS:E} == "py"
|
||||
# we can afford to do this all the time.
|
||||
DPDEPS ?= no
|
||||
META2DEPS_CMD = ${_time} ${PYTHON} ${META2DEPS} ${_py_d}
|
||||
.if ${DPDEPS:tl} != "no"
|
||||
META2DEPS_CMD += -D ${DPDEPS}
|
||||
.endif
|
||||
META2DEPS_FILTER = sed 's,^src:,${SRCTOP}/,;s,^\([^/]\),${OBJTOP}/\1,' |
|
||||
.elif ${META2DEPS:E} == "sh"
|
||||
META2DEPS_CMD = ${_time} ${_sh_x} ${META2DEPS} OBJTOP=${_OBJTOP}
|
||||
.else
|
||||
META2DEPS_CMD ?= ${META2DEPS}
|
||||
.endif
|
||||
|
||||
.if ${TARGET_OBJ_SPEC:U${MACHINE}} != ${MACHINE}
|
||||
META2DEPS_CMD += -T ${TARGET_OBJ_SPEC}
|
||||
.endif
|
||||
META2DEPS_CMD += \
|
||||
-R ${RELDIR} -H ${HOST_TARGET} \
|
||||
${M2D_OBJROOTS:O:u:@o@-O $o@} \
|
||||
${M2D_EXCLUDES:O:u:@o@-X $o@} \
|
||||
|
||||
|
||||
M2D_OBJROOTS += ${OBJTOP} ${_OBJROOT} ${_objroot}
|
||||
.if defined(SB_OBJROOT)
|
||||
M2D_OBJROOTS += ${SB_OBJROOT}
|
||||
.endif
|
||||
.if defined(STAGE_ROOT)
|
||||
M2D_OBJROOTS += ${STAGE_ROOT}
|
||||
.endif
|
||||
.if ${.MAKE.DEPENDFILE_PREFERENCE:U${.MAKE.DEPENDFILE}:M*.${MACHINE}} == ""
|
||||
# meta2deps.py only groks objroot
|
||||
# so we need to give it what it expects
|
||||
# and tell it not to add machine qualifiers
|
||||
META2DEPS_ARGS += MACHINE=none
|
||||
.endif
|
||||
.if defined(SB_BACKING_SB)
|
||||
META2DEPS_CMD += -S ${SB_BACKING_SB}/src
|
||||
M2D_OBJROOTS += ${SB_BACKING_SB}/${SB_OBJPREFIX}
|
||||
.endif
|
||||
|
||||
GENDIRDEPS_SEDCMDS += \
|
||||
-e 's,//*$$,,;s,\.${HOST_TARGET:Uhost}$$,.host,' \
|
||||
-e 's,\.${HOST_TARGET32:Uhost32}$$,.host32,' \
|
||||
-e 's,\.${MACHINE}$$,,' \
|
||||
-e 's:\.${TARGET_SPEC:U${MACHINE}}$$::'
|
||||
|
||||
# we are only interested in the dirs
|
||||
# specifically those we read something from.
|
||||
# we canonicalize them to keep things simple
|
||||
# if we are using a split-fs sandbox, it gets a little messier.
|
||||
_objtop := ${_OBJTOP:tA}
|
||||
|
||||
# some people put *.meta in META_XTRAS to make sure we get here
|
||||
_meta_files := ${META_FILES:N\*.meta:O:u}
|
||||
# assume a big list
|
||||
_meta_files_arg= @meta.list
|
||||
.if empty(_meta_files) && ${META_FILES:M\*.meta} != ""
|
||||
# XXX this should be considered a bad idea,
|
||||
# since we cannot ignore stale .meta
|
||||
x != cd ${_OBJDIR} && find . -name '*.meta' -print -o \( -type d ! -name . -prune \) | sed 's,^./,,' > meta.list; echo
|
||||
.elif ${_meta_files:[#]} > 500
|
||||
.export _meta_files
|
||||
x != echo; for m in $$_meta_files; do echo $$m; done > meta.list
|
||||
# _meta_files is consuming a lot of env space
|
||||
# that can impact command line length,
|
||||
# and we do not need it any more
|
||||
.undef _meta_files
|
||||
.unexport _meta_files
|
||||
.else
|
||||
_meta_files_arg:= ${_meta_files}
|
||||
.endif
|
||||
|
||||
dir_list != cd ${_OBJDIR} && \
|
||||
${META2DEPS_CMD} MACHINE=${MACHINE} \
|
||||
SRCTOP=${SRCTOP} RELDIR=${RELDIR} CURDIR=${_CURDIR} \
|
||||
${META2DEPS_ARGS} \
|
||||
${_meta_files_arg} | ${META2DEPS_FILTER} ${_skip_gendirdeps} \
|
||||
sed ${GENDIRDEPS_SEDCMDS}
|
||||
|
||||
.if ${dir_list:M*ERROR\:*} != ""
|
||||
.warning ${dir_list:tW:C,.*(ERROR),\1,}
|
||||
.warning Skipping ${_DEPENDFILE:S,${SRCTOP}/,,}
|
||||
# we are not going to update anything
|
||||
.else
|
||||
dpadd_dir_list=
|
||||
.if !empty(DPADD)
|
||||
_nonlibs := ${DPADD:T:Nlib*:N*include}
|
||||
.if !empty(_nonlibs)
|
||||
ddep_list =
|
||||
.for f in ${_nonlibs:@x@${DPADD:M*/$x}@}
|
||||
.if exists($f.dirdep)
|
||||
ddep_list += $f.dirdep
|
||||
.elif exists(${f:H}.dirdep)
|
||||
ddep_list += ${f:H}.dirdep
|
||||
.else
|
||||
dir_list += ${f:H:tA}
|
||||
dpadd_dir_list += ${f:H:tA}
|
||||
.endif
|
||||
.endfor
|
||||
.if !empty(ddep_list)
|
||||
ddeps != cat ${ddep_list:O:u} | ${META2DEPS_FILTER} ${_skip_gendirdeps} \
|
||||
sed ${GENDIRDEPS_SEDCMDS}
|
||||
|
||||
.if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != ""
|
||||
.info ${RELDIR}: raw_dir_list='${dir_list}'
|
||||
.info ${RELDIR}: ddeps='${ddeps}'
|
||||
.endif
|
||||
dir_list += ${ddeps}
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# DIRDEPS represent things that had to have been built first
|
||||
# so they should all be undir OBJTOP.
|
||||
# Note that ${_OBJTOP}/bsd/include/machine will get reported
|
||||
# to us as $SRCTOP/bsd/sys/$MACHINE_ARCH/include meaning we
|
||||
# will want to visit bsd/include
|
||||
# so we add
|
||||
# ${"${dir_list:M*bsd/sys/${MACHINE_ARCH}/include}":?bsd/include:}
|
||||
# to GENDIRDEPS_DIR_LIST_XTRAS
|
||||
_objtops = ${OBJTOP} ${_OBJTOP} ${_objtop}
|
||||
_objtops := ${_objtops:O:u}
|
||||
dirdep_list = \
|
||||
${_objtops:@o@${dir_list:M$o*/*:C,$o[^/]*/,,}@} \
|
||||
${GENDIRDEPS_DIR_LIST_XTRAS}
|
||||
|
||||
# sort longest first
|
||||
M2D_OBJROOTS := ${M2D_OBJROOTS:O:u:[-1..1]}
|
||||
|
||||
# anything we use from an object dir other than ours
|
||||
# needs to be qualified with its .<machine> suffix
|
||||
# (we used the pseudo machine "host" for the HOST_TARGET).
|
||||
skip_ql= ${SRCTOP}* ${_objtops:@o@$o*@}
|
||||
.for o in ${M2D_OBJROOTS:${skip_ql:${M_ListToSkip}}}
|
||||
# we need := so only skip_ql to this point applies
|
||||
ql.$o := ${dir_list:${skip_ql:${M_ListToSkip}}:M$o*/*/*:C,$o([^/]+)/(.*),\2.\1,:S,.${HOST_TARGET},.host,}
|
||||
qualdir_list += ${ql.$o}
|
||||
.if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != ""
|
||||
.info ${RELDIR}: o=$o ${ql.$o qualdir_list:L:@v@$v=${$v}@}
|
||||
.endif
|
||||
skip_ql+= $o*
|
||||
.endfor
|
||||
|
||||
dirdep_list := ${dirdep_list:O:u}
|
||||
qualdir_list := ${qualdir_list:N*.${MACHINE}:O:u}
|
||||
|
||||
DIRDEPS = \
|
||||
${dirdep_list:N${RELDIR}:N${RELDIR}/*} \
|
||||
${qualdir_list:N${RELDIR}.*:N${RELDIR}/*}
|
||||
|
||||
# We only consider things below $RELDIR/ if they have a makefile.
|
||||
# This is the same test that _DIRDEP_USE applies.
|
||||
# We have do a double test with dirdep_list as it _may_ contain
|
||||
# qualified dirs - if we got anything from a stage dir.
|
||||
# qualdir_list we know are all qualified.
|
||||
# It would be nice do peform this check for all of DIRDEPS,
|
||||
# but we cannot assume that all of the tree is present,
|
||||
# in fact we can only assume that RELDIR is.
|
||||
DIRDEPS += \
|
||||
${dirdep_list:M${RELDIR}/*:@d@${.MAKE.MAKEFILE_PREFERENCE:@m@${exists(${SRCTOP}/$d/$m):?$d:${exists(${SRCTOP}/${d:R}/$m):?$d:}}@}@} \
|
||||
${qualdir_list:M${RELDIR}/*:@d@${.MAKE.MAKEFILE_PREFERENCE:@m@${exists(${SRCTOP}/${d:R}/$m):?$d:}@}@}
|
||||
|
||||
# what modifiers do we allow in GENDIRDEPS_FILTER
|
||||
GENDIRDEPS_FILTER_MASK += @CMNS
|
||||
DIRDEPS := ${DIRDEPS:${GENDIRDEPS_FILTER:UNno:M[${GENDIRDEPS_FILTER_MASK:O:u:ts}]*:ts:}:C,//+,/,g:O:u}
|
||||
|
||||
.if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != ""
|
||||
.info ${RELDIR}: M2D_OBJROOTS=${M2D_OBJROOTS}
|
||||
.info ${RELDIR}: M2D_EXCLUDES=${M2D_EXCLUDES}
|
||||
.info ${RELDIR}: dir_list='${dir_list}'
|
||||
.info ${RELDIR}: dpadd_dir_list='${dpadd_dir_list}'
|
||||
.info ${RELDIR}: dirdep_list='${dirdep_list}'
|
||||
.info ${RELDIR}: qualdir_list='${qualdir_list}'
|
||||
.info ${RELDIR}: SKIP_GENDIRDEPS='${SKIP_GENDIRDEPS}'
|
||||
.info ${RELDIR}: GENDIRDEPS_FILTER='${GENDIRDEPS_FILTER}'
|
||||
.info ${RELDIR}: FORCE_DPADD='${DPADD}'
|
||||
.info ${RELDIR}: DIRDEPS='${DIRDEPS}'
|
||||
.endif
|
||||
|
||||
# SRC_DIRDEPS is for checkout logic
|
||||
src_dirdep_list = \
|
||||
${dir_list:M${SRCTOP}/*:S,${SRCTOP}/,,}
|
||||
|
||||
SRC_DIRDEPS = \
|
||||
${src_dirdep_list:N${RELDIR}:N${RELDIR}/*:C,(/h)/.*,,}
|
||||
|
||||
SRC_DIRDEPS := ${SRC_DIRDEPS:${GENDIRDEPS_SRC_FILTER:UN/*:ts:}:C,//+,/,g:O:u}
|
||||
|
||||
# if you want to capture SRC_DIRDEPS in .MAKE.DEPENDFILE put
|
||||
# SRC_DIRDEPS_FILE = ${_DEPENDFILE}
|
||||
# in local.gendirdeps.mk
|
||||
.if ${SRC_DIRDEPS_FILE:Uno:tl} != "no"
|
||||
ECHO_SRC_DIRDEPS = echo 'SRC_DIRDEPS = \'; echo '${SRC_DIRDEPS:@d@ $d \\${.newline}@}'; echo;
|
||||
|
||||
.if ${SRC_DIRDEPS_FILE:T} == ${_DEPENDFILE:T}
|
||||
_include_src_dirdeps = ${ECHO_SRC_DIRDEPS}
|
||||
.else
|
||||
all: ${SRC_DIRDEPS_FILE}
|
||||
.if !target(${SRC_DIRDEPS_FILE})
|
||||
${SRC_DIRDEPS_FILE}: ${META_FILES} ${_this} ${META2DEPS}
|
||||
@(${ECHO_SRC_DIRDEPS}) > $@
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
_include_src_dirdeps ?=
|
||||
|
||||
all: ${_DEPENDFILE}
|
||||
|
||||
# if this is going to exist it would be there by now
|
||||
.if !exists(.depend)
|
||||
CAT_DEPEND = /dev/null
|
||||
.endif
|
||||
CAT_DEPEND ?= .depend
|
||||
|
||||
.if !empty(_DIRDEPS) && ${DIRDEPS} != ${_DIRDEPS}
|
||||
# we may have changed a filter
|
||||
.PHONY: ${_DEPENDFILE}
|
||||
.endif
|
||||
|
||||
LOCAL_DEPENDS_GUARD ?= _{.MAKE.LEVEL} > 0
|
||||
|
||||
# 'cat .depend' should suffice, but if we are mixing build modes
|
||||
# .depend may contain things we don't want.
|
||||
# The sed command at the end of the stream, allows for the filters
|
||||
# to output _{VAR} tokens which we will turn into proper ${VAR} references.
|
||||
${_DEPENDFILE}: .NOMETA ${CAT_DEPEND:M.depend} ${META_FILES:O:u:@m@${exists($m):?$m:}@} ${_this} ${META2DEPS}
|
||||
@(${GENDIRDEPS_HEADER} echo '# Autogenerated - do NOT edit!'; echo; \
|
||||
echo 'DIRDEPS = \'; \
|
||||
echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \
|
||||
${_include_src_dirdeps} \
|
||||
echo '.include <dirdeps.mk>'; \
|
||||
echo; \
|
||||
echo '.if ${LOCAL_DEPENDS_GUARD}'; \
|
||||
echo '# local dependencies - needed for -jN in clean tree'; \
|
||||
[ -s ${CAT_DEPEND} ] && { grep : ${CAT_DEPEND} | grep -v '[/\\]'; }; \
|
||||
echo '.endif' ) | sed 's,_\([{(]\),$$\1,g' > $@.new${.MAKE.PID}
|
||||
@${InstallNew}; InstallNew -s $@.new${.MAKE.PID}
|
||||
|
||||
.endif # meta2deps failed
|
||||
.elif !empty(SUBDIR)
|
||||
|
||||
DIRDEPS := ${SUBDIR:S,^,${RELDIR}/,:O:u}
|
||||
|
||||
all: ${_DEPENDFILE}
|
||||
|
||||
${_DEPENDFILE}: .NOMETA ${MAKEFILE} ${_this}
|
||||
@(${GENDIRDEPS_HEADER} echo '# Autogenerated - do NOT edit!'; echo; \
|
||||
echo 'DIRDEPS = \'; \
|
||||
echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \
|
||||
echo '.include <dirdeps.mk>'; \
|
||||
echo ) | sed 's,_\([{(]\),$$\1,g' > $@.new
|
||||
@${InstallNew}; InstallNew $@.new
|
||||
|
||||
.else
|
||||
|
||||
# nothing to do
|
||||
all ${_DEPENDFILE}:
|
||||
|
||||
.endif
|
||||
${_DEPENDFILE}: .PRECIOUS
|
||||
|
||||
# don't waste time looking for ways to make .meta files
|
||||
.SUFFIXES:
|
49
20200902/mk/host-target.mk
Normal file
49
20200902/mk/host-target.mk
Normal file
@ -0,0 +1,49 @@
|
||||
# RCSid:
|
||||
# $Id: host-target.mk,v 1.13 2020/08/05 23:32:08 sjg Exp $
|
||||
|
||||
# Host platform information; may be overridden
|
||||
.if !defined(_HOST_OSNAME)
|
||||
_HOST_OSNAME != uname -s
|
||||
.export _HOST_OSNAME
|
||||
.endif
|
||||
.if !defined(_HOST_OSREL)
|
||||
_HOST_OSREL != uname -r
|
||||
.export _HOST_OSREL
|
||||
.endif
|
||||
.if !defined(_HOST_MACHINE)
|
||||
_HOST_MACHINE != uname -m
|
||||
.export _HOST_MACHINE
|
||||
.endif
|
||||
.if !defined(_HOST_ARCH)
|
||||
# for NetBSD prefer $MACHINE (amd64 rather than x86_64)
|
||||
.if ${_HOST_OSNAME:NDarwin:NNetBSD} == ""
|
||||
_HOST_ARCH := ${_HOST_MACHINE}
|
||||
.else
|
||||
_HOST_ARCH != uname -p 2> /dev/null || uname -m
|
||||
# uname -p may produce garbage on linux
|
||||
.if ${_HOST_ARCH:[\#]} > 1 || ${_HOST_ARCH:Nunknown} == ""
|
||||
_HOST_ARCH := ${_HOST_MACHINE}
|
||||
.endif
|
||||
.endif
|
||||
.export _HOST_ARCH
|
||||
.endif
|
||||
.if !defined(HOST_MACHINE)
|
||||
HOST_MACHINE := ${_HOST_MACHINE}
|
||||
.export HOST_MACHINE
|
||||
.endif
|
||||
|
||||
HOST_OSMAJOR := ${_HOST_OSREL:C/[^0-9].*//}
|
||||
HOST_OSTYPE := ${_HOST_OSNAME:S,/,,g}-${_HOST_OSREL:C/\([^\)]*\)//}-${_HOST_ARCH}
|
||||
HOST_OS := ${_HOST_OSNAME}
|
||||
host_os := ${_HOST_OSNAME:tl}
|
||||
HOST_TARGET := ${host_os:S,/,,g}${HOST_OSMAJOR}-${_HOST_ARCH}
|
||||
# sometimes we want HOST_TARGET32
|
||||
MACHINE32.amd64 = i386
|
||||
MACHINE32.x86_64 = i386
|
||||
_HOST_ARCH32 := ${MACHINE32.${_HOST_ARCH}:U${_HOST_ARCH:S,64$,,}}
|
||||
HOST_TARGET32 := ${host_os:S,/,,g}${HOST_OSMAJOR}-${_HOST_ARCH32}
|
||||
|
||||
# tr is insanely non-portable, accommodate the lowest common denominator
|
||||
TR ?= tr
|
||||
toLower = ${TR} 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'
|
||||
toUpper = ${TR} 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
29
20200902/mk/host.libnames.mk
Normal file
29
20200902/mk/host.libnames.mk
Normal file
@ -0,0 +1,29 @@
|
||||
# $Id: host.libnames.mk,v 1.5 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2007-2009, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
|
||||
DLIBEXT ?= .a
|
||||
DSHLIBEXT ?= ${DLIBEXT}
|
||||
HOST_LIBEXT ?= ${DSHLIBEXT}
|
||||
HOST_LIBDIRS ?= /usr/lib /lib
|
||||
HOST_LIBS ?=
|
||||
|
||||
.for x in ${HOST_LIBS:O:u}
|
||||
.for d in ${HOST_LIBDIRS}
|
||||
.if exists($d/lib$x${HOST_LIBEXT})
|
||||
LIB${x:tu} ?= $d/lib$x${HOST_LIBEXT}
|
||||
.endif
|
||||
.endfor
|
||||
.endfor
|
89
20200902/mk/inc.mk
Normal file
89
20200902/mk/inc.mk
Normal file
@ -0,0 +1,89 @@
|
||||
# $Id: inc.mk,v 1.8 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2008, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.include <init.mk>
|
||||
|
||||
.if !empty(LIBOWN)
|
||||
INC_INSTALL_OWN ?= -o ${LIBOWN} -g ${LIBGRP}
|
||||
.endif
|
||||
INCMODE ?= 444
|
||||
INC_COPY ?= -C
|
||||
INCSDIR ?= ${INCDIR}
|
||||
|
||||
STAGE_INCSDIR?= ${STAGE_OBJTOP}${INCSDIR}
|
||||
|
||||
# accommodate folk used to freebsd
|
||||
INCGROUPS ?= ${INCSGROUPS:UINCS}
|
||||
INCGROUPS := ${INCGROUPS:O:u}
|
||||
|
||||
.if !target(buildincludes)
|
||||
.for group in ${INCGROUPS}
|
||||
buildincludes: ${${group}}
|
||||
.endfor
|
||||
.endif
|
||||
buildincludes:
|
||||
includes: buildincludes
|
||||
|
||||
.if !target(incinstall)
|
||||
.for group in ${INCGROUPS}
|
||||
.if !empty(${group})
|
||||
.if ${group} != "INC"
|
||||
${group}_INSTALL_OWN ?= ${INC_INSTALL_OWN}
|
||||
${group}DIR ?= ${INCDIR}
|
||||
.endif
|
||||
# incase we are staging
|
||||
STAGE_DIR.${group} ?= ${STAGE_OBJTOP}${${group}DIR}
|
||||
|
||||
.for header in ${${group}:O:u}
|
||||
${group}_INSTALL_OWN.${header:T} ?= ${${group}_INSTALL_OWN}
|
||||
${group}DIR.${header:T} ?= ${${group}DIR}
|
||||
inc_mkdir_list += ${${group}DIR.${header:T}}
|
||||
|
||||
.if defined(${group}NAME.${header:T})
|
||||
STAGE_AS_SETS += ${group}
|
||||
STAGE_AS_${header} = ${${group}NAME.${header:T}}
|
||||
stage_as.${group}: ${header}
|
||||
|
||||
incinstall: incinstall.${group}.${header:T}
|
||||
incinstall.${group}.${header:T}: ${header} inc_mkdirs
|
||||
${INSTALL} ${INC_COPY} ${${group}_INSTALL_OWN.${header:T}} -m ${INCMODE} ${.ALLSRC:Ninc_mkdirs} ${DESTDIR}${${group}DIR}/${${group}NAME.${header:T}}
|
||||
|
||||
.else
|
||||
STAGE_SETS += ${group}
|
||||
stage_files.${group}: ${header}
|
||||
incinstall.${group}: ${header}
|
||||
incinstall: incinstall.${group}
|
||||
.endif
|
||||
|
||||
.endfor # header
|
||||
|
||||
incinstall.${group}: inc_mkdirs
|
||||
${INSTALL} ${INC_COPY} ${${group}_INSTALL_OWN} -m ${INCMODE} \
|
||||
${.ALLSRC:Ninc_mkdirs:O:u} ${DESTDIR}${${group}DIR}
|
||||
|
||||
.endif # !empty
|
||||
.endfor # group
|
||||
|
||||
inc_mkdirs:
|
||||
@for d in ${inc_mkdir_list:O:u}; do \
|
||||
test -d ${DESTDIR}$$d || \
|
||||
${INSTALL} -d ${INC_INSTALL_OWN} -m 775 ${DESTDIR}$$d; \
|
||||
done
|
||||
|
||||
.endif # !target(incinstall)
|
||||
|
||||
beforeinstall:
|
||||
realinstall: incinstall
|
||||
.ORDER: beforeinstall incinstall
|
93
20200902/mk/init.mk
Normal file
93
20200902/mk/init.mk
Normal file
@ -0,0 +1,93 @@
|
||||
# $Id: init.mk,v 1.21 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2002, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
.if ${MAKE_VERSION:U0} > 20100408
|
||||
_this_mk_dir := ${.PARSEDIR:tA}
|
||||
.else
|
||||
_this_mk_dir := ${.PARSEDIR}
|
||||
.endif
|
||||
|
||||
.-include <local.init.mk>
|
||||
.-include <${.CURDIR:H}/Makefile.inc>
|
||||
.include <own.mk>
|
||||
.include <compiler.mk>
|
||||
|
||||
.MAIN: all
|
||||
|
||||
# should have been set by sys.mk
|
||||
CXX_SUFFIXES?= .cc .cpp .cxx .C
|
||||
|
||||
.if !empty(WARNINGS_SET) || !empty(WARNINGS_SET_${MACHINE_ARCH})
|
||||
.include <warnings.mk>
|
||||
.endif
|
||||
|
||||
# these are applied in order, least specific to most
|
||||
VAR_QUALIFIER_LIST += \
|
||||
${TARGET_SPEC_VARS:UMACHINE:@v@${$v}@} \
|
||||
${COMPILER_TYPE} \
|
||||
${.TARGET:T:R} \
|
||||
${.TARGET:T} \
|
||||
${.IMPSRC:T} \
|
||||
${VAR_QUALIFIER_XTRA_LIST}
|
||||
|
||||
QUALIFIED_VAR_LIST += \
|
||||
CFLAGS \
|
||||
COPTS \
|
||||
CPPFLAGS \
|
||||
CPUFLAGS \
|
||||
LDFLAGS \
|
||||
|
||||
# a final :U avoids errors if someone uses :=
|
||||
.for V in ${QUALIFIED_VAR_LIST:O:u:@q@$q $q_LAST@}
|
||||
.for Q in ${VAR_QUALIFIER_LIST:u}
|
||||
$V += ${$V.$Q:U} ${$V.$Q.${COMPILER_TYPE}:U}
|
||||
.endfor
|
||||
.endfor
|
||||
|
||||
CC_PG?= -pg
|
||||
CXX_PG?= ${CC_PG}
|
||||
CC_PIC?= -DPIC
|
||||
CXX_PIC?= ${CC_PIC}
|
||||
PROFFLAGS?= -DGPROF -DPROF
|
||||
|
||||
# targets that are ok at level 0
|
||||
LEVEL0_TARGETS += clean* destory*
|
||||
M_ListToSkip= O:u:S,^,N,:ts:
|
||||
|
||||
.if ${.MAKE.LEVEL:U1} == 0 && ${MK_DIRDEPS_BUILD:Uno} == "yes" && ${.TARGETS:Uall:${LEVEL0_TARGETS:${M_ListToSkip}}} != ""
|
||||
# this tells lib.mk and prog.mk to not actually build anything
|
||||
_SKIP_BUILD = not building at level 0
|
||||
.endif
|
||||
|
||||
.if !defined(.PARSEDIR)
|
||||
# no-op is the best we can do if not bmake.
|
||||
.WAIT:
|
||||
.endif
|
||||
|
||||
# define this once for consistency
|
||||
.if empty(_SKIP_BUILD)
|
||||
# beforebuild is a hook for things that must be done early
|
||||
all: beforebuild .WAIT realbuild
|
||||
.else
|
||||
all: .PHONY
|
||||
.warning ${_SKIP_BUILD}
|
||||
.endif
|
||||
beforebuild:
|
||||
realbuild:
|
||||
|
||||
.endif
|
185
20200902/mk/install-mk
Normal file
185
20200902/mk/install-mk
Normal file
@ -0,0 +1,185 @@
|
||||
:
|
||||
# NAME:
|
||||
# install-mk - install mk files
|
||||
#
|
||||
# SYNOPSIS:
|
||||
# install-mk [options] [var=val] [dest]
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# This tool installs mk files in a semi-intelligent manner into
|
||||
# "dest".
|
||||
#
|
||||
# Options:
|
||||
#
|
||||
# -n just say what we want to do, but don't touch anything.
|
||||
#
|
||||
# -f use -f when copying sys,mk.
|
||||
#
|
||||
# -v be verbose
|
||||
#
|
||||
# -q be quiet
|
||||
#
|
||||
# -m "mode"
|
||||
# Use "mode" for installed files (444).
|
||||
#
|
||||
# -o "owner"
|
||||
# Use "owner" for installed files.
|
||||
#
|
||||
# -g "group"
|
||||
# Use "group" for installed files.
|
||||
#
|
||||
# var=val
|
||||
# Set "var" to "val". See below.
|
||||
#
|
||||
# All our *.mk files are copied to "dest" with appropriate
|
||||
# ownership and permissions.
|
||||
#
|
||||
# By default if a sys.mk can be found in a standard location
|
||||
# (that bmake will find) then no sys.mk will be put in "dest".
|
||||
#
|
||||
# SKIP_SYS_MK:
|
||||
# If set, we will avoid installing our 'sys.mk'
|
||||
# This is probably a bad idea.
|
||||
#
|
||||
# SKIP_BSD_MK:
|
||||
# If set, we will skip making bsd.*.mk links to *.mk
|
||||
#
|
||||
# sys.mk:
|
||||
#
|
||||
# By default (and provided we are not installing to the system
|
||||
# mk dir - '/usr/share/mk') we install our own 'sys.mk' which
|
||||
# includes a sys specific file, or a generic one.
|
||||
#
|
||||
#
|
||||
# AUTHOR:
|
||||
# Simon J. Gerraty <sjg@crufty.net>
|
||||
|
||||
# RCSid:
|
||||
# $Id: install-mk,v 1.179 2020/08/26 21:49:45 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1994 Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
MK_VERSION=20200826
|
||||
OWNER=
|
||||
GROUP=
|
||||
MODE=444
|
||||
BINMODE=555
|
||||
ECHO=:
|
||||
SKIP=
|
||||
cp_f=-f
|
||||
|
||||
while :
|
||||
do
|
||||
case "$1" in
|
||||
*=*) eval "$1"; shift;;
|
||||
+f) cp_f=; shift;;
|
||||
-f) cp_f=-f; shift;;
|
||||
-m) MODE=$2; shift 2;;
|
||||
-o) OWNER=$2; shift 2;;
|
||||
-g) GROUP=$2; shift 2;;
|
||||
-v) ECHO=echo; shift;;
|
||||
-q) ECHO=:; shift;;
|
||||
-n) ECHO=echo SKIP=:; shift;;
|
||||
--) shift; break;;
|
||||
*) break;;
|
||||
esac
|
||||
done
|
||||
|
||||
case $# in
|
||||
0) echo "$0 [options] <destination> [<os>]"
|
||||
echo "eg."
|
||||
echo "$0 -o bin -g bin -m 444 /usr/local/share/mk"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
dest=$1
|
||||
os=${2:-`uname`}
|
||||
osrel=${3:-`uname -r`}
|
||||
|
||||
Do() {
|
||||
$ECHO "$@"
|
||||
$SKIP "$@"
|
||||
}
|
||||
|
||||
Error() {
|
||||
echo "ERROR: $@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
Warning() {
|
||||
echo "WARNING: $@" >&2
|
||||
}
|
||||
|
||||
[ "$FORCE_SYS_MK" ] && Warning "ignoring: FORCE_{BSD,SYS}_MK (no longer supported)"
|
||||
|
||||
SYS_MK_DIR=${SYS_MK_DIR:-/usr/share/mk}
|
||||
SYS_MK=${SYS_MK:-$SYS_MK_DIR/sys.mk}
|
||||
|
||||
realpath() {
|
||||
[ -d $1 ] && cd $1 && 'pwd' && return
|
||||
echo $1
|
||||
}
|
||||
|
||||
if [ -s $SYS_MK -a -d $dest ]; then
|
||||
# if this is a BSD system we don't want to touch $SYS_MK
|
||||
dest=`realpath $dest`
|
||||
sys_mk_dir=`realpath $SYS_MK_DIR`
|
||||
if [ $dest = $sys_mk_dir ]; then
|
||||
case "$os" in
|
||||
*BSD*) SKIP_SYS_MK=:
|
||||
SKIP_BSD_MK=:
|
||||
;;
|
||||
*) # could be fake?
|
||||
if [ ! -d $dest/sys -a ! -s $dest/Generic.sys.mk ]; then
|
||||
SKIP_SYS_MK=: # play safe
|
||||
SKIP_BSD_MK=:
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -d $dest/sys ] || Do mkdir -p $dest/sys
|
||||
[ -d $dest/sys ] || Do mkdir $dest/sys || exit 1
|
||||
[ -z "$SKIP" ] && dest=`realpath $dest`
|
||||
|
||||
cd `dirname $0`
|
||||
mksrc=`'pwd'`
|
||||
if [ $mksrc = $dest ]; then
|
||||
SKIP_MKFILES=:
|
||||
else
|
||||
# we do not install the examples
|
||||
mk_files=`grep '^[a-z].*\.mk' FILES | egrep -v '(examples/|^sys\.mk|sys/)'`
|
||||
mk_scripts=`egrep '^[a-z].*\.(sh|py)' FILES | egrep -v '/'`
|
||||
sys_mk_files=`grep 'sys/.*\.mk' FILES`
|
||||
SKIP_MKFILES=
|
||||
[ -z "$SKIP_SYS_MK" ] && mk_files="sys.mk $mk_files"
|
||||
fi
|
||||
$SKIP_MKFILES Do cp $cp_f $mk_files $dest
|
||||
$SKIP_MKFILES Do cp $cp_f $sys_mk_files $dest/sys
|
||||
$SKIP_MKFILES Do cp $cp_f $mk_scripts $dest
|
||||
$SKIP cd $dest
|
||||
$SKIP_MKFILES Do chmod $MODE $mk_files $sys_mk_files
|
||||
$SKIP_MKFILES Do chmod $BINMODE $mk_scripts
|
||||
[ "$GROUP" ] && $SKIP_MKFILES Do chgrp $GROUP $mk_files $sys_mk_files
|
||||
[ "$OWNER" ] && $SKIP_MKFILES Do chown $OWNER $mk_files $sys_mk_files
|
||||
# if this is a BSD system the bsd.*.mk should exist and be used.
|
||||
if [ -z "$SKIP_BSD_MK" ]; then
|
||||
for f in dep doc files inc init lib links man nls obj own prog subdir
|
||||
do
|
||||
b=bsd.$f.mk
|
||||
[ -s $b ] || Do ln -s $f.mk $b
|
||||
done
|
||||
fi
|
||||
exit 0
|
53
20200902/mk/install-new.mk
Normal file
53
20200902/mk/install-new.mk
Normal file
@ -0,0 +1,53 @@
|
||||
# $Id: install-new.mk,v 1.4 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2009, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.if !defined(InstallNew)
|
||||
|
||||
# copy if src and target are different making a backup if desired
|
||||
CmpCp= CmpCp() { \
|
||||
src=$$1 target=$$2 _bak=$$3; \
|
||||
if ! test -s $$target || ! cmp -s $$target $$src; then \
|
||||
trap "" 1 2 3 15; \
|
||||
if test -s $$target; then \
|
||||
if test "x$$_bak" != x; then \
|
||||
rm -f $$target$$_bak; \
|
||||
mv $$target $$target$$_bak; \
|
||||
else \
|
||||
rm -f $$target; \
|
||||
fi; \
|
||||
fi; \
|
||||
cp $$src $$target; \
|
||||
fi; }
|
||||
|
||||
# If the .new file is different, we want it.
|
||||
# Note: this function will work as is for *.new$RANDOM"
|
||||
InstallNew= ${CmpCp}; InstallNew() { \
|
||||
_t=-e; _bak=; \
|
||||
while :; do \
|
||||
case "$$1" in \
|
||||
-?) _t=$$1; shift;; \
|
||||
--bak) _bak=$$2; shift 2;; \
|
||||
*) break;; \
|
||||
esac; \
|
||||
done; \
|
||||
for new in "$$@"; do \
|
||||
if test $$_t $$new; then \
|
||||
target=`expr $$new : '\(.*\).new'`; \
|
||||
CmpCp $$new $$target $$_bak; \
|
||||
fi; \
|
||||
rm -f $$new; \
|
||||
done; :; }
|
||||
|
||||
.endif
|
97
20200902/mk/java.mk
Normal file
97
20200902/mk/java.mk
Normal file
@ -0,0 +1,97 @@
|
||||
#
|
||||
# RCSid:
|
||||
# $Id: java.mk,v 1.15 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
# @(#) Copyright (c) 1998-2001, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
.include <init.mk>
|
||||
|
||||
CLASSPATH?=.
|
||||
|
||||
.if defined(PROG)
|
||||
SRCS?= ${PROG:.class=.java}
|
||||
.endif
|
||||
.if !defined(SRCS) || empty(SRCS)
|
||||
SRCS!=cd ${.CURDIR} && echo *.java
|
||||
.endif
|
||||
.SUFFIXES: .class .java
|
||||
|
||||
CLEANFILES+= *.class
|
||||
|
||||
JAVAC?= javac
|
||||
JAVADOC?= javadoc
|
||||
|
||||
.if !target(docs)
|
||||
docs:
|
||||
${JAVADOC} ${JAVADOC_FLAGS} ${SRCS}
|
||||
.endif
|
||||
|
||||
.if defined(JAVADESTDIR) && !empty(JAVADESTDIR)
|
||||
JAVASRCDIR?=${JAVADESTDIR:H}/src
|
||||
__classdest:=${JAVADESTDIR}${.CURDIR:S,${JAVASRCDIR},,}/
|
||||
CLASSPATH:=${CLASSPATH}:${JAVADESTDIR}
|
||||
JAVAC_FLAGS+= -d ${JAVADESTDIR}
|
||||
.else
|
||||
__classdest=
|
||||
.endif
|
||||
|
||||
JAVAC_FLAGS+= ${JAVAC_DBG}
|
||||
|
||||
.if defined(MAKE_VERSION) && !defined(NO_CLASSES_COOKIE)
|
||||
# java works best by compiling a bunch of classes at once.
|
||||
# this lot does that but needs a recent netbsd make or
|
||||
# or its portable cousin bmake.
|
||||
.for __s in ${SRCS}
|
||||
__c:= ${__classdest}${__s:.java=.class}
|
||||
.if !target(${__c})
|
||||
# We need to do something to force __c's parent to be made.
|
||||
${__c}: ${__s}
|
||||
@rm -f ${.TARGET}
|
||||
.endif
|
||||
SRCS_${__c}=${__s}
|
||||
__classes:= ${__classes} ${__c}
|
||||
.endfor
|
||||
__classes_cookie=${__classdest}.classes.done
|
||||
CLEANFILES+= ${__classes} ${__classes_cookie}
|
||||
|
||||
${__classes_cookie}: ${__classes}
|
||||
CLASSPATH=${CLASSPATH} ${JAVAC} ${JAVAC_FLAGS} ${.OODATE:@c@${SRCS_$c}@}
|
||||
@touch ${.TARGET}
|
||||
|
||||
all: ${__classes_cookie}
|
||||
|
||||
.else
|
||||
# this will work with other BSD make's
|
||||
.for __s in ${SRCS}
|
||||
__c:= ${__classdest}${__s:.java=.class}
|
||||
${__c}: ${__s}
|
||||
CLASSPATH=${CLASSPATH} ${JAVAC} ${JAVAC_FLAGS} ${.OODATE}
|
||||
.endfor
|
||||
|
||||
all: ${SRCS:%.java=${__classdest}%.class}
|
||||
|
||||
.endif
|
||||
|
||||
.if !target(cleanjava)
|
||||
cleanjava:
|
||||
rm -f [Ee]rrs mklog core *.core ${PROG} ${CLEANFILES}
|
||||
|
||||
clean: cleanjava
|
||||
cleandir: cleanjava
|
||||
.endif
|
||||
|
||||
.endif
|
156
20200902/mk/ldorder.mk
Normal file
156
20200902/mk/ldorder.mk
Normal file
@ -0,0 +1,156 @@
|
||||
# $Id: ldorder.mk,v 1.25 2018/04/24 23:50:26 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2015, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
# Try to compute optimal link order.
|
||||
# When using only shared libs link order does not much matter,
|
||||
# but archive libs are a different matter.
|
||||
|
||||
# We can construct a graph of .ldorder-lib${LIB*} dependencies
|
||||
# and associate each with _LDORDER_USE to output the relevant
|
||||
# ld flags.
|
||||
# Due to the nature of make, the result will be in the reverse order
|
||||
# that we want to feed to ld.
|
||||
# So we need to reverse it before use.
|
||||
|
||||
.if !target(_LDORDER_USE)
|
||||
# does caller want to use ldorder?
|
||||
# yes for prog, normally no for lib
|
||||
.if ${.ALLTARGETS:Mldorder} != ""
|
||||
_ldorder_use:
|
||||
.endif
|
||||
|
||||
# define this if we need a barrier between local and external libs
|
||||
# see below
|
||||
LDORDER_EXTERN_BARRIER ?= .ldorder-extern-barrier
|
||||
|
||||
.-include <local.ldorder.mk>
|
||||
|
||||
# convert /path/to/libfoo.a into _{LIBFOO}
|
||||
LDORDER_INC_FILTER += S,+,PLUS,g S,.so$$,,g
|
||||
LDORDER_LIBS_FILTER += O:u
|
||||
LDORDER_INC ?= ldorder.inc
|
||||
# for meta mode
|
||||
REFERENCE_FILE ?= :
|
||||
|
||||
_LDORDER_USE: .ldorder-rm .USE .NOTMAIN
|
||||
@echo depends: ${.ALLSRC:M.ldorder-lib*} > /dev/null
|
||||
@echo ${LDADD_${.TARGET:T:S,.ldorder-,,}:U${.TARGET:T:S/.ldorder-lib/-l/}} >> .ldorder
|
||||
@${META_COOKIE_TOUCH}
|
||||
|
||||
# we need to truncate our working file
|
||||
.ldorder-rm: .NOTMAIN
|
||||
@rm -f .ldorder ldorder-*
|
||||
@${.ALLSRC:O:u:@f@${REFERENCE_FILE} < $f;@}
|
||||
@${META_COOKIE_TOUCH}
|
||||
|
||||
# make sure this exists
|
||||
.ldorder: .NOTMAIN
|
||||
|
||||
# and finally we need to reverse the order of content
|
||||
ldorder: .ldorder .NOTMAIN
|
||||
@{ test ! -s .ldorder || cat -n .ldorder | sort -rn | \
|
||||
sed '/ldorder-/d;s,^[[:space:]0-9]*,,'; } > ${.TARGET}
|
||||
|
||||
# Initially we hook contents of DPLIBS and DPADD into our graph
|
||||
LDORDER_LIBS ?= ${DPLIBS} ${DPADD:M*/lib*} ${__dpadd_libs}
|
||||
# we need to remember this
|
||||
_LDORDER_LIBS := ${LDORDER_LIBS:${LDORDER_LIBS_FILTER:ts:}}
|
||||
|
||||
.if empty(_LDORDER_LIBS)
|
||||
# don't use stale ldorder
|
||||
LDADD_LDORDER =
|
||||
.else
|
||||
# this is how you use it
|
||||
LDADD_LDORDER ?= `cat ldorder`
|
||||
.endif
|
||||
|
||||
# for debug below
|
||||
_ldorder = ${RELDIR}.${TARGET_SPEC}
|
||||
|
||||
# we make have some libs that exist outside of $SB
|
||||
# and want to insert a barrier
|
||||
.if target(${LDORDER_EXTERN_BARRIER})
|
||||
# eg. in local.ldorder.mk
|
||||
# ${LDORDER_EXTERN_BARRIER}:
|
||||
# @test -z "${extern_ldorders}" || \
|
||||
# echo -Wl,-Bdynamic >> .ldorder
|
||||
#
|
||||
# feel free to put more suitable version in local.ldorder.mk if needed
|
||||
# we do *not* count host libs in extern_ldorders
|
||||
extern_ldorders ?= ${__dpadd_libs:tA:N/lib*:N/usr/lib*:N${SB}/*:N${SB_OBJROOT:tA}*:T:${LDORDER_LIBS_FILTER:ts:}:R:C/\.so.*//:S,^,.ldorder-,:N.ldorder-}
|
||||
sb_ldorders ?= ${.ALLTARGETS:M.ldorder-*:N${LDORDER_EXTERN_BARRIER}:N.ldorder-rm:${extern_ldorders:${M_ListToSkip}}:N.ldorder-}
|
||||
|
||||
# finally in Makefile after include of *.mk put
|
||||
# .ldorder ${sb_ldorders}: ${LDORDER_EXTERN_BARRIER}
|
||||
# ${LDORDER_EXTERN_BARRIER}: ${extern_ldorders}
|
||||
.endif
|
||||
|
||||
.endif # !target(_LDORDER_USE)
|
||||
|
||||
.if !empty(LDORDER_LIBS) && target(_ldorder_use)
|
||||
# canonicalize - these are just tokens anyway
|
||||
LDORDER_LIBS := ${LDORDER_LIBS:${LDORDER_LIBS_FILTER:ts:}:R:C/\.so.*//}
|
||||
_ldorders := ${LDORDER_LIBS:T:Mlib*:S,^,.ldorder-,}
|
||||
|
||||
.for t in ${_ldorders}
|
||||
.if !target($t)
|
||||
$t: _LDORDER_USE
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
# and this makes it all happen
|
||||
.ldorder: ${_ldorders}
|
||||
|
||||
# this is how we get the dependencies
|
||||
.if ${.INCLUDEDFROMFILE:M*.${LDORDER_INC}} != ""
|
||||
_ldorder := .ldorder-${.INCLUDEDFROMFILE:S/.${LDORDER_INC}//}
|
||||
${_ldorder}: ${_ldorders}
|
||||
.ldorder-rm: ${.INCLUDEDFROMDIR}/${.INCLUDEDFROMFILE}
|
||||
.endif
|
||||
|
||||
# set DEBUG_LDORDER to pattern[s] that match the dirs of interest
|
||||
.if ${DEBUG_LDORDER:Uno:@x@${RELDIR:M$x}@} != ""
|
||||
.info ${_ldorder}: ${_ldorders}
|
||||
.endif
|
||||
|
||||
# now try to find more ...
|
||||
# each *.${LDORDER_INC} should set LDORDER_LIBS to what it needs
|
||||
# it can also add to CFLAGS etc.
|
||||
.for __inc in ${LDORDER_LIBS:S,$,.${LDORDER_INC},}
|
||||
.if !target(__${__inc}__)
|
||||
__${__inc}__:
|
||||
# make sure this is reset
|
||||
LDORDER_LIBS =
|
||||
_ldorders =
|
||||
.-include <${__inc}>
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
.endif # !empty(LDORDER_LIBS)
|
||||
|
||||
.ifdef LIB
|
||||
# you can make this depend on files (must match *ldorder*)
|
||||
# to add extra content - like CFLAGS
|
||||
libLDORDER_INC = lib${LIB}.${LDORDER_INC}
|
||||
.if !commands(${libLDORDER_INC})
|
||||
.if target(ldorder-header)
|
||||
${libLDORDER_INC}: ldorder-header
|
||||
.endif
|
||||
${libLDORDER_INC}:
|
||||
@(cat /dev/null ${.ALLSRC:M*ldorder*}; \
|
||||
echo 'LDORDER_LIBS= ${_LDORDER_LIBS:T:R:${LDORDER_INC_FILTER:ts:}:tu:C,.*,_{&},:N_{}}'; \
|
||||
echo; echo '.include <ldorder.mk>' ) | sed 's,_{,$${,g' > ${.TARGET}
|
||||
.endif
|
||||
.endif
|
609
20200902/mk/lib.mk
Normal file
609
20200902/mk/lib.mk
Normal file
@ -0,0 +1,609 @@
|
||||
# $Id: lib.mk,v 1.71 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
.include <init.mk>
|
||||
|
||||
.if ${OBJECT_FMT} == "ELF"
|
||||
NEED_SOLINKS?= yes
|
||||
.endif
|
||||
|
||||
SHLIB_VERSION_FILE?= ${.CURDIR}/shlib_version
|
||||
.if !defined(SHLIB_MAJOR) && exists(${SHLIB_VERSION_FILE})
|
||||
SHLIB_MAJOR != . ${SHLIB_VERSION_FILE} ; echo $$major
|
||||
SHLIB_MINOR != . ${SHLIB_VERSION_FILE} ; echo $$minor
|
||||
SHLIB_TEENY != . ${SHLIB_VERSION_FILE} ; echo $$teeny
|
||||
.endif
|
||||
|
||||
.for x in major minor teeny
|
||||
print-shlib-$x:
|
||||
.if defined(SHLIB_${x:tu}) && ${MK_PIC} != "no"
|
||||
@echo ${SHLIB_${x:tu}}
|
||||
.else
|
||||
@false
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
SHLIB_FULLVERSION ?= ${${SHLIB_MAJOR} ${SHLIB_MINOR} ${SHLIB_TEENY}:L:ts.}
|
||||
SHLIB_FULLVERSION := ${SHLIB_FULLVERSION}
|
||||
|
||||
# add additional suffixes not exported.
|
||||
# .po is used for profiling object files.
|
||||
# ${PICO} is used for PIC object files.
|
||||
PICO?= .pico
|
||||
.SUFFIXES: .out .a .ln ${PICO} .po .o .s .S .c .cc .C .m .F .f .r .y .l .cl .p .h
|
||||
.SUFFIXES: .sh .m4 .m
|
||||
|
||||
CFLAGS+= ${COPTS}
|
||||
|
||||
META_NOECHO?= echo
|
||||
|
||||
# Originally derrived from NetBSD-1.6
|
||||
|
||||
# Set PICFLAGS to cc flags for producing position-independent code,
|
||||
# if not already set. Includes -DPIC, if required.
|
||||
|
||||
# Data-driven table using make variables to control how shared libraries
|
||||
# are built for different platforms and object formats.
|
||||
# OBJECT_FMT: currently either "ELF" or "a.out", from <bsd.own.mk>
|
||||
# SHLIB_SOVERSION: version number to be compiled into a shared library
|
||||
# via -soname. Usually ${SHLIB_MAJOR} on ELF.
|
||||
# NetBSD/pmax used to use ${SHLIB_MAJOR}[.${SHLIB_MINOR}
|
||||
# [.${SHLIB_TEENY}]]
|
||||
# SHLIB_SHFLAGS: Flags to tell ${LD} to emit shared library.
|
||||
# with ELF, also set shared-lib version for ld.so.
|
||||
# SHLIB_LDSTARTFILE: support .o file, call C++ file-level constructors
|
||||
# SHLIB_LDENDFILE: support .o file, call C++ file-level destructors
|
||||
# FPICFLAGS: flags for ${FC} to compile .[fF] files to ${PICO} objects.
|
||||
# CPPICFLAGS: flags for ${CPP} to preprocess .[sS] files for ${AS}
|
||||
# CPICFLAGS: flags for ${CC} to compile .[cC] files to ${PICO} objects.
|
||||
# CAPICFLAGS flags for {$CC} to compiling .[Ss] files
|
||||
# (usually just ${CPPPICFLAGS} ${CPICFLAGS})
|
||||
# APICFLAGS: flags for ${AS} to assemble .[sS] to ${PICO} objects.
|
||||
|
||||
.if ${TARGET_OSNAME} == "NetBSD"
|
||||
.if ${MACHINE_ARCH} == "alpha"
|
||||
# Alpha-specific shared library flags
|
||||
FPICFLAGS ?= -fPIC
|
||||
CPICFLAGS ?= -fPIC -DPIC
|
||||
CPPPICFLAGS?= -DPIC
|
||||
CAPICFLAGS?= ${CPPPICFLAGS} ${CPICFLAGS}
|
||||
APICFLAGS ?=
|
||||
.elif ${MACHINE_ARCH} == "mipsel" || ${MACHINE_ARCH} == "mipseb"
|
||||
# mips-specific shared library flags
|
||||
|
||||
# On mips, all libs are compiled with ABIcalls, not just sharedlibs.
|
||||
MKPICLIB= no
|
||||
|
||||
# so turn shlib PIC flags on for ${AS}.
|
||||
AINC+=-DABICALLS
|
||||
AFLAGS+= -fPIC
|
||||
AS+= -KPIC
|
||||
|
||||
.elif ${MACHINE_ARCH} == "vax" && ${OBJECT_FMT} == "ELF"
|
||||
# On the VAX, all object are PIC by default, not just sharedlibs.
|
||||
MKPICLIB= no
|
||||
|
||||
.elif (${MACHINE_ARCH} == "sparc" || ${MACHINE_ARCH} == "sparc64") && \
|
||||
${OBJECT_FMT} == "ELF"
|
||||
# If you use -fPIC you need to define BIGPIC to turn on 32-bit
|
||||
# relocations in asm code
|
||||
FPICFLAGS ?= -fPIC
|
||||
CPICFLAGS ?= -fPIC -DPIC
|
||||
CPPPICFLAGS?= -DPIC -DBIGPIC
|
||||
CAPICFLAGS?= ${CPPPICFLAGS} ${CPICFLAGS}
|
||||
APICFLAGS ?= -KPIC
|
||||
|
||||
.else
|
||||
|
||||
# Platform-independent flags for NetBSD a.out shared libraries
|
||||
SHLIB_SOVERSION=${SHLIB_FULLVERSION}
|
||||
SHLIB_SHFLAGS=
|
||||
FPICFLAGS ?= -fPIC
|
||||
CPICFLAGS?= -fPIC -DPIC
|
||||
CPPPICFLAGS?= -DPIC
|
||||
CAPICFLAGS?= ${CPPPICFLAGS} ${CPICFLAGS}
|
||||
APICFLAGS?= -k
|
||||
|
||||
.endif
|
||||
|
||||
# Platform-independent linker flags for ELF shared libraries
|
||||
.if ${OBJECT_FMT} == "ELF"
|
||||
SHLIB_SOVERSION= ${SHLIB_MAJOR}
|
||||
SHLIB_SHFLAGS= -soname lib${LIB}.so.${SHLIB_SOVERSION}
|
||||
SHLIB_LDSTARTFILE?= /usr/lib/crtbeginS.o
|
||||
SHLIB_LDENDFILE?= /usr/lib/crtendS.o
|
||||
.endif
|
||||
|
||||
# for compatibility with the following
|
||||
CC_PIC?= ${CPICFLAGS}
|
||||
LD_shared=${SHLIB_SHFLAGS}
|
||||
|
||||
.endif # NetBSD
|
||||
|
||||
.if ${TARGET_OSNAME} == "FreeBSD"
|
||||
.if ${OBJECT_FMT} == "ELF"
|
||||
SHLIB_SOVERSION= ${SHLIB_MAJOR}
|
||||
SHLIB_SHFLAGS= -soname lib${LIB}.so.${SHLIB_SOVERSION}
|
||||
.else
|
||||
SHLIB_SHFLAGS= -assert pure-text
|
||||
.endif
|
||||
SHLIB_LDSTARTFILE=
|
||||
SHLIB_LDENDFILE=
|
||||
CC_PIC?= -fpic
|
||||
LD_shared=${SHLIB_SHFLAGS}
|
||||
|
||||
.endif # FreeBSD
|
||||
|
||||
MKPICLIB?= yes
|
||||
|
||||
# sys.mk can override these
|
||||
LD_X?=-X
|
||||
LD_x?=-x
|
||||
LD_r?=-r
|
||||
|
||||
# Non BSD machines will be using bmake.
|
||||
.if ${TARGET_OSNAME} == "SunOS"
|
||||
LD_shared=-assert pure-text
|
||||
.if ${OBJECT_FMT} == "ELF" || ${MACHINE} == "solaris"
|
||||
# Solaris
|
||||
LD_shared=-h lib${LIB}.so.${SHLIB_MAJOR} -G
|
||||
.endif
|
||||
.elif ${TARGET_OSNAME} == "HP-UX"
|
||||
LD_shared=-b
|
||||
LD_so=sl
|
||||
DLLIB=
|
||||
# HPsUX lorder does not grok anything but .o
|
||||
LD_sobjs=`${LORDER} ${OBJS} | ${TSORT} | sed 's,\.o,${PICO},'`
|
||||
LD_pobjs=`${LORDER} ${OBJS} | ${TSORT} | sed 's,\.o,.po,'`
|
||||
.elif ${TARGET_OSNAME} == "OSF1"
|
||||
LD_shared= -msym -shared -expect_unresolved '*'
|
||||
LD_solib= -all lib${LIB}_pic.a
|
||||
DLLIB=
|
||||
# lorder does not grok anything but .o
|
||||
LD_sobjs=`${LORDER} ${OBJS} | ${TSORT} | sed 's,\.o,${PICO},'`
|
||||
LD_pobjs=`${LORDER} ${OBJS} | ${TSORT} | sed 's,\.o,.po,'`
|
||||
AR_cq= -cqs
|
||||
.elif ${TARGET_OSNAME} == "FreeBSD"
|
||||
LD_solib= lib${LIB}_pic.a
|
||||
.elif ${TARGET_OSNAME} == "Linux"
|
||||
SHLIB_LD = ${CC}
|
||||
# this is ambiguous of course
|
||||
LD_shared=-shared -Wl,"-soname lib${LIB}.so.${SHLIB_MAJOR}"
|
||||
LD_solib= -Wl,--whole-archive lib${LIB}_pic.a -Wl,--no-whole-archive
|
||||
.if ${COMPILER_TYPE} == "gcc"
|
||||
# Linux uses GNU ld, which is a multi-pass linker
|
||||
# so we don't need to use lorder or tsort
|
||||
LD_objs = ${OBJS}
|
||||
LD_pobjs = ${POBJS}
|
||||
LD_sobjs = ${SOBJS}
|
||||
.endif
|
||||
.elif ${TARGET_OSNAME} == "Darwin"
|
||||
SHLIB_LD = ${CC}
|
||||
SHLIB_INSTALL_VERSION ?= ${SHLIB_MAJOR}
|
||||
SHLIB_COMPATABILITY_VERSION ?= ${SHLIB_MAJOR}.${SHLIB_MINOR:U0}
|
||||
SHLIB_COMPATABILITY ?= \
|
||||
-compatibility_version ${SHLIB_COMPATABILITY_VERSION} \
|
||||
-current_version ${SHLIB_FULLVERSION}
|
||||
LD_shared = -dynamiclib \
|
||||
-flat_namespace -undefined suppress \
|
||||
-install_name ${LIBDIR}/lib${LIB}.${SHLIB_INSTALL_VERSION}.${LD_solink} \
|
||||
${SHLIB_COMPATABILITY}
|
||||
SHLIB_LINKS =
|
||||
.for v in ${SHLIB_COMPATABILITY_VERSION} ${SHLIB_INSTALL_VERSION}
|
||||
.if "$v" != "${SHLIB_FULLVERSION}"
|
||||
SHLIB_LINKS += lib${LIB}.$v.${LD_solink}
|
||||
.endif
|
||||
.endfor
|
||||
.if ${MK_LINKLIB} != "no"
|
||||
SHLIB_LINKS += lib${LIB}.${LD_solink}
|
||||
.endif
|
||||
|
||||
LD_so = ${SHLIB_FULLVERSION}.dylib
|
||||
LD_sobjs = ${SOBJS:O:u}
|
||||
LD_solib = ${LD_sobjs}
|
||||
SOLIB = ${LD_sobjs}
|
||||
LD_solink = dylib
|
||||
.if ${MACHINE_ARCH} == "i386"
|
||||
PICFLAG ?= -fPIC
|
||||
.else
|
||||
PICFLAG ?= -fPIC -fno-common
|
||||
.endif
|
||||
RANLIB = :
|
||||
.endif
|
||||
|
||||
SHLIB_LD ?= ${LD}
|
||||
|
||||
.if !empty(SHLIB_MAJOR)
|
||||
.if ${NEED_SOLINKS} && empty(SHLIB_LINKS)
|
||||
.if ${MK_LINKLIB} != "no"
|
||||
SHLIB_LINKS = lib${LIB}.${LD_solink}
|
||||
.endif
|
||||
.if "${SHLIB_FULLVERSION}" != "${SHLIB_MAJOR}"
|
||||
SHLIB_LINKS += lib${LIB}.${LD_solink}.${SHLIB_MAJOR}
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
||||
LIBTOOL?=libtool
|
||||
LD_shared ?= -Bshareable -Bforcearchive
|
||||
LD_so ?= so.${SHLIB_FULLVERSION}
|
||||
LD_solink ?= so
|
||||
.if empty(LORDER)
|
||||
LD_objs ?= ${OBJS}
|
||||
LD_pobjs ?= ${POBJS}
|
||||
LD_sobjs ?= ${SOBJS}
|
||||
.else
|
||||
LD_objs ?= `${LORDER} ${OBJS} | ${TSORT}`
|
||||
LD_sobjs ?= `${LORDER} ${SOBJS} | ${TSORT}`
|
||||
LD_pobjs ?= `${LORDER} ${POBJS} | ${TSORT}`
|
||||
.endif
|
||||
LD_solib ?= ${LD_sobjs}
|
||||
AR_cq ?= cq
|
||||
.if exists(/netbsd) && exists(${DESTDIR}/usr/lib/libdl.so)
|
||||
DLLIB ?= -ldl
|
||||
.endif
|
||||
|
||||
# some libs have lots of objects, and scanning all .o, .po and ${PICO} meta files
|
||||
# is a waste of time, this tells meta.autodep.mk to just pick one
|
||||
# (typically ${PICO})
|
||||
# yes, 42 is a random number.
|
||||
.if ${MK_DIRDEPS_BUILD} == "yes" && ${SRCS:Uno:[\#]} > 42
|
||||
OPTIMIZE_OBJECT_META_FILES ?= yes
|
||||
.endif
|
||||
|
||||
|
||||
.if ${MK_LIBTOOL} == "yes"
|
||||
# because libtool is so fascist about naming the object files,
|
||||
# we cannot (yet) build profiled libs
|
||||
MK_PROFILE=no
|
||||
_LIBS=lib${LIB}.a
|
||||
.if exists(${.CURDIR}/shlib_version)
|
||||
SHLIB_AGE != . ${.CURDIR}/shlib_version ; echo $$age
|
||||
.endif
|
||||
.else
|
||||
# for the normal .a we do not want to strip symbols
|
||||
.c.o:
|
||||
${COMPILE.c} ${.IMPSRC}
|
||||
|
||||
# for the normal .a we do not want to strip symbols
|
||||
${CXX_SUFFIXES:%=%.o}:
|
||||
${COMPILE.cc} ${.IMPSRC}
|
||||
|
||||
.S.o .s.o:
|
||||
${COMPILE.S} ${CFLAGS:M-[ID]*} ${AINC} ${.IMPSRC}
|
||||
|
||||
.if (${LD_X} == "")
|
||||
.c.po:
|
||||
${COMPILE.c} ${CC_PG} ${PROFFLAGS} ${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
${CXX_SUFFIXES:%=%.po}:
|
||||
${COMPILE.cc} -pg ${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
.S${PICO} .s${PICO}:
|
||||
${COMPILE.S} ${PICFLAG} ${CC_PIC} ${CFLAGS:M-[ID]*} ${AINC} ${.IMPSRC} -o ${.TARGET}
|
||||
.else
|
||||
.c.po:
|
||||
${COMPILE.c} ${CC_PG} ${PROFFLAGS} ${.IMPSRC} -o ${.TARGET}.o
|
||||
@${LD} ${LD_X} ${LD_r} ${.TARGET}.o -o ${.TARGET}
|
||||
@rm -f ${.TARGET}.o
|
||||
|
||||
${CXX_SUFFIXES:%=%.po}:
|
||||
${COMPILE.cc} ${CXX_PG} ${.IMPSRC} -o ${.TARGET}.o
|
||||
${LD} ${LD_X} ${LD_r} ${.TARGET}.o -o ${.TARGET}
|
||||
@rm -f ${.TARGET}.o
|
||||
|
||||
.S${PICO} .s${PICO}:
|
||||
${COMPILE.S} ${PICFLAG} ${CC_PIC} ${CFLAGS:M-[ID]*} ${AINC} ${.IMPSRC} -o ${.TARGET}.o
|
||||
${LD} ${LD_x} ${LD_r} ${.TARGET}.o -o ${.TARGET}
|
||||
@rm -f ${.TARGET}.o
|
||||
.endif
|
||||
|
||||
.if (${LD_x} == "")
|
||||
.c${PICO}:
|
||||
${COMPILE.c} ${PICFLAG} ${CC_PIC} ${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
${CXX_SUFFIXES:%=%${PICO}}:
|
||||
${COMPILE.cc} ${PICFLAG} ${CC_PIC} ${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
.S.po .s.po:
|
||||
${COMPILE.S} ${PROFFLAGS} ${CFLAGS:M-[ID]*} ${AINC} ${.IMPSRC} -o ${.TARGET}
|
||||
.else
|
||||
|
||||
.c${PICO}:
|
||||
${COMPILE.c} ${PICFLAG} ${CC_PIC} ${.IMPSRC} -o ${.TARGET}.o
|
||||
${LD} ${LD_x} ${LD_r} ${.TARGET}.o -o ${.TARGET}
|
||||
@rm -f ${.TARGET}.o
|
||||
|
||||
${CXX_SUFFIXES:%=%${PICO}}:
|
||||
${COMPILE.cc} ${PICFLAG} ${CC_PIC} ${.IMPSRC} -o ${.TARGET}.o
|
||||
${LD} ${LD_x} ${LD_r} ${.TARGET}.o -o ${.TARGET}
|
||||
@rm -f ${.TARGET}.o
|
||||
|
||||
.S.po .s.po:
|
||||
${COMPILE.S} ${PROFFLAGS} ${CFLAGS:M-[ID]*} ${AINC} ${.IMPSRC} -o ${.TARGET}.o
|
||||
${LD} ${LD_X} ${LD_r} ${.TARGET}.o -o ${.TARGET}
|
||||
@rm -f ${.TARGET}.o
|
||||
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.c.ln:
|
||||
${LINT} ${LINTFLAGS} ${CFLAGS:M-[IDU]*} -i ${.IMPSRC}
|
||||
|
||||
.if ${MK_LIBTOOL} != "yes"
|
||||
|
||||
.if !defined(PICFLAG)
|
||||
PICFLAG=-fpic
|
||||
.endif
|
||||
|
||||
_LIBS=
|
||||
|
||||
.if ${MK_ARCHIVE} != "no"
|
||||
_LIBS += lib${LIB}.a
|
||||
.endif
|
||||
|
||||
.if ${MK_PROFILE} != "no"
|
||||
_LIBS+=lib${LIB}_p.a
|
||||
POBJS+=${OBJS:.o=.po}
|
||||
.endif
|
||||
|
||||
.if ${MK_PIC} != "no"
|
||||
.if ${MK_PICLIB} == "no"
|
||||
SOLIB ?= lib${LIB}.a
|
||||
.else
|
||||
SOLIB=lib${LIB}_pic.a
|
||||
_LIBS+=${SOLIB}
|
||||
.endif
|
||||
.if !empty(SHLIB_FULLVERSION)
|
||||
_LIBS+=lib${LIB}.${LD_so}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${MK_LINT} != "no"
|
||||
_LIBS+=llib-l${LIB}.ln
|
||||
.endif
|
||||
|
||||
# here is where you can define what LIB* are
|
||||
.-include <libnames.mk>
|
||||
.if ${MK_DPADD_MK} == "yes"
|
||||
# lots of cool magic, but might not suit everyone.
|
||||
.include <dpadd.mk>
|
||||
.endif
|
||||
|
||||
.if empty(LIB)
|
||||
_LIBS=
|
||||
.elif ${MK_LDORDER_MK} != "no"
|
||||
# Record any libs that we need to be linked with
|
||||
_LIBS+= ${libLDORDER_INC}
|
||||
|
||||
.include <ldorder.mk>
|
||||
.endif
|
||||
|
||||
.if !defined(_SKIP_BUILD)
|
||||
realbuild: ${_LIBS}
|
||||
.endif
|
||||
|
||||
all: _SUBDIRUSE
|
||||
|
||||
.for s in ${SRCS:N*.h:M*/*}
|
||||
${.o ${PICO} .po .lo:L:@o@${s:T:R}$o@}: $s
|
||||
.endfor
|
||||
|
||||
OBJS+= ${SRCS:T:N*.h:R:S/$/.o/g}
|
||||
.NOPATH: ${OBJS}
|
||||
|
||||
.if ${MK_LIBTOOL} == "yes"
|
||||
.if ${MK_PIC} == "no"
|
||||
LT_STATIC=-static
|
||||
.else
|
||||
LT_STATIC=
|
||||
.endif
|
||||
SHLIB_AGE?=0
|
||||
|
||||
# .lo's are created as a side effect
|
||||
.s.o .S.o .c.o:
|
||||
${LIBTOOL} --mode=compile ${CC} ${LT_STATIC} ${CFLAGS} ${CPPFLAGS} ${IMPFLAGS} -c ${.IMPSRC}
|
||||
|
||||
# can't really do profiled libs with libtool - its too fascist about
|
||||
# naming the output...
|
||||
lib${LIB}.a: ${OBJS}
|
||||
@rm -f ${.TARGET}
|
||||
${LIBTOOL} --mode=link ${CC} ${LT_STATIC} -o ${.TARGET:.a=.la} ${OBJS:.o=.lo} -rpath ${SHLIBDIR}:/usr/lib -version-info ${SHLIB_MAJOR}:${SHLIB_MINOR}:${SHLIB_AGE}
|
||||
@ln .libs/${.TARGET} .
|
||||
|
||||
lib${LIB}.${LD_so}: lib${LIB}.a
|
||||
@[ -s ${.TARGET}.${SHLIB_AGE} ] || { ln -s .libs/lib${LIB}.${LD_so}* . 2>/dev/null; : }
|
||||
@[ -s ${.TARGET} ] || ln -s ${.TARGET}.${SHLIB_AGE} ${.TARGET}
|
||||
|
||||
.else # MK_LIBTOOL=yes
|
||||
|
||||
lib${LIB}.a: ${OBJS}
|
||||
@${META_NOECHO} building standard ${LIB} library
|
||||
@rm -f ${.TARGET}
|
||||
@${AR} ${AR_cq} ${.TARGET} ${LD_objs}
|
||||
${RANLIB} ${.TARGET}
|
||||
|
||||
POBJS+= ${OBJS:.o=.po}
|
||||
.NOPATH: ${POBJS}
|
||||
lib${LIB}_p.a: ${POBJS}
|
||||
@${META_NOECHO} building profiled ${LIB} library
|
||||
@rm -f ${.TARGET}
|
||||
@${AR} ${AR_cq} ${.TARGET} ${LD_pobjs}
|
||||
${RANLIB} ${.TARGET}
|
||||
|
||||
SOBJS+= ${OBJS:.o=${PICO}}
|
||||
.NOPATH: ${SOBJS}
|
||||
lib${LIB}_pic.a: ${SOBJS}
|
||||
@${META_NOECHO} building shared object ${LIB} library
|
||||
@rm -f ${.TARGET}
|
||||
@${AR} ${AR_cq} ${.TARGET} ${LD_sobjs}
|
||||
${RANLIB} ${.TARGET}
|
||||
|
||||
#SHLIB_LDADD?= ${LDADD}
|
||||
|
||||
# bound to be non-portable...
|
||||
# this is known to work for NetBSD 1.6 and FreeBSD 4.2
|
||||
lib${LIB}.${LD_so}: ${SOLIB} ${DPADD}
|
||||
@${META_NOECHO} building shared ${LIB} library \(version ${SHLIB_FULLVERSION}\)
|
||||
@rm -f ${.TARGET}
|
||||
.if ${TARGET_OSNAME} == "NetBSD" || ${TARGET_OSNAME} == "FreeBSD"
|
||||
.if ${OBJECT_FMT} == "ELF"
|
||||
${SHLIB_LD} -x -shared ${SHLIB_SHFLAGS} -o ${.TARGET} \
|
||||
${SHLIB_LDSTARTFILE} \
|
||||
--whole-archive ${SOLIB} --no-whole-archive ${SHLIB_LDADD} \
|
||||
${SHLIB_LDENDFILE}
|
||||
.else
|
||||
${SHLIB_LD} ${LD_x} ${LD_shared} \
|
||||
-o ${.TARGET} ${SOLIB} ${SHLIB_LDADD}
|
||||
.endif
|
||||
.else
|
||||
${SHLIB_LD} -o ${.TARGET} ${LD_shared} ${LD_solib} ${DLLIB} ${SHLIB_LDADD}
|
||||
.endif
|
||||
.endif
|
||||
.if !empty(SHLIB_LINKS)
|
||||
rm -f ${SHLIB_LINKS}; ${SHLIB_LINKS:O:u:@x@ln -s ${.TARGET} $x;@}
|
||||
.endif
|
||||
|
||||
LOBJS+= ${LSRCS:.c=.ln} ${SRCS:M*.c:.c=.ln}
|
||||
.NOPATH: ${LOBJS}
|
||||
LLIBS?= -lc
|
||||
llib-l${LIB}.ln: ${LOBJS}
|
||||
@${META_NOECHO} building llib-l${LIB}.ln
|
||||
@rm -f llib-l${LIB}.ln
|
||||
@${LINT} -C${LIB} ${LOBJS} ${LLIBS}
|
||||
|
||||
.if !target(clean)
|
||||
cleanlib: .PHONY
|
||||
rm -f a.out [Ee]rrs mklog core *.core ${CLEANFILES}
|
||||
rm -f lib${LIB}.a ${OBJS}
|
||||
rm -f lib${LIB}_p.a ${POBJS}
|
||||
rm -f lib${LIB}_pic.a lib${LIB}.so.*.* ${SOBJS}
|
||||
rm -f llib-l${LIB}.ln ${LOBJS}
|
||||
.if !empty(SHLIB_LINKS)
|
||||
rm -f ${SHLIB_LINKS}
|
||||
.endif
|
||||
|
||||
clean: _SUBDIRUSE cleanlib
|
||||
cleandir: _SUBDIRUSE cleanlib
|
||||
.else
|
||||
cleandir: _SUBDIRUSE clean
|
||||
.endif
|
||||
|
||||
.if defined(SRCS) && (!defined(MKDEP) || ${MKDEP} != autodep)
|
||||
afterdepend: .depend
|
||||
@(TMP=/tmp/_depend$$$$; \
|
||||
sed -e 's/^\([^\.]*\).o[ ]*:/\1.o \1.po \1${PICO} \1.ln:/' \
|
||||
< .depend > $$TMP; \
|
||||
mv $$TMP .depend)
|
||||
.endif
|
||||
|
||||
.if !target(install)
|
||||
.if !target(beforeinstall)
|
||||
beforeinstall:
|
||||
.endif
|
||||
|
||||
.if !empty(LIBOWN)
|
||||
LIB_INSTALL_OWN ?= -o ${LIBOWN} -g ${LIBGRP}
|
||||
.endif
|
||||
|
||||
.include <links.mk>
|
||||
|
||||
.if !target(libinstall) && !empty(LIB)
|
||||
realinstall: libinstall
|
||||
libinstall:
|
||||
[ -d ${DESTDIR}/${LIBDIR} ] || \
|
||||
${INSTALL} -d ${LIB_INSTALL_OWN} -m 775 ${DESTDIR}${LIBDIR}
|
||||
.if ${MK_ARCHIVE} != "no"
|
||||
${INSTALL} ${COPY} ${LIB_INSTALL_OWN} -m 644 lib${LIB}.a \
|
||||
${DESTDIR}${LIBDIR}
|
||||
${RANLIB} ${DESTDIR}${LIBDIR}/lib${LIB}.a
|
||||
chmod ${LIBMODE} ${DESTDIR}${LIBDIR}/lib${LIB}.a
|
||||
.endif
|
||||
.if ${MK_PROFILE} != "no"
|
||||
${INSTALL} ${COPY} ${LIB_INSTALL_OWN} -m 644 \
|
||||
lib${LIB}_p.a ${DESTDIR}${LIBDIR}
|
||||
${RANLIB} ${DESTDIR}${LIBDIR}/lib${LIB}_p.a
|
||||
chmod ${LIBMODE} ${DESTDIR}${LIBDIR}/lib${LIB}_p.a
|
||||
.endif
|
||||
.if ${MK_LDORDER_MK} != "no"
|
||||
${INSTALL} ${COPY} ${LIB_INSTALL_OWN} -m 644 \
|
||||
lib${LIB}.ldorder.inc ${DESTDIR}${LIBDIR}
|
||||
.endif
|
||||
.if ${MK_PIC} != "no"
|
||||
.if ${MK_PICLIB} != "no"
|
||||
${INSTALL} ${COPY} ${LIB_INSTALL_OWN} -m 644 \
|
||||
lib${LIB}_pic.a ${DESTDIR}${LIBDIR}
|
||||
${RANLIB} ${DESTDIR}${LIBDIR}/lib${LIB}_pic.a
|
||||
chmod ${LIBMODE} ${DESTDIR}${LIBDIR}/lib${LIB}_pic.a
|
||||
.endif
|
||||
.if !empty(SHLIB_MAJOR)
|
||||
${INSTALL} ${COPY} ${LIB_INSTALL_OWN} -m ${LIBMODE} \
|
||||
lib${LIB}.${LD_so} ${DESTDIR}${LIBDIR}
|
||||
.if !empty(SHLIB_LINKS)
|
||||
(cd ${DESTDIR}${LIBDIR} && { rm -f ${SHLIB_LINKS}; ${SHLIB_LINKS:O:u:@x@ln -s lib${LIB}.${LD_so} $x;@} })
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
.if ${MK_LINT} != "no" && ${MK_LINKLIB} != "no" && !empty(LOBJS)
|
||||
${INSTALL} ${COPY} ${LIB_INSTALL_OWN} -m ${LIBMODE} \
|
||||
llib-l${LIB}.ln ${DESTDIR}${LINTLIBDIR}
|
||||
.endif
|
||||
.if defined(LINKS) && !empty(LINKS)
|
||||
@set ${LINKS}; ${_LINKS_SCRIPT}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${MK_MAN} != "no"
|
||||
install: maninstall _SUBDIRUSE
|
||||
maninstall: afterinstall
|
||||
.endif
|
||||
afterinstall: realinstall
|
||||
libinstall: beforeinstall
|
||||
realinstall: beforeinstall
|
||||
.endif
|
||||
|
||||
.if defined(FILES) || defined(FILESGROUPS)
|
||||
.include <files.mk>
|
||||
.endif
|
||||
|
||||
.if ${MK_MAN} != "no"
|
||||
.include <man.mk>
|
||||
.endif
|
||||
|
||||
.if ${MK_NLS} != "no"
|
||||
.include <nls.mk>
|
||||
.endif
|
||||
|
||||
.include <obj.mk>
|
||||
.include <inc.mk>
|
||||
.include <dep.mk>
|
||||
.include <subdir.mk>
|
||||
.endif
|
||||
|
||||
# during building we usually need/want to install libs somewhere central
|
||||
# note that we do NOT ch{own,grp} as that would likely fail at this point.
|
||||
# otherwise it is the same as realinstall
|
||||
# Note that we don't need this when using dpadd.mk
|
||||
.libinstall: ${_LIBS}
|
||||
test -d ${DESTDIR}${LIBDIR} || ${INSTALL} -d -m775 ${DESTDIR}${LIBDIR}
|
||||
.for _lib in ${_LIBS:M*.a}
|
||||
${INSTALL} ${COPY} -m 644 ${_lib} ${DESTDIR}${LIBDIR}
|
||||
${RANLIB} ${DESTDIR}${LIBDIR}/${_lib}
|
||||
.endfor
|
||||
.for _lib in ${_LIBS:M*.${LD_solink}*:O:u}
|
||||
${INSTALL} ${COPY} -m ${LIBMODE} ${_lib} ${DESTDIR}${LIBDIR}
|
||||
.if !empty(SHLIB_LINKS)
|
||||
(cd ${DESTDIR}${LIBDIR} && { ${SHLIB_LINKS:O:u:@x@ln -sf ${_lib} $x;@}; })
|
||||
.endif
|
||||
.endfor
|
||||
@touch ${.TARGET}
|
||||
|
||||
.if !empty(LIB)
|
||||
STAGE_LIBDIR?= ${STAGE_OBJTOP}${LIBDIR}
|
||||
stage_libs: ${_LIBS}
|
||||
.endif
|
||||
|
||||
.include <final.mk>
|
||||
.endif
|
22
20200902/mk/libnames.mk
Normal file
22
20200902/mk/libnames.mk
Normal file
@ -0,0 +1,22 @@
|
||||
# $Id: libnames.mk,v 1.9 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2007-2009, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
DLIBEXT ?= .a
|
||||
DSHLIBEXT ?= .so
|
||||
|
||||
.-include <local.libnames.mk>
|
||||
.-include <sjg.libnames.mk>
|
||||
.-include <fwall.libnames.mk>
|
||||
.-include <host.libnames.mk>
|
99
20200902/mk/libs.mk
Normal file
99
20200902/mk/libs.mk
Normal file
@ -0,0 +1,99 @@
|
||||
# $Id: libs.mk,v 1.6 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2006, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.MAIN: all
|
||||
|
||||
.if defined(LIBS)
|
||||
|
||||
# In meta mode, we can capture dependenices for _one_ of the progs.
|
||||
# if makefile doesn't nominate one, we use the first.
|
||||
.ifndef UPDATE_DEPENDFILE_LIB
|
||||
UPDATE_DEPENDFILE_LIB = ${LIBS:[1]}
|
||||
.export UPDATE_DEPENDFILE_LIB
|
||||
.endif
|
||||
|
||||
.ifndef LIB
|
||||
# They may have asked us to build just one
|
||||
.for t in ${LIBS:R:T:S,^lib,,}
|
||||
.if make(lib$t)
|
||||
LIB?= $t
|
||||
lib$t: all
|
||||
.endif
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
.if defined(LIB)
|
||||
# just one of many
|
||||
LIB_VARS += \
|
||||
LIBDIR \
|
||||
CFLAGS \
|
||||
COPTS \
|
||||
CPPFLAGS \
|
||||
CXXFLAGS \
|
||||
DPADD \
|
||||
DPLIBS \
|
||||
LDADD \
|
||||
LDFLAGS \
|
||||
MAN \
|
||||
SRCS
|
||||
|
||||
.for v in ${LIB_VARS:O:u}
|
||||
.if defined(${v}.${LIB}) || defined(${v}_${LIB})
|
||||
$v += ${${v}_${LIB}:U${${v}.${LIB}}}
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
# for meta mode, there can be only one!
|
||||
.if ${LIB} == ${UPDATE_DEPENDFILE_LIB:Uno}
|
||||
UPDATE_DEPENDFILE ?= yes
|
||||
.endif
|
||||
UPDATE_DEPENDFILE ?= NO
|
||||
|
||||
# ensure that we don't clobber each other's dependencies
|
||||
DEPENDFILE?= .depend.${LIB}
|
||||
# lib.mk will do the rest
|
||||
.else
|
||||
all: ${LIBS:S,^lib,,:@t@lib$t.a@} .MAKE
|
||||
|
||||
# We cannot capture dependencies for meta mode here
|
||||
UPDATE_DEPENDFILE = NO
|
||||
# nor can we safely run in parallel.
|
||||
.NOTPARALLEL:
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# handle being called [bsd.]libs.mk
|
||||
.include <${.PARSEFILE:S,libs,lib,}>
|
||||
|
||||
.ifndef LIB
|
||||
# tell libs.mk we might want to install things
|
||||
LIBS_TARGETS+= cleandepend cleandir cleanobj depend install
|
||||
|
||||
.for b in ${LIBS:R:T:S,^lib,,}
|
||||
lib$b.a: ${SRCS} ${DPADD} ${SRCS_lib$b} ${DPADD_lib$b}
|
||||
(cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$b -DWITHOUT_META_STATS)
|
||||
|
||||
.for t in ${LIBS_TARGETS:O:u}
|
||||
$b.$t: .PHONY .MAKE
|
||||
(cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$b ${@:E} -DWITHOUT_META_STATS)
|
||||
.endfor
|
||||
.endfor
|
||||
|
||||
.if !defined(WITHOUT_META_STATS) && ${.MAKE.LEVEL} > 0
|
||||
.END: _reldir_finish
|
||||
.ERROR: _reldir_failed
|
||||
.endif
|
||||
|
||||
.endif
|
80
20200902/mk/links.mk
Normal file
80
20200902/mk/links.mk
Normal file
@ -0,0 +1,80 @@
|
||||
# $Id: links.mk,v 1.7 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2005, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
# some platforms need something special
|
||||
LN?= ln
|
||||
ECHO?= echo
|
||||
|
||||
LINKS?=
|
||||
SYMLINKS?=
|
||||
|
||||
__SYMLINK_SCRIPT= \
|
||||
${ECHO} "$$t -> $$l"; \
|
||||
case `'ls' -l $$t 2> /dev/null` in \
|
||||
*"> $$l") ;; \
|
||||
*) \
|
||||
mkdir -p `dirname $$t`; \
|
||||
rm -f $$t; \
|
||||
${LN} -s $$l $$t;; \
|
||||
esac
|
||||
|
||||
|
||||
__LINK_SCRIPT= \
|
||||
${ECHO} "$$t -> $$l"; \
|
||||
mkdir -p `dirname $$t`; \
|
||||
rm -f $$t; \
|
||||
${LN} $$l $$t
|
||||
|
||||
_SYMLINKS_SCRIPT= \
|
||||
while test $$\# -ge 2; do \
|
||||
l=$$1; shift; \
|
||||
t=${DESTDIR}$$1; shift; \
|
||||
${__SYMLINK_SCRIPT}; \
|
||||
done; :;
|
||||
|
||||
_LINKS_SCRIPT= \
|
||||
while test $$\# -ge 2; do \
|
||||
l=${DESTDIR}$$1; shift; \
|
||||
t=${DESTDIR}$$1; shift; \
|
||||
${__LINK_SCRIPT}; \
|
||||
done; :;
|
||||
|
||||
_SYMLINKS_USE: .USE
|
||||
@set ${$@_SYMLINKS:U${SYMLINKS}}; ${_SYMLINKS_SCRIPT}
|
||||
|
||||
_LINKS_USE: .USE
|
||||
@set ${$@_LINKS:U${LINKS}}; ${_LINKS_SCRIPT}
|
||||
|
||||
|
||||
# sometimes we want to ensure DESTDIR is ignored
|
||||
_BUILD_SYMLINKS_SCRIPT= \
|
||||
while test $$\# -ge 2; do \
|
||||
l=$$1; shift; \
|
||||
t=$$1; shift; \
|
||||
${__SYMLINK_SCRIPT}; \
|
||||
done; :;
|
||||
|
||||
_BUILD_LINKS_SCRIPT= \
|
||||
while test $$\# -ge 2; do \
|
||||
l=$$1; shift; \
|
||||
t=$$1; shift; \
|
||||
${__LINK_SCRIPT}; \
|
||||
done; :;
|
||||
|
||||
_BUILD_SYMLINKS_USE: .USE
|
||||
@set ${$@_SYMLINKS:U${SYMLINKS}}; ${_BUILD_SYMLINKS_SCRIPT}
|
||||
|
||||
_BUILD_LINKS_USE: .USE
|
||||
@set ${$@_LINKS:U${LINKS}}; ${_BUILD_LINKS_SCRIPT}
|
137
20200902/mk/man.mk
Normal file
137
20200902/mk/man.mk
Normal file
@ -0,0 +1,137 @@
|
||||
# $Id: man.mk,v 1.20 2012/12/13 01:51:01 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
.include <init.mk>
|
||||
|
||||
# unlike bsd.man.mk we handle 3 approaches
|
||||
# 1. install unformated nroff (default)
|
||||
# 2. install formatted pages
|
||||
# 3. install formatted pages but with extension of .0
|
||||
# sadly we cannot rely on a shell that supports ${foo#...} and ${foo%...}
|
||||
# so we have to use sed(1).
|
||||
|
||||
# set MANTARGET=cat for formatted pages
|
||||
MANTARGET?= man
|
||||
# set this to .0 for same behavior as bsd.man.mk
|
||||
MCATEXT?=
|
||||
|
||||
NROFF?= nroff
|
||||
MANDIR?= /usr/share/man
|
||||
MANDOC?= man
|
||||
|
||||
.SUFFIXES: .1 .2 .3 .4 .5 .6 .7 .8 .9 .cat1 .cat2 .cat3 .cat4 .cat5 .cat6 \
|
||||
.cat7 .cat8 .cat9
|
||||
|
||||
.9.cat9 .8.cat8 .7.cat7 .6.cat6 .5.cat5 .4.cat4 .3.cat3 .2.cat2 .1.cat1:
|
||||
@echo "${NROFF} -${MANDOC} ${.IMPSRC} > ${.TARGET:T}"
|
||||
@${NROFF} -${MANDOC} ${.IMPSRC} > ${.TARGET:T} || ( rm -f ${.TARGET:T} ; false )
|
||||
|
||||
.if defined(MAN) && !empty(MAN)
|
||||
|
||||
# we use cmt2doc.pl to extract manpages from source
|
||||
# this is triggered by the setting of EXTRACT_MAN or MAN being set but
|
||||
# not existsing.
|
||||
|
||||
.if !exists(${MAN:[1]}) && !target(${MAN:[1]})
|
||||
.if defined(EXTRACT_MAN) && ${EXTRACT_MAN} == "no"
|
||||
MAN=
|
||||
.else
|
||||
.if exists(/usr/local/share/bin/cmt2doc.pl)
|
||||
CMT2DOC?= cmt2doc.pl
|
||||
CMT2DOC_OPTS?= ${CMT2DOC_ORGOPT} -pmS${.TARGET:E}
|
||||
.endif
|
||||
.ifdef CMT2DOC
|
||||
.c.8 .c.5 .c.3 .c.4 .c.1 \
|
||||
.cc.8 .cc.5 .cc.3 .cc.4 .cc.1 \
|
||||
.h.8 .h.5 .h.3 .h.4 .h.1 \
|
||||
.sh.8 .sh.5 .sh.3 .sh.4 .sh.1 \
|
||||
.pl.8 .pl.5 .pl.3 .pl.4 .pl.1:
|
||||
@echo "${CMT2DOC} ${.IMPSRC} > ${.TARGET:T}"
|
||||
@${CMT2DOC} ${CMT2DOC_OPTS} ${.IMPSRC} > ${.TARGET:T} || ( rm -f ${.TARGET:T} ; false )
|
||||
.else
|
||||
MAN=
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
||||
_mandir=${DESTDIR}${MANDIR}/${MANTARGET}`echo $$page | sed -e 's/.*\.cat/./' -e 's/.*\.//'`
|
||||
.if ${MANTARGET} == "cat"
|
||||
_mfromdir?=.
|
||||
MANALL= ${MAN:S/.1$/.cat1/g:S/.2$/.cat2/g:S/.3$/.cat3/g:S/.4$/.cat4/g:S/.5$/.cat5/g:S/.6$/.cat6/g:S/.7$/.cat7/g:S/.8$/.cat8/g:S/.9$/.cat9/g}
|
||||
.if ${MCATEXT} == ""
|
||||
_minstpage=`echo $$page | sed 's/\.cat/./'`
|
||||
.else
|
||||
_minstpage=`echo $$page | sed 's/\.cat.*//'`${MCATEXT}
|
||||
.endif
|
||||
.endif
|
||||
.if target(${MAN:[1]})
|
||||
_mfromdir?=.
|
||||
.endif
|
||||
_mfromdir?=${.CURDIR}
|
||||
MANALL?= ${MAN}
|
||||
_minstpage?=$${page}
|
||||
.endif
|
||||
|
||||
.if !empty(MANOWN)
|
||||
MAN_INSTALL_OWN ?= -o ${MANOWN} -g ${MANGRP}
|
||||
MAN_CHOWN ?= chown
|
||||
.else
|
||||
MAN_CHOWN = :
|
||||
.endif
|
||||
|
||||
MINSTALL= ${INSTALL} ${COPY} ${MAN_INSTALL_OWN} -m ${MANMODE}
|
||||
.if defined(MANZ)
|
||||
# chown and chmod are done afterward automatically
|
||||
MCOMPRESS= gzip -cf
|
||||
MCOMPRESSSUFFIX= .gz
|
||||
.endif
|
||||
|
||||
maninstall:
|
||||
.if defined(MANALL) && !empty(MANALL)
|
||||
@for page in ${MANALL:T}; do \
|
||||
test -s ${_mfromdir}/$$page || continue; \
|
||||
dir=${_mandir}; \
|
||||
test -d $$dir || ${INSTALL} -d ${MAN_INSTALL_OWN} -m 775 $$dir; \
|
||||
instpage=$${dir}${MANSUBDIR}/${_minstpage}${MCOMPRESSSUFFIX}; \
|
||||
if [ X"${MCOMPRESS}" = X ]; then \
|
||||
echo ${MINSTALL} ${_mfromdir}/$$page $$instpage; \
|
||||
${MINSTALL} ${_mfromdir}/$$page $$instpage; \
|
||||
else \
|
||||
rm -f $$instpage; \
|
||||
echo ${MCOMPRESS} ${_mfromdir}/$$page \> $$instpage; \
|
||||
${MCOMPRESS} ${_mfromdir}/$$page > $$instpage; \
|
||||
${MAN_CHOWN} ${MANOWN}:${MANGRP} $$instpage; \
|
||||
chmod ${MANMODE} $$instpage; \
|
||||
fi \
|
||||
done
|
||||
.if defined(MLINKS) && !empty(MLINKS)
|
||||
@set ${MLINKS}; \
|
||||
while test $$# -ge 2; do \
|
||||
page=$$1; \
|
||||
shift; \
|
||||
dir=${_mandir}; \
|
||||
l=${_minstpage}${MCOMPRESSSUFFIX}; \
|
||||
page=$$1; \
|
||||
shift; \
|
||||
dir=${_mandir}; \
|
||||
t=$${dir}${MANSUBDIR}/${_minstpage}${MCOMPRESSSUFFIX}; \
|
||||
echo $$t -\> $$l; \
|
||||
rm -f $$t; \
|
||||
ln -s $$l $$t; \
|
||||
done
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if defined(MANALL) && !empty(MANALL)
|
||||
manall: ${MANALL}
|
||||
all: manall
|
||||
.endif
|
||||
|
||||
.if defined(CLEANMAN) && !empty(CLEANMAN)
|
||||
cleandir: cleanman
|
||||
cleanman:
|
||||
rm -f ${CLEANMAN}
|
||||
.endif
|
||||
.endif
|
66
20200902/mk/manifest.mk
Normal file
66
20200902/mk/manifest.mk
Normal file
@ -0,0 +1,66 @@
|
||||
# $Id: manifest.mk,v 1.3 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2014, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
# generate mtree style manifest supported by makefs in FreeBSD
|
||||
|
||||
# input looks like
|
||||
# MANIFEST= my.mtree
|
||||
# for each MANIFEST we have a list of dirs
|
||||
# ${MANIFEST}.DIRS += bin sbin usr/bin ...
|
||||
# for each dir we have a ${MANIFEST}.SRCS.$dir
|
||||
# that provides the absolute path to the contents
|
||||
# ${MANIFEST}.SRCS.bin += ${OBJTOP}/bin/sh/sh
|
||||
# ${MANIFEST}.SYMLINKS is a list of src target pairs
|
||||
# for each file/dir there are a number of attributes
|
||||
# UID GID MODE FLAGS
|
||||
# which can be set per dir, per file or we use defaults
|
||||
# eg.
|
||||
# MODE.sbin = 550
|
||||
# MODE.usr/sbin = 550
|
||||
# MODE.dirs = 555
|
||||
# means that sbin and usr/sbin get 550 all other dirs get 555
|
||||
# MODE.usr/bin/passwd = 4555
|
||||
# MODE.usr/bin.files = 555
|
||||
# MODE.usr/sbin.files = 500
|
||||
# means passwd gets 4555 other files in usr/bin get 555 and
|
||||
# files in usr/sbin get 500
|
||||
# STORE defaults to basename of src and target directory
|
||||
# but we can use
|
||||
# ${MANIFEST}.SRCS.sbin += ${OBJTOP}/bin/sh-static/sh-static
|
||||
# STORE.sbin/sh-static = sbin/sh
|
||||
#
|
||||
# the above is a little overkill but means we can easily adapt to
|
||||
# different formats
|
||||
|
||||
UID.dirs ?= 0
|
||||
GID.dirs ?= 0
|
||||
MODE.dirs ?= 775
|
||||
FLAGS.dirs ?=
|
||||
|
||||
UID.files ?= 0
|
||||
GID.files ?= 0
|
||||
MODE.files ?= 555
|
||||
|
||||
# a is attribute name d is dirname
|
||||
M_DIR_ATTR = L:@a@$${$$a.$$d:U$${$$a.dirs}}@
|
||||
# as above and s is set to the name we store f as
|
||||
M_FILE_ATTR = L:@a@$${$$a.$$s:U$${$$a.$$d.files:U$${$$a.files}}}@
|
||||
|
||||
# this produces the body of the manifest
|
||||
# there should typically be a header prefixed
|
||||
_GEN_MTREE_MANIFEST_USE: .USE
|
||||
@(${${.TARGET}.DIRS:O:u:@d@echo '$d type=dir uid=${UID:${M_DIR_ATTR}} gid=${GID:${M_DIR_ATTR}} mode=${MODE:${M_DIR_ATTR}} ${FLAGS:${M_DIR_ATTR}}';@} \
|
||||
${${.TARGET}.DIRS:O:u:@d@${${.TARGET}.SRCS.$d:O:u:@f@echo '${s::=${STORE.$d/${f:T}:U$d/${f:T}}}$s contents="$f" type=file uid=${UID:${M_FILE_ATTR}} gid=${GID:${M_FILE_ATTR}} mode=${MODE:${M_FILE_ATTR}} ${FLAGS:${M_FILE_ATTR}}';@}@} \
|
||||
set ${${.TARGET}.SYMLINKS}; while test $$# -ge 2; do echo "$$2 type=link link=$$1"; shift 2; done) > ${.TARGET}
|
316
20200902/mk/meta.autodep.mk
Normal file
316
20200902/mk/meta.autodep.mk
Normal file
@ -0,0 +1,316 @@
|
||||
# $Id: meta.autodep.mk,v 1.52 2020/07/18 05:57:57 sjg Exp $
|
||||
|
||||
#
|
||||
# @(#) Copyright (c) 2010, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
_this ?= ${.PARSEFILE}
|
||||
.if !target(__${_this}__)
|
||||
__${_this}__: .NOTMAIN
|
||||
|
||||
.-include <local.autodep.mk>
|
||||
|
||||
PICO?= .pico
|
||||
|
||||
.if defined(SRCS)
|
||||
# it would be nice to be able to query .SUFFIXES
|
||||
OBJ_EXTENSIONS+= .o .po .lo ${PICO}
|
||||
|
||||
# explicit dependencies help short-circuit .SUFFIX searches
|
||||
SRCS_DEP_FILTER+= N*.[hly]
|
||||
.for s in ${SRCS:${SRCS_DEP_FILTER:O:u:ts:}}
|
||||
.for e in ${OBJ_EXTENSIONS:O:u}
|
||||
.if !target(${s:T:R}$e)
|
||||
${s:T:R}$e: $s
|
||||
.endif
|
||||
.endfor
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
.if make(gendirdeps)
|
||||
# you are supposed to know what you are doing!
|
||||
UPDATE_DEPENDFILE = yes
|
||||
.elif !empty(.TARGETS) && !make(all)
|
||||
# do not update the *depend* files
|
||||
# unless we are building the entire directory or the default target.
|
||||
# NO means don't update .depend - or Makefile.depend*
|
||||
# no means update .depend but not Makefile.depend*
|
||||
UPDATE_DEPENDFILE = NO
|
||||
.elif ${.MAKEFLAGS:M-k} != ""
|
||||
# it is a bad idea to update anything
|
||||
UPDATE_DEPENDFILE = NO
|
||||
.endif
|
||||
|
||||
_CURDIR ?= ${.CURDIR}
|
||||
_OBJDIR ?= ${.OBJDIR}
|
||||
_OBJTOP ?= ${OBJTOP}
|
||||
_OBJROOT ?= ${OBJROOT:U${_OBJTOP}}
|
||||
_DEPENDFILE := ${_CURDIR}/${.MAKE.DEPENDFILE:T}
|
||||
|
||||
.if ${.MAKE.LEVEL} > 0
|
||||
# do not allow auto update if we ever built this dir without filemon
|
||||
NO_FILEMON_COOKIE = .nofilemon
|
||||
CLEANFILES += ${NO_FILEMON_COOKIE}
|
||||
.if ${.MAKE.MODE:Uno:Mnofilemon} != ""
|
||||
UPDATE_DEPENDFILE = NO
|
||||
all: ${NO_FILEMON_COOKIE}
|
||||
${NO_FILEMON_COOKIE}: .NOMETA
|
||||
@echo UPDATE_DEPENDFILE=NO > ${.TARGET}
|
||||
.elif exists(${NO_FILEMON_COOKIE})
|
||||
UPDATE_DEPENDFILE = NO
|
||||
.warning ${RELDIR} built with nofilemon; UPDATE_DEPENDFILE=NO
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0
|
||||
UPDATE_DEPENDFILE = NO
|
||||
.endif
|
||||
.if !exists(${_DEPENDFILE})
|
||||
_bootstrap_dirdeps = yes
|
||||
.endif
|
||||
_bootstrap_dirdeps ?= no
|
||||
UPDATE_DEPENDFILE ?= yes
|
||||
|
||||
.if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
|
||||
.info ${_DEPENDFILE:S,${SRCTOP}/,,} update=${UPDATE_DEPENDFILE}
|
||||
.endif
|
||||
|
||||
.if !empty(XMAKE_META_FILE)
|
||||
.if exists(${.OBJDIR}/${XMAKE_META_FILE})
|
||||
# we cannot get accurate dependencies from an update build
|
||||
UPDATE_DEPENDFILE = NO
|
||||
.else
|
||||
META_XTRAS += ${XMAKE_META_FILE}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${_bootstrap_dirdeps} == "yes" || exists(${_DEPENDFILE})
|
||||
# if it isn't supposed to be touched by us the Makefile should have
|
||||
# UPDATE_DEPENDFILE = no
|
||||
WANT_UPDATE_DEPENDFILE ?= yes
|
||||
.endif
|
||||
|
||||
.if ${WANT_UPDATE_DEPENDFILE:Uno:tl} != "no"
|
||||
.if ${.MAKE.MODE:Uno:Mmeta*} == "" || ${.MAKE.MODE:Uno:M*read*} != ""
|
||||
UPDATE_DEPENDFILE = no
|
||||
.endif
|
||||
|
||||
.if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
|
||||
.info ${_DEPENDFILE:S,${SRCTOP}/,,} update=${UPDATE_DEPENDFILE}
|
||||
.endif
|
||||
|
||||
.if ${UPDATE_DEPENDFILE:tl} == "yes"
|
||||
# sometimes we want .meta files generated to aid debugging/error detection
|
||||
# but do not want to consider them for dependencies
|
||||
# for example the result of running configure
|
||||
# just make sure this is not empty
|
||||
META_FILE_FILTER ?= N.meta
|
||||
# never consider these
|
||||
META_FILE_FILTER += Ndirdeps.cache*
|
||||
|
||||
.if !empty(DPADD)
|
||||
# if we have any non-libs in DPADD,
|
||||
# they probably need to be paid attention to
|
||||
.if !empty(DPLIBS)
|
||||
FORCE_DPADD = ${DPADD:${DPLIBS:${M_ListToSkip}}:${DPADD_LAST:${M_ListToSkip}}}
|
||||
.else
|
||||
_nonlibs := ${DPADD:T:Nlib*:N*include}
|
||||
.if !empty(_nonlibs)
|
||||
FORCE_DPADD += ${_nonlibs:@x@${DPADD:M*/$x}@}
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if !make(gendirdeps)
|
||||
.END: gendirdeps
|
||||
.endif
|
||||
|
||||
# if we don't have OBJS, then .depend isn't useful
|
||||
.if !target(.depend) && (!empty(OBJS) || ${.ALLTARGETS:M*.o} != "")
|
||||
# some makefiles and/or targets contain
|
||||
# circular dependencies if you dig too deep
|
||||
# (as meta mode is apt to do)
|
||||
# so we provide a means of suppressing them.
|
||||
# the input to the loop below is target: dependency
|
||||
# with just one dependency per line.
|
||||
# Also some targets are not really local, or use random names.
|
||||
# Use local.autodep.mk to provide local additions!
|
||||
SUPPRESS_DEPEND += \
|
||||
${SB:S,/,_,g}* \
|
||||
*:y.tab.c \
|
||||
*.c:*.c \
|
||||
*.h:*.h
|
||||
|
||||
.NOPATH: .depend
|
||||
# we use ${.MAKE.META.CREATED} to trigger an update but
|
||||
# we process using ${.MAKE.META.FILES}
|
||||
# the double $$ defers initial evaluation
|
||||
# if necessary, we fake .po dependencies, just so the result
|
||||
# in Makefile.depend* is stable
|
||||
# The current objdir may be referred to in various ways
|
||||
OBJDIR_REFS += ${.OBJDIR} ${.OBJDIR:tA} ${_OBJDIR} ${RELOBJTOP}/${RELDIR}
|
||||
_depend = .depend
|
||||
# it would be nice to be able to get .SUFFIXES as ${.SUFFIXES}
|
||||
# we actually only care about the .SUFFIXES of files that might be
|
||||
# generated by tools like yacc.
|
||||
DEPEND_SUFFIXES += .c .h .cpp .hpp .cxx .hxx .cc .hh
|
||||
.depend: .NOMETA $${.MAKE.META.CREATED} ${_this}
|
||||
@echo "Updating $@: ${.OODATE:T:[1..8]}"
|
||||
@egrep -i '^R .*\.(${DEPEND_SUFFIXES:tl:O:u:S,^.,,:ts|})$$' /dev/null ${.MAKE.META.FILES:T:O:u:${META_FILE_FILTER:ts:}:M*o.meta} | \
|
||||
sed -e 's, \./, ,${OBJDIR_REFS:O:u:@d@;s, $d/, ,@};/\//d' \
|
||||
-e 's,^\([^/][^/]*\).meta...[0-9]* ,\1: ,' | \
|
||||
sort -u | \
|
||||
while read t d; do \
|
||||
case "$$d:" in $$t) continue;; esac; \
|
||||
case "$$t$$d" in ${SUPPRESS_DEPEND:U.:O:u:ts|}) continue;; esac; \
|
||||
echo $$t $$d; \
|
||||
done > $@.${.MAKE.PID}
|
||||
@case "${.MAKE.META.FILES:T:M*.po.*}" in \
|
||||
*.po.*) mv $@.${.MAKE.PID} $@;; \
|
||||
*) { cat $@.${.MAKE.PID}; \
|
||||
sed 's,\${PICO}:,.o:,;s,\.o:,.po:,' $@.${.MAKE.PID}; } | sort -u > $@; \
|
||||
rm -f $@.${.MAKE.PID};; \
|
||||
esac
|
||||
.else
|
||||
# make sure this exists
|
||||
.depend:
|
||||
# do _not_ assume that .depend is in any fit state for us to use
|
||||
CAT_DEPEND = /dev/null
|
||||
.if ${.MAKE.LEVEL} > 0
|
||||
.export CAT_DEPEND
|
||||
.endif
|
||||
_depend =
|
||||
.endif
|
||||
|
||||
.if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
|
||||
.info ${_DEPENDFILE:S,${SRCTOP}/,,} _depend=${_depend}
|
||||
.endif
|
||||
|
||||
.if ${UPDATE_DEPENDFILE} == "yes"
|
||||
gendirdeps: ${_DEPENDFILE}
|
||||
.endif
|
||||
|
||||
.if !target(${_DEPENDFILE})
|
||||
.if ${_bootstrap_dirdeps} == "yes"
|
||||
# We are boot-strapping a new directory
|
||||
# Use DPADD to seed DIRDEPS
|
||||
.if !empty(DPADD)
|
||||
# anything which matches ${_OBJROOT}* but not ${_OBJTOP}*
|
||||
# needs to be qualified in DIRDEPS
|
||||
# The pseudo machine "host" is used for HOST_TARGET
|
||||
DIRDEPS += \
|
||||
${DPADD:M${_OBJTOP}*:H:C,${_OBJTOP}[^/]*/,,:N.:O:u} \
|
||||
${DPADD:M${_OBJROOT}*:N${_OBJTOP}*:N${STAGE_ROOT:U${_OBJTOP}}/*:H:S,${_OBJROOT},,:C,^([^/]+)/(.*),\2.\1,:S,${HOST_TARGET}$,host,:N.*:O:u}
|
||||
|
||||
.endif
|
||||
.endif
|
||||
|
||||
_gendirdeps_mutex =
|
||||
.if defined(NEED_GENDIRDEPS_MUTEX)
|
||||
# If a src dir gets built with multiple object dirs,
|
||||
# we need a mutex. Obviously, this is best avoided.
|
||||
# Note if .MAKE.DEPENDFILE is common for all ${MACHINE}
|
||||
# you either need to mutex, or ensure only one machine builds at a time!
|
||||
# lockf is an example of a suitable tool
|
||||
LOCKF ?= /usr/bin/lockf
|
||||
.if exists(${LOCKF})
|
||||
GENDIRDEPS_MUTEXER ?= ${LOCKF} -k
|
||||
.endif
|
||||
.if empty(GENDIRDEPS_MUTEXER)
|
||||
.error NEED_GENDIRDEPS_MUTEX defined, but GENDIRDEPS_MUTEXER not set
|
||||
.else
|
||||
_gendirdeps_mutex = ${GENDIRDEPS_MUTEXER} ${GENDIRDEPS_MUTEX:U${_CURDIR}/Makefile}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# If we have META_XTRAS we most likely did not create them
|
||||
# but we need to behave as if we did.
|
||||
# Avoid adding glob patterns to .MAKE.META.CREATED though.
|
||||
.MAKE.META.CREATED += ${META_XTRAS:N*\**:O:u}
|
||||
|
||||
.if make(gendirdeps)
|
||||
META_FILES = *.meta
|
||||
.elif ${OPTIMIZE_OBJECT_META_FILES:Uno:tl} == "no"
|
||||
META_FILES = ${.MAKE.META.FILES:T:N.depend*:O:u}
|
||||
.else
|
||||
# if we have 1000's of .o.meta, ${PICO}.meta etc we need only look at one set
|
||||
# it is left as an exercise for the reader to work out what this does
|
||||
META_FILES = ${.MAKE.META.FILES:T:N.depend*:N*o.meta:O:u} \
|
||||
${.MAKE.META.FILES:T:M*.${.MAKE.META.FILES:M*o.meta:R:E:O:u:[1]}.meta:O:u}
|
||||
.endif
|
||||
|
||||
.if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
|
||||
.info ${_DEPENDFILE:S,${SRCTOP}/,,}: ${_depend} ${.PARSEDIR}/gendirdeps.mk ${META2DEPS} xtras=${META_XTRAS}
|
||||
.endif
|
||||
|
||||
.if ${.MAKE.LEVEL} > 0
|
||||
.if ${UPDATE_DEPENDFILE} == "yes"
|
||||
.-include <${.CURDIR}/${.MAKE.DEPENDFILE_PREFIX}.options>
|
||||
.endif
|
||||
.if !empty(GENDIRDEPS_FILTER)
|
||||
.export GENDIRDEPS_FILTER
|
||||
.endif
|
||||
# export to avoid blowing command line limit
|
||||
META_FILES := ${META_XTRAS:U:O:u} ${META_FILES:U:T:O:u:${META_FILE_FILTER:ts:}}
|
||||
.export META_FILES
|
||||
.endif
|
||||
|
||||
# we might have .../ in MAKESYSPATH
|
||||
_makesyspath:= ${_PARSEDIR}
|
||||
${_DEPENDFILE}: ${_depend} ${.PARSEDIR}/gendirdeps.mk ${META2DEPS} $${.MAKE.META.CREATED}
|
||||
@echo Checking $@: ${.OODATE:T:[1..8]}
|
||||
@(cd . && ${GENDIRDEPS_ENV} \
|
||||
SKIP_GENDIRDEPS='${SKIP_GENDIRDEPS:O:u}' \
|
||||
DPADD='${FORCE_DPADD:O:u}' ${_gendirdeps_mutex} \
|
||||
MAKESYSPATH=${_makesyspath} \
|
||||
${.MAKE} -f gendirdeps.mk RELDIR=${RELDIR} _DEPENDFILE=${_DEPENDFILE})
|
||||
@test -s $@ && touch $@; :
|
||||
.endif
|
||||
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${_bootstrap_dirdeps} == "yes"
|
||||
DIRDEPS+= ${RELDIR}.${TARGET_SPEC:U${MACHINE}}
|
||||
# make sure this is included at least once
|
||||
.include <dirdeps.mk>
|
||||
.else
|
||||
${_DEPENDFILE}: .PRECIOUS
|
||||
.endif
|
||||
|
||||
CLEANFILES += *.meta filemon.* *.db
|
||||
|
||||
# these make it easy to gather some stats
|
||||
now_utc = ${%s:L:gmtime}
|
||||
start_utc := ${now_utc}
|
||||
|
||||
meta_stats= meta=${empty(.MAKE.META.FILES):?0:${.MAKE.META.FILES:[#]}} \
|
||||
created=${empty(.MAKE.META.CREATED):?0:${.MAKE.META.CREATED:[#]}}
|
||||
|
||||
#.END: _reldir_finish
|
||||
.if target(gendirdeps)
|
||||
_reldir_finish: gendirdeps
|
||||
.endif
|
||||
_reldir_finish: .NOMETA
|
||||
@echo "${TIME_STAMP} Finished ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}"
|
||||
|
||||
#.ERROR: _reldir_failed
|
||||
_reldir_failed: .NOMETA
|
||||
@echo "${TIME_STAMP} Failed ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}"
|
||||
|
||||
.if !defined(WITHOUT_META_STATS) && ${.MAKE.LEVEL} > 0
|
||||
.END: _reldir_finish
|
||||
.ERROR: _reldir_failed
|
||||
.endif
|
||||
|
||||
.endif
|
366
20200902/mk/meta.stage.mk
Normal file
366
20200902/mk/meta.stage.mk
Normal file
@ -0,0 +1,366 @@
|
||||
# $Id: meta.stage.mk,v 1.60 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2011-2017, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.ifndef NO_STAGING
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
# the guard target is defined later
|
||||
|
||||
.-include <local.meta.stage.mk>
|
||||
|
||||
.if ${.MAKE.DEPENDFILE_PREFERENCE:U${.MAKE.DEPENDFILE}:M*.${MACHINE}} != ""
|
||||
# this is generally safer anyway
|
||||
_dirdep ?= ${RELDIR}.${TARGET_SPEC:U${MACHINE}}
|
||||
.else
|
||||
_dirdep ?= ${RELDIR}
|
||||
.endif
|
||||
|
||||
CLEANFILES+= .dirdep
|
||||
|
||||
# this allows us to trace dependencies back to their src dir
|
||||
.dirdep: .NOPATH
|
||||
@echo '${_dirdep}' > $@
|
||||
|
||||
.if defined(NO_POSIX_SHELL) || ${type printf:L:sh:Mbuiltin} == ""
|
||||
_stage_file_basename = `basename $$f`
|
||||
_stage_target_dirname = `dirname $$t`
|
||||
.else
|
||||
_stage_file_basename = $${f\#\#*/}
|
||||
_stage_target_dirname = $${t%/*}
|
||||
.endif
|
||||
|
||||
_OBJROOT ?= ${OBJROOT:U${OBJTOP:H}}
|
||||
.if ${_OBJROOT:M*/} != ""
|
||||
_objroot ?= ${_OBJROOT:tA}/
|
||||
.else
|
||||
_objroot ?= ${_OBJROOT:tA}
|
||||
.endif
|
||||
|
||||
# make sure this is global
|
||||
_STAGED_DIRS ?=
|
||||
.export _STAGED_DIRS
|
||||
# add each dir we stage to to _STAGED_DIRS
|
||||
# and make sure we have absolute paths so that bmake
|
||||
# will match against .MAKE.META.BAILIWICK
|
||||
STAGE_DIR_FILTER = tA:@d@$${_STAGED_DIRS::+=$$d}$$d@
|
||||
# convert _STAGED_DIRS into suitable filters
|
||||
GENDIRDEPS_FILTER += Nnot-empty-is-important \
|
||||
${_STAGED_DIRS:O:u:M${OBJTOP}*:S,${OBJTOP}/,N,} \
|
||||
${_STAGED_DIRS:O:u:M${_objroot}*:N${OBJTOP}*:S,${_objroot},,:C,^([^/]+)/(.*),N\2.\1,:S,${HOST_TARGET},.host,}
|
||||
|
||||
LN_CP_SCRIPT = LnCp() { \
|
||||
rm -f $$2 2> /dev/null; \
|
||||
{ [ -z "$$mode" ] && ${LN:Uln} $$1 $$2 2> /dev/null; } || \
|
||||
cp -p $$1 $$2; }
|
||||
|
||||
# a staging conflict should cause an error
|
||||
# a warning is handy when bootstapping different options.
|
||||
STAGE_CONFLICT?= ERROR
|
||||
.if ${STAGE_CONFLICT:tl} == "error"
|
||||
STAGE_CONFLICT_ACTION= exit 1
|
||||
.else
|
||||
STAGE_CONFLICT_ACTION=
|
||||
.endif
|
||||
|
||||
# it is an error for more than one src dir to try and stage
|
||||
# the same file
|
||||
STAGE_DIRDEP_SCRIPT = ${LN_CP_SCRIPT}; StageDirdep() { \
|
||||
t=$$1; \
|
||||
if [ -s $$t.dirdep ]; then \
|
||||
cmp -s .dirdep $$t.dirdep && return; \
|
||||
x=`cat $$t.dirdep`; \
|
||||
case "${RELDIR}:${_dirdep}" in $${x%.*}:$${x}*) ;; \
|
||||
*) echo "${STAGE_CONFLICT}: $$t installed by $$x not ${_dirdep}" >&2; \
|
||||
${STAGE_CONFLICT_ACTION} ;; esac; \
|
||||
fi; \
|
||||
LnCp .dirdep $$t.dirdep || exit 1; }
|
||||
|
||||
# common logic for staging files
|
||||
# this all relies on RELDIR being set to a subdir of SRCTOP
|
||||
# we use ln(1) if we can, else cp(1)
|
||||
STAGE_FILE_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageFiles() { \
|
||||
case "$$1" in "") return;; -m) mode=$$2; shift 2;; *) mode=;; esac; \
|
||||
dest=$$1; shift; \
|
||||
mkdir -p $$dest; \
|
||||
[ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \
|
||||
for f in "$$@"; do \
|
||||
case "$$f" in */*) t=$$dest/${_stage_file_basename};; *) t=$$dest/$$f;; esac; \
|
||||
StageDirdep $$t; \
|
||||
LnCp $$f $$t || exit 1; \
|
||||
[ -z "$$mode" ] || chmod $$mode $$t; \
|
||||
done; :; }
|
||||
|
||||
STAGE_LINKS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageLinks() { \
|
||||
case "$$1" in "") return;; --) shift;; -*) ldest= lnf=$$1; shift;; /*) ldest=$$1/;; esac; \
|
||||
dest=$$1; shift; \
|
||||
mkdir -p $$dest; \
|
||||
[ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \
|
||||
while test $$\# -ge 2; do \
|
||||
l=$$ldest$$1; shift; \
|
||||
t=$$dest/$$1; \
|
||||
case "$$1" in */*) mkdir -p ${_stage_target_dirname};; esac; \
|
||||
shift; \
|
||||
StageDirdep $$t; \
|
||||
rm -f $$t 2>/dev/null; \
|
||||
ln $$lnf $$l $$t || exit 1; \
|
||||
done; :; }
|
||||
|
||||
STAGE_AS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageAs() { \
|
||||
case "$$1" in "") return;; -m) mode=$$2; shift 2;; *) mode=;; esac; \
|
||||
dest=$$1; shift; \
|
||||
mkdir -p $$dest; \
|
||||
[ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \
|
||||
while test $$\# -ge 2; do \
|
||||
s=$$1; shift; \
|
||||
t=$$dest/$$1; \
|
||||
case "$$1" in */*) mkdir -p ${_stage_target_dirname};; esac; \
|
||||
shift; \
|
||||
StageDirdep $$t; \
|
||||
LnCp $$s $$t || exit 1; \
|
||||
[ -z "$$mode" ] || chmod $$mode $$t; \
|
||||
done; :; }
|
||||
|
||||
# this is simple, a list of the "staged" files depends on this,
|
||||
_STAGE_BASENAME_USE: .USE .dirdep ${.TARGET:T}
|
||||
@${STAGE_FILE_SCRIPT}; StageFiles ${.TARGET:H:${STAGE_DIR_FILTER}} ${.TARGET:T}
|
||||
|
||||
_STAGE_AS_BASENAME_USE: .USE .dirdep ${.TARGET:T}
|
||||
@${STAGE_AS_SCRIPT}; StageAs ${.TARGET:H:${STAGE_DIR_FILTER}} ${.TARGET:T} ${STAGE_AS_${.TARGET:T}:U${.TARGET:T}}
|
||||
|
||||
|
||||
.endif # first time
|
||||
|
||||
|
||||
.if !empty(STAGE_INCSDIR)
|
||||
.if !empty(STAGE_INCS)
|
||||
stage_incs: ${STAGE_INCS:N*\**}
|
||||
.endif
|
||||
.if target(stage_incs) || !empty(.ALLTARGETS:Mstage_includes)
|
||||
STAGE_TARGETS += stage_incs
|
||||
STAGE_INCS ?= ${.ALLSRC:N.dirdep:Nstage_*}
|
||||
stage_includes: stage_incs
|
||||
stage_incs: .dirdep
|
||||
@${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_INCSDIR:${STAGE_DIR_FILTER}} ${STAGE_INCS}
|
||||
@touch $@
|
||||
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if !empty(STAGE_LIBDIR)
|
||||
.if !empty(STAGE_LIBS)
|
||||
stage_libs: ${STAGE_LIBS:N*\**}
|
||||
.endif
|
||||
.if target(stage_libs)
|
||||
STAGE_TARGETS += stage_libs
|
||||
STAGE_LIBS ?= ${.ALLSRC:N.dirdep:Nstage_*}
|
||||
stage_libs: .dirdep
|
||||
@${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} ${STAGE_LIBS}
|
||||
.if !defined(NO_SHLIB_LINKS)
|
||||
.if !empty(SHLIB_LINKS)
|
||||
@${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} \
|
||||
${SHLIB_LINKS:@t@${STAGE_LIBS:T:M$t.*} $t@}
|
||||
.elif !empty(SHLIB_LINK) && !empty(SHLIB_NAME)
|
||||
@${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} ${SHLIB_NAME} ${SHLIB_LINK}
|
||||
.endif
|
||||
.endif
|
||||
@touch $@
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if !empty(STAGE_DIR)
|
||||
STAGE_SETS += _default
|
||||
STAGE_DIR._default = ${STAGE_DIR}
|
||||
STAGE_LINKS_DIR._default = ${STAGE_LINKS_DIR:U${STAGE_OBJTOP}}
|
||||
STAGE_SYMLINKS_DIR._default = ${STAGE_SYMLINKS_DIR:U${STAGE_OBJTOP}}
|
||||
STAGE_FILES._default = ${STAGE_FILES}
|
||||
STAGE_LINKS._default = ${STAGE_LINKS}
|
||||
STAGE_SYMLINKS._default = ${STAGE_SYMLINKS}
|
||||
.endif
|
||||
|
||||
.if !empty(STAGE_SETS)
|
||||
CLEANFILES += ${STAGE_SETS:@s@stage*$s@}
|
||||
|
||||
# some makefiles need to populate multiple directories
|
||||
.for s in ${STAGE_SETS:O:u}
|
||||
.if !empty(STAGE_FILES.$s)
|
||||
stage_files.$s: ${STAGE_FILES.$s:N*\**}
|
||||
.endif
|
||||
.if target(stage_files.$s) || target(stage_files${s:S,^,.,:N._default})
|
||||
STAGE_TARGETS += stage_files
|
||||
STAGE_FILES.$s ?= ${.ALLSRC:N.dirdep:Nstage_*}
|
||||
.if !target(.stage_files.$s)
|
||||
.stage_files.$s:
|
||||
.if $s != "_default"
|
||||
stage_files: stage_files.$s
|
||||
stage_files.$s: .dirdep
|
||||
.else
|
||||
STAGE_FILES ?= ${.ALLSRC:N.dirdep:Nstage_*}
|
||||
stage_files: .dirdep
|
||||
.endif
|
||||
@${STAGE_FILE_SCRIPT}; StageFiles ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_FILES.$s:O}
|
||||
@touch $@
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if !empty(STAGE_LINKS.$s)
|
||||
stage_links.$s:
|
||||
.endif
|
||||
.if target(stage_links.$s) || target(stage_links${s:S,^,.,:N._default})
|
||||
STAGE_LINKS_DIR.$s ?= ${STAGE_OBJTOP}
|
||||
STAGE_TARGETS += stage_links
|
||||
.if !target(.stage_links.$s)
|
||||
.stage_links.$s:
|
||||
.if $s != "_default"
|
||||
stage_links: stage_links.$s
|
||||
stage_links.$s: .dirdep
|
||||
.else
|
||||
stage_links: .dirdep
|
||||
.endif
|
||||
@${STAGE_LINKS_SCRIPT}; StageLinks ${STAGE_LINKS_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_LINKS.$s}
|
||||
@touch $@
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if !empty(STAGE_SYMLINKS.$s)
|
||||
stage_symlinks.$s:
|
||||
.endif
|
||||
.if target(stage_symlinks.$s) || target(stage_symlinks${s:S,^,.,:N._default})
|
||||
STAGE_SYMLINKS_DIR.$s ?= ${STAGE_OBJTOP}
|
||||
STAGE_TARGETS += stage_symlinks
|
||||
.if !target(.stage_symlinks.$s)
|
||||
.stage_symlinks.$s:
|
||||
.if $s != "_default"
|
||||
stage_symlinks: stage_symlinks.$s
|
||||
stage_symlinks.$s: .dirdep
|
||||
.else
|
||||
stage_symlinks: .dirdep
|
||||
.endif
|
||||
@${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_SYMLINKS_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_SYMLINKS.$s}
|
||||
@touch $@
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
.if !empty(STAGE_AS_SETS)
|
||||
CLEANFILES += ${STAGE_AS_SETS:@s@stage*$s@}
|
||||
|
||||
# sometimes things need to be renamed as they are staged
|
||||
# each ${file} will be staged as ${STAGE_AS_${file:T}}
|
||||
# one could achieve the same with SYMLINKS
|
||||
# stage_as_and_symlink makes the original name a symlink to the new name
|
||||
# it is the same as using stage_as and stage_symlinks but ensures
|
||||
# both operations happen together
|
||||
.for s in ${STAGE_AS_SETS:O:u}
|
||||
.if !empty(STAGE_AS.$s)
|
||||
stage_as.$s: ${STAGE_AS.$s:N*\**}
|
||||
.endif
|
||||
.if target(stage_as.$s)
|
||||
STAGE_TARGETS += stage_as
|
||||
STAGE_AS.$s ?= ${.ALLSRC:N.dirdep:Nstage_*}
|
||||
.if !target(.stage_as.$s)
|
||||
.stage_as.$s:
|
||||
stage_as: stage_as.$s
|
||||
stage_as.$s: .dirdep
|
||||
@${STAGE_AS_SCRIPT}; StageAs ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS.$s:O:@f@$f ${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}}@}
|
||||
@touch $@
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if !empty(STAGE_AS_AND_SYMLINK.$s)
|
||||
stage_as_and_symlink.$s: ${STAGE_AS_AND_SYMLINK.$s:N*\**}
|
||||
.endif
|
||||
.if target(stage_as_and_symlink.$s)
|
||||
STAGE_TARGETS += stage_as_and_symlink
|
||||
STAGE_AS_AND_SYMLINK.$s ?= ${.ALLSRC:N.dirdep:Nstage_*}
|
||||
.if !target(.stage_as_and_symlink.$s)
|
||||
.stage_as_and_symlink.$s:
|
||||
stage_as_and_symlink: stage_as_and_symlink.$s
|
||||
stage_as_and_symlink.$s: .dirdep
|
||||
@${STAGE_AS_SCRIPT}; StageAs ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS_AND_SYMLINK.$s:O:@f@$f ${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}}@}
|
||||
@${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS_AND_SYMLINK.$s:O:@f@${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}} $f@}
|
||||
@touch $@
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
CLEANFILES += ${STAGE_TARGETS} stage_incs stage_includes
|
||||
|
||||
# this lot also only makes sense the first time...
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
# stage_*links usually needs to follow any others.
|
||||
# for non-jobs mode the order here matters
|
||||
staging: ${STAGE_TARGETS:N*_links} ${STAGE_TARGETS:M*_links}
|
||||
|
||||
.if ${.MAKE.JOBS:U0} > 0 && ${STAGE_TARGETS:U:M*_links} != ""
|
||||
# the above isn't sufficient
|
||||
.for t in ${STAGE_TARGETS:N*links:O:u}
|
||||
.ORDER: $t stage_links
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
# generally we want staging to wait until everything else is done
|
||||
STAGING_WAIT ?= .WAIT
|
||||
|
||||
.if ${.MAKE.LEVEL} > 0
|
||||
all: ${STAGING_WAIT} staging
|
||||
.endif
|
||||
|
||||
.if exists(${.PARSEDIR}/stage-install.sh) && !defined(STAGE_INSTALL)
|
||||
# this will run install(1) and then followup with .dirdep files.
|
||||
STAGE_INSTALL := sh ${.PARSEDIR:tA}/stage-install.sh INSTALL="${INSTALL}" OBJDIR=${.OBJDIR:tA}
|
||||
.endif
|
||||
|
||||
# if ${INSTALL} gets run during 'all' assume it is for staging?
|
||||
.if ${.TARGETS:Nall} == "" && defined(STAGE_INSTALL)
|
||||
INSTALL := ${STAGE_INSTALL}
|
||||
.if target(beforeinstall)
|
||||
beforeinstall: .dirdep
|
||||
.endif
|
||||
.endif
|
||||
.NOPATH: ${STAGE_FILES}
|
||||
|
||||
.if !empty(STAGE_TARGETS)
|
||||
# for backwards compat make sure they exist
|
||||
${STAGE_TARGETS}:
|
||||
|
||||
.NOPATH: ${CLEANFILES}
|
||||
|
||||
MK_STALE_STAGED?= no
|
||||
.if ${MK_STALE_STAGED} == "yes"
|
||||
all: stale_staged
|
||||
# get a list of paths that we have just staged
|
||||
# get a list of paths that we have previously staged to those same dirs
|
||||
# anything in the 2nd list but not the first is stale - remove it.
|
||||
stale_staged: staging .NOMETA
|
||||
@egrep '^[WL] .*${STAGE_OBJTOP}' /dev/null ${.MAKE.META.FILES:M*stage_*} | \
|
||||
sed "/\.dirdep/d;s,.* '*\(${STAGE_OBJTOP}/[^ '][^ ']*\).*,\1," | \
|
||||
sort > ${.TARGET}.staged1
|
||||
@grep -l '${_dirdep}' /dev/null ${_STAGED_DIRS:M${STAGE_OBJTOP}*:O:u:@d@$d/*.dirdep@} | \
|
||||
sed 's,\.dirdep,,' | sort > ${.TARGET}.staged2
|
||||
@comm -13 ${.TARGET}.staged1 ${.TARGET}.staged2 > ${.TARGET}.stale
|
||||
@test ! -s ${.TARGET}.stale || { \
|
||||
echo "Removing stale staged files..."; \
|
||||
sed 's,.*,& &.dirdep,' ${.TARGET}.stale | xargs rm -f; }
|
||||
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
79
20200902/mk/meta.subdir.mk
Normal file
79
20200902/mk/meta.subdir.mk
Normal file
@ -0,0 +1,79 @@
|
||||
# $Id: meta.subdir.mk,v 1.12 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
#
|
||||
# @(#) Copyright (c) 2010, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.if !defined(NO_SUBDIR) && !empty(SUBDIR)
|
||||
.if make(destroy*) || make(clean*)
|
||||
.MAKE.MODE = compat
|
||||
.if !commands(destroy)
|
||||
.-include <bsd.obj.mk>
|
||||
.endif
|
||||
.elif ${.MAKE.LEVEL} == 0
|
||||
|
||||
.MAIN: all
|
||||
|
||||
.if !exists(${.CURDIR}/${.MAKE.DEPENDFILE:T}) || make(gendirdeps)
|
||||
# start with this
|
||||
DIRDEPS = ${SUBDIR:N.WAIT:O:u:@d@${RELDIR}/$d@}
|
||||
|
||||
.if make(gendirdeps)
|
||||
.include <meta.autodep.mk>
|
||||
.else
|
||||
# this is the cunning bit
|
||||
# actually it is probably a bit risky
|
||||
# since we may pickup subdirs which are not relevant
|
||||
# the alternative is a walk through the tree though
|
||||
# which is difficult without a sub-make.
|
||||
|
||||
.if defined(BOOTSTRAP_DEPENDFILES)
|
||||
_find_name = ${.MAKE.MAKEFILE_PREFERENCE:@m@-o -name $m@:S,^-o,,1}
|
||||
DIRDEPS = ${_subdeps:H:O:u:@d@${RELDIR}/$d@}
|
||||
.elif ${.MAKE.DEPENDFILE:E} == ${MACHINE} && defined(ALL_MACHINES)
|
||||
# we want to find Makefile.depend.* ie for all machines
|
||||
# and turn the dirs into dir.<machine>
|
||||
_find_name = -name '${.MAKE.DEPENDFILE:T:R}*'
|
||||
DIRDEPS = ${_subdeps:O:u:${NIgnoreFiles}:@d@${RELDIR}/${d:H}.${d:E}@:S,.${MACHINE}$,,:S,.depend$,,}
|
||||
.else
|
||||
# much simpler
|
||||
_find_name = -name ${.MAKE.DEPENDFILE:T}
|
||||
.if ${.MAKE.DEPENDFILE:E} == ${MACHINE}
|
||||
_find_name += -o -name ${.MAKE.DEPENDFILE:T:R}
|
||||
.endif
|
||||
DIRDEPS = ${_subdeps:H:O:u:@d@${RELDIR}/$d@}
|
||||
.endif
|
||||
|
||||
_subdeps != cd ${.CURDIR} && \
|
||||
find ${SUBDIR:N.WAIT} -type f \( ${_find_name} \) -print -o \
|
||||
-name .svn -prune 2> /dev/null; echo
|
||||
|
||||
.if empty(_subdeps)
|
||||
DIRDEPS =
|
||||
.else
|
||||
# clean up if needed
|
||||
DIRDEPS := ${DIRDEPS:S,^./,,:S,/./,/,g:${SUBDIRDEPS_FILTER:Uu}}
|
||||
.endif
|
||||
# we just dealt with it, if we leave it defined,
|
||||
# dirdeps.mk will compute some interesting combinations.
|
||||
.undef ALL_MACHINES
|
||||
|
||||
DEP_RELDIR = ${RELDIR}
|
||||
.include <dirdeps.mk>
|
||||
.endif
|
||||
.endif
|
||||
.else
|
||||
all: .PHONY
|
||||
.endif
|
||||
|
||||
.endif
|
167
20200902/mk/meta.sys.mk
Normal file
167
20200902/mk/meta.sys.mk
Normal file
@ -0,0 +1,167 @@
|
||||
# $Id: meta.sys.mk,v 1.38 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
#
|
||||
# @(#) Copyright (c) 2010-2020, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
# include this if you want to enable meta mode
|
||||
# for maximum benefit, requires filemon(4) driver.
|
||||
|
||||
.if ${MAKE_VERSION:U0} > 20100901
|
||||
.if !target(.ERROR)
|
||||
|
||||
.-include <local.meta.sys.mk>
|
||||
|
||||
# absolute path to what we are reading.
|
||||
_PARSEDIR = ${.PARSEDIR:tA}
|
||||
|
||||
.if !defined(SYS_MK_DIR)
|
||||
SYS_MK_DIR := ${_PARSEDIR}
|
||||
.endif
|
||||
|
||||
META_MODE += meta verbose
|
||||
.MAKE.MODE ?= ${META_MODE}
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0
|
||||
_make_mode := ${.MAKE.MODE} ${META_MODE}
|
||||
.if ${_make_mode:M*read*} != "" || ${_make_mode:M*nofilemon*} != ""
|
||||
# tell everyone we are not updating Makefile.depend*
|
||||
UPDATE_DEPENDFILE = NO
|
||||
.export UPDATE_DEPENDFILE
|
||||
.endif
|
||||
.if ${UPDATE_DEPENDFILE:Uyes:tl} == "no" && !exists(/dev/filemon)
|
||||
# we should not get upset
|
||||
META_MODE += nofilemon
|
||||
.export META_MODE
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if !defined(NO_SILENT)
|
||||
.if ${MAKE_VERSION} > 20110818
|
||||
# only be silent when we have a .meta file
|
||||
META_MODE += silent=yes
|
||||
.else
|
||||
.SILENT:
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# we use the pseudo machine "host" for the build host.
|
||||
# this should be taken care of before we get here
|
||||
.if ${OBJTOP:Ua} == ${HOST_OBJTOP:Ub}
|
||||
MACHINE = host
|
||||
.endif
|
||||
|
||||
.if !defined(MACHINE0)
|
||||
# it can be handy to know which MACHINE kicked off the build
|
||||
# for example, if using Makefild.depend for multiple machines,
|
||||
# allowing only MACHINE0 to update can keep things simple.
|
||||
MACHINE0 := ${MACHINE}
|
||||
.export MACHINE0
|
||||
.endif
|
||||
|
||||
.if !defined(META2DEPS)
|
||||
.if defined(PYTHON) && exists(${PYTHON})
|
||||
# we prefer the python version of this - it is much faster
|
||||
META2DEPS ?= ${.PARSEDIR}/meta2deps.py
|
||||
.else
|
||||
META2DEPS ?= ${.PARSEDIR}/meta2deps.sh
|
||||
.endif
|
||||
META2DEPS := ${META2DEPS}
|
||||
.export META2DEPS
|
||||
.endif
|
||||
|
||||
MAKE_PRINT_VAR_ON_ERROR += \
|
||||
.ERROR_TARGET \
|
||||
.ERROR_META_FILE \
|
||||
.MAKE.LEVEL \
|
||||
MAKEFILE \
|
||||
.MAKE.MODE
|
||||
|
||||
.if !defined(SB) && defined(SRCTOP)
|
||||
SB = ${SRCTOP:H}
|
||||
.endif
|
||||
ERROR_LOGDIR ?= ${SB}/error
|
||||
meta_error_log = ${ERROR_LOGDIR}/meta-${.MAKE.PID}.log
|
||||
|
||||
# we are not interested in make telling us a failure happened elsewhere
|
||||
.ERROR: _metaError
|
||||
_metaError: .NOMETA .NOTMAIN
|
||||
-@[ "${.ERROR_META_FILE}" ] && { \
|
||||
grep -q 'failure has been detected in another branch' ${.ERROR_META_FILE} && exit 0; \
|
||||
mkdir -p ${meta_error_log:H}; \
|
||||
cp ${.ERROR_META_FILE} ${meta_error_log}; \
|
||||
echo "ERROR: log ${meta_error_log}" >&2; }; :
|
||||
|
||||
.endif
|
||||
|
||||
# Are we, after all, in meta mode?
|
||||
.if ${.MAKE.MODE:Uno:Mmeta*} != ""
|
||||
MKDEP_MK = meta.autodep.mk
|
||||
|
||||
.if ${.MAKE.MAKEFILES:M*sys.dependfile.mk} == ""
|
||||
# this does all the smarts of setting .MAKE.DEPENDFILE
|
||||
.-include <sys.dependfile.mk>
|
||||
# check if we got anything sane
|
||||
.if ${.MAKE.DEPENDFILE} == ".depend"
|
||||
.undef .MAKE.DEPENDFILE
|
||||
.endif
|
||||
.MAKE.DEPENDFILE ?= Makefile.depend
|
||||
.endif
|
||||
|
||||
# we can afford to use cookies to prevent some targets
|
||||
# re-running needlessly
|
||||
META_COOKIE_TOUCH?= touch ${COOKIE.${.TARGET}:U${.OBJDIR}/${.TARGET:T}}
|
||||
META_NOPHONY=
|
||||
META_NOECHO= :
|
||||
|
||||
# some targets involve old pre-built targets
|
||||
# ignore mtime of shell
|
||||
# and mtime of makefiles does not matter in meta mode
|
||||
.MAKE.META.IGNORE_PATHS += \
|
||||
${MAKEFILE} \
|
||||
${MAKE_SHELL} \
|
||||
${SHELL} \
|
||||
${SYS_MK_DIR} \
|
||||
|
||||
|
||||
.if ${UPDATE_DEPENDFILE:Uyes:tl} != "no"
|
||||
.if ${.MAKEFLAGS:Uno:M-k} != ""
|
||||
# make this more obvious
|
||||
.warning Setting UPDATE_DEPENDFILE=NO due to -k
|
||||
UPDATE_DEPENDFILE= NO
|
||||
.export UPDATE_DEPENDFILE
|
||||
.elif !exists(/dev/filemon)
|
||||
.error ${.newline}ERROR: The filemon module (/dev/filemon) is not loaded.
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0
|
||||
# make sure dirdeps target exists and do it first
|
||||
all: dirdeps .WAIT
|
||||
dirdeps:
|
||||
.NOPATH: dirdeps
|
||||
|
||||
.if defined(ALL_MACHINES)
|
||||
# the first .MAIN: is what counts
|
||||
# by default dirdeps is all we want at level0
|
||||
.MAIN: dirdeps
|
||||
.endif
|
||||
|
||||
.endif
|
||||
.else
|
||||
META_COOKIE_TOUCH=
|
||||
# some targets need to be .PHONY in non-meta mode
|
||||
META_NOPHONY= .PHONY
|
||||
META_NOECHO= echo
|
||||
.endif
|
||||
.endif
|
767
20200902/mk/meta2deps.py
Executable file
767
20200902/mk/meta2deps.py
Executable file
@ -0,0 +1,767 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
"""
|
||||
This script parses each "meta" file and extracts the
|
||||
information needed to deduce build and src dependencies.
|
||||
|
||||
It works much the same as the original shell script, but is
|
||||
*much* more efficient.
|
||||
|
||||
The parsing work is handled by the class MetaFile.
|
||||
We only pay attention to a subset of the information in the
|
||||
"meta" files. Specifically:
|
||||
|
||||
'CWD' to initialize our notion.
|
||||
|
||||
'C' to track chdir(2) on a per process basis
|
||||
|
||||
'R' files read are what we really care about.
|
||||
directories read, provide a clue to resolving
|
||||
subsequent relative paths. That is if we cannot find
|
||||
them relative to 'cwd', we check relative to the last
|
||||
dir read.
|
||||
|
||||
'W' files opened for write or read-write,
|
||||
for filemon V3 and earlier.
|
||||
|
||||
'E' files executed.
|
||||
|
||||
'L' files linked
|
||||
|
||||
'V' the filemon version, this record is used as a clue
|
||||
that we have reached the interesting bit.
|
||||
|
||||
"""
|
||||
|
||||
"""
|
||||
RCSid:
|
||||
$Id: meta2deps.py,v 1.33 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
Copyright (c) 2011-2020, Simon J. Gerraty
|
||||
Copyright (c) 2011-2017, Juniper Networks, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""
|
||||
|
||||
import os, re, sys
|
||||
|
||||
def getv(dict, key, d=None):
|
||||
"""Lookup key in dict and return value or the supplied default."""
|
||||
if key in dict:
|
||||
return dict[key]
|
||||
return d
|
||||
|
||||
def resolve(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr):
|
||||
"""
|
||||
Return an absolute path, resolving via cwd or last_dir if needed.
|
||||
"""
|
||||
if path.endswith('/.'):
|
||||
path = path[0:-2]
|
||||
if len(path) > 0 and path[0] == '/':
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
if debug > 2:
|
||||
print("skipping non-existent:", path, file=debug_out)
|
||||
return None
|
||||
if path == '.':
|
||||
return cwd
|
||||
if path.startswith('./'):
|
||||
return cwd + path[1:]
|
||||
if last_dir == cwd:
|
||||
last_dir = None
|
||||
for d in [last_dir, cwd]:
|
||||
if not d:
|
||||
continue
|
||||
if path == '..':
|
||||
dw = d.split('/')
|
||||
p = '/'.join(dw[:-1])
|
||||
if not p:
|
||||
p = '/'
|
||||
return p
|
||||
p = '/'.join([d,path])
|
||||
if debug > 2:
|
||||
print("looking for:", p, end=' ', file=debug_out)
|
||||
if not os.path.exists(p):
|
||||
if debug > 2:
|
||||
print("nope", file=debug_out)
|
||||
p = None
|
||||
continue
|
||||
if debug > 2:
|
||||
print("found:", p, file=debug_out)
|
||||
return p
|
||||
return None
|
||||
|
||||
def cleanpath(path):
|
||||
"""cleanup path without using realpath(3)"""
|
||||
if path.startswith('/'):
|
||||
r = '/'
|
||||
else:
|
||||
r = ''
|
||||
p = []
|
||||
w = path.split('/')
|
||||
for d in w:
|
||||
if not d or d == '.':
|
||||
continue
|
||||
if d == '..':
|
||||
try:
|
||||
p.pop()
|
||||
continue
|
||||
except:
|
||||
break
|
||||
p.append(d)
|
||||
|
||||
return r + '/'.join(p)
|
||||
|
||||
def abspath(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr):
|
||||
"""
|
||||
Return an absolute path, resolving via cwd or last_dir if needed.
|
||||
this gets called a lot, so we try to avoid calling realpath.
|
||||
"""
|
||||
rpath = resolve(path, cwd, last_dir, debug, debug_out)
|
||||
if rpath:
|
||||
path = rpath
|
||||
elif len(path) > 0 and path[0] == '/':
|
||||
return None
|
||||
if (path.find('/') < 0 or
|
||||
path.find('./') > 0 or
|
||||
path.endswith('/..')):
|
||||
path = cleanpath(path)
|
||||
return path
|
||||
|
||||
def sort_unique(list, cmp=None, key=None, reverse=False):
|
||||
list.sort(cmp, key, reverse)
|
||||
nl = []
|
||||
le = None
|
||||
for e in list:
|
||||
if e == le:
|
||||
continue
|
||||
le = e
|
||||
nl.append(e)
|
||||
return nl
|
||||
|
||||
def add_trims(x):
|
||||
return ['/' + x + '/',
|
||||
'/' + x,
|
||||
x + '/',
|
||||
x]
|
||||
|
||||
class MetaFile:
|
||||
"""class to parse meta files generated by bmake."""
|
||||
|
||||
conf = None
|
||||
dirdep_re = None
|
||||
host_target = None
|
||||
srctops = []
|
||||
objroots = []
|
||||
excludes = []
|
||||
seen = {}
|
||||
obj_deps = []
|
||||
src_deps = []
|
||||
file_deps = []
|
||||
|
||||
def __init__(self, name, conf={}):
|
||||
"""if name is set we will parse it now.
|
||||
conf can have the follwing keys:
|
||||
|
||||
SRCTOPS list of tops of the src tree(s).
|
||||
|
||||
CURDIR the src directory 'bmake' was run from.
|
||||
|
||||
RELDIR the relative path from SRCTOP to CURDIR
|
||||
|
||||
MACHINE the machine we built for.
|
||||
set to 'none' if we are not cross-building.
|
||||
More specifically if machine cannot be deduced from objdirs.
|
||||
|
||||
TARGET_SPEC
|
||||
Sometimes MACHINE isn't enough.
|
||||
|
||||
HOST_TARGET
|
||||
when we build for the pseudo machine 'host'
|
||||
the object tree uses HOST_TARGET rather than MACHINE.
|
||||
|
||||
OBJROOTS a list of the common prefix for all obj dirs it might
|
||||
end in '/' or '-'.
|
||||
|
||||
DPDEPS names an optional file to which per file dependencies
|
||||
will be appended.
|
||||
For example if 'some/path/foo.h' is read from SRCTOP
|
||||
then 'DPDEPS_some/path/foo.h +=' "RELDIR" is output.
|
||||
This can allow 'bmake' to learn all the dirs within
|
||||
the tree that depend on 'foo.h'
|
||||
|
||||
EXCLUDES
|
||||
A list of paths to ignore.
|
||||
ccache(1) can otherwise be trouble.
|
||||
|
||||
debug desired debug level
|
||||
|
||||
debug_out open file to send debug output to (sys.stderr)
|
||||
|
||||
"""
|
||||
|
||||
self.name = name
|
||||
self.debug = getv(conf, 'debug', 0)
|
||||
self.debug_out = getv(conf, 'debug_out', sys.stderr)
|
||||
|
||||
self.machine = getv(conf, 'MACHINE', '')
|
||||
self.machine_arch = getv(conf, 'MACHINE_ARCH', '')
|
||||
self.target_spec = getv(conf, 'TARGET_SPEC', '')
|
||||
self.curdir = getv(conf, 'CURDIR')
|
||||
self.reldir = getv(conf, 'RELDIR')
|
||||
self.dpdeps = getv(conf, 'DPDEPS')
|
||||
self.line = 0
|
||||
|
||||
if not self.conf:
|
||||
# some of the steps below we want to do only once
|
||||
self.conf = conf
|
||||
self.host_target = getv(conf, 'HOST_TARGET')
|
||||
for srctop in getv(conf, 'SRCTOPS', []):
|
||||
if srctop[-1] != '/':
|
||||
srctop += '/'
|
||||
if not srctop in self.srctops:
|
||||
self.srctops.append(srctop)
|
||||
_srctop = os.path.realpath(srctop)
|
||||
if _srctop[-1] != '/':
|
||||
_srctop += '/'
|
||||
if not _srctop in self.srctops:
|
||||
self.srctops.append(_srctop)
|
||||
|
||||
trim_list = add_trims(self.machine)
|
||||
if self.machine == 'host':
|
||||
trim_list += add_trims(self.host_target)
|
||||
if self.target_spec:
|
||||
trim_list += add_trims(self.target_spec)
|
||||
|
||||
for objroot in getv(conf, 'OBJROOTS', []):
|
||||
for e in trim_list:
|
||||
if objroot.endswith(e):
|
||||
# this is not what we want - fix it
|
||||
objroot = objroot[0:-len(e)]
|
||||
|
||||
if objroot[-1] != '/':
|
||||
objroot += '/'
|
||||
if not objroot in self.objroots:
|
||||
self.objroots.append(objroot)
|
||||
_objroot = os.path.realpath(objroot)
|
||||
if objroot[-1] == '/':
|
||||
_objroot += '/'
|
||||
if not _objroot in self.objroots:
|
||||
self.objroots.append(_objroot)
|
||||
|
||||
# we want the longest match
|
||||
self.srctops.sort(reverse=True)
|
||||
self.objroots.sort(reverse=True)
|
||||
|
||||
self.excludes = getv(conf, 'EXCLUDES', [])
|
||||
|
||||
if self.debug:
|
||||
print("host_target=", self.host_target, file=self.debug_out)
|
||||
print("srctops=", self.srctops, file=self.debug_out)
|
||||
print("objroots=", self.objroots, file=self.debug_out)
|
||||
print("excludes=", self.excludes, file=self.debug_out)
|
||||
|
||||
self.dirdep_re = re.compile(r'([^/]+)/(.+)')
|
||||
|
||||
if self.dpdeps and not self.reldir:
|
||||
if self.debug:
|
||||
print("need reldir:", end=' ', file=self.debug_out)
|
||||
if self.curdir:
|
||||
srctop = self.find_top(self.curdir, self.srctops)
|
||||
if srctop:
|
||||
self.reldir = self.curdir.replace(srctop,'')
|
||||
if self.debug:
|
||||
print(self.reldir, file=self.debug_out)
|
||||
if not self.reldir:
|
||||
self.dpdeps = None # we cannot do it?
|
||||
|
||||
self.cwd = os.getcwd() # make sure this is initialized
|
||||
self.last_dir = self.cwd
|
||||
|
||||
if name:
|
||||
self.try_parse()
|
||||
|
||||
def reset(self):
|
||||
"""reset state if we are being passed meta files from multiple directories."""
|
||||
self.seen = {}
|
||||
self.obj_deps = []
|
||||
self.src_deps = []
|
||||
self.file_deps = []
|
||||
|
||||
def dirdeps(self, sep='\n'):
|
||||
"""return DIRDEPS"""
|
||||
return sep.strip() + sep.join(self.obj_deps)
|
||||
|
||||
def src_dirdeps(self, sep='\n'):
|
||||
"""return SRC_DIRDEPS"""
|
||||
return sep.strip() + sep.join(self.src_deps)
|
||||
|
||||
def file_depends(self, out=None):
|
||||
"""Append DPDEPS_${file} += ${RELDIR}
|
||||
for each file we saw, to the output file."""
|
||||
if not self.reldir:
|
||||
return None
|
||||
for f in sort_unique(self.file_deps):
|
||||
print('DPDEPS_%s += %s' % (f, self.reldir), file=out)
|
||||
# these entries provide for reverse DIRDEPS lookup
|
||||
for f in self.obj_deps:
|
||||
print('DEPDIRS_%s += %s' % (f, self.reldir), file=out)
|
||||
|
||||
def seenit(self, dir):
|
||||
"""rememer that we have seen dir."""
|
||||
self.seen[dir] = 1
|
||||
|
||||
def add(self, list, data, clue=''):
|
||||
"""add data to list if it isn't already there."""
|
||||
if data not in list:
|
||||
list.append(data)
|
||||
if self.debug:
|
||||
print("%s: %sAdd: %s" % (self.name, clue, data), file=self.debug_out)
|
||||
|
||||
def find_top(self, path, list):
|
||||
"""the logical tree may be split across multiple trees"""
|
||||
for top in list:
|
||||
if path.startswith(top):
|
||||
if self.debug > 2:
|
||||
print("found in", top, file=self.debug_out)
|
||||
return top
|
||||
return None
|
||||
|
||||
def find_obj(self, objroot, dir, path, input):
|
||||
"""return path within objroot, taking care of .dirdep files"""
|
||||
ddep = None
|
||||
for ddepf in [path + '.dirdep', dir + '/.dirdep']:
|
||||
if not ddep and os.path.exists(ddepf):
|
||||
ddep = open(ddepf, 'r').readline().strip('# \n')
|
||||
if self.debug > 1:
|
||||
print("found %s: %s\n" % (ddepf, ddep), file=self.debug_out)
|
||||
if ddep.endswith(self.machine):
|
||||
ddep = ddep[0:-(1+len(self.machine))]
|
||||
elif self.target_spec and ddep.endswith(self.target_spec):
|
||||
ddep = ddep[0:-(1+len(self.target_spec))]
|
||||
|
||||
if not ddep:
|
||||
# no .dirdeps, so remember that we've seen the raw input
|
||||
self.seenit(input)
|
||||
self.seenit(dir)
|
||||
if self.machine == 'none':
|
||||
if dir.startswith(objroot):
|
||||
return dir.replace(objroot,'')
|
||||
return None
|
||||
m = self.dirdep_re.match(dir.replace(objroot,''))
|
||||
if m:
|
||||
ddep = m.group(2)
|
||||
dmachine = m.group(1)
|
||||
if dmachine != self.machine:
|
||||
if not (self.machine == 'host' and
|
||||
dmachine == self.host_target):
|
||||
if self.debug > 2:
|
||||
print("adding .%s to %s" % (dmachine, ddep), file=self.debug_out)
|
||||
ddep += '.' + dmachine
|
||||
|
||||
return ddep
|
||||
|
||||
def try_parse(self, name=None, file=None):
|
||||
"""give file and line number causing exception"""
|
||||
try:
|
||||
self.parse(name, file)
|
||||
except:
|
||||
# give a useful clue
|
||||
print('{}:{}: '.format(self.name, self.line), end=' ', file=sys.stderr)
|
||||
raise
|
||||
|
||||
def parse(self, name=None, file=None):
|
||||
"""A meta file looks like:
|
||||
|
||||
# Meta data file "path"
|
||||
CMD "command-line"
|
||||
CWD "cwd"
|
||||
TARGET "target"
|
||||
-- command output --
|
||||
-- filemon acquired metadata --
|
||||
# buildmon version 3
|
||||
V 3
|
||||
C "pid" "cwd"
|
||||
E "pid" "path"
|
||||
F "pid" "child"
|
||||
R "pid" "path"
|
||||
W "pid" "path"
|
||||
X "pid" "status"
|
||||
D "pid" "path"
|
||||
L "pid" "src" "target"
|
||||
M "pid" "old" "new"
|
||||
S "pid" "path"
|
||||
# Bye bye
|
||||
|
||||
We go to some effort to avoid processing a dependency more than once.
|
||||
Of the above record types only C,E,F,L,R,V and W are of interest.
|
||||
"""
|
||||
|
||||
version = 0 # unknown
|
||||
if name:
|
||||
self.name = name;
|
||||
if file:
|
||||
f = file
|
||||
cwd = self.last_dir = self.cwd
|
||||
else:
|
||||
f = open(self.name, 'r')
|
||||
skip = True
|
||||
pid_cwd = {}
|
||||
pid_last_dir = {}
|
||||
last_pid = 0
|
||||
|
||||
self.line = 0
|
||||
if self.curdir:
|
||||
self.seenit(self.curdir) # we ignore this
|
||||
|
||||
interesting = 'CEFLRV'
|
||||
for line in f:
|
||||
self.line += 1
|
||||
# ignore anything we don't care about
|
||||
if not line[0] in interesting:
|
||||
continue
|
||||
if self.debug > 2:
|
||||
print("input:", line, end=' ', file=self.debug_out)
|
||||
w = line.split()
|
||||
|
||||
if skip:
|
||||
if w[0] == 'V':
|
||||
skip = False
|
||||
version = int(w[1])
|
||||
"""
|
||||
if version < 4:
|
||||
# we cannot ignore 'W' records
|
||||
# as they may be 'rw'
|
||||
interesting += 'W'
|
||||
"""
|
||||
elif w[0] == 'CWD':
|
||||
self.cwd = cwd = self.last_dir = w[1]
|
||||
self.seenit(cwd) # ignore this
|
||||
if self.debug:
|
||||
print("%s: CWD=%s" % (self.name, cwd), file=self.debug_out)
|
||||
continue
|
||||
|
||||
pid = int(w[1])
|
||||
if pid != last_pid:
|
||||
if last_pid:
|
||||
pid_last_dir[last_pid] = self.last_dir
|
||||
cwd = getv(pid_cwd, pid, self.cwd)
|
||||
self.last_dir = getv(pid_last_dir, pid, self.cwd)
|
||||
last_pid = pid
|
||||
|
||||
# process operations
|
||||
if w[0] == 'F':
|
||||
npid = int(w[2])
|
||||
pid_cwd[npid] = cwd
|
||||
pid_last_dir[npid] = cwd
|
||||
last_pid = npid
|
||||
continue
|
||||
elif w[0] == 'C':
|
||||
cwd = abspath(w[2], cwd, None, self.debug, self.debug_out)
|
||||
if not cwd:
|
||||
cwd = w[2]
|
||||
if self.debug > 1:
|
||||
print("missing cwd=", cwd, file=self.debug_out)
|
||||
if cwd.endswith('/.'):
|
||||
cwd = cwd[0:-2]
|
||||
self.last_dir = pid_last_dir[pid] = cwd
|
||||
pid_cwd[pid] = cwd
|
||||
if self.debug > 1:
|
||||
print("cwd=", cwd, file=self.debug_out)
|
||||
continue
|
||||
|
||||
if w[2] in self.seen:
|
||||
if self.debug > 2:
|
||||
print("seen:", w[2], file=self.debug_out)
|
||||
continue
|
||||
# file operations
|
||||
if w[0] in 'ML':
|
||||
# these are special, tread src as read and
|
||||
# target as write
|
||||
self.parse_path(w[2].strip("'"), cwd, 'R', w)
|
||||
self.parse_path(w[3].strip("'"), cwd, 'W', w)
|
||||
continue
|
||||
elif w[0] in 'ERWS':
|
||||
path = w[2]
|
||||
if path == '.':
|
||||
continue
|
||||
self.parse_path(path, cwd, w[0], w)
|
||||
|
||||
if not file:
|
||||
f.close()
|
||||
|
||||
def is_src(self, base, dir, rdir):
|
||||
"""is base in srctop"""
|
||||
for dir in [dir,rdir]:
|
||||
if not dir:
|
||||
continue
|
||||
path = '/'.join([dir,base])
|
||||
srctop = self.find_top(path, self.srctops)
|
||||
if srctop:
|
||||
if self.dpdeps:
|
||||
self.add(self.file_deps, path.replace(srctop,''), 'file')
|
||||
self.add(self.src_deps, dir.replace(srctop,''), 'src')
|
||||
self.seenit(dir)
|
||||
return True
|
||||
return False
|
||||
|
||||
def parse_path(self, path, cwd, op=None, w=[]):
|
||||
"""look at a path for the op specified"""
|
||||
|
||||
if not op:
|
||||
op = w[0]
|
||||
|
||||
# we are never interested in .dirdep files as dependencies
|
||||
if path.endswith('.dirdep'):
|
||||
return
|
||||
for p in self.excludes:
|
||||
if p and path.startswith(p):
|
||||
if self.debug > 2:
|
||||
print("exclude:", p, path, file=self.debug_out)
|
||||
return
|
||||
# we don't want to resolve the last component if it is
|
||||
# a symlink
|
||||
path = resolve(path, cwd, self.last_dir, self.debug, self.debug_out)
|
||||
if not path:
|
||||
return
|
||||
dir,base = os.path.split(path)
|
||||
if dir in self.seen:
|
||||
if self.debug > 2:
|
||||
print("seen:", dir, file=self.debug_out)
|
||||
return
|
||||
# we can have a path in an objdir which is a link
|
||||
# to the src dir, we may need to add dependencies for each
|
||||
rdir = dir
|
||||
dir = abspath(dir, cwd, self.last_dir, self.debug, self.debug_out)
|
||||
rdir = os.path.realpath(dir)
|
||||
if rdir == dir:
|
||||
rdir = None
|
||||
# now put path back together
|
||||
path = '/'.join([dir,base])
|
||||
if self.debug > 1:
|
||||
print("raw=%s rdir=%s dir=%s path=%s" % (w[2], rdir, dir, path), file=self.debug_out)
|
||||
if op in 'RWS':
|
||||
if path in [self.last_dir, cwd, self.cwd, self.curdir]:
|
||||
if self.debug > 1:
|
||||
print("skipping:", path, file=self.debug_out)
|
||||
return
|
||||
if os.path.isdir(path):
|
||||
if op in 'RW':
|
||||
self.last_dir = path;
|
||||
if self.debug > 1:
|
||||
print("ldir=", self.last_dir, file=self.debug_out)
|
||||
return
|
||||
|
||||
if op in 'ER':
|
||||
# finally, we get down to it
|
||||
if dir == self.cwd or dir == self.curdir:
|
||||
return
|
||||
if self.is_src(base, dir, rdir):
|
||||
self.seenit(w[2])
|
||||
if not rdir:
|
||||
return
|
||||
|
||||
objroot = None
|
||||
for dir in [dir,rdir]:
|
||||
if not dir:
|
||||
continue
|
||||
objroot = self.find_top(dir, self.objroots)
|
||||
if objroot:
|
||||
break
|
||||
if objroot:
|
||||
ddep = self.find_obj(objroot, dir, path, w[2])
|
||||
if ddep:
|
||||
self.add(self.obj_deps, ddep, 'obj')
|
||||
if self.dpdeps and objroot.endswith('/stage/'):
|
||||
sp = '/'.join(path.replace(objroot,'').split('/')[1:])
|
||||
self.add(self.file_deps, sp, 'file')
|
||||
else:
|
||||
# don't waste time looking again
|
||||
self.seenit(w[2])
|
||||
self.seenit(dir)
|
||||
|
||||
|
||||
def main(argv, klass=MetaFile, xopts='', xoptf=None):
|
||||
"""Simple driver for class MetaFile.
|
||||
|
||||
Usage:
|
||||
script [options] [key=value ...] "meta" ...
|
||||
|
||||
Options and key=value pairs contribute to the
|
||||
dictionary passed to MetaFile.
|
||||
|
||||
-S "SRCTOP"
|
||||
add "SRCTOP" to the "SRCTOPS" list.
|
||||
|
||||
-C "CURDIR"
|
||||
|
||||
-O "OBJROOT"
|
||||
add "OBJROOT" to the "OBJROOTS" list.
|
||||
|
||||
-m "MACHINE"
|
||||
|
||||
-a "MACHINE_ARCH"
|
||||
|
||||
-H "HOST_TARGET"
|
||||
|
||||
-D "DPDEPS"
|
||||
|
||||
-d bumps debug level
|
||||
|
||||
"""
|
||||
import getopt
|
||||
|
||||
# import Psyco if we can
|
||||
# it can speed things up quite a bit
|
||||
have_psyco = 0
|
||||
try:
|
||||
import psyco
|
||||
psyco.full()
|
||||
have_psyco = 1
|
||||
except:
|
||||
pass
|
||||
|
||||
conf = {
|
||||
'SRCTOPS': [],
|
||||
'OBJROOTS': [],
|
||||
'EXCLUDES': [],
|
||||
}
|
||||
|
||||
try:
|
||||
machine = os.environ['MACHINE']
|
||||
if machine:
|
||||
conf['MACHINE'] = machine
|
||||
machine_arch = os.environ['MACHINE_ARCH']
|
||||
if machine_arch:
|
||||
conf['MACHINE_ARCH'] = machine_arch
|
||||
srctop = os.environ['SB_SRC']
|
||||
if srctop:
|
||||
conf['SRCTOPS'].append(srctop)
|
||||
objroot = os.environ['SB_OBJROOT']
|
||||
if objroot:
|
||||
conf['OBJROOTS'].append(objroot)
|
||||
except:
|
||||
pass
|
||||
|
||||
debug = 0
|
||||
output = True
|
||||
|
||||
opts, args = getopt.getopt(argv[1:], 'a:dS:C:O:R:m:D:H:qT:X:' + xopts)
|
||||
for o, a in opts:
|
||||
if o == '-a':
|
||||
conf['MACHINE_ARCH'] = a
|
||||
elif o == '-d':
|
||||
debug += 1
|
||||
elif o == '-q':
|
||||
output = False
|
||||
elif o == '-H':
|
||||
conf['HOST_TARGET'] = a
|
||||
elif o == '-S':
|
||||
if a not in conf['SRCTOPS']:
|
||||
conf['SRCTOPS'].append(a)
|
||||
elif o == '-C':
|
||||
conf['CURDIR'] = a
|
||||
elif o == '-O':
|
||||
if a not in conf['OBJROOTS']:
|
||||
conf['OBJROOTS'].append(a)
|
||||
elif o == '-R':
|
||||
conf['RELDIR'] = a
|
||||
elif o == '-D':
|
||||
conf['DPDEPS'] = a
|
||||
elif o == '-m':
|
||||
conf['MACHINE'] = a
|
||||
elif o == '-T':
|
||||
conf['TARGET_SPEC'] = a
|
||||
elif o == '-X':
|
||||
if a not in conf['EXCLUDES']:
|
||||
conf['EXCLUDES'].append(a)
|
||||
elif xoptf:
|
||||
xoptf(o, a, conf)
|
||||
|
||||
conf['debug'] = debug
|
||||
|
||||
# get any var=val assignments
|
||||
eaten = []
|
||||
for a in args:
|
||||
if a.find('=') > 0:
|
||||
k,v = a.split('=')
|
||||
if k in ['SRCTOP','OBJROOT','SRCTOPS','OBJROOTS']:
|
||||
if k == 'SRCTOP':
|
||||
k = 'SRCTOPS'
|
||||
elif k == 'OBJROOT':
|
||||
k = 'OBJROOTS'
|
||||
if v not in conf[k]:
|
||||
conf[k].append(v)
|
||||
else:
|
||||
conf[k] = v
|
||||
eaten.append(a)
|
||||
continue
|
||||
break
|
||||
|
||||
for a in eaten:
|
||||
args.remove(a)
|
||||
|
||||
debug_out = getv(conf, 'debug_out', sys.stderr)
|
||||
|
||||
if debug:
|
||||
print("config:", file=debug_out)
|
||||
print("psyco=", have_psyco, file=debug_out)
|
||||
for k,v in list(conf.items()):
|
||||
print("%s=%s" % (k,v), file=debug_out)
|
||||
|
||||
m = None
|
||||
for a in args:
|
||||
if a.endswith('.meta'):
|
||||
if not os.path.exists(a):
|
||||
continue
|
||||
m = klass(a, conf)
|
||||
elif a.startswith('@'):
|
||||
# there can actually multiple files per line
|
||||
for line in open(a[1:]):
|
||||
for f in line.strip().split():
|
||||
if not os.path.exists(f):
|
||||
continue
|
||||
m = klass(f, conf)
|
||||
|
||||
if output and m:
|
||||
print(m.dirdeps())
|
||||
|
||||
print(m.src_dirdeps('\nsrc:'))
|
||||
|
||||
dpdeps = getv(conf, 'DPDEPS')
|
||||
if dpdeps:
|
||||
m.file_depends(open(dpdeps, 'wb'))
|
||||
|
||||
return m
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main(sys.argv)
|
||||
except:
|
||||
# yes, this goes to stdout
|
||||
print("ERROR: ", sys.exc_info()[1])
|
||||
raise
|
||||
|
405
20200902/mk/meta2deps.sh
Executable file
405
20200902/mk/meta2deps.sh
Executable file
@ -0,0 +1,405 @@
|
||||
#!/bin/sh
|
||||
|
||||
# NAME:
|
||||
# meta2deps.sh - extract useful info from .meta files
|
||||
#
|
||||
# SYNOPSIS:
|
||||
# meta2deps.sh SB="SB" "meta" ...
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# This script looks each "meta" file and extracts the
|
||||
# information needed to deduce build and src dependencies.
|
||||
#
|
||||
# To do this, we extract the 'CWD' record as well as all the
|
||||
# syscall traces which describe 'R'ead, 'C'hdir and 'E'xec
|
||||
# syscalls.
|
||||
#
|
||||
# The typical meta file looks like::
|
||||
#.nf
|
||||
#
|
||||
# # Meta data file "path"
|
||||
# CMD "command-line"
|
||||
# CWD "cwd"
|
||||
# TARGET "target"
|
||||
# -- command output --
|
||||
# -- filemon acquired metadata --
|
||||
# # buildmon version 2
|
||||
# V 2
|
||||
# E "pid" "path"
|
||||
# R "pid" "path"
|
||||
# C "pid" "cwd"
|
||||
# R "pid" "path"
|
||||
# X "pid" "status"
|
||||
#.fi
|
||||
#
|
||||
# The fact that all the syscall entry lines start with a single
|
||||
# character make these files quite easy to process using sed(1).
|
||||
#
|
||||
# To simplify the logic the 'CWD' line is made to look like a
|
||||
# normal 'C'hdir entry, and "cwd" is remembered so that it can
|
||||
# be prefixed to any "path" which is not absolute.
|
||||
#
|
||||
# If the "path" being read ends in '.srcrel' it is the content
|
||||
# of (actually the first line of) that file that we are
|
||||
# interested in.
|
||||
#
|
||||
# Any "path" which lies outside of the sandbox "SB" is generally
|
||||
# not of interest and is ignored.
|
||||
#
|
||||
# The output, is a set of absolute paths with "SB" like:
|
||||
#.nf
|
||||
#
|
||||
# $SB/obj-i386/bsd/gnu/lib/csu
|
||||
# $SB/obj-i386/bsd/gnu/lib/libgcc
|
||||
# $SB/obj-i386/bsd/include
|
||||
# $SB/obj-i386/bsd/lib/csu/i386-elf
|
||||
# $SB/obj-i386/bsd/lib/libc
|
||||
# $SB/src/bsd/include
|
||||
# $SB/src/bsd/sys/i386/include
|
||||
# $SB/src/bsd/sys/sys
|
||||
# $SB/src/pan-release/rtsock
|
||||
# $SB/src/pfe-shared/include/jnx
|
||||
#.fi
|
||||
#
|
||||
# Which can then be further processed by 'gendirdeps.mk'
|
||||
#
|
||||
# If we are passed 'DPDEPS='"dpdeps", then for each src file
|
||||
# outside of "CURDIR" we read, we output a line like:
|
||||
#.nf
|
||||
#
|
||||
# DPDEPS_$path += $RELDIR
|
||||
#.fi
|
||||
#
|
||||
# with "$path" geting turned into reldir's, so that we can end
|
||||
# up with a list of all the directories which depend on each src
|
||||
# file in another directory. This can allow for efficient yet
|
||||
# complete testing of changes.
|
||||
|
||||
|
||||
# RCSid:
|
||||
# $Id: meta2deps.sh,v 1.13 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
# Copyright (c) 2010-2013, Juniper Networks, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
meta2src() {
|
||||
cat /dev/null "$@" |
|
||||
sed -n '/^R .*\.[chyl]$/s,^..[0-9]* ,,p' |
|
||||
sort -u
|
||||
}
|
||||
|
||||
meta2dirs() {
|
||||
cat /dev/null "$@" |
|
||||
sed -n '/^R .*\/.*\.[a-z0-9][^\/]*$/s,^..[0-9]* \(.*\)/[^/]*$,\1,p' |
|
||||
sort -u
|
||||
}
|
||||
|
||||
add_list() {
|
||||
sep=' '
|
||||
suffix=
|
||||
while :
|
||||
do
|
||||
case "$1" in
|
||||
"|") sep="$1"; shift;;
|
||||
-s) suffix="$2"; shift 2;;
|
||||
*) break;;
|
||||
esac
|
||||
done
|
||||
name=$1
|
||||
shift
|
||||
eval list="\$$name"
|
||||
for top in "$@"
|
||||
do
|
||||
case "$sep$list$sep" in
|
||||
*"$sep$top$suffix$sep"*) continue;;
|
||||
esac
|
||||
list="${list:+$list$sep}$top$suffix"
|
||||
done
|
||||
eval "$name=\"$list\""
|
||||
}
|
||||
|
||||
_excludes_f() {
|
||||
egrep -v "$EXCLUDES"
|
||||
}
|
||||
|
||||
meta2deps() {
|
||||
DPDEPS=
|
||||
SRCTOPS=$SRCTOP
|
||||
OBJROOTS=
|
||||
EXCLUDES=
|
||||
while :
|
||||
do
|
||||
case "$1" in
|
||||
*=*) eval export "$1"; shift;;
|
||||
-a) MACHINE_ARCH=$2; shift 2;;
|
||||
-m) MACHINE=$2; shift 2;;
|
||||
-C) CURDIR=$2; shift 2;;
|
||||
-H) HOST_TARGET=$2; shift 2;;
|
||||
-S) add_list SRCTOPS $2; shift 2;;
|
||||
-O) add_list OBJROOTS $2; shift 2;;
|
||||
-X) add_list EXCLUDES '|' $2; shift 2;;
|
||||
-R) RELDIR=$2; shift 2;;
|
||||
-T) TARGET_SPEC=$2; shift 2;;
|
||||
*) break;;
|
||||
esac
|
||||
done
|
||||
|
||||
_th= _o=
|
||||
case "$MACHINE" in
|
||||
host) _ht=$HOST_TARGET;;
|
||||
esac
|
||||
|
||||
for o in $OBJROOTS
|
||||
do
|
||||
case "$MACHINE,/$o/" in
|
||||
host,*$HOST_TARGET*) ;;
|
||||
*$MACHINE*|*${TARGET_SPEC:-$MACHINE}*) ;;
|
||||
*) add_list _o $o; continue;;
|
||||
esac
|
||||
for x in $_ht $TARGET_SPEC $MACHINE
|
||||
do
|
||||
case "$o" in
|
||||
"") continue;;
|
||||
*/$x/) add_list _o ${o%$x/}; o=;;
|
||||
*/$x) add_list _o ${o%$x}; o=;;
|
||||
*$x/) add_list _o ${o%$x/}; o=;;
|
||||
*$x) add_list _o ${o%$x}; o=;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
OBJROOTS="$_o"
|
||||
|
||||
case "$OBJTOP" in
|
||||
"")
|
||||
for o in $OBJROOTS
|
||||
do
|
||||
OBJTOP=$o${TARGET_SPEC:-$MACHINE}
|
||||
break
|
||||
done
|
||||
;;
|
||||
esac
|
||||
src_re=
|
||||
obj_re=
|
||||
add_list '|' -s '/*' src_re $SRCTOPS
|
||||
add_list '|' -s '*' obj_re $OBJROOTS
|
||||
|
||||
[ -z "$RELDIR" ] && unset DPDEPS
|
||||
tf=/tmp/m2d$$-$USER
|
||||
rm -f $tf.*
|
||||
trap 'rm -f $tf.*; trap 0' 0
|
||||
|
||||
> $tf.dirdep
|
||||
> $tf.qual
|
||||
> $tf.srcdep
|
||||
> $tf.srcrel
|
||||
> $tf.dpdeps
|
||||
|
||||
seenit=
|
||||
seensrc=
|
||||
lpid=
|
||||
case "$EXCLUDES" in
|
||||
"") _excludes=cat;;
|
||||
*) _excludes=_excludes_f;;
|
||||
esac
|
||||
# handle @list files
|
||||
case "$@" in
|
||||
*@[!.]*)
|
||||
for f in "$@"
|
||||
do
|
||||
case "$f" in
|
||||
*.meta) cat $f;;
|
||||
@*) xargs cat < ${f#@};;
|
||||
*) cat $f;;
|
||||
esac
|
||||
done
|
||||
;;
|
||||
*) cat /dev/null "$@";;
|
||||
esac 2> /dev/null |
|
||||
sed -e 's,^CWD,C C,;/^[CREFLM] /!d' -e "s,',,g" |
|
||||
$_excludes |
|
||||
while read op pid path junk
|
||||
do
|
||||
: op=$op pid=$pid path=$path
|
||||
# we track cwd and ldir (of interest) per pid
|
||||
# CWD is bmake's cwd
|
||||
case "$lpid,$pid" in
|
||||
,C) CWD=$path cwd=$path ldir=$path
|
||||
if [ -z "$SB" ]; then
|
||||
SB=`echo $CWD | sed 's,/obj.*,,'`
|
||||
fi
|
||||
SRCTOP=${SRCTOP:-$SB/src}
|
||||
continue
|
||||
;;
|
||||
$pid,$pid) ;;
|
||||
*)
|
||||
case "$lpid" in
|
||||
"") ;;
|
||||
*) eval ldir_$lpid=$ldir;;
|
||||
esac
|
||||
eval ldir=\${ldir_$pid:-$CWD} cwd=\${cwd_$pid:-$CWD}
|
||||
lpid=$pid
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$op,$path" in
|
||||
W,*srcrel|*.dirdep) continue;;
|
||||
C,*)
|
||||
case "$path" in
|
||||
/*) cwd=$path;;
|
||||
*) cwd=`cd $cwd/$path 2> /dev/null && /bin/pwd`;;
|
||||
esac
|
||||
# watch out for temp dirs that no longer exist
|
||||
test -d ${cwd:-/dev/null/no/such} || cwd=$CWD
|
||||
eval cwd_$pid=$cwd
|
||||
continue
|
||||
;;
|
||||
F,*) # $path is new pid
|
||||
eval cwd_$path=$cwd ldir_$path=$ldir
|
||||
continue
|
||||
;;
|
||||
*) dir=${path%/*}
|
||||
case "$path" in
|
||||
$src_re|$obj_re) ;;
|
||||
/*/stage/*) ;;
|
||||
/*) continue;;
|
||||
*) for path in $ldir/$path $cwd/$path
|
||||
do
|
||||
test -e $path && break
|
||||
done
|
||||
dir=${path%/*}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
# avoid repeating ourselves...
|
||||
case "$DPDEPS,$seensrc," in
|
||||
,*)
|
||||
case ",$seenit," in
|
||||
*,$dir,*) continue;;
|
||||
esac
|
||||
;;
|
||||
*,$path,*) continue;;
|
||||
esac
|
||||
# canonicalize if needed
|
||||
case "/$dir/" in
|
||||
*/../*|*/./*)
|
||||
rdir=$dir
|
||||
dir=`cd $dir 2> /dev/null && /bin/pwd`
|
||||
seen="$rdir,$dir"
|
||||
;;
|
||||
*) seen=$dir;;
|
||||
esac
|
||||
case "$dir" in
|
||||
${CURDIR:-.}|"") continue;;
|
||||
$src_re)
|
||||
# avoid repeating ourselves...
|
||||
case "$DPDEPS,$seensrc," in
|
||||
,*)
|
||||
case ",$seenit," in
|
||||
*,$dir,*) continue;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
case ",$seenit," in
|
||||
*,$dir,*) continue;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
if [ -d $path ]; then
|
||||
case "$path" in
|
||||
*/..) ldir=${dir%/*};;
|
||||
*) ldir=$path;;
|
||||
esac
|
||||
continue
|
||||
fi
|
||||
[ -f $path ] || continue
|
||||
case "$dir" in
|
||||
$CWD) continue;; # ignore
|
||||
$src_re)
|
||||
seenit="$seenit,$seen"
|
||||
echo $dir >> $tf.srcdep
|
||||
case "$DPDEPS,$reldir,$seensrc," in
|
||||
,*) ;;
|
||||
*) seensrc="$seensrc,$path"
|
||||
echo "DPDEPS_$dir/${path##*/} += $RELDIR" >> $tf.dpdeps
|
||||
;;
|
||||
esac
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
# if there is a .dirdep we cannot skip
|
||||
# just because we've seen the dir before.
|
||||
if [ -s $path.dirdep ]; then
|
||||
# this file contains:
|
||||
# '# ${RELDIR}.<machine>'
|
||||
echo $path.dirdep >> $tf.qual
|
||||
continue
|
||||
elif [ -s $dir.dirdep ]; then
|
||||
echo $dir.dirdep >> $tf.qual
|
||||
seenit="$seenit,$seen"
|
||||
continue
|
||||
fi
|
||||
seenit="$seenit,$seen"
|
||||
case "$dir" in
|
||||
$obj_re)
|
||||
echo $dir;;
|
||||
esac
|
||||
done > $tf.dirdep
|
||||
_nl=echo
|
||||
for f in $tf.dirdep $tf.qual $tf.srcdep
|
||||
do
|
||||
[ -s $f ] || continue
|
||||
case $f in
|
||||
*qual) # a list of .dirdep files
|
||||
# we can prefix everything with $OBJTOP to
|
||||
# tell gendirdeps.mk that these are
|
||||
# DIRDEP entries, since they are already
|
||||
# qualified with .<machine> as needed.
|
||||
# We strip .$MACHINE though
|
||||
xargs cat < $f | sort -u |
|
||||
sed "s,^# ,,;s,^,$OBJTOP/,;s,\.${TARGET_SPEC:-$MACHINE}\$,,;s,\.$MACHINE\$,,"
|
||||
;;
|
||||
*) sort -u $f;;
|
||||
esac
|
||||
_nl=:
|
||||
done
|
||||
if [ -s $tf.dpdeps ]; then
|
||||
case "$DPDEPS" in
|
||||
*/*) ;;
|
||||
*) echo > $DPDEPS;; # the echo is needed!
|
||||
esac
|
||||
sort -u $tf.dpdeps |
|
||||
sed "s,${SRCTOP}/,,;s,${SB_BACKING_SB:-$SB}/src/,," >> $DPDEPS
|
||||
fi
|
||||
# ensure we produce _something_ else egrep -v gets upset
|
||||
$_nl
|
||||
}
|
||||
|
||||
case /$0 in
|
||||
*/meta2dep*) meta2deps "$@";;
|
||||
*/meta2dirs*) meta2dirs "$@";;
|
||||
*/meta2src*) meta2src "$@";;
|
||||
esac
|
500
20200902/mk/mk-files.txt
Normal file
500
20200902/mk/mk-files.txt
Normal file
@ -0,0 +1,500 @@
|
||||
mk-files
|
||||
********
|
||||
|
||||
The term ``mk-files`` refers to a collection of ``*.mk`` files.
|
||||
|
||||
You need bmake_ or a *recent* NetBSD_ make.
|
||||
If in doubt use bmake_.
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Many years ago, when building large software projects, I used GNU make
|
||||
(or my own patched version of it), and had developed a set of macros
|
||||
to simplify developing complex build trees.
|
||||
|
||||
Since the early 90's my main development machines, run BSD
|
||||
(NetBSD_ to be precise, and more recently FreeBSD), and the BSD source
|
||||
tree is good example of a large software project.
|
||||
It quickly became clear that ``/usr/share/mk/*.mk`` were a great
|
||||
model, but at the time were quite tightly linked to building the BSD tree.
|
||||
|
||||
Much as I liked using NetBSD, my customers were more likely to be
|
||||
using SunOS, HP-UX etc, so I started on bmake_ and a portable collection
|
||||
of mk-files (mk.tar.gz_). NetBSD provided much of the original structure.
|
||||
|
||||
Since then I've added a lot of features to NetBSD's make and hence to
|
||||
bmake which is kept closely in sync. The mk-files however have
|
||||
diverged quite a bit, though ideas are still picked up from NetBSD
|
||||
and FreeBSD.
|
||||
|
||||
Basics
|
||||
------
|
||||
|
||||
The BSD build model is very simple. A directory produces one
|
||||
component, which is generally either a library or a program.
|
||||
Library makefiles include ``lib.mk`` and programs include ``prog.mk``
|
||||
and they *do the right thing*.
|
||||
|
||||
A simple library makefile might look like::
|
||||
|
||||
LIB = sig
|
||||
|
||||
SRCS = \
|
||||
sigaction.c \
|
||||
sigcompat.c \
|
||||
sighdl.c
|
||||
|
||||
.include <lib.mk>
|
||||
|
||||
a simple program makefile::
|
||||
|
||||
PROG = cat
|
||||
|
||||
SRCS = cat.c
|
||||
|
||||
.include <prog.mk>
|
||||
|
||||
in such cases even the ``SRCS`` line is unnecessary as ``prog.mk``
|
||||
will default it to ``${PROG}.c``.
|
||||
|
||||
It is the sensible use of defaults and the plethora of macro modifiers
|
||||
provided by bmake_ that allow simple makefiles such as the above to
|
||||
*just work* on many different systems.
|
||||
|
||||
|
||||
mk-files
|
||||
========
|
||||
|
||||
This section provides a brief description of some of the ``*.mk``
|
||||
files.
|
||||
|
||||
sys.mk
|
||||
------
|
||||
|
||||
When bmake starts, it looks for ``sys.mk`` and reads it before doing
|
||||
anything else. Thus, this is the place to setup the environment for
|
||||
everyone else.
|
||||
|
||||
In this distribution, ``sys.mk`` avoids doing anything platform dependent.
|
||||
It is quite short, and includes a number of other files (which may or
|
||||
may not exists)
|
||||
|
||||
sys.env.mk
|
||||
If it exists, is expected to do things like conditioning the
|
||||
environment. Since it will only be included by the initial
|
||||
instance of bmake, it should ``.export`` anything that
|
||||
sub-makes might need.
|
||||
|
||||
examples/sys.clean-env.mk
|
||||
An example of how to clean the environment.
|
||||
See the file for all the details::
|
||||
|
||||
.if ${MAKE_VERSION} >= 20100606 && ${.MAKE.LEVEL} == 0
|
||||
# we save any env var that starts with these
|
||||
MAKE_SAVE_ENV_PREFIX += SB MK MAKE MACHINE NEED_ CCACHE DISTCC USE_ SSH
|
||||
MAKE_SAVE_ENV_VARS += \
|
||||
PATH HOME USER LOGNAME \
|
||||
SRCTOP OBJTOP OBJROOT \
|
||||
${_env_vars}
|
||||
|
||||
_env_vars != env | egrep '^(${MAKE_SAVE_ENV_PREFIX:ts|})' | sed 's,=.*,,'; echo
|
||||
_export_list =
|
||||
.for v in ${MAKE_SAVE_ENV_VARS:O:u}
|
||||
.if !empty($v)
|
||||
_export_list += $v
|
||||
$v := ${$v}
|
||||
.endif
|
||||
.endfor
|
||||
# now clobber the environment
|
||||
.unexport-env
|
||||
|
||||
# list of vars that we handle specially below
|
||||
_tricky_env_vars = MAKEOBJDIR
|
||||
# export our selection - sans tricky ones
|
||||
.export ${_export_list:${_tricky_env_vars:${M_ListToSkip}}}
|
||||
|
||||
# this next bit may need tweaking
|
||||
.if defined(MAKEOBJDIR)
|
||||
srctop := ${SRCTOP:U${SB_SRC:U${SB}/src}}
|
||||
objroot := ${OBJROOT:U${SB_OBJROOT:U${SB}/${SB_OBJPREFIX}}}
|
||||
# we'll take care of MACHINE below
|
||||
objtop := ${OBJTOP:U${objroot}${MACHINE}}
|
||||
.if !empty(objtop)
|
||||
# we would normally want something like (/bin/sh):
|
||||
# MAKEOBJDIR="\${.CURDIR:S,${SRCTOP},${OBJROOT}\${MACHINE},}"
|
||||
# the $$ below is how we achieve the same result here.
|
||||
# since everything saved from the environment above
|
||||
# has run through := we need to compensate for ${MACHINE}
|
||||
MAKEOBJDIR = $${.CURDIR:S,${srctop},${objtop:S,${MACHINE},\${MACHINE},},}
|
||||
|
||||
# export these as-is, and do not track...
|
||||
.export-env ${_tricky_env_vars}
|
||||
# now evaluate for ourselves
|
||||
.for v in ${_tricky_env_vars}
|
||||
$v := ${$v}
|
||||
.endfor
|
||||
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
||||
|
||||
host-target.mk
|
||||
Is used to set macros like ``HOST_TARGET``, ``HOST_OS`` and
|
||||
``host_os`` which are used to find the next step.
|
||||
|
||||
sys/\*.mk
|
||||
Platform specific additions, such as ``Darwin.mk`` or ``SunOS.mk``
|
||||
set things like ``HOST_LIBEXT = .dylib`` for Darwin or
|
||||
``SHLIB_FULLVERSION = ${SHLIB_MAJOR}`` for SunOS 5.
|
||||
If there is no OS specific file, ``sys/Generic.mk`` is used.
|
||||
|
||||
local.sys.mk
|
||||
Any ``local.*.mk`` file is not part of the distribution.
|
||||
This provides a hook for sites to do extra setup without
|
||||
having to edit the distributed files.
|
||||
|
||||
|
||||
The above arrangement makes it easy for the mk files to be part of a
|
||||
src tree on an NFS volume and to allow building on multiple platforms.
|
||||
|
||||
lib.mk
|
||||
------
|
||||
|
||||
This file is used to build a number of different libraries from the
|
||||
same SRCS.
|
||||
|
||||
lib${LIB}.a
|
||||
An archive lib of ``.o`` files, this is the default
|
||||
|
||||
lib${LIB}_p.a
|
||||
A profiled lib of ``.po`` files.
|
||||
Still an archive lib, but all the objects are built with
|
||||
profiling in mind - hence the different extension.
|
||||
It is skipped if ``MKPROFILE`` is "no".
|
||||
|
||||
lib${LIB}_pic.a
|
||||
An archive of ``.so`` objects compiled for relocation.
|
||||
On NetBSD this is the input to ``lib${LIB}.${LD_so}``, it is
|
||||
skipped if ``MKPICLIB`` is "no".
|
||||
|
||||
lib${LIB}.${LD_so}
|
||||
A shared library. The value of ``LD_so`` is very platform
|
||||
specific. For example::
|
||||
|
||||
# SunOS 5 and most other ELF systems
|
||||
libsslfd.so.1
|
||||
|
||||
# Darwin
|
||||
libsslfd.1.dylib
|
||||
|
||||
This library will only be built if ``SHLIB_MAJOR`` has
|
||||
a value, and ``MKPIC`` is not set to "no".
|
||||
|
||||
There is a lot of platform specific tweaking in ``lib.mk``, largely the
|
||||
result of the original distributions trying to avoid interfering with
|
||||
the system's ``sys.mk``.
|
||||
|
||||
libnames.mk
|
||||
-----------
|
||||
|
||||
This is included by both ``prog.mk`` and ``lib.mk`` and tries to
|
||||
include ``*.libnames.mk`` of which:
|
||||
|
||||
local.libnames.mk
|
||||
does not exist unless you create it. It is a handy way for you
|
||||
to customize without touching the distributed files.
|
||||
For example, on a test machine I needed to build openssl but
|
||||
not install it, so put the following in ``local.libnames.mk``::
|
||||
|
||||
.if ${host_os} == "sunos"
|
||||
LIBCRYPTO = ${OBJTOP}/openssl/lib/crypto/libcrypto${DLIBEXT}
|
||||
LIBSSL = ${OBJTOP}/openssl/lib/ssl/libssl${DLIBEXT}
|
||||
INCLUDES_libcrypto = -I${OBJ_libcrypto}
|
||||
.endif
|
||||
|
||||
The makefile created an openssl dir in ``${OBJ_libcrypto}`` to
|
||||
gather all the headers. dpadd.mk_ did the rest.
|
||||
|
||||
host.libnames.mk
|
||||
contains logic to find any libs named in ``HOST_LIBS`` in
|
||||
``HOST_LIBDIRS``.
|
||||
|
||||
Each file above gets an opportunity to define things like::
|
||||
|
||||
LIBSSLFD ?= ${OBJTOP}/ssl/lib/sslfd/libsslfd${DLIBEXT}
|
||||
INCLUDES_libsslfd = -I${SRC_libsslfd}/h -I${OBJ_libslfd}
|
||||
|
||||
these are used by dpadd.mk_ and will be explained below.
|
||||
|
||||
dpadd.mk
|
||||
--------
|
||||
|
||||
This file looks like line noise, and is best considered read-only.
|
||||
However it provides some very useful functionality, which simplifies the build.
|
||||
|
||||
Makefiles can use the LIB* macros defined via libnames.mk_ or anywhere
|
||||
else in various ways::
|
||||
|
||||
# indicate that we need to include headers from LIBCRYPTO
|
||||
# this would result in ${INCLUDES_libcrypto} being added to CFLAGS.
|
||||
SRC_LIBS += ${LIBCRYPTO}
|
||||
|
||||
# indicate that libsslfd must be built already.
|
||||
# it also has the same effect as SRC_LIBS
|
||||
DPADD += ${LIBSSLFD}
|
||||
|
||||
# indicate that not only must libsslfd be built,
|
||||
# but that we need to link with it.
|
||||
# this is almost exactly equivalent to
|
||||
# DPADD += ${LIBSSLFD}
|
||||
# LDADD += -L${LIBSSLFD:H} -lsslfd
|
||||
# and mostly serves to ensure that DPADD and LDADD are in sync.
|
||||
DPLIBS += ${LIBSSLFD}
|
||||
|
||||
Any library (referenced by its full path) in any of the above, is
|
||||
added to ``DPMAGIC_LIBS`` with the following results, for each lib *foo*.
|
||||
|
||||
SRC_libfoo
|
||||
Is set to indicate where the src for libfoo is.
|
||||
By default it is derived from ``LIBFOO`` by replacing
|
||||
``${OBJTOP}`` with ``${SRCTOP}``.
|
||||
|
||||
OBJ_libfoo
|
||||
Not very exciting, is just the dir where libfoo lives.
|
||||
|
||||
INCLUDES_libfoo
|
||||
What to add to ``CFLAGS`` to find the public headers.
|
||||
The default varies. If ``${SRC_libfoo}/h`` exists, it is assumed
|
||||
to be the home of all public headers and thus the default is
|
||||
``-I${SRC_libfoo}/h``
|
||||
|
||||
Otherwise we make no assumptions and the default is
|
||||
``-I${SRC_libfoo} -I${OBJ_libfoo}``
|
||||
|
||||
LDADD_libfoo
|
||||
This only applies to libs reference via ``DPLIBS``.
|
||||
The default is ``-lfoo``, ``LDADD_*`` provides a hook to
|
||||
instantiate other linker flags at the appropriate point
|
||||
without losing the benfits of ``DPLIBS``.
|
||||
|
||||
prog.mk
|
||||
-------
|
||||
|
||||
Compiles the specified SRCS and links them and the nominated libraries
|
||||
into a program. Prog makefiles usually need to list the libraries
|
||||
that need to be linked. We prefer use of ``DPLIBS`` but the more
|
||||
traditional ``DPADD`` and ``LDADD`` work just as well.
|
||||
That is::
|
||||
|
||||
DPLIBS += ${LIBCRYPTO}
|
||||
|
||||
is equivalent to::
|
||||
|
||||
DPADD += ${LIBCRYPTO}
|
||||
LDADD += -lcrypto
|
||||
|
||||
obj.mk
|
||||
------
|
||||
|
||||
One of the cool aspects of BSD make, is its support for separating
|
||||
object files from the src tree. This is also the source of much
|
||||
confusion to some.
|
||||
|
||||
Traditionally one had to do a separate ``make obj`` pass through the
|
||||
tree. If ``MKOBJDIRS`` is "auto", we include auto.obj.mk_.
|
||||
|
||||
auto.obj.mk
|
||||
-----------
|
||||
|
||||
This leverages the ``.OBJDIR`` target introduced some years ago to
|
||||
NetBSD make, to automatically create the desired object dir.
|
||||
|
||||
subdir.mk
|
||||
---------
|
||||
|
||||
This is the traditional means of walking the tree. A makefile sets
|
||||
``SUBDIR`` to the list of sub-dirs to visit.
|
||||
|
||||
If ``SUBDIR_MUST_EXIST`` is set, missing directories cause an error,
|
||||
otherwise a warning is issued. If you don't even want the warning,
|
||||
set ``MISSING_DIR=continue``.
|
||||
|
||||
Traditionally, ``subdir.mk`` prints clues as it visits each subdir::
|
||||
|
||||
===> ssl
|
||||
===> ssl/lib
|
||||
===> ssl/lib/sslfd
|
||||
|
||||
you can suppress that - or enhance it by setting ``ECHO_DIR``::
|
||||
|
||||
# suppress subdir noise
|
||||
ECHO_DIR=:
|
||||
# print time stamps
|
||||
ECHO_DIR=echo @ `date "+%s [%Y-%m-%d %T] "`
|
||||
|
||||
links.mk
|
||||
--------
|
||||
|
||||
Provides rules for processing lists of ``LINKS`` and ``SYMLINKS``.
|
||||
Each is expected to be a list of ``link`` and ``target`` pairs
|
||||
(``link`` -> ``target``).
|
||||
|
||||
The logic is generally in a ``_*_SCRIPT`` which is referenced in a
|
||||
``_*_USE`` (``.USE``) target.
|
||||
|
||||
The ``_BUILD_*`` forms are identical, but do not use ``${DESTDIR}``
|
||||
and so are useful for creating symlinks during the build phase.
|
||||
For example::
|
||||
|
||||
SYMLINKS += ${.CURDIR}/${MACHINE_ARCH}/include machine
|
||||
header_links: _BUILD_SYMLINKS_USE
|
||||
|
||||
md.o: header_links
|
||||
|
||||
would create a symlink called ``machine`` in ``${.OBJDIR}`` pointing to
|
||||
``${.CURDIR}/${MACHINE_ARCH}/include`` before compiling ``md.o``
|
||||
|
||||
|
||||
autoconf.mk
|
||||
-----------
|
||||
|
||||
Deals with running (or generating) GNU autoconf ``configure`` scripts.
|
||||
|
||||
dep.mk
|
||||
------
|
||||
|
||||
Deals with collecting dependencies. Another useful feature of BSD
|
||||
make is the separation of this sort of information into a ``.depend``
|
||||
file. ``MKDEP`` needs to point to a suitable tool (like mkdeps.sh_)
|
||||
|
||||
If ``USE_AUTODEP_MK`` is "yes" includes autodep.mk_
|
||||
|
||||
autodep.mk
|
||||
----------
|
||||
|
||||
Leverages the ``-MD`` feature of recent GCC to collect dependency
|
||||
information as a side effect of compilation. With this GCC puts
|
||||
dependency info into a ``.d`` file.
|
||||
|
||||
Unfortunately GCC bases the name of the ``.d`` file on the name of the
|
||||
input rather than the output file, which causes problems when the same
|
||||
source is compiled different ways. The latest GCC supports ``-MF`` to
|
||||
name the ``.d`` file and ``-MT`` to control the name to put as the
|
||||
dependent.
|
||||
|
||||
Recent bmake allows dependencies for the ``.END`` target (run at the
|
||||
end if everything was successful), and ``autodep.mk`` uses this to
|
||||
post process the ``.d`` files into ``.depend``.
|
||||
|
||||
auto.dep.mk
|
||||
-----------
|
||||
|
||||
A much simpler implementation than autodep.mk_ it uses
|
||||
``-MF ${.TARGET:T}.d``
|
||||
to avoid possible conflicts during parallel builds.
|
||||
This precludes the use of suffix rules to drive ``make depend``, so
|
||||
dep.mk_ handles that if specifically requested.
|
||||
|
||||
options.mk
|
||||
----------
|
||||
|
||||
Inspired by FreeBSD's ``bsd.own.mk`` more flexible.
|
||||
FreeBSD now have similar functionality in ``bsd.mkopt.mk``.
|
||||
|
||||
It allows users to express their intent with respect to options
|
||||
``MK_*`` by setting ``WITH_*`` or ``WITHOUT_*``.
|
||||
|
||||
Note: ``WITHOUT_*`` wins if both are set, and makefiles can set
|
||||
``NO_*`` to say they cannot handle that option, or even ``MK_*`` if
|
||||
they really need to.
|
||||
|
||||
|
||||
own.mk
|
||||
------
|
||||
|
||||
Normally included by ``init.mk`` (included by ``lib.mk`` and
|
||||
``prog.mk`` etc), sets macros for default ownership etc.
|
||||
|
||||
It includes ``${MAKECONF}`` if it is defined and exists.
|
||||
|
||||
ldorder.mk
|
||||
----------
|
||||
|
||||
Leverages ``bmake`` to compute optimal link order for libraries.
|
||||
This works nicely and makes refactoring a breeze - so long as you
|
||||
have not (or few) cicular dependencies between libraries.
|
||||
|
||||
man.mk
|
||||
------
|
||||
|
||||
Deals with man pages.
|
||||
|
||||
warnings.mk
|
||||
-----------
|
||||
|
||||
This provides a means of fine grained control over warnings on a per
|
||||
``${MACHINE}`` or even file basis.
|
||||
|
||||
A makefile sets ``WARNINGS_SET`` to name a list of warnings
|
||||
and individual ``W_*`` macros can be used to tweak them.
|
||||
For example::
|
||||
|
||||
WARNINGS_SET = HIGH
|
||||
W_unused_sparc = -Wno-unused
|
||||
|
||||
would add all the warnings in ``${HIGH_WARNINGS}`` to CFLAGS, but
|
||||
on sparc, ``-Wno-unused`` would replace ``-Wunused``.
|
||||
|
||||
You should never need to edit ``warnings.mk``, it will include
|
||||
``warnings-sets.mk`` if it exists and you use that to make any local
|
||||
customizations.
|
||||
|
||||
rst2htm.mk
|
||||
----------
|
||||
|
||||
Logic to simplify generating HTML (and PDF) documents from ReStructuredText.
|
||||
|
||||
cython.mk
|
||||
---------
|
||||
|
||||
Logic to build Python C interface modules using Cython_
|
||||
|
||||
.. _Cython: http://www.cython.org/
|
||||
|
||||
Meta mode
|
||||
=========
|
||||
|
||||
The 20110505 and later versions of ``mk-files`` include a number of
|
||||
makefiles contributed by Juniper Networks, Inc.
|
||||
These allow the latest version of bmake_ to run in `meta mode`_
|
||||
see `dirdeps.mk`_
|
||||
|
||||
.. _`dirdeps.mk`: /help/sjg/dirdeps.htm
|
||||
.. _`meta mode`: bmake-meta-mode.htm
|
||||
|
||||
Install
|
||||
=======
|
||||
|
||||
You can use the content of mk.tar.gz_ without installing at all.
|
||||
|
||||
The script ``install-mk`` takes care of copying ``*.mk`` into a
|
||||
destination directory, and unless told not to, create ``bsd.*.mk`` links
|
||||
for ``lib.mk`` etc.
|
||||
|
||||
If you just want to create the ``bsd.*.mk`` links in the directory
|
||||
where you unpacked the tar file, you can::
|
||||
|
||||
./mk/install-mk ./mk
|
||||
|
||||
------
|
||||
|
||||
.. _bmake: bmake.htm
|
||||
.. _NetBSD: http://www.netbsd.org/
|
||||
.. _mkdeps.sh: http://www.crufty.net/ftp/pub/sjg/mkdeps.sh
|
||||
.. _mk.tar.gz: http://www.crufty.net/ftp/pub/sjg/mk.tar.gz
|
||||
|
||||
:Author: sjg@crufty.net
|
||||
:Revision: $Id: mk-files.txt,v 1.20 2020/08/19 17:51:53 sjg Exp $
|
||||
:Copyright: Crufty.NET
|
104
20200902/mk/mkopt.sh
Executable file
104
20200902/mk/mkopt.sh
Executable file
@ -0,0 +1,104 @@
|
||||
#!/bin/sh
|
||||
|
||||
# $Id: mkopt.sh,v 1.13 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2014, 2020, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
# handle WITH[OUT]_* options in a manner compatible with
|
||||
# options.mk and bsd.mkopt.mk in recent FreeBSD
|
||||
|
||||
# no need to be included more than once
|
||||
_MKOPT_SH=:
|
||||
_MKOPT_PREFIX=${_MKOPT_PREFIX:-MK_}
|
||||
|
||||
#
|
||||
# _mk_opt default OPT
|
||||
#
|
||||
# Set MK_$OPT
|
||||
#
|
||||
# The semantics are simple, if MK_$OPT has no value
|
||||
# WITHOUT_$OPT results in MK_$OPT=no
|
||||
# otherwise WITH_$OPT results in MK_$OPT=yes.
|
||||
# Note WITHOUT_$OPT overrides WITH_$OPT.
|
||||
#
|
||||
# For backwards compatability reasons we treat WITH_$OPT=no
|
||||
# the same as WITHOUT_$OPT.
|
||||
#
|
||||
_mk_opt() {
|
||||
_d=$1
|
||||
_mo=${_MKOPT_PREFIX}$2 _wo=WITHOUT_$2 _wi=WITH_$2
|
||||
eval "_mov=\$$_mo _wov=\$$_wo _wiv=\$$_wi"
|
||||
|
||||
case "$_wiv" in
|
||||
[Nn][Oo]) _wov=no;;
|
||||
esac
|
||||
_v=${_mov:-${_wov:+no}}
|
||||
_v=${_v:-${_wiv:+yes}}
|
||||
_v=${_v:-$_d}
|
||||
_opt_list="$_opt_list $_mo"
|
||||
case "$_v" in
|
||||
yes|no) ;; # sane
|
||||
0|[NnFf]*) _v=no;; # they mean no
|
||||
1|[YyTt]*) _v=yes;; # they mean yes
|
||||
*) _v=$_d;; # ignore bogus value
|
||||
esac
|
||||
eval "$_mo=$_v"
|
||||
}
|
||||
|
||||
#
|
||||
# _mk_opts default opt ... [default [opt] ...]
|
||||
#
|
||||
# see _mk_opts_defaults for example
|
||||
#
|
||||
_mk_opts() {
|
||||
_d=no
|
||||
for _o in "$@"
|
||||
do
|
||||
case "$_o" in
|
||||
*/*) # option is dirname default comes from basename
|
||||
eval "_d=\$${_MKOPT_PREFIX}${_o#*/}"
|
||||
_o=${_o%/*}
|
||||
;;
|
||||
yes|no) _d=$_o; continue;;
|
||||
esac
|
||||
_mk_opt $_d $_o
|
||||
done
|
||||
}
|
||||
|
||||
# handle either options.mk style OPTIONS_DEFAULT_*
|
||||
# or FreeBSD's new bsd.mkopt.mk style __DEFAULT_*_OPTIONS
|
||||
_mk_opts_defaults() {
|
||||
_mk_opts no $OPTIONS_DEFAULT_NO $__DEFAULT_NO_OPTIONS \
|
||||
yes $OPTIONS_DEFAULT_YES $__DEFAULT_YES_OPTIONS \
|
||||
$OPTIONS_DEFAULT_DEPENDENT $__DEFAULT_DEPENDENT_OPTIONS
|
||||
}
|
||||
|
||||
case "/$0" in
|
||||
*/mkopt*)
|
||||
_list=no
|
||||
while :
|
||||
do
|
||||
case "$1" in
|
||||
*=*) eval "$1"; shift;;
|
||||
--no|no) _list="$_list no"; shift;;
|
||||
--yes|yes) _list="$_list yes"; shift;;
|
||||
-DWITH*) eval "${1#-D}=1"; shift;;
|
||||
[A-Z]*) _list="$_list $1"; shift;;
|
||||
*) break;;
|
||||
esac
|
||||
done
|
||||
_mk_opts $_list
|
||||
;;
|
||||
esac
|
||||
|
47
20200902/mk/nls.mk
Normal file
47
20200902/mk/nls.mk
Normal file
@ -0,0 +1,47 @@
|
||||
# $NetBSD: bsd.nls.mk,v 1.3 1996/10/18 02:34:45 thorpej Exp $
|
||||
|
||||
.if !target(.MAIN)
|
||||
# init.mk not included
|
||||
.-include <${.CURDIR:H}/Makefile.inc>
|
||||
|
||||
.MAIN: all
|
||||
.endif
|
||||
|
||||
.SUFFIXES: .cat .msg
|
||||
|
||||
.msg.cat:
|
||||
@rm -f ${.TARGET}
|
||||
gencat ${.TARGET} ${.IMPSRC}
|
||||
|
||||
.if defined(NLS) && !empty(NLS)
|
||||
NLSALL= ${NLS:.msg=.cat}
|
||||
.NOPATH: ${NLSALL}
|
||||
.endif
|
||||
|
||||
.if !defined(NLSNAME)
|
||||
.if defined(PROG)
|
||||
NLSNAME=${PROG}
|
||||
.else
|
||||
NLSNAME=lib${LIB}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
nlsinstall:
|
||||
.if defined(NLSALL)
|
||||
@for msg in ${NLSALL}; do \
|
||||
NLSLANG=`basename $$msg .cat`; \
|
||||
dir=${DESTDIR}${NLSDIR}/$${NLSLANG}; \
|
||||
${INSTALL} -d $$dir; \
|
||||
${INSTALL} ${COPY} -o ${NLSOWN} -g ${NLSGRP} -m ${NLSMODE} $$msg $$dir/${NLSNAME}.cat; \
|
||||
done
|
||||
.endif
|
||||
|
||||
.if defined(NLSALL)
|
||||
all: ${NLSALL}
|
||||
|
||||
install: nlsinstall
|
||||
|
||||
cleandir: cleannls
|
||||
cleannls:
|
||||
rm -f ${NLSALL}
|
||||
.endif
|
113
20200902/mk/obj.mk
Normal file
113
20200902/mk/obj.mk
Normal file
@ -0,0 +1,113 @@
|
||||
# $Id: obj.mk,v 1.16 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1999-2010, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE:S,bsd.,,}__)
|
||||
__${.PARSEFILE:S,bsd.,,}__:
|
||||
|
||||
.include <init.mk>
|
||||
|
||||
ECHO_TRACE ?= echo
|
||||
|
||||
.if ${MK_OBJDIRS} == "no"
|
||||
obj:
|
||||
objlink:
|
||||
objwarn:
|
||||
.else
|
||||
|
||||
# this has to match how make behaves
|
||||
.if defined(MAKEOBJDIRPREFIX) || defined(MAKEOBJDIR)
|
||||
.if defined(MAKEOBJDIRPREFIX)
|
||||
__objdir:= ${MAKEOBJDIRPREFIX}${.CURDIR}
|
||||
.else
|
||||
__objdir:= ${MAKEOBJDIR}
|
||||
.endif
|
||||
.else
|
||||
__objdir= ${__objlink}
|
||||
.endif
|
||||
|
||||
.if defined(OBJMACHINE)
|
||||
__objlink= obj.${MACHINE}
|
||||
.else
|
||||
__objlink= obj
|
||||
.endif
|
||||
|
||||
.if ${MK_AUTO_OBJ} == "yes"
|
||||
.-include "auto.obj.mk"
|
||||
.endif
|
||||
|
||||
.NOPATH: ${__objdir}
|
||||
.PHONY: obj
|
||||
|
||||
obj: _SUBDIRUSE
|
||||
@if test ! -d ${__objdir}/.; then \
|
||||
mkdir -p ${__objdir}; \
|
||||
if test ! -d ${__objdir}; then \
|
||||
mkdir ${__objdir}; exit 1; \
|
||||
fi; \
|
||||
${ECHO_TRACE} "[Creating objdir ${__objdir}...]" >&2; \
|
||||
fi
|
||||
|
||||
.if !target(_SUBDIRUSE)
|
||||
# this just allows us to be included by ourselves
|
||||
_SUBDIRUSE:
|
||||
.endif
|
||||
|
||||
# so we can interact with freebsd makefiles
|
||||
.if !target(objwarn)
|
||||
objwarn:
|
||||
.if ${.OBJDIR} == ${.CURDIR}
|
||||
@echo "Warning Object directory is ${.CURDIR}"
|
||||
.elif ${.OBJDIR} != ${__objdir}
|
||||
@echo "Warning Object directory is ${.OBJDIR} vs. ${__objdir}"
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if !target(objlink)
|
||||
objlink:
|
||||
.if ${__objdir:T} != ${__objlink}
|
||||
@if test -d ${__objdir}/.; then \
|
||||
${RM} -f ${.CURDIR}/${__objlink}; \
|
||||
${LN} -s ${__objdir} ${.CURDIR}/${__objlink}; \
|
||||
echo "${__objlink} -> ${__objdir}"; \
|
||||
else \
|
||||
echo "No ${__objdir} to link to - do a 'make obj'"; \
|
||||
fi
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
||||
_CURDIR?= ${.CURDIR}
|
||||
_OBJDIR?= ${.OBJDIR}
|
||||
|
||||
.if !target(print-objdir)
|
||||
print-objdir:
|
||||
@echo ${_OBJDIR}
|
||||
.endif
|
||||
|
||||
.if !target(whereobj)
|
||||
whereobj:
|
||||
@echo ${_OBJDIR}
|
||||
.endif
|
||||
|
||||
.if !target(destroy)
|
||||
.if ${.CURDIR} != ${.OBJDIR}
|
||||
destroy:
|
||||
(cd ${_CURDIR} && rm -rf ${_OBJDIR})
|
||||
.else
|
||||
destroy: clean
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.endif
|
82
20200902/mk/options.mk
Normal file
82
20200902/mk/options.mk
Normal file
@ -0,0 +1,82 @@
|
||||
# $Id: options.mk,v 1.13 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2012, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
# Inspired by FreeBSD bsd.own.mk, but intentionally simpler and more flexible.
|
||||
|
||||
# Options are normally listed in either OPTIONS_DEFAULT_{YES,NO}
|
||||
# We convert these to ${OPTION}/{yes,no} in OPTIONS_DEFAULT_VALUES.
|
||||
# We add the OPTIONS_DEFAULT_NO first so they take precedence.
|
||||
# This allows override of an OPTIONS_DEFAULT_YES by adding it to
|
||||
# OPTIONS_DEFAULT_NO or adding ${OPTION}/no to OPTIONS_DEFAULT_VALUES.
|
||||
# An OPTIONS_DEFAULT_NO option can only be overridden by putting
|
||||
# ${OPTION}/yes in OPTIONS_DEFAULT_VALUES.
|
||||
# A makefile may set NO_* (or NO*) to indicate it cannot do something.
|
||||
# User sets WITH_* and WITHOUT_* to indicate what they want.
|
||||
# We set ${OPTION_PREFIX:UMK_}* which is then all we need care about.
|
||||
OPTIONS_DEFAULT_VALUES += \
|
||||
${OPTIONS_DEFAULT_NO:O:u:S,$,/no,} \
|
||||
${OPTIONS_DEFAULT_YES:O:u:S,$,/yes,}
|
||||
|
||||
OPTION_PREFIX ?= MK_
|
||||
|
||||
# NO_* takes precedence
|
||||
# If both WITH_* and WITHOUT_* are defined, WITHOUT_ wins unless
|
||||
# DOMINANT_* is set to "yes"
|
||||
# Otherwise WITH_* and WITHOUT_* override the default.
|
||||
.for o in ${OPTIONS_DEFAULT_VALUES:M*/*}
|
||||
.if defined(NO_${o:H}) || defined(NO${o:H})
|
||||
# we cannot do it
|
||||
${OPTION_PREFIX}${o:H} ?= no
|
||||
.elif defined(WITH_${o:H}) && defined(WITHOUT_${o:H})
|
||||
# normally WITHOUT_ wins
|
||||
DOMINANT_${o:H} ?= no
|
||||
${OPTION_PREFIX}${o:H} ?= ${DOMINANT_${o:H}}
|
||||
.elif ${o:T:tl} == "no"
|
||||
.if defined(WITH_${o:H})
|
||||
${OPTION_PREFIX}${o:H} ?= yes
|
||||
.else
|
||||
${OPTION_PREFIX}${o:H} ?= no
|
||||
.endif
|
||||
.else
|
||||
.if defined(WITHOUT_${o:H})
|
||||
${OPTION_PREFIX}${o:H} ?= no
|
||||
.else
|
||||
${OPTION_PREFIX}${o:H} ?= yes
|
||||
.endif
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
# OPTIONS_DEFAULT_DEPENDENT += FOO_UTILS/FOO
|
||||
# If neither WITH[OUT]_FOO_UTILS is set, (see rules above)
|
||||
# use the value of ${OPTION_PREFIX}FOO
|
||||
.for o in ${OPTIONS_DEFAULT_DEPENDENT:M*/*:O:u}
|
||||
.if defined(NO_${o:H}) || defined(NO${o:H})
|
||||
# we cannot do it
|
||||
${OPTION_PREFIX}${o:H} ?= no
|
||||
.elif defined(WITH_${o:H}) && defined(WITHOUT_${o:H})
|
||||
# normally WITHOUT_ wins
|
||||
DOMINANT_${o:H} ?= no
|
||||
${OPTION_PREFIX}${o:H} ?= ${DOMINANT_${o:H}}
|
||||
.elif defined(WITH_${o:H})
|
||||
${OPTION_PREFIX}${o:H} ?= yes
|
||||
.elif defined(WITHOUT_${o:H})
|
||||
${OPTION_PREFIX}${o:H} ?= no
|
||||
.else
|
||||
${OPTION_PREFIX}${o:H} ?= ${${OPTION_PREFIX}${o:T}}
|
||||
.endif
|
||||
.endfor
|
||||
.undef OPTIONS_DEFAULT_VALUES
|
||||
.undef OPTIONS_DEFAULT_NO
|
||||
.undef OPTIONS_DEFAULT_YES
|
271
20200902/mk/own.mk
Normal file
271
20200902/mk/own.mk
Normal file
@ -0,0 +1,271 @@
|
||||
# $Id: own.mk,v 1.41 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
.if !target(__init.mk__)
|
||||
.include "init.mk"
|
||||
.endif
|
||||
|
||||
.if !defined(NOMAKECONF) && !defined(NO_MAKECONF)
|
||||
MAKECONF?= /etc/mk.conf
|
||||
.-include "${MAKECONF}"
|
||||
.endif
|
||||
|
||||
.include <host-target.mk>
|
||||
|
||||
TARGET_OSNAME?= ${_HOST_OSNAME}
|
||||
TARGET_OSREL?= ${_HOST_OSREL}
|
||||
TARGET_OSTYPE?= ${HOST_OSTYPE}
|
||||
TARGET_HOST?= ${HOST_TARGET}
|
||||
|
||||
# these may or may not exist
|
||||
.-include <${TARGET_HOST}.mk>
|
||||
.-include <config.mk>
|
||||
|
||||
RM?= rm
|
||||
LN?= ln
|
||||
INSTALL?= install
|
||||
|
||||
prefix?= /usr
|
||||
.if exists(${prefix}/lib)
|
||||
libprefix?= ${prefix}
|
||||
.else
|
||||
libprefix?= /usr
|
||||
.endif
|
||||
|
||||
# FreeBSD at least does not set this
|
||||
MACHINE_ARCH?= ${MACHINE}
|
||||
# we need to make sure these are defined too in case sys.mk fails to.
|
||||
COMPILE.s?= ${CC} ${AFLAGS} -c
|
||||
LINK.s?= ${CC} ${AFLAGS} ${LDFLAGS}
|
||||
COMPILE.S?= ${CC} ${AFLAGS} ${CPPFLAGS} -c -traditional-cpp
|
||||
LINK.S?= ${CC} ${AFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
COMPILE.c?= ${CC} ${CFLAGS} ${CPPFLAGS} -c
|
||||
LINK.c?= ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
CXXFLAGS?= ${CFLAGS}
|
||||
COMPILE.cc?= ${CXX} ${CXXFLAGS} ${CPPFLAGS} -c
|
||||
LINK.cc?= ${CXX} ${CXXFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
COMPILE.m?= ${OBJC} ${OBJCFLAGS} ${CPPFLAGS} -c
|
||||
LINK.m?= ${OBJC} ${OBJCFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
COMPILE.f?= ${FC} ${FFLAGS} -c
|
||||
LINK.f?= ${FC} ${FFLAGS} ${LDFLAGS}
|
||||
COMPILE.F?= ${FC} ${FFLAGS} ${CPPFLAGS} -c
|
||||
LINK.F?= ${FC} ${FFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
COMPILE.r?= ${FC} ${FFLAGS} ${RFLAGS} -c
|
||||
LINK.r?= ${FC} ${FFLAGS} ${RFLAGS} ${LDFLAGS}
|
||||
LEX.l?= ${LEX} ${LFLAGS}
|
||||
COMPILE.p?= ${PC} ${PFLAGS} ${CPPFLAGS} -c
|
||||
LINK.p?= ${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
YACC.y?= ${YACC} ${YFLAGS}
|
||||
|
||||
# for suffix rules
|
||||
IMPFLAGS?= ${COPTS.${.IMPSRC:T}} ${CPUFLAGS.${.IMPSRC:T}} ${CPPFLAGS.${.IMPSRC:T}}
|
||||
.for s in .c .cc
|
||||
COMPILE.$s += ${IMPFLAGS}
|
||||
LINK.$s += ${IMPFLAGS}
|
||||
.endfor
|
||||
|
||||
PRINT.VAR.MAKE = MAKESYSPATH=${MAKESYSPATH:U${.PARSEDIR}} ${.MAKE}
|
||||
.if empty(.MAKEFLAGS:M-V*)
|
||||
.if defined(MAKEOBJDIRPREFIX) || defined(MAKEOBJDIR)
|
||||
PRINTOBJDIR= ${PRINT.VAR.MAKE} -r -V .OBJDIR -f /dev/null xxx
|
||||
.else
|
||||
PRINTOBJDIR= ${PRINT.VAR.MAKE} -V .OBJDIR
|
||||
.endif
|
||||
.else
|
||||
PRINTOBJDIR= echo # prevent infinite recursion
|
||||
.endif
|
||||
|
||||
# we really like to have SRCTOP and OBJTOP defined...
|
||||
.if !defined(SRCTOP) || !defined(OBJTOP)
|
||||
.-include <srctop.mk>
|
||||
.endif
|
||||
|
||||
.if !defined(SRCTOP) || !defined(OBJTOP)
|
||||
# dpadd.mk is rather pointless without these
|
||||
OPTIONS_DEFAULT_NO+= DPADD_MK
|
||||
.endif
|
||||
|
||||
# process options
|
||||
OPTIONS_DEFAULT_NO+= \
|
||||
INSTALL_AS_USER \
|
||||
GPROF \
|
||||
PROG_LDORDER_MK \
|
||||
LIBTOOL \
|
||||
LINT \
|
||||
|
||||
OPTIONS_DEFAULT_YES+= \
|
||||
ARCHIVE \
|
||||
AUTODEP \
|
||||
CRYPTO \
|
||||
DOC \
|
||||
DPADD_MK \
|
||||
GDB \
|
||||
KERBEROS \
|
||||
LINKLIB \
|
||||
MAN \
|
||||
NLS \
|
||||
OBJ \
|
||||
PIC \
|
||||
SHARE \
|
||||
SKEY \
|
||||
YP \
|
||||
|
||||
OPTIONS_DEFAULT_DEPENDENT+= \
|
||||
CATPAGES/MAN \
|
||||
LDORDER_MK/PROG_LDORDER_MK \
|
||||
OBJDIRS/OBJ \
|
||||
PICINSTALL/LINKLIB \
|
||||
PICLIB/PIC \
|
||||
PROFILE/LINKLIB \
|
||||
STAGING_PROG/STAGING \
|
||||
|
||||
.include <options.mk>
|
||||
|
||||
.if ${MK_INSTALL_AS_USER} == "yes"
|
||||
# We ignore this if user is root.
|
||||
_uid!= id -u
|
||||
.if ${_uid} != 0
|
||||
.if !defined(USERGRP)
|
||||
USERGRP!= id -g
|
||||
.export USERGRP
|
||||
.endif
|
||||
.for x in BIN CONF DOC INC INFO FILES KMOD LIB MAN NLS PROG SHARE
|
||||
$xOWN= ${USER}
|
||||
$xGRP= ${USERGRP}
|
||||
$x_INSTALL_OWN=
|
||||
.endfor
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# override this in sys.mk
|
||||
ROOT_GROUP?= wheel
|
||||
BINGRP?= ${ROOT_GROUP}
|
||||
BINOWN?= root
|
||||
BINMODE?= 555
|
||||
NONBINMODE?= 444
|
||||
DIRMODE?= 755
|
||||
|
||||
INCLUDEDIR?= ${prefix}/include
|
||||
INCDIR?= ${INCLUDEDIR}
|
||||
|
||||
# Define MANZ to have the man pages compressed (gzip)
|
||||
#MANZ= 1
|
||||
|
||||
MANTARGET?= cat
|
||||
MANDIR?= ${prefix}/share/man/${MANTARGET}
|
||||
MANGRP?= ${BINGRP}
|
||||
MANOWN?= ${BINOWN}
|
||||
MANMODE?= ${NONBINMODE}
|
||||
|
||||
INCLUDEDIR?= ${libprefix}/include
|
||||
LIBDIR?= ${libprefix}/lib
|
||||
SHLIBDIR?= ${libprefix}/lib
|
||||
.if ${USE_SHLIBDIR:Uno} == "yes"
|
||||
_LIBSODIR?= ${SHLIBDIR}
|
||||
.else
|
||||
_LIBSODIR?= ${LIBDIR}
|
||||
.endif
|
||||
# this is where ld.*so lives
|
||||
SHLINKDIR?= /usr/libexec
|
||||
LINTLIBDIR?= ${libprefix}/libdata/lint
|
||||
LIBGRP?= ${BINGRP}
|
||||
LIBOWN?= ${BINOWN}
|
||||
LIBMODE?= ${NONBINMODE}
|
||||
|
||||
DOCDIR?= ${prefix}/share/doc
|
||||
DOCGRP?= ${BINGRP}
|
||||
DOCOWN?= ${BINOWN}
|
||||
DOCMODE?= ${NONBINMODE}
|
||||
|
||||
NLSDIR?= ${prefix}/share/nls
|
||||
NLSGRP?= ${BINGRP}
|
||||
NLSOWN?= ${BINOWN}
|
||||
NLSMODE?= ${NONBINMODE}
|
||||
|
||||
KMODDIR?= ${prefix}/lkm
|
||||
KMODGRP?= ${BINGRP}
|
||||
KMODOWN?= ${BINOWN}
|
||||
KMODMODE?= ${NONBINMODE}
|
||||
|
||||
SHAREGRP?= ${BINGRP}
|
||||
SHAREOWN?= ${BINOWN}
|
||||
SHAREMODE?= ${NONBINMODE}
|
||||
|
||||
COPY?= -c
|
||||
STRIP_FLAG?= -s
|
||||
|
||||
.if ${TARGET_OSNAME} == "NetBSD"
|
||||
.if exists(/usr/libexec/ld.elf_so)
|
||||
OBJECT_FMT=ELF
|
||||
.endif
|
||||
OBJECT_FMT?=a.out
|
||||
.endif
|
||||
# sys.mk should set something appropriate if need be.
|
||||
OBJECT_FMT?=ELF
|
||||
|
||||
.if (${_HOST_OSNAME} == "FreeBSD")
|
||||
CFLAGS+= ${CPPFLAGS}
|
||||
.endif
|
||||
|
||||
# allow for per target flags
|
||||
# apply the :T:R first, so the more specific :T can override if needed
|
||||
CPPFLAGS += ${CPPFLAGS_${.TARGET:T:R}} ${CPPFLAGS_${.TARGET:T}}
|
||||
CFLAGS += ${CFLAGS_${.TARGET:T:R}} ${CFLAGS_${.TARGET:T}}
|
||||
|
||||
# Define SYS_INCLUDE to indicate whether you want symbolic links to the system
|
||||
# source (``symlinks''), or a separate copy (``copies''); (latter useful
|
||||
# in environments where it's not possible to keep /sys publicly readable)
|
||||
#SYS_INCLUDE= symlinks
|
||||
|
||||
# don't try to generate PIC versions of libraries on machines
|
||||
# which don't support PIC.
|
||||
.if (${MACHINE_ARCH} == "vax") || \
|
||||
((${MACHINE_ARCH} == "mips") && defined(STATIC_TOOLCHAIN)) || \
|
||||
((${MACHINE_ARCH} == "alpha") && defined(ECOFF_TOOLCHAIN))
|
||||
MK_PIC=no
|
||||
.endif
|
||||
|
||||
# No lint, for now.
|
||||
NOLINT=
|
||||
|
||||
|
||||
.if ${MK_LINKLIB} == "no"
|
||||
MK_PICINSTALL= no
|
||||
MK_PROFILE= no
|
||||
.endif
|
||||
|
||||
.if ${MK_MAN} == "no"
|
||||
MK_CATPAGES= no
|
||||
.endif
|
||||
|
||||
.if ${MK_OBJ} == "no"
|
||||
MK_OBJDIRS= no
|
||||
MK_AUTO_OBJ= no
|
||||
.endif
|
||||
|
||||
.if ${MK_SHARE} == "no"
|
||||
MK_CATPAGES= no
|
||||
MK_DOC= no
|
||||
MK_INFO= no
|
||||
MK_MAN= no
|
||||
MK_NLS= no
|
||||
.endif
|
||||
|
||||
# :U incase not using our sys.mk
|
||||
.if ${MK_META_MODE:Uno} == "yes"
|
||||
# should all be set by sys.mk if not default
|
||||
TARGET_SPEC_VARS ?= MACHINE
|
||||
.if ${TARGET_SPEC_VARS:[#]} > 1
|
||||
TARGET_SPEC_VARS_REV := ${TARGET_SPEC_VARS:[-1..1]}
|
||||
.else
|
||||
TARGET_SPEC_VARS_REV = ${TARGET_SPEC_VARS}
|
||||
.endif
|
||||
.if ${MK_STAGING} == "yes"
|
||||
STAGE_ROOT?= ${OBJROOT}/stage
|
||||
STAGE_OBJTOP?= ${STAGE_ROOT}/${TARGET_SPEC_VARS_REV:ts/}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.endif
|
36
20200902/mk/prlist.mk
Normal file
36
20200902/mk/prlist.mk
Normal file
@ -0,0 +1,36 @@
|
||||
# $Id: prlist.mk,v 1.4 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2006, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
# this needs to be included after all the lists it will process
|
||||
# are defined - which is why it is a separate file.
|
||||
# Usage looks like:
|
||||
# MAKEFLAGS= ${.MAKE} -f ${MAKEFILE} prlist.SOMETHING_HUGE | xargs whatever
|
||||
#
|
||||
.if make(prlist.*)
|
||||
.for t in ${.TARGETS:Mprlist.*:E}
|
||||
.if empty($t)
|
||||
prlist.$t:
|
||||
.else
|
||||
prlist.$t: ${$t:O:u:S,^,prlist-,}
|
||||
${$t:O:u:S,^,prlist-,}: .PHONY
|
||||
@echo "${.TARGET:S,prlist-,,}"
|
||||
.endif
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
.endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user