[81754] branches/gsoc11-rev-upgrade/base/src/macports1.0/macports.tcl

cal at macports.org cal at macports.org
Thu Aug 4 10:48:47 PDT 2011


Revision: 81754
          http://trac.macports.org/changeset/81754
Author:   cal at macports.org
Date:     2011-08-04 10:48:47 -0700 (Thu, 04 Aug 2011)
Log Message:
-----------
rev-upgrade: Handle macros in loadcommands, handle some broken ports (GitX installing precompiled binaries...)

Modified Paths:
--------------
    branches/gsoc11-rev-upgrade/base/src/macports1.0/macports.tcl

Modified: branches/gsoc11-rev-upgrade/base/src/macports1.0/macports.tcl
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/macports1.0/macports.tcl	2011-08-04 17:43:22 UTC (rev 81753)
+++ branches/gsoc11-rev-upgrade/base/src/macports1.0/macports.tcl	2011-08-04 17:48:47 UTC (rev 81754)
@@ -3807,7 +3807,7 @@
 
         set i 1
         foreach b $binaries {
-            ui_debug "Scanning binary $i of [llength $binaries]: [$b path]"
+            ui_debug "$i/[llength $binaries]: [$b path]"
             incr i
 
             set resultlist [machista::parse_file $handle [$b path]]
@@ -3815,7 +3815,12 @@
             set result     [lindex $resultlist 1]
 
             if {$returncode != $machista::SUCCESS} {
-                ui_info "Error parsing file [$b path]: [machista::strerror $returncode]"
+                if {$returncode == $machista::EMAGIC} {
+                    # not a Mach-O file
+                    ui_debug "Error parsing file [$b path]: [machista::strerror $returncode]"
+                } else {
+                    ui_warn "Error parsing file [$b path]: [machista::strerror $returncode]"
+                }
                 continue;
             }
 
@@ -3824,18 +3829,24 @@
                 set loadcommand [$architecture cget -mat_loadcmds]
 
                 while {$loadcommand != "NULL"} {
-                    set libresultlist [machista::parse_file $handle [$loadcommand cget -mlt_install_name]]
+                    if {0 != [catch {set filepath [revupgrade_handle_special_paths [$b path] [$loadcommand cget -mlt_install_name]]}]} {
+                        set loadcommand [$loadcommand cget -next]
+                        continue;
+                    }
+
+                    set libresultlist [machista::parse_file $handle $filepath]
                     set libreturncode [lindex $libresultlist 0]
                     set libresult     [lindex $libresultlist 1]
 
                     # if {[string first "/usr/" [$loadcommand cget -mlt_install_name]] == 0} {
                     #     # TODO: Filter whitelist
-                    #     ui_warn "File links against /usr/*: `[$b path]' links against `[$loadcommand cget -mlt_install_name]'"
+                    #     ui_warn "File links against /usr/*: [$b path] links against [$loadcommand cget -mlt_install_name]"
                     # }
 
                     if {$libreturncode != $machista::SUCCESS} {
-                        ui_info "Could not open `[$loadcommand cget -mlt_install_name]': [machista::strerror $libreturncode]"
+                        ui_warn "Could not open $filepath: [machista::strerror $libreturncode]"
                         if {$libreturncode == $machista::EFILE} {
+                            ui_debug "Marking [$b path] as broken"
                             lappend broken_files [$b path]
                         }
                         set loadcommand [$loadcommand cget -next]
@@ -3851,8 +3862,9 @@
                         }
 
                         if {[$loadcommand cget -mlt_version] != [$libarchitecture cget -mat_version] && [$loadcommand cget -mlt_comp_version] != [$libarchitecture cget -mat_comp_version]} {
-                            ui_info "Incompatible library version of file `[$loadcommand cget -mlt_install_name]': Expected [$loadcommand cget -mlt_comp_version], but got [$libarchitecture cget -mat_comp_version]"
-                            lappend broken_files [$architecture cget -mat_install_name]
+                            ui_warn "Incompatible library version of file [$loadcommand cget -mlt_install_name]: Expected [$loadcommand cget -mlt_comp_version], but got [$libarchitecture cget -mat_comp_version]"
+                            ui_debug "Marking [$b path] as broken"
+                            lappend broken_files [$b path]
                         }
 
                         set libarch_found true;
@@ -3860,8 +3872,14 @@
                     }
 
                     if {$libarch_found == false} {
-                        ui_info "Missing architecture [$architecture cget -mat_arch] in file `[$loadcommand cget -mlt_install_name]'"
-                        lappend broken_files [$architecture cget -mat_install_name]
+                        ui_debug "Missing architecture [$architecture cget -mat_arch] in file $filepath"
+                        if {[path_is_in_prefix $filepath]} {
+                            ui_debug "Marking [$b path] as broken"
+                            lappend broken_files [$b path]
+                        } else {
+                            ui_warn "Missing architecture [$architecture cget -mat_arch] in file outside prefix referenced from [$b path]"
+                            ui_warn "   How did you get that compiled anyway?"
+                        }
                     }
                     set loadcommand [$loadcommand cget -next]
                 }
@@ -3881,7 +3899,7 @@
         foreach file $broken_files {
             set port [registry::entry owner $file]
             if {$port == ""} {
-                ui_error "Broken file `$file' doesn't belong to any port."
+                ui_error "Broken file $file doesn't belong to any port."
             }
             lappend broken_ports $port
         }
@@ -3987,6 +4005,44 @@
     return 0;
 }
 
+# Return whether a path is in the macports prefix
+# Usage: path_is_in_prefix path_to_test
+# Returns true if the path is in the prefix, false otherwise
+proc path_is_in_prefix {path} {
+    return [string first $macports::prefix $path] == 0 || [string first $macports::applications_dir $path] == 0
+}
+
+# Function to replace macros in loadcommand paths with their proper values (which are usually determined at load time)
+# Usage: revupgrade_handle_special_paths name_of_file path_from_loadcommand
+# Returns the corrected path on success or an error in case of failure.
+# Note that we can't reliably replace @executable_path, because it's only clear when executing a file where it was executed from.
+# Replacing @rpath does not work yet, but it might be possible to get it working using the rpath attribute in the file containing the
+# loadcommand
+proc revupgrade_handle_special_paths {fname path} {
+    set corrected_path $path
+
+    set loaderpath_idx [string first "@loader_path" $corrected_path]
+    if {$loaderpath_idx != -1} {
+        set corrected_path [string replace $corrected_path $loaderpath_idx $loaderpath_idx+11 [file dirname $fname]]
+    }
+
+    set executablepath_idx [string first "@executable_path" $corrected_path]
+    if {$executablepath_idx != -1} {
+        ui_warn "Ignoring loadcommand containing @exectuable_path in $fname"
+        error "@exectuable_path in loadcommand"
+    }
+
+    set rpath_idx [string first "@rpath" $corrected_path]
+    if {$rpath_idx != -1} {
+        ui_warn "Ignoring loadcommand containing @rpath in $fname"
+        error "@rpath in loadcommand"
+    }
+
+    return $corrected_path
+}
+
+# Recursively build the dependency graph between broken ports
+# Usage: revupgrade_buildgraph start_port name_of_stack name_of_adjacency_list name_of_reverse_adjacency_list name_of_visited_map
 proc revupgrade_buildgraph {port stackname adjlistname revadjlistname visitedname} {
     upvar $stackname stack
     upvar $adjlistname adjlist
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20110804/06c92079/attachment.html>


More information about the macports-changes mailing list