[80618] branches/gsoc11-post-destroot/base/src

fotanus at macports.org fotanus at macports.org
Fri Jul 15 16:02:26 PDT 2011


Revision: 80618
          http://trac.macports.org/changeset/80618
Author:   fotanus at macports.org
Date:     2011-07-15 16:02:25 -0700 (Fri, 15 Jul 2011)
Log Message:
-----------
Added macos C extension

*) to get the dynamic libraries from an binary
*) to get the arches from an binary

The C and Tcl codes needs a cleanup and more comments.

Modified Paths:
--------------
    branches/gsoc11-post-destroot/base/src/pextlib1.0/Makefile
    branches/gsoc11-post-destroot/base/src/pextlib1.0/Pextlib.c
    branches/gsoc11-post-destroot/base/src/port1.0/portcheckdestroot.tcl

Added Paths:
-----------
    branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.c
    branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.h

Modified: branches/gsoc11-post-destroot/base/src/pextlib1.0/Makefile
===================================================================
--- branches/gsoc11-post-destroot/base/src/pextlib1.0/Makefile	2011-07-15 22:07:24 UTC (rev 80617)
+++ branches/gsoc11-post-destroot/base/src/pextlib1.0/Makefile	2011-07-15 23:02:25 UTC (rev 80618)
@@ -3,7 +3,7 @@
 	fs-traverse.o strcasecmp.o vercomp.o filemap.o base32cmd.o \
 	sha1cmd.o curl.o rmd160cmd.o sha256cmd.o readline.o uid.o \
 	tracelib.o tty.o readdir.o pipe.o flock.o \
-	system.o mktemp.o realpath.o
+	system.o mktemp.o realpath.o macho.o
 SHLIB_NAME= Pextlib${SHLIB_SUFFIX}
 INSTALLDIR= ${DESTDIR}${datadir}/macports/Tcl/pextlib1.0
 

Modified: branches/gsoc11-post-destroot/base/src/pextlib1.0/Pextlib.c
===================================================================
--- branches/gsoc11-post-destroot/base/src/pextlib1.0/Pextlib.c	2011-07-15 22:07:24 UTC (rev 80617)
+++ branches/gsoc11-post-destroot/base/src/pextlib1.0/Pextlib.c	2011-07-15 23:02:25 UTC (rev 80618)
@@ -78,6 +78,7 @@
 #include "system.h"
 #include "mktemp.h"
 #include "realpath.h"
+#include "macho.h"
 
 #if HAVE_CRT_EXTERNS_H
 #include <crt_externs.h>
@@ -513,6 +514,8 @@
 	Tcl_CreateObjCommand(interp, "uname_to_gid", uname_to_gidCmd, NULL, NULL);
 	Tcl_CreateObjCommand(interp, "name_to_gid", name_to_gidCmd, NULL, NULL);
 	Tcl_CreateObjCommand(interp, "gid_to_name", gid_to_nameCmd, NULL, NULL);
+	Tcl_CreateObjCommand(interp, "list_dlibs", list_dlibs, NULL, NULL);
+	Tcl_CreateObjCommand(interp, "list_archs", list_archs, NULL, NULL);
 
 	Tcl_CreateObjCommand(interp, "tracelib", TracelibCmd, NULL, NULL);
 	Tcl_CreateObjCommand(interp, "isatty", IsattyCmd, NULL, NULL);

