Merge from vendor branch TNF:
[pkgsrc.git] / mk / subst.mk
1 # $NetBSD: subst.mk,v 1.22 2005/06/09 19:49:48 rillig Exp $
2 #
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.
7 #
8 # The following variables are used:
9 #
10 # SUBST_CLASSES
11 #       A list of class names.  A new class name must be appended (+=).
12 #
13 # SUBST_STAGE.<class>
14 #       "stage" at which we do the text replacement. Should be one of
15 #       {pre,do,post}-{extract,patch,configure,build,install}.
16 #
17 # SUBST_MESSAGE.<class>
18 #       The message to display when the substitution is done.
19 #
20 # SUBST_FILES.<class>
21 #       A list of file patterns on which to run the substitution;
22 #       the filenames are relative to ${WRKSRC}.
23 #
24 # SUBST_SED.<class>
25 #       sed(1) substitution expression to run on the specified files.
26 #
27 # SUBST_FILTER_CMD.<class>
28 #       Filter used to perform the actual substitution on the specified
29 #       files.  Defaults to ${SED} ${SUBST_SED.<class>}.
30 #
31 # SUBST_POSTCMD.<class>
32 #       Command to clean up after sed(1). Defaults to ${RM} -f
33 #       $$file${_SUBST_BACKUP_SUFFIX}. For debugging, set it to ${DO_NADA}.
34
35 ECHO_SUBST_MSG?=        ${ECHO}
36
37 # _SUBST_IS_TEXT_FILE returns 0 if $${file} is a text file.
38 _SUBST_IS_TEXT_FILE?= \
39         { ${TEST} -f "$$file"                                           \
40           && ${FILE_CMD} "$$file"                                       \
41              | ${EGREP} "(executable .* script|shell script|text)";     \
42         } >/dev/null 2>&1
43
44 _SUBST_BACKUP_SUFFIX=   .subst.sav
45
46 .for _class_ in ${SUBST_CLASSES}
47 _SUBST_COOKIE.${_class_}=       ${WRKDIR}/.subst_${_class_}_done
48
49 SUBST_FILTER_CMD.${_class_}?=   ${SED} ${SUBST_SED.${_class_}}
50 SUBST_POSTCMD.${_class_}?=      ${RM} -f "$$tmpfile"
51
52 SUBST_TARGETS+=                 subst-${_class_}
53 _SUBST_TARGETS.${_class_}=      subst-${_class_}-message
54 _SUBST_TARGETS.${_class_}+=     ${_SUBST_COOKIE.${_class_}}
55 _SUBST_TARGETS.${_class_}+=     subst-${_class_}-cookie
56
57 .ORDER: ${_SUBST_TARGETS.${_class_}}
58
59 .  if defined(SUBST_STAGE.${_class_})
60 ${SUBST_STAGE.${_class_}}: subst-${_class_}
61 .  endif
62
63 .PHONY: subst-${_class_}
64 subst-${_class_}: ${_SUBST_TARGETS.${_class_}}
65
66 .PHONY: subst-${_class_}-message
67  subst-${_class_}-message:
68 .  if defined(SUBST_MESSAGE.${_class_})
69         ${_PKG_SILENT}${_PKG_DEBUG}                                     \
70         ${ECHO_SUBST_MSG} "=> "${SUBST_MESSAGE.${_class_}}
71 .  endif
72
73 .PHONY: subst-${_class_}-cookie
74  subst-${_class_}-cookie:
75         ${_PKG_SILENT}${_PKG_DEBUG}                                     \
76         ${TOUCH} ${TOUCH_FLAGS} ${_SUBST_COOKIE.${_class_}}
77
78 ${_SUBST_COOKIE.${_class_}}:
79         ${_PKG_SILENT}${_PKG_DEBUG}                                     \
80         cd ${WRKSRC:Q};                                                 \
81         files=${SUBST_FILES.${_class_}:Q};                              \
82         for file in $$files; do                                         \
83                 file="./$$file";                                        \
84                 tmpfile="$$file"${_SUBST_BACKUP_SUFFIX:Q};              \
85                 if ${_SUBST_IS_TEXT_FILE}; then                         \
86                         ${MV} -f "$$file" "$$tmpfile" || exit 1;        \
87                         ${CAT} "$$tmpfile"                              \
88                         | ${SUBST_FILTER_CMD.${_class_}}                \
89                         > "$$file";                                     \
90                         if ${TEST} -x "$$tmpfile"; then                 \
91                                 ${CHMOD} +x "$$file";                   \
92                         fi;                                             \
93                         if ${CMP} -s "$$tmpfile" "$$file"; then         \
94                                 ${MV} -f "$$tmpfile" "$$file";          \
95                         else                                            \
96                                 ${SUBST_POSTCMD.${_class_}};            \
97                                 ${ECHO} "$$file" >> ${.TARGET};         \
98                         fi;                                             \
99                 fi;                                                     \
100         done
101 .endfor