summaryrefslogtreecommitdiff
path: root/mk
diff options
context:
space:
mode:
authorjperkin <jperkin@pkgsrc.org>2015-08-17 17:35:23 +0000
committerjperkin <jperkin@pkgsrc.org>2015-08-17 17:35:23 +0000
commit26b4a8ca3328bde29b5b20789fc8f41b3680a19a (patch)
tree919760cb33f7fb2ccf8aec3d92e8257165fc25f7 /mk
parentfeac269ad0c68877eeb61245c485df4b7a0b138f (diff)
downloadpkgsrc-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.mk12
-rw-r--r--mk/check/check-shlibs-macho.awk117
-rw-r--r--mk/check/check-shlibs.mk28
-rw-r--r--mk/platform/Darwin.mk4
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