Added: branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.c
===================================================================
--- branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.c	                        (rev 0)
+++ branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.c	2011-07-15 23:02:25 UTC (rev 80618)
@@ -0,0 +1,409 @@
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <err.h>
+#include <string.h>
+
+#include <mach-o/arch.h>
+#include <mach-o/loader.h>
+#include <mach-o/fat.h>
+
+#include <libkern/OSAtomic.h>
+
+#include <tcl.h>
+
+#include "macho.h"
+Tcl_Interp *interp2;
+typedef struct macho_input {
+	const void *data;
+	size_t length;
+} macho_input_t;
+
+/* Verify that the given range is within bounds. */
+static const void *macho_read (macho_input_t *input, const void *address, size_t length) {
+	if ((((uint8_t *) address) - ((uint8_t *) input->data)) + length > input->length) {
+		warnx("Short read parsing Mach-O input");
+		return NULL;
+	}
+
+	return address;
+}
+
+/* Verify that address + offset + length is within bounds. */
+static const void *macho_offset (macho_input_t *input, const void *address, size_t offset, size_t length) {
+	void *result = ((uint8_t *) address) + offset;
+	return macho_read(input, result, length);
+}
+
+/* return a human readable formatted version number. the result must be free()'d. */
+char *macho_format_dylib_version (uint32_t version) {
+	char *result;
+	asprintf(&result, "%"PRIu32".%"PRIu32".%"PRIu32, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);
+	return result;
+}
+
+/* Some byteswap wrappers */
+static uint32_t macho_swap32 (uint32_t input) {
+	return OSSwapInt32(input);
+}
+
+static uint32_t macho_nswap32(uint32_t input) {
+	return input;
+}
+
+/* Parse a Mach-O header */
+Tcl_Obj * list_macho_dlibs_l (macho_input_t *input, Tcl_Obj * dlibs) {
+	/* Read the file type. */
+	const uint32_t *magic = macho_read(input, input->data, sizeof(uint32_t));
+
+	/* Parse the Mach-O header */
+	bool m64 = false;
+	bool universal = false;
+	uint32_t (*swap32)(uint32_t) = macho_nswap32;
+
+	const struct mach_header *header;
+	const struct mach_header_64 *header64;
+	size_t header_size;
+	const struct fat_header *fat_header;
+
+	const NXArchInfo *archInfo;
+	const struct load_command *cmd;
+	uint32_t ncmds;
+	uint32_t i;
+
+
+	if (magic == NULL)
+		return TCL_ERROR;
+
+	switch (*magic) {
+		case MH_CIGAM:
+			swap32 = macho_swap32;
+			/* Fall-through */
+
+		case MH_MAGIC:
+			header_size = sizeof(*header);
+			header = macho_read(input, input->data, header_size);
+			if (header == NULL) {
+				return false;
+			}
+			break;
+
+		case MH_CIGAM_64:
+			swap32 = macho_swap32;
+			/* Fall-through */
+
+		case MH_MAGIC_64:
+			header_size = sizeof(*header64);
+			header64 = macho_read(input, input->data, sizeof(*header64));
+			if (header64 == NULL)
+				return false;
+
+			/* The 64-bit header is a direct superset of the 32-bit header */
+
+			header = (struct mach_header *) header64;
+
+			m64 = true;
+			break;
+
+		case FAT_CIGAM:
+		case FAT_MAGIC:
+			fat_header = macho_read(input, input->data, sizeof(*fat_header));
+			universal = true;
+			break;
+
+		default:
+			warnx("Unknown Mach-O magic: 0x%" PRIx32 "", *magic);
+			return false;
+	}
+
+	/* Parse universal file. */
+	if (universal) {
+		uint32_t i;
+		uint32_t nfat = OSSwapBigToHostInt32(fat_header->nfat_arch);
+		const struct fat_arch *archs = macho_offset(input, fat_header, sizeof(struct fat_header), sizeof(struct fat_arch));
+		if (archs == NULL)
+			return false;
+
+		for (i = 0; i < nfat; i++) {
+			const struct fat_arch *arch = macho_read(input, archs + i, sizeof(struct fat_arch));
+			macho_input_t arch_input;
+			if (arch == NULL)
+				return false;
+
+			/* Fetch a pointer to the architecture's Mach-O header. */
+			arch_input.length = OSSwapBigToHostInt32(arch->size);
+			arch_input.data = macho_offset(input, input->data, OSSwapBigToHostInt32(arch->offset), arch_input.length);
+			if (arch_input.data == NULL)
+				return false;
+
+			/* Parse the architecture's Mach-O header */
+			if (!list_macho_dlibs_l(&arch_input,dlibs))
+				return false;
+		}
+
+		return dlibs;
+	}
+
+	/* Fetch the arch name */
+	archInfo = NXGetArchInfoFromCpuType(swap32(header->cputype), swap32(header->cpusubtype));
+
+	/* Parse the Mach-O load commands */
+	cmd = macho_offset(input, header, header_size, sizeof(struct load_command));
+	if (cmd == NULL)
+		return false;
+	ncmds = swap32(header->ncmds);
+
+	/* Iterate over the load commands */
+	for (i = 0; i < ncmds; i++) {
+		/* Load the full command */
+		uint32_t cmdsize = swap32(cmd->cmdsize);
+		cmd = macho_read(input, cmd, cmdsize);
+		if (cmd == NULL)
+			return false;
+
+		/* Handle known types */
+		uint32_t cmd_type = swap32(cmd->cmd);
+		switch (cmd_type) {
+			case LC_RPATH: {
+				/* Fetch the path */
+				if (cmdsize < sizeof(struct rpath_command)) {
+					warnx("Incorrect cmd size");
+					return false;
+				}
+
+				size_t pathlen = cmdsize - sizeof(struct rpath_command);
+				const void *pathptr = macho_offset(input, cmd, sizeof(struct rpath_command), pathlen);
+				if (pathptr == NULL)
+					return false;
+
+				char *path = malloc(pathlen);
+				strlcpy(path, pathptr, pathlen);
+				free(path);
+				break;
+			}
+
+			case LC_ID_DYLIB:
+			case LC_LOAD_WEAK_DYLIB:
+			case LC_REEXPORT_DYLIB:
+			case LC_LOAD_DYLIB: {
+				const struct dylib_command *dylib_cmd = (const struct dylib_command *) cmd;
+
+				/* Extract the install name */
+				if (cmdsize < sizeof(struct dylib_command)) {
+					warnx("Incorrect name size");
+					return false;
+				}
+
+				size_t namelen = cmdsize - sizeof(struct dylib_command);
+				const void *nameptr = macho_offset(input, cmd, sizeof(struct dylib_command), namelen);
+				if (nameptr == NULL)
+					return false;
+
+				char *name = malloc(namelen);
+				strlcpy(name, nameptr, namelen);
+
+				/* This is a dyld library identifier */
+				Tcl_ListObjAppendElement(interp2, dlibs, Tcl_NewStringObj(name, -1));
+
+				free(name);
+				break;
+			}
+
+			default:
+					break;
+		}
+
+		/* Load the next command */
+		cmd = macho_offset(input, cmd, cmdsize, sizeof(struct load_command));
+		if (cmd == NULL)
+			return TCL_ERROR;
+	}
+
+	return dlibs;
+}
+
+Tcl_Obj * list_macho_dlibs(macho_input_t *input) {
+	return list_macho_dlibs_l(input, Tcl_NewListObj(0,NULL));
+}
+
+/* List Mach-O archs */
+Tcl_Obj * list_macho_archs_l(macho_input_t *input, Tcl_Obj * archs_list) {
+	/* Read the file type. */
+	const uint32_t *magic = macho_read(input, input->data, sizeof(uint32_t));
+	if (magic == NULL)
+		return false;
+
+	/* Parse the Mach-O header */
+	bool universal = false;
+	uint32_t (*swap32)(uint32_t) = macho_nswap32;
+
+	const struct mach_header *header;
+	const struct mach_header_64 *header64;
+	size_t header_size;
+	const struct fat_header *fat_header;
+
+	switch (*magic) {
+		case MH_CIGAM:
+			swap32 = macho_swap32;
+			/* Fall-through */
+
+		case MH_MAGIC:
+			header_size = sizeof(*header);
+			header = macho_read(input, input->data, header_size);
+			if (header == NULL) {
+				return TCL_ERROR;
+			}
+			break;
+
+
+		case MH_CIGAM_64:
+			swap32 = macho_swap32;
+			/* Fall-through */
+
+		case MH_MAGIC_64:
+			header_size = sizeof(*header64);
+			header64 = macho_read(input, input->data, sizeof(*header64));
+			if (header64 == NULL)
+				return TCL_ERROR;
+
+			/* The 64-bit header is a direct superset of the 32-bit header */
+			header = (struct mach_header *) header64;
+
+			break;
+
+		case FAT_CIGAM:
+		case FAT_MAGIC:
+			fat_header = macho_read(input, input->data, sizeof(*fat_header));
+			universal = true;
+			break;
+
+		default:
+			warnx("Unknown Mach-O magic: 0x%" PRIx32 "", *magic);
+			return TCL_ERROR;
+	}
+
+	/* Parse universal file. */
+	if (universal) {
+		uint32_t nfat = OSSwapBigToHostInt32(fat_header->nfat_arch);
+		const struct fat_arch *archs = macho_offset(input, fat_header, sizeof(struct fat_header), sizeof(struct fat_arch));
+		if (archs == NULL)
+			return TCL_ERROR;
+
+		uint32_t i;
+		for (i = 0; i < nfat; i++) {
+			const struct fat_arch *arch = macho_read(input, archs + i, sizeof(struct fat_arch));
+			if (arch == NULL)
+				return TCL_ERROR;
+
+			/* Fetch a pointer to the architecture's Mach-O header. */
+			macho_input_t arch_input;
+			arch_input.length = OSSwapBigToHostInt32(arch->size);
+			arch_input.data = macho_offset(input, input->data, OSSwapBigToHostInt32(arch->offset), arch_input.length);
+			if (arch_input.data == NULL)
+				return TCL_ERROR;
+
+			/* Parse the architecture's Mach-O header */
+			if (!list_macho_archs_l(&arch_input, archs_list))
+				return TCL_ERROR;
+		}
+
+		return archs_list;
+	}
+
+	/* Fetch the arch name */
+	const NXArchInfo *archInfo = NXGetArchInfoFromCpuType(swap32(header->cputype), swap32(header->cpusubtype));
+	if (archInfo != NULL) {
+		Tcl_ListObjAppendElement(interp2, archs_list, Tcl_NewStringObj(archInfo->name,-1));
+	}
+	return archs_list;
+}
+
+Tcl_Obj * list_macho_archs(macho_input_t *input) {
+	return list_macho_archs_l(input, Tcl_NewListObj(0,NULL));
+}
+
+int list_dlibs(ClientData clientData , Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){
+	const char *path;
+	interp2 = interp;
+
+	if (objc != 2) {
+		Tcl_WrongNumArgs(interp, 1, objv, "directory");
+		return TCL_ERROR;
+	}
+
+	path = Tcl_GetString(objv[1]);
+
+	int fd = open(path, O_RDONLY);
+	if (fd < 0) {
+		return TCL_ERROR;
+	}
+
+	struct stat stbuf;
+	if (fstat(fd, &stbuf) != 0) {
+		return TCL_ERROR;
+	}
+
+	/* mmap */
+	void *data = mmap(NULL, stbuf.st_size, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0);
+	if (data == MAP_FAILED)
+		err(1, "mmap()");
+
+	/* Parse */
+	macho_input_t input_file;
+	input_file.data = data;
+	input_file.length = stbuf.st_size;
+
+	Tcl_Obj * libs = list_macho_dlibs(&input_file);
+
+	munmap(data, stbuf.st_size);
+	close(fd);
+	Tcl_SetObjResult(interp, libs);
+	return TCL_OK;
+}
+
+
+int list_archs(ClientData clientData , Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){
+	interp2 = interp;
+	const char *path;
+
+	if (objc != 2) {
+		Tcl_WrongNumArgs(interp, 1, objv, "directory");
+		return TCL_ERROR;
+	}
+
+	path = Tcl_GetString(objv[1]);
+
+	int fd = open(path, O_RDONLY);
+	if (fd < 0) {
+		return TCL_ERROR;
+	}
+
+	struct stat stbuf;
+	if (fstat(fd, &stbuf) != 0) {
+		return TCL_ERROR;
+	}
+
+	/* mmap */
+	void *data = mmap(NULL, stbuf.st_size, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0);
+	if (data == MAP_FAILED)
+		err(1, "mmap()");
+
+	/* Parse */
+	macho_input_t input_file;
+	input_file.data = data;
+	input_file.length = stbuf.st_size;
+
+	Tcl_Obj * archs = list_macho_archs(&input_file);
+
+	munmap(data, stbuf.st_size);
+	close(fd);
+	Tcl_SetObjResult(interp, archs);
+	return TCL_OK;
+}

