[79576] branches/gsoc11-post-destroot/base/src/port1.0/portcheckdestroot. tcl
fotanus at macports.org
fotanus at macports.org
Sat Jun 18 19:07:14 PDT 2011
Revision: 79576
http://trac.macports.org/changeset/79576
Author: fotanus at macports.org
Date: 2011-06-18 19:07:13 -0700 (Sat, 18 Jun 2011)
Log Message:
-----------
Added architecture and dynamic library checks
Currently, it uses otool and lipo system calls. We should replace it with
C extensions in order to optimize performance.
Modified Paths:
--------------
branches/gsoc11-post-destroot/base/src/port1.0/portcheckdestroot.tcl
Modified: branches/gsoc11-post-destroot/base/src/port1.0/portcheckdestroot.tcl
===================================================================
--- branches/gsoc11-post-destroot/base/src/port1.0/portcheckdestroot.tcl 2011-06-18 23:27:51 UTC (rev 79575)
+++ branches/gsoc11-post-destroot/base/src/port1.0/portcheckdestroot.tcl 2011-06-19 02:07:13 UTC (rev 79576)
@@ -13,14 +13,14 @@
}
#options
-options destroot.violate_mtree destroot.asroot
+options destroot.violate_mtree destroot.asroot depends_lib
#defaults
default destroot.violate_mtree no
+default destroot.depends_lib {}
set_ui_prefix
-
# Starting procedure from checkdestroot phase. Check for permissions.
proc portcheckdestroot::checkdestroot_start {args} {
if { [getuid] == 0 && [geteuid] != 0 } {
@@ -36,18 +36,57 @@
# List all links on a directory recursively. This function is for internal use.
proc portcheckdestroot::links_list {dir} {
+ return [types_list $dir "l"]
+}
+
+# List all links on a directory recursively. This function is for internal use.
+proc portcheckdestroot::files_list {dir} {
+ return [types_list $dir "f"]
+}
+
+# List all files of a type on a directory recursively. This function is for internal use.
+proc portcheckdestroot::types_list {dir type} {
set ret {}
- foreach item [glob -nocomplain -type {d l} -directory $dir *] {
+ foreach item [glob -nocomplain -type "d $type" -directory $dir *] {
if {[file isdirectory $item]} {
- set ret [concat $ret [links_list $item]]
+ set ret [concat $ret [types_list $item $type]]
} else {
- #is link
+ #is from the correct type
lappend ret $item
}
}
return $ret
}
+# Get files from a list. For internal use only
+proc portcheckdestroot::get_files { list } {
+ set files {}
+ foreach element $list {
+ if { [regexp {^/?[A-Za-z0-9\.-]+(/[A-Za-z0-9\.-]+)*$} $element] } {
+ if { [file exists $element] } {
+ lappend files $element
+ }
+ }
+ }
+ return $files
+}
+
+# List dependencies from the current package
+proc portcheckdestroot::get_dependencies {} {
+ global destroot destroot.depends_lib subport depends_lib
+ set deps {}
+ if {[info exists depends_lib]} {
+ foreach dep [set depends_lib] {
+ set dep_portname [_get_dep_port $dep]
+ if {$dep_portname != ""} {
+ set dep_portname [_get_dep_port $dep]
+ lappend deps $dep_portname
+ }
+ }
+ }
+ return $deps
+}
+
# Check for errors on port symlinks
proc portcheckdestroot::checkdestroot_symlink {} {
global UI_PREFIX destroot prefix
@@ -158,11 +197,84 @@
}
}
+# Check for dynamic links that aren't in the dependency list
+proc portcheckdestroot::checkdestroot_libs {} {
+ global destroot destroot.depends_lib subport depends_lib UI_PREFIX
+ ui_notice "$UI_PREFIX Checking for wrong dynamic links"
+
+ #Files that don't need to be alerted if not on dependencies.
+ #TODO: Compile these files (and move for configuration folder?)
+ set dep_whitelist {/usr/lib/libSystem.B.dylib}
+
+ #Get dependencies files list.
+ set dep_files {}
+ foreach dep [get_dependencies] {
+ lappend dep_files [get_files [exec port contents $dep]]
+ }
+ set dep_files [concat $dep_files $dep_whitelist]
+
+ #Get package files
+ foreach file [files_list $destroot] {
+ if { [file executable "$file"] } {
+ #Check it dinamic links with otool
+ foreach line [split [exec -keepnewline otool -L $file] "\n"] {
+ #match they with dependency files
+ if { [regexp {\(.*} $line] } {
+ set lib [string trim [regsub {\(.*} $line ""]]
+ if { [regexp $lib $file] } {
+ ui_debug "skipping, should be the file itself"
+ } else {
+ if { [regexp $lib [join $dep_files]] } {
+ ui_debug "$lib binary dependency is met"
+ } else {
+ return -code error "$lib binary dependencies are NOT met"
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+#For the given archs, check if the files from destroot are compatible
+proc portcheckdestroot::checkdestroot_arches { archs } {
+ global destroot
+ foreach file [files_list $destroot] {
+ if { [file executable "$file"] } {
+ set lipo_arches [checkdestroot_get_lipo_arches $file]
+ # Chekcs if every arch is present on the lipo output
+ foreach arch $archs {
+ if { [regexp $arch $lipo_arches] == 0 } {
+ return -code error "$file supports the arch $arch, and should not"
+ }
+ }
+ }
+ }
+}
+
+# Recover the arches from a file, from it's lipo output. For internal use only.
+proc portcheckdestroot::checkdestroot_get_lipo_arches { file } {
+ set lipo_output [exec lipo -info $file]
+ return [regsub "Architectures in the.*are:" $lipo_output ""]
+}
+
+# Check for arch constraints
+proc portcheckdestroot::checkdestroot_arch {} {
+ global UI_PREFIX
+ ui_notice "$UI_PREFIX Checking for archs"
+ set archs [get_canonical_archs]
+ if { "archs" != "noarch" } {
+ checkdestroot_arches $archs
+ }
+}
+
proc portcheckdestroot::checkdestroot_main {args} {
global UI_PREFIX
ui_notice "$UI_PREFIX Executing check-destroot phase"
checkdestroot_symlink
checkdestroot_mtree
+ checkdestroot_libs
+ checkdestroot_arch
return 0
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20110618/3f34f334/attachment-0001.html>
More information about the macports-changes
mailing list