Add lang/perl5 early, but not specifically as part of BULK_PREREQ, so that
[pkgsrc.git] / mk / bsd.pkg.patch.mk
1 # $NetBSD: bsd.pkg.patch.mk,v 1.19 2005/09/28 10:06:05 rillig Exp $
2 #
3 # This Makefile fragment is included by bsd.pkg.mk and defines the
4 # relevant variables and targets for the "patch" phase.
5 #
6 # The following variables may be set in a package Makefile and control
7 # how pkgsrc patches are applied.
8 #
9 #    PATCH_STRIP is a patch(1) argument that sets the pathname strip
10 #       count to help find the correct files to patch.  See the patch(1)
11 #       man page for more details.  Defaults to "-p0".
12 #
13 #    PATCH_ARGS is the base set of arguments passed to patch(1).
14 #       The default set of arguments will apply the patches to the
15 #       files in ${WRKSRC} with any ${PATCH_STRIP} arguments set.
16 #
17 # The following variables may be set in a package Makefile and control
18 # how "distribution" patches are applied.
19 #
20 #    PATCHFILES is a list of distribution patches relative to
21 #       ${_DISTDIR} that are applied first to the package.
22 #
23 #    PATCH_DIST_STRIP is a patch(1) argument that sets the pathname
24 #       strip count to help find the correct files to patch.  See the
25 #       patch(1) man page for more details.  Defaults to "-p0".
26 #
27 #    PATCH_DIST_ARGS is the base set of arguments passed to patch(1).
28 #       The default set of arguments will apply the patches to the
29 #       files in ${WRKSRC} with any ${PATCH_DIST_STRIP} arguments set.
30 #
31 #    PATCH_DIST_CAT is the command that outputs the contents of the
32 #       "$patchfile" to stdout.  The default value is a command that
33 #       can output gzipped, bzipped, or plain patches to stdout.
34 #
35 #    PATCH_DIST_STRIP.<patchfile>
36 #    PATCH_DIST_ARGS.<patchfile>
37 #    PATCH_DIST_CAT.<patchfile>
38 #       These are versions of the previous three variables which allow
39 #       for customization of their values for specific patchfiles.
40 #
41 # The following variables may be set by the user and affect how patching
42 # occurs:
43 #
44 #    PATCH_DEBUG, if defined, causes the the patch process to be more
45 #       verbose.
46 #
47 #    PATCH_FUZZ_FACTOR is a patch(1) argument that specifies how much
48 #       fuzz to accept when applying pkgsrc patches.  See the patch(1)
49 #       man page for more details.  Defaults to "-F0" for zero fuzz.
50 #
51 #    LOCALPATCHES is the location of local patches that are maintained
52 #       in a directory tree reflecting the same hierarchy as the pkgsrc
53 #       tree, e.g., local patches for www/apache would be found in
54 #       ${LOCALPATCHES}/www/apache.  These patches are applied after
55 #       the patches in ${PATCHDIR}.
56 #
57 # The following targets are defined by bsd.pkg.patch.mk:
58 #
59 #    do-patch is the target that causes the actual patching of the
60 #       extracted sources to occur during the "patch" phase.
61 #
62
63 .if (defined(PATCHFILES) && !empty(PATCHFILES)) || \
64     (defined(PATCHDIR) && exists(${PATCHDIR})) || \
65     (defined(LOCALPATCHES) && exists(${LOCALPATCHES}/${PKGPATH}))
66 USE_TOOLS+=     patch
67 .endif
68
69 # These tools are used to output the contents of the distribution patches
70 # to stdout.
71 #
72 .if defined(PATCHFILES)
73 USE_TOOLS+=     cat
74 .  if !empty(PATCHFILES:M*.Z) || !empty(PATCHFILES:M*.gz)
75 USE_TOOLS+=     gzcat
76 .  endif
77 .  if !empty(PATCHFILES:M*.bz2)
78 USE_TOOLS+=     bzcat
79 .  endif
80 .endif
81
82 .if defined(PATCH_DEBUG) || defined(PKG_VERBOSE)
83 _PATCH_DEBUG=           yes
84 ECHO_PATCH_MSG?=        ${ECHO_MSG}
85 .else
86 _PATCH_DEBUG=           no
87 ECHO_PATCH_MSG?=        ${TRUE}
88 .endif
89
90 PATCH_STRIP?=           -p0
91 .if !empty(_PATCH_DEBUG:M[yY][eE][sS])
92 PATCH_ARGS?=            -d ${WRKSRC} -E ${PATCH_STRIP}
93 .else
94 PATCH_ARGS?=            -d ${WRKSRC} --forward --quiet -E ${PATCH_STRIP}
95 .endif
96 .if defined(BATCH)
97 PATCH_ARGS+=            --batch
98 .endif
99 .if defined(_PATCH_CAN_BACKUP) && (${_PATCH_CAN_BACKUP} == "yes")
100 PATCH_ARGS+=            ${_PATCH_BACKUP_ARG} .orig
101 .endif
102 PATCH_FUZZ_FACTOR?=     -F0     # Default to zero fuzz
103
104 # The following variables control how "distribution" patches are extracted
105 # and applied to the package sources.
106 #
107 # PATCH_DIST_STRIP is a patch option that sets the pathname strip count.
108 # PATCH_DIST_ARGS is the list of arguments to pass to the patch command.
109 # PATCH_DIST_CAT is the command that outputs the patch to stdout.
110 #
111 # For each of these variables, there is a patch-specific variant that
112 # may be set, i.e. PATCH_DIST_STRIP.<patch>, PATCH_DIST_ARGS.<patch>,
113 # PATCH_DIST_CAT.<patch>.
114 #
115 PATCH_DIST_STRIP?=              -p0
116 .for i in ${PATCHFILES}
117 PATCH_DIST_STRIP.${i:S/=/--/}?= ${PATCH_DIST_STRIP}
118 .  if defined(PATCH_DIST_ARGS)
119 PATCH_DIST_ARGS.${i:S/=/--/}?=  ${PATCH_DIST_ARGS}
120 .  elif !empty(_PATCH_DEBUG:M[yY][eE][sS])
121 PATCH_DIST_ARGS.${i:S/=/--/}?=  -d ${WRKSRC} -E ${PATCH_DIST_STRIP.${i:S/=/--/}}
122 .  else
123 PATCH_DIST_ARGS.${i:S/=/--/}?=  -d ${WRKSRC} --forward --quiet -E ${PATCH_DIST_STRIP.${i:S/=/--/}}
124 .  endif
125 .endfor
126 .if defined(BATCH)
127 PATCH_DIST_ARGS+=               --batch
128 .  for i in ${PATCHFILES}
129 PATCH_DIST_ARGS.${i:S/=/--/}+=  --batch
130 .  endfor
131 .endif
132 .if defined(_PATCH_CAN_BACKUP) && (${_PATCH_CAN_BACKUP} == "yes")
133 PATCH_DIST_ARGS+=               ${_PATCH_BACKUP_ARG} .orig_dist
134 .  for i in ${PATCHFILES}
135 PATCH_DIST_ARGS.${i:S/=/--/}+=  ${_PATCH_BACKUP_ARG} .orig_dist
136 .  endfor
137 .endif
138 PATCH_DIST_CAT?=        { case $$patchfile in                           \
139                           *.Z|*.gz) ${GZCAT} $$patchfile ;;             \
140                           *.bz2)    ${BZCAT} $$patchfile ;;             \
141                           *)        ${CAT} $$patchfile ;;               \
142                           esac; }
143 .for i in ${PATCHFILES}
144 PATCH_DIST_CAT.${i:S/=/--/}?=   { patchfile=${i}; ${PATCH_DIST_CAT}; }
145 .endfor
146
147 _PKGSRC_PATCH_TARGETS=  uptodate-digest
148 .if defined(PATCHFILES)
149 _PKGSRC_PATCH_TARGETS+= distribution-patch-message do-distribution-patch
150 .endif
151 .if (defined(PATCHDIR) && exists(${PATCHDIR})) || \
152     (defined(LOCALPATCHES) && exists(${LOCALPATCHES}/${PKGPATH}))
153 _PKGSRC_PATCH_TARGETS+= pkgsrc-patch-message do-pkgsrc-patch
154 .endif
155
156 .PHONY: do-patch
157 .if !target(do-patch)
158 .ORDER: ${_PKGSRC_PATCH_TARGETS}
159 do-patch: ${_PKGSRC_PATCH_TARGETS}
160 .endif
161
162 _PKGSRC_PATCH_FAIL=                                                     \
163 if ${TEST} -n ${PKG_OPTIONS:Q}"" ||                                     \
164    ${TEST} -n ${LOCALPATCHES:Q}"" -a -d ${LOCALPATCHES:Q}/${PKGPATH:Q}; then \
165         ${ECHO} "=========================================================================="; \
166         ${ECHO};                                                        \
167         ${ECHO} "Some of the selected build options and/or local patches may be incompatible."; \
168         ${ECHO} "Please try building with fewer options or patches.";   \
169         ${ECHO};                                                        \
170         ${ECHO} "=========================================================================="; \
171 fi; exit 1
172
173 _PATCH_COOKIE_TMP=      ${_PATCH_COOKIE}.tmp
174 _GENERATE_PATCH_COOKIE= \
175         if ${TEST} -f ${_PATCH_COOKIE_TMP:Q}; then                      \
176                 ${CAT} ${_PATCH_COOKIE_TMP:Q} >> ${_PATCH_COOKIE:Q};    \
177                 ${RM} -f ${_PATCH_COOKIE_TMP:Q};                        \
178         else                                                            \
179                 ${TOUCH} ${TOUCH_FLAGS} ${_PATCH_COOKIE:Q};             \
180         fi
181
182 .PHONY: distribution-patch-message do-distribution-patch
183
184 distribution-patch-message:
185         @${ECHO_MSG} "${_PKGSRC_IN}> Applying distribution patches for ${PKGNAME}"
186
187 .if !target(do-distribution-patch)
188 do-distribution-patch:
189 .  for i in ${PATCHFILES}
190         @${ECHO_PATCH_MSG} "${_PKGSRC_IN}> Applying distribution patch ${i}"
191         ${_PKG_SILENT}${_PKG_DEBUG}cd ${_DISTDIR};                      \
192         ${PATCH_DIST_CAT.${i:S/=/--/}} |                                \
193         ${PATCH} ${PATCH_DIST_ARGS.${i:S/=/--/}}                        \
194                 || { ${ECHO} "Patch ${i} failed"; ${_PKGSRC_PATCH_FAIL}; }
195         ${_PKG_SILENT}${_PKG_DEBUG}${ECHO} ${i:Q} >> ${_PATCH_COOKIE_TMP:Q}
196 .  endfor
197 .endif
198
199 _PKGSRC_PATCHES=        # empty
200 .if defined(PATCHDIR) && exists(${PATCHDIR})
201 _PKGSRC_PATCHES+=       ${PATCHDIR}/patch-*
202 .endif
203 .if defined(LOCALPATCHES) && exists(${LOCALPATCHES}/${PKGPATH})
204 _PKGSRC_PATCHES+=       ${LOCALPATCHES}/${PKGPATH}/*
205 .endif
206
207 .PHONY: pkgsrc-patch-message do-pkgsrc-patch
208
209 pkgsrc-patch-message:
210         @${ECHO_MSG} "${_PKGSRC_IN}> Applying pkgsrc patches for ${PKGNAME}"
211
212 .if !target(do-pkgsrc-patch)
213 do-pkgsrc-patch:
214         ${_PKG_SILENT}${_PKG_DEBUG}                                     \
215         fail=;                                                          \
216         patches=${_PKGSRC_PATCHES:Q};                                   \
217         patch_warning() {                                               \
218                 ${ECHO_MSG} "**************************************";   \
219                 ${ECHO_MSG} "$$1";                                      \
220                 ${ECHO_MSG} "**************************************";   \
221         };                                                              \
222         for i in $$patches; do                                          \
223                 ${TEST} -f "$$i" || continue;                           \
224                 case "$$i" in                                           \
225                 *.orig|*.rej|*~)                                        \
226                         ${ECHO_MSG} "${_PKGSRC_IN}> Ignoring patchfile $$i"; \
227                         continue;                                       \
228                         ;;                                              \
229                 ${PATCHDIR}/patch-local-*)                              \
230                         ;;                                              \
231                 ${PATCHDIR}/patch-*)                                    \
232                         if ${TEST} ! -f ${DISTINFO_FILE:Q}; then        \
233                                 patch_warning "Ignoring patch file $$i: distinfo not found"; \
234                                 continue;                               \
235                         fi;                                             \
236                         filename=`${BASENAME} $$i`;                     \
237                         algsum=`${AWK} '(NF == 4) && ($$2 == "('$$filename')") && ($$3 == "=") {print $$1 " " $$4}' ${DISTINFO_FILE} || ${TRUE}`; \
238                         if ${TEST} -z "$$algsum"; then                  \
239                                 patch_warning "Ignoring patch file $$i: no checksum found"; \
240                                 continue;                               \
241                         fi;                                             \
242                         set -- $$algsum;                                \
243                         alg="$$1";                                      \
244                         recorded="$$2";                                 \
245                         calcsum=`${SED} -e '/\$$NetBSD.*/d' $$i | ${DIGEST} $$alg`; \
246                         ${ECHO_PATCH_MSG} "=> Verifying $$filename (using digest algorithm $$alg)"; \
247                         if ${TEST} "$$calcsum" != "$$recorded"; then    \
248                                 patch_warning "Ignoring patch file $$i: invalid checksum"; \
249                                 fail="$$fail $$i";                      \
250                                 continue;                               \
251                         fi;                                             \
252                         ;;                                              \
253                 esac;                                                   \
254                 ${ECHO_PATCH_MSG} "${_PKGSRC_IN}> Applying pkgsrc patch $$i"; \
255                 fuzz_flags=;                                            \
256                 if ${PATCH} -v >/dev/null 2>&1; then                    \
257                         fuzz_flags=${PATCH_FUZZ_FACTOR:Q};              \
258                 fi;                                                     \
259                 if ${PATCH} $$fuzz_flags ${PATCH_ARGS} < $$i; then      \
260                         ${ECHO} "$$i" >> ${_PATCH_COOKIE_TMP:Q};        \
261                 else                                                    \
262                         ${ECHO_MSG} "Patch $$i failed";                 \
263                         fail="$$fail $$i";                              \
264                 fi;                                                     \
265         done;                                                           \
266         if ${TEST} -n "$$fail"; then                                    \
267                 ${ECHO_MSG} "Patching failed due to modified or broken patch file(s):"; \
268                 for i in $$fail; do                                     \
269                         ${ECHO_MSG} "   $$i";                           \
270                 done;                                                   \
271                 ${_PKGSRC_PATCH_FAIL};                                  \
272         fi
273 .endif