Added: branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.h
===================================================================
--- branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.h	                        (rev 0)
+++ branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.h	2011-07-15 23:02:25 UTC (rev 80618)
@@ -0,0 +1,2 @@
+int list_dlibs(ClientData clientData , Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
+int list_archs(ClientData clientData , Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);

Modified: branches/gsoc11-post-destroot/base/src/port1.0/portcheckdestroot.tcl
===================================================================
--- branches/gsoc11-post-destroot/base/src/port1.0/portcheckdestroot.tcl	2011-07-15 22:07:24 UTC (rev 80617)
+++ branches/gsoc11-post-destroot/base/src/port1.0/portcheckdestroot.tcl	2011-07-15 23:02:25 UTC (rev 80618)
@@ -3,6 +3,7 @@
 
 package provide portcheckdestroot 1.0
 package require portutil 1.0
+package require Pextlib 1.0
 
 
 set org.macports.checkdestroot [target_new org.macports.checkdestroot portcheckdestroot::checkdestroot_main]
@@ -150,136 +151,121 @@
     global os.platform applications_dir frameworks_dir
     global UI_PREFIX
 
-    set mtree [findBinary mtree ${portutil::autoconf::mtree_path}]
+        set mtree [findBinary mtree ${portutil::autoconf::mtree_path}]
 
-    # test for violations of mtree
-    if { ${destroot.violate_mtree} != "yes" } {
-        ui_notice "$UI_PREFIX Executing mtree check"
-        ui_debug "checking for mtree violations"
-        set mtree_violation "no"
+        # test for violations of mtree
+        if { ${destroot.violate_mtree} != "yes" } {
+            ui_notice "$UI_PREFIX Executing mtree check"
+            ui_debug "checking for mtree violations"
+            set mtree_violation "no"
 
-        set prefixPaths [list bin etc include lib libexec sbin share src var www Applications Developer Library]
+            set prefixPaths [list bin etc include lib libexec sbin share src var www Applications Developer Library]
 
-        set pathsToCheck [list /]
-        while {[llength $pathsToCheck] > 0} {
-            set pathToCheck [lshift pathsToCheck]
-            foreach file [glob -nocomplain -directory $destroot$pathToCheck .* *] {
-                if {[file tail $file] eq "." || [file tail $file] eq ".."} {
-                    continue
-                }
-                if {[string equal -length [string length $destroot] $destroot $file]} {
-                    # just double-checking that $destroot is a prefix, as is appropriate
-                    set dfile [file join / [string range $file [string length $destroot] end]]
-                } else {
-                    throw MACPORTS "Unexpected filepath `${file}' while checking for mtree violations"
-                }
-                if {$dfile eq $prefix} {
-                    # we've found our prefix
-                    foreach pfile [glob -nocomplain -tails -directory $file .* *] {
-                        if {$pfile eq "." || $pfile eq ".."} {
-                            continue
-                        }
-                        if {[lsearch -exact $prefixPaths $pfile] == -1} {
-                            ui_warn "violation by [file join $dfile $pfile]"
-                            set mtree_violation "yes"
-                        }
+            set pathsToCheck [list /]
+            while {[llength $pathsToCheck] > 0} {
+                set pathToCheck [lshift pathsToCheck]
+                foreach file [glob -nocomplain -directory $destroot$pathToCheck .* *] {
+                    if {[file tail $file] eq "." || [file tail $file] eq ".."} {
+                        continue
                     }
-                } elseif {[string equal -length [expr [string length $dfile] + 1] $dfile/ $prefix]} {
-                    # we've found a subpath of our prefix
-                    lpush pathsToCheck $dfile
-                } else {
-                    set dir_allowed no
-                    # these files are (at least potentially) outside of the prefix
-                    foreach dir "$applications_dir $frameworks_dir /Library/LaunchAgents /Library/LaunchDaemons /Library/StartupItems" {
-                        if {[string equal -length [expr [string length $dfile] + 1] $dfile/ $dir]} {
-                            # it's a prefix of one of the allowed paths
-                            set dir_allowed yes
-                            break
-                        }
+                    if {[string equal -length [string length $destroot] $destroot $file]} {
+                        # just double-checking that $destroot is a prefix, as is appropriate
+                        set dfile [file join / [string range $file [string length $destroot] end]]
+                    } else {
+                        throw MACPORTS "Unexpected filepath `${file}' while checking for mtree violations"
                     }
-                    if {$dir_allowed} {
+                    if {$dfile eq $prefix} {
+                        # we've found our prefix
+                        foreach pfile [glob -nocomplain -tails -directory $file .* *] {
+                            if {$pfile eq "." || $pfile eq ".."} {
+                                continue
+                            }
+                            if {[lsearch -exact $prefixPaths $pfile] == -1} {
+                                ui_warn "violation by [file join $dfile $pfile]"
+                                set mtree_violation "yes"
+                            }
+                        }
+                    } elseif {[string equal -length [expr [string length $dfile] + 1] $dfile/ $prefix]} {
+                        # we've found a subpath of our prefix
                         lpush pathsToCheck $dfile
                     } else {
-                        # not a prefix of an allowed path, so it's either the path itself or a violation
-                        switch -- $dfile \
-                            $applications_dir - \
-                            $frameworks_dir - \
-                            /Library/LaunchAgents - \
-                            /Library/LaunchDaemons - \
-                            /Library/StartupItems { ui_debug "port installs files in $dfile" } \
-                            default {
-                                ui_warn "violation by $dfile"
-                                set mtree_violation "yes"
+                        set dir_allowed no
+                        # these files are (at least potentially) outside of the prefix
+                        foreach dir "$applications_dir $frameworks_dir /Library/LaunchAgents /Library/LaunchDaemons /Library/StartupItems" {
+                            if {[string equal -length [expr [string length $dfile] + 1] $dfile/ $dir]} {
+                                # it's a prefix of one of the allowed paths
+                                set dir_allowed yes
+                                break
                             }
+                        }
+                        if {$dir_allowed} {
+                            lpush pathsToCheck $dfile
+                        } else {
+                            # not a prefix of an allowed path, so it's either the path itself or a violation
+                            switch -- $dfile \
+                                $applications_dir - \
+                                $frameworks_dir - \
+                                /Library/LaunchAgents - \
+                                /Library/LaunchDaemons - \
+                                /Library/StartupItems { ui_debug "port installs files in $dfile" } \
+                                default {
+                                    ui_warn "violation by $dfile"
+                                    set mtree_violation "yes"
+                                }
+                        }
                     }
                 }
             }
-        }
 
-        # abort here only so all violations can be observed
-        if { ${mtree_violation} != "no" } {
-            ui_warn "[format [msgcat::mc "%s violates the layout of the ports-filesystems!"] [option subport]]"
-            ui_warn "Please fix or indicate this misbehavior (if it is intended), it will be an error in future releases!"
-            # error "mtree violation!"
+            # abort here only so all violations can be observed
+            if { ${mtree_violation} != "no" } {
+                ui_warn "[format [msgcat::mc "%s violates the layout of the ports-filesystems!"] [option subport]]"
+                ui_warn "Please fix or indicate this misbehavior (if it is intended), it will be an error in future releases!"
+                # error "mtree violation!"
+            }
+        } else {
+            ui_warn "[format [msgcat::mc "%s installs files outside the common directory structure."] [option subport]]"
         }
-    } else {
-        ui_warn "[format [msgcat::mc "%s installs files outside the common directory structure."] [option subport]]"
     }
-}
 
-# Check for dynamic links that aren't in the dependency list
-proc portcheckdestroot::checkdestroot_libs {} {
-    global destroot prefix UI_PREFIX subport
-    ui_notice "$UI_PREFIX Checking for wrong dynamic links"
+    # Check for dynamic links that aren't in the dependency list
+    proc portcheckdestroot::checkdestroot_libs {} {
+        global destroot prefix UI_PREFIX subport
+        ui_notice "$UI_PREFIX Checking for wrong dynamic links"
 
-    #Folders that don't need to be alerted if not on dependencies.
-    #TODO: Compile whitelist folders
-    set dep_whitelist {/usr/lib/ /System/Library/ /lib/}
+        #Folders that don't need to be alerted if not on dependencies.
+        #TODO: Compile whitelist folders
+        set dep_whitelist {/usr/lib/ /System/Library/ /lib/}
 
-    #Get dependencies files list.
-    set dep_files {}
-    foreach dep [get_dependencies] {
-        lappend dep_files [registry_port_registered $dep]
-    }
-    set self_files [bin_list $destroot$prefix]
-    set dep_files [concat $dep_files $self_files]
+        #Get dependencies files list.
+        set dep_files {}
+        foreach dep [get_dependencies] {
+            lappend dep_files [file tail [registry_port_registered $dep]]
+        }
+        set self_files [bin_list $destroot$prefix]
+        set dep_files [concat $dep_files $self_files]
 
-    #Get package files
-    foreach file [files_list $destroot] {
-        if { [binary? "$file"] } {
-            #Check it dinamic links with otool
-            set otool_output [get_otool_libs $file]
-            if { $otool_output == "ignore" } {
-                ui_debug "Ignoring $file otool output"
-            } else {
-                foreach line [get_otool_libs $file] {
-                    #match they with dependency files
-                    if { [regexp {\(.*} $line] } {
-                        set lib [string trim [regsub {\(.*} $line ""]]
-                        #match against itself
-                        if { [regexp [escape_chars $lib] $file] } {
-                            ui_debug "skipping, should be the file itself"
-                        } else {
-                            #match against dependencies or self files
-                            if { [regexp [escape_chars $lib] [join $dep_files]] } {
-                                ui_debug "$lib binary dependency is met"
-                            } else {
-                                #match file folder agains whitelist
-                                set found 0
-                                foreach dep $dep_whitelist {
-                                    if { [regexp "^$dep" [regsub $prefix $lib ""]] } {
-                                        set found 1
-                                        break
-                                    }
-                                }
-                                if { $found } {
-                                    ui_debug "$lib binary dependency folder is on whitelist"
-                                } else {
-                                    return -code error "$lib binary dependencies are NOT met"
-                                }
-                            }
+
+        #Get package files
+        foreach file [files_list $destroot] {
+            if { [binary? "$file"] } {
+                foreach file_lib [list_dlibs $file] {
+                if { [lsearch $dep_files $file_lib] != -1 } {
+                    ui_debug "$file_lib binary dependency is met"
+                } else {
+                    #match file folder agains whitelist
+                    set found 0
+                    foreach dep $dep_whitelist {
+                        if { [regexp "^$dep" [regsub $prefix $file_lib ""]] } {
+                            set found 1
+                            break
                         }
                     }
+                    if { $found } {
+                        ui_debug "$file_lib binary dependency folder is on whitelist"
+                    } else {
+                        return -code error "$file_lib binary dependencies are NOT met"
+                    }
                 }
             }
         }
@@ -291,15 +277,10 @@
     global destroot
     foreach file [files_list $destroot] {
         if { [binary? "$file"] } {
-            set lipo_arches [get_lipo_arches $file]
-            # Chekcs if every arch is present on the lipo output
-            if { $lipo_arches == "ignore" } {
-                ui_debug "Ignoring arch check for $file"
-            } else {
-                foreach arch $archs {
-                    if { [regexp $arch $lipo_arches] == 0 } {
-                        return -code error "$file supports the arch $arch, and should not"
-                    }
+            set file_archs [list_archs $file]
+            foreach arch $archs {
+                if { [lsearch $file_archs $arch] == -1 } {
+                    return -code error "$file supports the arch $arch, and should not"
                 }
             }
         }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20110715/30007c1e/attachment-0001.html>


More information about the macports-changes mailing list