diff options
author | joerg <joerg@pkgsrc.org> | 2007-08-20 11:04:02 +0000 |
---|---|---|
committer | joerg <joerg@pkgsrc.org> | 2007-08-20 11:04:02 +0000 |
commit | 80b8a5c96a24a3fb11b403a8320758d53fbb9414 (patch) | |
tree | 2f8068d6d67d1624c24dea7975d212687e312302 /mk | |
parent | 4e5efdff41d717b0a4d4ea2c0c0baed845ecd6e5 (diff) | |
download | pkgsrc-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')
-rw-r--r-- | mk/check/bsd.check-vars.mk | 7 | ||||
-rw-r--r-- | mk/check/check-shlibs-elf.awk | 112 | ||||
-rw-r--r-- | mk/check/check-shlibs.mk | 25 |
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 |