diff options
author | jperkin <jperkin@pkgsrc.org> | 2015-08-17 17:35:23 +0000 |
---|---|---|
committer | jperkin <jperkin@pkgsrc.org> | 2015-08-17 17:35:23 +0000 |
commit | 26b4a8ca3328bde29b5b20789fc8f41b3680a19a (patch) | |
tree | 919760cb33f7fb2ccf8aec3d92e8257165fc25f7 /mk | |
parent | feac269ad0c68877eeb61245c485df4b7a0b138f (diff) | |
download | pkgsrc-26b4a8ca3328bde29b5b20789fc8f41b3680a19a.tar.gz |
Introduce support for checking Mach-O dynamic libraries.
This works in a similar way to the ELF checks, but uses otool(1) to list the
library name and its dependencies, and the checks fail if there are WRKDIR
references or if the -install_name of the library does not match $PREFIX, as
well as ensuring that any libraries from pkgsrc are correctly registered as
full dependencies.
Removes support for the user to set USE_CHECK_SHLIBS_ELF, but there were no
reasonable reasons for doing so in the past anyway, and it may be masking
issues in platform files we should fix.
Diffstat (limited to 'mk')
-rw-r--r-- | mk/check/bsd.check-vars.mk | 12 | ||||
-rw-r--r-- | mk/check/check-shlibs-macho.awk | 117 | ||||
-rw-r--r-- | mk/check/check-shlibs.mk | 28 | ||||
-rw-r--r-- | mk/platform/Darwin.mk | 4 |
4 files changed, 140 insertions, 21 deletions
diff --git a/mk/check/bsd.check-vars.mk b/mk/check/bsd.check-vars.mk index 4dfadc74ef7..d7cc59e24fe 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.7 2009/07/26 05:32:43 agc Exp $ +# $NetBSD: bsd.check-vars.mk,v 1.8 2015/08/17 17:35:23 jperkin Exp $ # # This Makefile fragment is included separately by bsd.pkg.mk and # defines some variables which must be defined earlier than where @@ -8,14 +8,10 @@ CHECK_FILES_SUPPORTED?= yes CHECK_SHLIBS_SUPPORTED?= yes -.if ${_OPSYS_CAN_CHECK_SHLIBS} == "yes" -USE_CHECK_SHLIBS_ELF?= yes +.if ${_OPSYS_CAN_CHECK_SHLIBS:tl} == "yes" +_USE_CHECK_SHLIBS_NATIVE= yes .else -USE_CHECK_SHLIBS_ELF?= no +_USE_CHECK_SHLIBS_NATIVE= no .endif 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-macho.awk b/mk/check/check-shlibs-macho.awk new file mode 100644 index 00000000000..543c040d3ae --- /dev/null +++ b/mk/check/check-shlibs-macho.awk @@ -0,0 +1,117 @@ +# $NetBSD: check-shlibs-macho.awk,v 1.1 2015/08/17 17:35:23 jperkin Exp $ + +# +# Read a list of potential Mach-O binaries from stdin. +# For each, check the list of required DSOs and ensure that each of them can +# be found correctly, and check that any pkgsrc-installed DSOs belong to a +# full dependency. +# + +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, found) { + if (destdir == "") + return 0 + if (DSO in pkgcache) { + pkg = pkgcache[DSO] + } else { + cmd = pkg_info_cmd " -Fe " shquote(DSO) " 2>/dev/null" + if ((cmd | getline pkg) < 0) { + close(cmd) + return 0 + } + close(cmd) + pkgcache[DSO] = pkg + } + if (pkg == "") + return 0 + found=0 + while ((getline < depends_file) > 0) { + if ($3 == pkg) { + found=1 + if ($1 != "full") + continue + close(depends_file) + return 0 + } + } + if (found) + print DSO ": " pkg " is not a runtime dependency" + close(depends_file) +} + +function checkshlib(DSO, needed, found) { + cmd = "otool -XL " shquote(DSO) " 2>/dev/null" + while ((cmd | getline) > 0) { + needed[$1] = "" + } + close(cmd) + ndirs = split(cross_destdir ":" destdir, check_dirs, ":") + for (lib in needed) { + # + # Ensure we don't have any WRKDIR references. + # + if (lib == wrkdir || + substr(lib, 1, length(wrkdir) + 1) == wrkdir "/") { + print DSO ": path relative to WRKDIR: " lib + break + } + # + # Check destination dirs for library existence. If found in a + # system path (cross_destdir is somewhat confusing but if set + # it points to the populated cross destdir, otherwise we are + # checking '/') then check_pkg() ensures it is a runtime dep. + # + for (i = 1; i <= ndirs; i++) { + libfile = check_dirs[i] lib + if (!(libfile in libcache)) + libcache[libfile] = system("test -f " \ + shquote(libfile)) + if (libcache[libfile] == 0) { + check_pkg(lib) + found = 1 + break + } + } + if (found == 0) + print DSO ": missing library: " lib + } +} + +BEGIN { + cross_destdir = ENVIRON["CROSS_DESTDIR"] + destdir = ENVIRON["DESTDIR"] + wrkdir = ENVIRON["WRKDIR"] + pkg_info_cmd = ENVIRON["PKG_INFO_CMD"] + depends_file = ENVIRON["DEPENDS_FILE"] +} + +{ checkshlib($0); } diff --git a/mk/check/check-shlibs.mk b/mk/check/check-shlibs.mk index 2f7f5074678..b05143af83d 100644 --- a/mk/check/check-shlibs.mk +++ b/mk/check/check-shlibs.mk @@ -1,4 +1,4 @@ -# $NetBSD: check-shlibs.mk,v 1.25 2015/08/17 16:39:13 jperkin Exp $ +# $NetBSD: check-shlibs.mk,v 1.26 2015/08/17 17:35:23 jperkin Exp $ # # This file verifies that all libraries used by the package can be found # at run-time. @@ -50,17 +50,23 @@ _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=${_OPSYS_SYSTEM_RPATH:Q} -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=${_RRDEPENDS_FILE:Q} +.if ${_USE_CHECK_SHLIBS_NATIVE} == "yes" +CHECK_SHLIBS_NATIVE_ENV= +. if ${OBJECT_FMT} == "ELF" +USE_TOOLS+= readelf +CHECK_SHLIBS_NATIVE= ${PKGSRCDIR}/mk/check/check-shlibs-elf.awk +CHECK_SHLIBS_NATIVE_ENV+= PLATFORM_RPATH=${_OPSYS_SYSTEM_RPATH:Q} +CHECK_SHLIBS_NATIVE_ENV+= READELF=${TOOLS_PATH.readelf:Q} +. elif ${OBJECT_FMT} == "Mach-O" +CHECK_SHLIBS_NATIVE= ${PKGSRCDIR}/mk/check/check-shlibs-macho.awk +. endif +CHECK_SHLIBS_NATIVE_ENV+= CROSS_DESTDIR=${_CROSS_DESTDIR:Q} +CHECK_SHLIBS_NATIVE_ENV+= PKG_INFO_CMD=${PKG_INFO:Q} +CHECK_SHLIBS_NATIVE_ENV+= DEPENDS_FILE=${_RRDEPENDS_FILE:Q} . if ${_USE_DESTDIR} != "no" -CHECK_SHLIBS_ELF_ENV+= DESTDIR=${DESTDIR:Q} +CHECK_SHLIBS_NATIVE_ENV+= DESTDIR=${DESTDIR:Q} . endif -CHECK_SHLIBS_ELF_ENV+= WRKDIR=${WRKDIR:Q} +CHECK_SHLIBS_NATIVE_ENV+= WRKDIR=${WRKDIR:Q} _check-shlibs: error-check .PHONY @${STEP_MSG} "Checking for missing run-time search paths in ${PKGNAME}" @@ -76,7 +82,7 @@ _check-shlibs: error-check .PHONY esac; \ ${ECHO} $$file; \ done | \ - ${PKGSRC_SETENV} ${CHECK_SHLIBS_ELF_ENV} ${AWK} -f ${CHECK_SHLIBS_ELF} > ${ERROR_DIR}/${.TARGET} + ${PKGSRC_SETENV} ${CHECK_SHLIBS_NATIVE_ENV} ${AWK} -f ${CHECK_SHLIBS_NATIVE} > ${ERROR_DIR}/${.TARGET} .else . if ${_USE_DESTDIR} != "no" diff --git a/mk/platform/Darwin.mk b/mk/platform/Darwin.mk index 2fa7520d33d..3354c4c8634 100644 --- a/mk/platform/Darwin.mk +++ b/mk/platform/Darwin.mk @@ -1,4 +1,4 @@ -# $NetBSD: Darwin.mk,v 1.68 2015/07/01 17:47:14 tron Exp $ +# $NetBSD: Darwin.mk,v 1.69 2015/08/17 17:35:23 jperkin Exp $ # # Variable definitions for the Darwin operating system. @@ -139,7 +139,7 @@ _OPSYS_WHOLE_ARCHIVE_FLAG= -Wl,--whole-archive _OPSYS_NO_WHOLE_ARCHIVE_FLAG= -Wl,--no-whole-archive .endif -_OPSYS_CAN_CHECK_SHLIBS= no # can't use readelf in check/bsd.check-vars.mk +_OPSYS_CAN_CHECK_SHLIBS= yes # check shared libraries using otool(1) _STRIPFLAG_CC?= ${_INSTALL_UNSTRIPPED:D:U-Wl,-x} # cc(1) option to strip _STRIPFLAG_INSTALL?= ${_INSTALL_UNSTRIPPED:D:U-s} # install(1) option to strip |