summaryrefslogtreecommitdiff
path: root/mk/check
diff options
context:
space:
mode:
authorjoerg <joerg@pkgsrc.org>2007-08-20 11:04:02 +0000
committerjoerg <joerg@pkgsrc.org>2007-08-20 11:04:02 +0000
commit80b8a5c96a24a3fb11b403a8320758d53fbb9414 (patch)
tree2f8068d6d67d1624c24dea7975d212687e312302 /mk/check
parent4e5efdff41d717b0a4d4ea2c0c0baed845ecd6e5 (diff)
downloadpkgsrc-80b8a5c96a24a3fb11b403a8320758d53fbb9414.tar.gz
Add a cross-compile and DESTDIR safe alternative to ldd for
check-shlibs. This allows more stricter detection (e.g. it checks whether the package links against a build dependency). It also checks whether the rpath contains wrkdir references (like qt3-libs). It depends on readelf and is only available for ELF systems for now. To test it, add USE_CHECK_SHLIBS_ELF to mk.conf. Supported-by: Google SoC 2007
Diffstat (limited to 'mk/check')
-rw-r--r--mk/check/bsd.check-vars.mk7
-rw-r--r--mk/check/check-shlibs-elf.awk112
-rw-r--r--mk/check/check-shlibs.mk25
3 files changed, 142 insertions, 2 deletions
diff --git a/mk/check/bsd.check-vars.mk b/mk/check/bsd.check-vars.mk
index 7794e6dc4dd..5e23cffcf0a 100644
--- a/mk/check/bsd.check-vars.mk
+++ b/mk/check/bsd.check-vars.mk
@@ -1,4 +1,4 @@
-# $NetBSD: bsd.check-vars.mk,v 1.3 2006/06/09 16:12:08 jlam Exp $
+# $NetBSD: bsd.check-vars.mk,v 1.4 2007/08/20 11:04:02 joerg Exp $
#
# This Makefile fragment is included separately by bsd.pkg.mk and
# defines some variables which must be defined earlier than where
@@ -7,5 +7,10 @@
CHECK_FILES_SUPPORTED?= yes
CHECK_SHLIBS_SUPPORTED?= yes
+USE_CHECK_SHLIBS_ELF?= no
USE_TOOLS+= awk cat cmp diff echo find grep rm sed test touch true
+
+.if !empty(USE_CHECK_SHLIBS_ELF:M[yY][eE][sS])
+USE_TOOLS+= readelf
+.endif
diff --git a/mk/check/check-shlibs-elf.awk b/mk/check/check-shlibs-elf.awk
new file mode 100644
index 00000000000..d421cb4cefe
--- /dev/null
+++ b/mk/check/check-shlibs-elf.awk
@@ -0,0 +1,112 @@
+function shquote(IN, out) {
+ out = IN;
+ gsub("\\\\", "\\\\", out);
+ gsub("\\\n", "\\n", out);
+ gsub("\\\t", "\\t", out);
+ gsub(" ", "\\ ", out);
+ gsub("'", "\\'", out);
+ gsub("`", "\\`", out);
+ gsub("\"", "\\\"", out);
+ gsub(";", "\\;", out);
+ gsub("&", "\\&", out);
+ gsub("<", "\\<", out);
+ gsub(">", "\\>", out);
+ gsub("\\(", "\\(", out);
+ gsub("\\)", "\\)", out);
+ gsub("\\|", "\\|", out);
+ gsub("\\*", "\\*", out);
+ gsub("\\?", "\\?", out);
+ gsub("\\{", "\\{", out);
+ gsub("\\}", "\\}", out);
+ gsub("\\[", "\\[", out);
+ gsub("\\]", "\\]", out);
+ gsub("\\$", "\\$", out);
+ gsub("!", "\\!", out);
+ gsub("#", "\\#", out);
+ gsub("\\^", "\\^", out);
+ gsub("~", "\\~", out);
+ return out;
+}
+
+function check_pkg(DSO, pkg) {
+ if (destdir == "")
+ return 0
+ cmd = pkg_info_cmd " -Fe " shquote(DSO) " 2> /dev/null"
+ if ((cmd | getline pkg) < 0) {
+ close(cmd)
+ return 0
+ }
+ close(cmd)
+ if (pkg == "")
+ return 0
+ while ((getline < depends_file) > 0) {
+ if ($3 == pkg) {
+ if ($1 != "full")
+ print DSO ": " pkg " is not a runtime dependency"
+ close(depends_file)
+ return 0
+ }
+ }
+ # Not yet:
+ # print DSO ": " pkg " is not a dependency"
+ close(depends_file)
+}
+
+function checkshlib(DSO, needed, rpath, found, dso_rath, got_rpath) {
+ cmd = readelf " -Wd " shquote(DSO) " 2> /dev/null"
+ while ((cmd | getline) > 0) {
+ if ($2 == "(RPATH)") {
+ sub("^[[:space:]]*0[xX][[:xdigit:]]+[[:space:]]+\\(RPATH\\)[[:space:]]+Library rpath: \\[", "")
+ dso_rpath = substr($0, 1, length($0) - 1)
+ if (length(system_rpath) > 0)
+ split(dso_rpath ":" system_rpath, rpath, ":")
+ else
+ split(dso_rpath, rpath, ":")
+ got_rpath = 1
+ }
+ if ($2 == "(NEEDED)") {
+ sub("^[[:space:]]*0[xX][[:xdigit:]]+[[:space:]]+\\(NEEDED\\)[[:space:]]+Shared library: \\[", "")
+ needed[substr($0, 1, length($0) - 1)] = ""
+ }
+ }
+ if (!got_rpath)
+ split(system_rpath, rpath, ":")
+ close(cmd)
+ for (p in rpath) {
+ if (rpath[p] == wrkdir ||
+ substr(rpath[p], 1, length(wrkdir) + 1) == wrkdir "/") {
+ print DSO ": rpath relative to WRKDIR"
+ }
+ }
+ for (lib in needed) {
+ for (p in rpath) {
+ if (!system("test -f " shquote(cross_destdir rpath[p] "/" lib))) {
+ check_pkg(rpath[p] "/" lib)
+ found = 1
+ break
+ }
+ if (!system("test -f " shquote(destdir rpath[p] "/" lib))) {
+ found = 1
+ break
+ }
+ }
+ if (found == 0)
+ print DSO ": missing library: " lib;
+ }
+ delete rpath
+ delete needed
+}
+
+BEGIN {
+ system_rpath = ENVIRON["PLATFORM_RPATH"]
+ cross_destdir = ENVIRON["CROSS_DESTDIR"]
+ destdir = ENVIRON["DESTDIR"]
+ readelf = ENVIRON["PLATFORM_READELF"]
+ wrkdir = ENVIRON["WRKDIR"]
+ pkg_info_cmd = ENVIRON["PKG_INFO_CMD"]
+ depends_file = ENVIRON["DEPENDS_FILE"]
+ if (readelf == "")
+ readelf = "readelf"
+}
+
+{ checkshlib($0); }
diff --git a/mk/check/check-shlibs.mk b/mk/check/check-shlibs.mk
index a1b295c13b2..ef093b8002b 100644
--- a/mk/check/check-shlibs.mk
+++ b/mk/check/check-shlibs.mk
@@ -1,4 +1,4 @@
-# $NetBSD: check-shlibs.mk,v 1.11 2007/04/14 14:17:49 tnn Exp $
+# $NetBSD: check-shlibs.mk,v 1.12 2007/08/20 11:04:03 joerg Exp $
#
# This file verifies that all libraries used by the package can be found
# at run-time.
@@ -38,6 +38,28 @@ _CHECK_SHLIBS_FILELIST_CMD?= ${SED} -e '/^@/d' ${PLIST}
privileged-install-hook: _check-shlibs
.endif
+.if !empty(USE_CHECK_SHLIBS_ELF:M[yY][eE][sS])
+CHECK_SHLIBS_ELF= ${PKGSRCDIR}/mk/check/check-shlibs-elf.awk
+CHECK_SHLIBS_ELF_ENV= PLATFORM_RPATH=/usr/lib
+CHECK_SHLIBS_ELF_ENV+= READELF=${TOOLS_PATH.readelf:Q}
+CHECK_SHLIBS_ELF_ENV+= CROSS_DESTDIR=${_CROSS_DESTDIR:Q}
+CHECK_SHLIBS_ELF_ENV+= PKG_INFO_CMD=${PKG_INFO:Q}
+CHECK_SHLIBS_ELF_ENV+= DEPENDS_FILE=${_RDEPENDS_FILE:Q}
+.if ${_USE_DESTDIR} != "no"
+CHECK_SHLIBS_ELF_ENV+= DESTDIR=${DESTDIR:Q}
+.endif
+CHECK_SHLIBS_ELF_ENV+= WRKDIR=${WRKDIR:Q}
+
+_check-shlibs: error-check .PHONY
+ @${STEP_MSG} "Checking for missing run-time search paths in ${PKGNAME}"
+ ${RUN} rm -f ${ERROR_DIR}/${.TARGET}
+ ${_PKG_SILENT}${_PKG_DEBUG} \
+ cd ${DESTDIR:Q}${PREFIX:Q}; \
+ ${_CHECK_SHLIBS_FILELIST_CMD} | \
+ ${EGREP} -h ${_CHECK_SHLIBS_ERE:Q} | \
+ ${SETENV} ${CHECK_SHLIBS_ELF_ENV} ${AWK} -f ${CHECK_SHLIBS_ELF} > ${ERROR_DIR}/${.TARGET}
+
+.else
_check-shlibs: error-check .PHONY
@${STEP_MSG} "Checking for missing run-time search paths in ${PKGNAME}"
${RUN} rm -f ${ERROR_DIR}/${.TARGET}
@@ -63,3 +85,4 @@ _check-shlibs: error-check .PHONY
${ECHO} " Please fix the package (add -Wl,-R.../lib in the right places)!"; \
${SHCOMMENT} Might not error-out for non-pkg-developers; \
fi
+.endif