1 # $NetBSD: check-files.mk,v 1.23 2008/02/08 23:13:35 adrianp Exp $
3 # This file checks that the list of installed files matches the PLIST.
4 # For that purpose it records the file list of LOCALBASE before and
5 # after the installation of the package and compares these lists with
8 # User-settable variables:
11 # "yes" to enable the check, "no" to disable it.
13 # Default value: "yes" for PKG_DEVELOPERs, "no" otherwise.
16 # When set to "yes", VARBASE and PKG_SYSCONFDIR are checked in
17 # addition to LOCALBASE.
19 # Package-settable variables:
22 # A list of regular expressions (FIXME: all other checks use shell
23 # patterns) that names files to be skipped. This is useful to
24 # avoid getting errors triggered by changes in directories not
25 # really handled by pkgsrc.
28 _VARGROUPS+= check-files
29 _USER_VARS.check-files= CHECK_FILES CHECK_FILES_STRICT
30 _PKG_VARS.check-files= CHECK_FILES_SKIP
32 .if defined(PKG_DEVELOPER)
36 CHECK_FILES_STRICT?= no
38 # Info index files updated when a new info file is added.
39 .if defined(INFO_FILES)
40 CHECK_FILES_SKIP+= ${PREFIX}/.*/dir
43 # Perl's perllocal.pod index that is regenerated when a local module
46 CHECK_FILES_SKIP+= ${PERL5_INSTALLARCHLIB}/perllocal.pod
48 # R's index files that are regenerated when a local module
51 CHECK_FILES_SKIP+= ${PREFIX}/lib/R/doc/html/packages.html
52 CHECK_FILES_SKIP+= ${PREFIX}/lib/R/doc/html/search/index.txt
54 CHECK_FILES_SKIP+= ${PKG_DBDIR}/.*
56 # We don't care about what's under linux/proc and linux32/proc in Linux
57 # emulation, which just holds run-time generated data.
59 CHECK_FILES_SKIP+= ${PREFIX}/emul/linux/proc.*
60 CHECK_FILES_SKIP+= ${PREFIX}/emul/linux32/proc.*
62 # The reference-count meta-data directory used by the pkginstall framework.
63 CHECK_FILES_SKIP+= ${PKG_DBDIR}.refcount.*
65 # Some people have their distfiles and binary packages below ${LOCALBASE}.
66 CHECK_FILES_SKIP+= ${PACKAGES}/.*
67 CHECK_FILES_SKIP+= ${DISTDIR}/.*
69 # For unprivileged builds, VARBASE is below LOCALBASE.
70 .if !empty(CHECK_FILES_STRICT:M[Nn][Oo])
71 CHECK_FILES_SKIP+= ${VARBASE}/.*
74 # File that are outside of ${PREFIX} in directories we already know we'll
75 # be using for mutable data.
77 .for d in ${MAKE_DIRS} ${OWN_DIRS}
78 CHECK_FILES_SKIP+= ${d:C/^([^\/])/${PREFIX}\/\1/}.*
80 .for d o g m in ${MAKE_DIRS_PERMS} ${OWN_DIRS_PERMS}
81 CHECK_FILES_SKIP+= ${d:C/^([^\/])/${PREFIX}\/\1/}.*
84 # Mutable X11 font database files
85 .if (defined(FONTS_DIRS.x11) && !empty(FONTS_DIRS.x11:M*))
86 CHECK_FILES_SKIP+= ${PREFIX}/.*/encodings.dir
87 CHECK_FILES_SKIP+= ${PREFIX}/.*/fonts.dir
89 .if (defined(FONTS_DIRS.ttf) && !empty(FONTS_DIRS.ttf:M*)) || \
90 (defined(FONTS_DIRS.type1) && !empty(FONTS_DIRS.type1:M*))
91 CHECK_FILES_SKIP+= ${PREFIX}/.*/fonts.scale
93 .if (defined(FONTS_DIRS.ttf) && !empty(FONTS_DIRS.ttf:M*)) || \
94 (defined(FONTS_DIRS.type1) && !empty(FONTS_DIRS.type1:M*)) || \
95 (defined(FONTS_DIRS.x11) && !empty(FONTS_DIRS.x11:M*))
96 CHECK_FILES_SKIP+= ${PREFIX}/.*/fonts.cache-1
99 # Mutable charset.alias file
100 CHECK_FILES_SKIP+= ${PREFIX}/lib/charset.alias
102 _CHECK_FILES_SKIP_FILTER= ${GREP} -vx ${CHECK_FILES_SKIP:@f@-e ${DESTDIR:Q}${f:Q}@}
104 ###########################################################################
105 # These are the files generated and used by the check-files implementation
106 # used across several check-files targets.
108 # _CHECK_FILES_ERRMSG.* are the files that contain the error
109 # messages discovered during each stage of file-checking.
111 # _CHECK_FILES_PRE.* are the file lists generated before any files
112 # from the package are installed.
114 # _CHECK_FILES_POST.* are the file lists generated after all files
115 # from the package are installed.
117 # The "pre" and "post" file lists are compared against each other to
118 # determine if the package is installing files where it shouldn't be.
120 _CHECK_FILES_ERRMSG.prefix= ${ERROR_DIR}/check-files-prefix
121 _CHECK_FILES_PRE.prefix= ${WRKDIR}/.prefix.pre
122 _CHECK_FILES_POST.prefix= ${WRKDIR}/.prefix.post
124 _CHECK_FILES_ERRMSG.sysconfdir= ${ERROR_DIR}/.check-files-sysconfdir
125 _CHECK_FILES_PRE.sysconfdir= ${WRKDIR}/.sysconfdir.pre
126 _CHECK_FILES_POST.sysconfdir= ${WRKDIR}/.sysconfdir.post
128 _CHECK_FILES_ERRMSG.varbase= ${ERROR_DIR}/.check-files-varbase
129 _CHECK_FILES_PRE.varbase= ${WRKDIR}/.varbase.pre
130 _CHECK_FILES_POST.varbase= ${WRKDIR}/.varbase.post
132 _CHECK_FILES_ERRMSGS= # empty
133 _CHECK_FILES_ERRMSGS+= ${_CHECK_FILES_ERRMSG.prefix}
134 .if empty(CHECK_FILES_STRICT:M[nN][oO])
135 _CHECK_FILES_ERRMSGS+= ${_CHECK_FILES_ERRMSG.sysconfdir}
136 _CHECK_FILES_ERRMSGS+= ${_CHECK_FILES_ERRMSG.varbase}
139 ###########################################################################
140 # _CHECK_FILES_PRE holds the list of targets that are built as part of
141 # building the check-files-pre target. These targets should cause the
142 # "pre" file lists to be generated.
144 _CHECK_FILES_PRE= check-files-pre-message
145 _CHECK_FILES_PRE+= ${_CHECK_FILES_PRE.prefix}
146 .if empty(CHECK_FILES_STRICT:M[nN][oO])
147 _CHECK_FILES_PRE+= ${_CHECK_FILES_PRE.sysconfdir}
148 _CHECK_FILES_PRE+= ${_CHECK_FILES_PRE.varbase}
151 ###########################################################################
152 # _CHECK_FILES_POST holds the list of targets that are built as part of
153 # building the check-files-post target. These targets should cause the
154 # "post" file lists to be generated.
156 _CHECK_FILES_POST= check-files-post-message
157 _CHECK_FILES_POST+= ${_CHECK_FILES_POST.prefix}
158 .if empty(CHECK_FILES_STRICT:M[nN][oO])
159 _CHECK_FILES_POST+= ${_CHECK_FILES_POST.sysconfdir}
160 _CHECK_FILES_POST+= ${_CHECK_FILES_POST.varbase}
163 .if empty(CHECK_FILES:M[nN][oO])
164 privileged-install-hook: check-files
167 ###########################################################################
168 # check-files-pre and check-files-post targets and subtargets
170 .PHONY: check-files-pre check-files-post
171 check-files-pre: ${_CHECK_FILES_PRE}
172 check-files-post: ${_CHECK_FILES_POST}
174 .PHONY: check-files-pre-message check-files-post-message
175 check-files-pre-message:
176 @${STEP_MSG} "Generating pre-install file lists"
178 check-files-post-message:
179 @${STEP_MSG} "Generating post-install file lists"
181 ${_CHECK_FILES_PRE.prefix} ${_CHECK_FILES_POST.prefix}:
183 ${FIND} ${DESTDIR}${PREFIX}/. \( -type f -o -type l \) -print 2>/dev/null \
184 | ${SED} -e 's,/\./,/,' \
185 | ${_CHECK_FILES_SKIP_FILTER} \
186 | ${SORT} > ${.TARGET} \
189 ${_CHECK_FILES_PRE.sysconfdir} ${_CHECK_FILES_POST.sysconfdir}:
191 ${FIND} ${DESTDIR}${PKG_SYSCONFDIR}/. -print 2>/dev/null \
192 | ${SED} -e 's,/\./,/,' \
193 | ${_CHECK_FILES_SKIP_FILTER} \
194 | ${SORT} > ${.TARGET} \
197 ${_CHECK_FILES_PRE.varbase} ${_CHECK_FILES_POST.varbase}:
199 ${FIND} ${DESTDIR}${VARBASE}/. -print 2>/dev/null \
200 | ${SED} -e 's,/\./,/,' \
201 | ${_CHECK_FILES_SKIP_FILTER} \
202 | ${SORT} > ${.TARGET} \
205 ###########################################################################
206 # check-files targets and subtargets
208 .PHONY: check-files-prefix check-files-sysconfdir check-files-varbase
209 check-files-prefix: ${_CHECK_FILES_ERRMSG.prefix}
210 check-files-sysconfdir: ${_CHECK_FILES_ERRMSG.sysconfdir}
211 check-files-varbase: ${_CHECK_FILES_ERRMSG.varbase}
213 # The check-files target looks at the cookie files generated by the
214 # check-files-* subtargets, and if they are non-empty, then they
215 # contain the error messages collected during the build of each
219 .if !empty(CHECK_FILES_SUPPORTED:M[nN][oO])
223 check-files: check-files-message ${_CHECK_FILES_ERRMSGS} error-check
226 .PHONY: check-files-message
228 @${STEP_MSG} "Checking file-check results for ${PKGNAME}"
230 # Check ${PREFIX} for files which are not listed in the generated ${PLIST}
233 _CHECK_FILES_DIFF= ${WRKDIR}/.check_files_diff
234 _CHECK_FILES_ADDED= ${WRKDIR}/.check_files_added
235 _CHECK_FILES_DELETED= ${WRKDIR}/.check_files_deleted
236 _CHECK_FILES_EXPECTED= ${WRKDIR}/.check_files_expected
237 _CHECK_FILES_MISSING= ${WRKDIR}/.check_files_missing
238 _CHECK_FILES_MISSING_SKIP= ${WRKDIR}/.check_files_missing_skip
239 _CHECK_FILES_MISSING_REAL= ${WRKDIR}/.check_files_missing_real
240 _CHECK_FILES_EXTRA= ${WRKDIR}/.check_files_extra
242 ${_CHECK_FILES_DIFF}: ${_CHECK_FILES_PRE.prefix} ${_CHECK_FILES_POST.prefix}
244 ${DIFF} -u ${_CHECK_FILES_PRE.prefix} \
245 ${_CHECK_FILES_POST.prefix} \
246 > ${.TARGET} || ${TRUE}
248 ${_CHECK_FILES_ADDED}: ${_CHECK_FILES_DIFF}
250 ${GREP} '^+/' ${_CHECK_FILES_DIFF} | ${SED} "s|^+||" | ${SORT} \
253 ${_CHECK_FILES_DELETED}: ${_CHECK_FILES_DIFF}
255 ${GREP} '^-/' ${_CHECK_FILES_DIFF} | ${SED} "s|^-||" | ${SORT} \
258 ${_CHECK_FILES_EXPECTED}: plist
260 ${GREP} '^[^@]' ${PLIST} | ${SED} "s|^|${DESTDIR}${PREFIX}/|" | ${SORT} \
263 ${_CHECK_FILES_MISSING}: ${_CHECK_FILES_EXPECTED} ${_CHECK_FILES_ADDED}
265 ${DIFF} -u ${_CHECK_FILES_EXPECTED} ${_CHECK_FILES_ADDED} | \
266 ${GREP} '^-[^-]' | ${SED} "s|^-||" | \
267 while read file; do \
268 ${TEST} -f "$$file" -o -h "$$file" || ${ECHO} "$$file"; \
271 ${_CHECK_FILES_MISSING_REAL}: ${_CHECK_FILES_MISSING}
273 ${CAT} ${_CHECK_FILES_MISSING} | ${_CHECK_FILES_SKIP_FILTER} \
274 > ${.TARGET} || ${TRUE}
276 ${_CHECK_FILES_MISSING_SKIP}: \
277 ${_CHECK_FILES_MISSING} \
278 ${_CHECK_FILES_MISSING_REAL}
280 ${DIFF} -u ${_CHECK_FILES_MISSING} \
281 ${_CHECK_FILES_MISSING_REAL} | \
282 ${GREP} '^-[^-]' | ${SED} "s|^-||" \
285 ${_CHECK_FILES_EXTRA}: ${_CHECK_FILES_EXPECTED} ${_CHECK_FILES_ADDED}
287 ${DIFF} -u ${_CHECK_FILES_EXPECTED} ${_CHECK_FILES_ADDED} | \
288 ${GREP} '^+[^+]' | ${SED} "s|^+||" | \
289 while read file; do \
290 ${TEST} ! -f "$$file" -a ! -h "$$file" || ${ECHO} "$$file"; \
293 ${_CHECK_FILES_ERRMSG.prefix}: \
294 ${_CHECK_FILES_DELETED} \
295 ${_CHECK_FILES_MISSING} \
296 ${_CHECK_FILES_MISSING_REAL} \
297 ${_CHECK_FILES_MISSING_SKIP} \
298 ${_CHECK_FILES_EXTRA}
299 ${RUN}${RM} -f ${.TARGET}
301 if ${_NONZERO_FILESIZE_P} ${_CHECK_FILES_DELETED}; then \
302 ${ECHO} "The following files have been deleted" \
304 ${SED} "s|^| |" ${_CHECK_FILES_DELETED}; \
307 if ${_NONZERO_FILESIZE_P} ${_CHECK_FILES_MISSING_REAL}; then \
308 ${ECHO} "************************************************************"; \
309 ${ECHO} "The following files are in the" \
310 "PLIST but not in ${PREFIX}:"; \
311 ${SED} "s|^| |" ${_CHECK_FILES_MISSING_REAL}; \
314 if ${_NONZERO_FILESIZE_P} ${_CHECK_FILES_EXTRA}; then \
315 ${ECHO} "************************************************************"; \
316 ${ECHO} "The following files are in" \
317 "${PREFIX} but not in the PLIST:"; \
318 ${SED} "s|^| |" ${_CHECK_FILES_EXTRA}; \
321 if ${_NONZERO_FILESIZE_P} ${_CHECK_FILES_MISSING_SKIP}; then \
322 ${ECHO} "************************************************************"; \
323 ${ECHO} "The following files are in both the" \
324 "PLIST and CHECK_FILES_SKIP:"; \
325 ${SED} "s|^| |" ${_CHECK_FILES_MISSING_SKIP}; \
328 # Check ${SYSCONFDIR} for files which are not in the PLIST and are also
329 # not copied into place by the INSTALL scripts.
331 ${_CHECK_FILES_ERRMSG.sysconfdir}: \
332 ${_CHECK_FILES_PRE.sysconfdir} \
333 ${_CHECK_FILES_POST.sysconfdir}
335 if ${CMP} -s ${_CHECK_FILES_PRE.sysconfdir} \
336 ${_CHECK_FILES_POST.sysconfdir}; then \
339 ${ECHO} "************************************************************"; \
340 ${ECHO} "The package has modified ${PKG_SYSCONFDIR}" \
341 "contents directly!"; \
342 ${ECHO} " The offending files/directories are:"; \
343 ${DIFF} -u ${_CHECK_FILES_PRE.sysconfdir} \
344 ${_CHECK_FILES_POST.sysconfdir} | \
345 ${GREP} '^+[^+]' | ${SED} "s|^+| |"; \
348 # Check ${VARBASE} for files which are not in the PLIST and are also
349 # not created by the INSTALL scripts.
351 ${_CHECK_FILES_ERRMSG.varbase}: \
352 ${_CHECK_FILES_PRE.varbase} \
353 ${_CHECK_FILES_POST.varbase}
355 if ${CMP} -s ${_CHECK_FILES_PRE.varbase} \
356 ${_CHECK_FILES_POST.varbase}; then \
359 ${ECHO} "************************************************************"; \
360 ${ECHO} "The package has modified ${VARBASE}" \
361 "contents directly!"; \
362 ${ECHO} " The offending files/directories are:"; \
363 ${DIFF} -u ${_CHECK_FILES_PRE.varbase} \
364 ${_CHECK_FILES_POST.varbase} | \
365 ${GREP} '^+[^+]' | ${SED} "s|^+| |"; \
368 ###########################################################################
369 # check-files-clean removes the state files related to the "check-files"
370 # target so that the check-files-{pre,post} targets may be re-run.
372 .PHONY: check-files-clean
373 check-clean: check-files-clean
376 ${RM} -f ${_CHECK_FILES_ERRMSGS} \
377 ${_CHECK_FILES_PRE} ${_CHECK_FILES_POST} \
378 ${_CHECK_FILES_DIFF} ${_CHECK_FILES_ADDED} \
379 ${_CHECK_FILES_DELETED} ${_CHECK_FILES_EXPECTED} \
380 ${_CHECK_FILES_MISSING} ${_CHECK_FILES_MISSING_SKIP} \
381 ${_CHECK_FILES_MISSING_REAL} ${_CHECK_FILES_EXTRA}