1 # $NetBSD: subst.mk,v 1.52 2008/01/23 01:44:28 rillig Exp $
3 # This Makefile fragment implements a general text replacement facility.
4 # Package makefiles define a ``class'', for each of which a particular
5 # substitution description can be defined. For each class of files, a
6 # target subst-<class> is created to perform the text replacement.
8 # Package-settable variables:
11 # A list of class names. When adding new classes to this list, be
12 # sure to append them (+=) instead of overriding them (=).
15 # "stage" at which we do the text replacement. Should be one of
16 # {pre,do,post}-{extract,patch,configure,build,install}.
18 # SUBST_MESSAGE.<class>
19 # The message to display before doing the substitution.
22 # A list of file patterns on which to run the substitution;
23 # the filenames are either absolute or relative to ${WRKSRC}.
26 # List of sed(1) arguments to run on the specified files. Multiple
27 # commands can be specified using the -e option of sed.
30 # List of variables that are substituted whenever they appear in
31 # the form @VARNAME@. This is basically a short-cut for
33 # -e 's,@VARNAME@,${VARNAME},g'
35 # also taking care of (most) quoting issues. You can use both
36 # SUBST_SED and SUBST_VARS in a single class.
38 # SUBST_FILTER_CMD.<class>
39 # Filter used to perform the actual substitution on the specified
40 # files. Defaults to ${SED} ${SUBST_SED.<class>}.
42 # SUBST_POSTCMD.<class>
43 # Command to clean up after sed(1). Defaults to ${RM} -f
44 # $$file${_SUBST_BACKUP_SUFFIX}. For debugging, set it to ${DO_NADA}.
46 # SUBST_SKIP_TEXT_CHECK.<class>
47 # By default, each file is checked whether it really is a text file
48 # before any substitutions are done to it. Since that test is not
49 # perfect, it can be disabled by setting this variable to "yes".
58 _PKG_VARS.
subst= SUBST_CLASSES
59 .for c in
${SUBST_CLASSES}
60 . for pv in SUBST_STAGE SUBST_MESSAGE SUBST_FILES SUBST_SED SUBST_VARS \
61 SUBST_FILTER_CMD SUBST_POSTCMD SUBST_SKIP_TEXT_CHECK
62 _PKG_VARS.
subst+= ${pv}.
${c}
66 ECHO_SUBST_MSG?
= ${STEP_MSG}
68 # _SUBST_IS_TEXT_FILE returns 0 if $${file} is a text file.
69 _SUBST_IS_TEXT_FILE?
= \
70 { nchars
=`${WC} -c < "$$file"`; \
71 notnull
=`LC_ALL=C ${TR} -d '\\0' < "$$file" | ${WC} -c`; \
72 [ "$$nchars" = "$$notnull" ] ||
${FALSE} ; \
75 _SUBST_BACKUP_SUFFIX
= .
subst.sav
77 .for _class_ in
${SUBST_CLASSES}
78 _SUBST_COOKIE.
${_class_}= ${WRKDIR}/.subst_
${_class_}_done
80 SUBST_FILTER_CMD.
${_class_}?
= ${SED} ${SUBST_SED.
${_class_}}
81 SUBST_VARS.
${_class_}?
= # none
82 SUBST_MESSAGE.
${_class_}?
= Substituting
"${_class_}" in
${SUBST_FILES.
${_class_}}
83 . for v in
${SUBST_VARS.
${_class_}}
84 SUBST_FILTER_CMD.
${_class_} += -e s
,@
${v}@
,${${v}:S|
\\|
\\\\|gW
:S|
,|
\\,|gW
:S|
&|
\\\
&|gW
:Q
},g
86 SUBST_POSTCMD.
${_class_}?
= ${RM} -f
"$$tmpfile"
87 SUBST_SKIP_TEXT_CHECK.
${_class_}?
= no
89 .if
!empty
(SUBST_SKIP_TEXT_CHECK.
${_class_}:M
[Yy
][Ee
][Ss
])
90 _SUBST_IS_TEXT_FILE.
${_class_}= ${TRUE}
92 _SUBST_IS_TEXT_FILE.
${_class_}= ${_SUBST_IS_TEXT_FILE}
95 SUBST_TARGETS
+= subst-
${_class_}
97 . if defined
(SUBST_STAGE.
${_class_})
98 ${SUBST_STAGE.
${_class_}}: subst-
${_class_}
100 # SUBST_STAGE.* does not need to be defined.
101 #PKG_FAIL_REASON+= "SUBST_STAGE missing for ${_class_}."
104 .PHONY
: subst-
${_class_}
105 subst-
${_class_}: ${_SUBST_COOKIE.
${_class_}}
107 ${_SUBST_COOKIE.
${_class_}}:
108 . if
!empty
(SUBST_MESSAGE.
${_class_})
109 ${RUN} ${ECHO_SUBST_MSG} ${SUBST_MESSAGE.
${_class_}:Q
}
111 ${RUN} cd
${WRKSRC
:Q
}; \
112 files
=${SUBST_FILES.
${_class_}:Q
}; \
113 for file in
$$files; do \
114 case
$$file in
/*) ;; *) file
="./$$file";; esac
; \
115 tmpfile
="$$file"${_SUBST_BACKUP_SUFFIX
:Q
}; \
116 if
[ ! -f
"$$file" ]; then \
117 ${WARNING_MSG} "[subst.mk:${_class_}] Ignoring non-existent file \"$$file\"."; \
118 elif
${_SUBST_IS_TEXT_FILE.
${_class_}}; then \
119 ${MV} -f
"$$file" "$$tmpfile" || exit
1; \
120 ${SUBST_FILTER_CMD.
${_class_}} \
123 if
${TEST} -x
"$$tmpfile"; then \
124 ${CHMOD} +x
"$$file"; \
126 if
${CMP} -s
"$$tmpfile" "$$file"; then \
127 ${INFO_MSG} "[subst.mk:${_class_}] Nothing changed in $$file."; \
128 ${MV} -f
"$$tmpfile" "$$file"; \
130 ${SUBST_POSTCMD.
${_class_}}; \
131 ${ECHO} "$$file" >> ${.TARGET
}; \
134 ${WARNING_MSG} "[subst.mk:${_class_}] Ignoring non-text file \"$$file\"."; \
137 ${RUN} ${TOUCH} ${TOUCH_FLAGS} ${.TARGET
:Q
}