Changeset 80762
- Timestamp:
- 07/16/11 15:21:19 (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/gsoc11-rev-upgrade/base/src/macports1.0/macports.tcl
r80186 r80762 38 38 package require macports_index 1.0 39 39 package require macports_util 1.0 40 package require machista 1.0 40 41 41 42 namespace eval macports { … … 3759 3760 } 3760 3761 } 3762 3763 set broken_files {}; 3761 3764 set binaries [registry::file search active 1 binary 1] 3762 3765 ui_msg "---> Scanning binaries for linking errors" 3763 set i 1 3764 foreach b $binaries { 3765 ui_debug "Scanning binary $i of [llength $binaries]: [$b path]" 3766 incr i 3767 # TODO: Call something, that will use 3768 # http://www.opensource.apple.com/source/cctools/cctools-800/otool/main.c 3769 # as if it was called with otool -L, thus using 3770 # http://www.opensource.apple.com/source/cctools/cctools-800/libstuff/ofile.c 3771 # and print_libraries from 3772 # http://www.opensource.apple.com/source/cctools/cctools-800/otool/ofile_print.c, 3773 # but don't actually print the libs, but write them into a list and check them for existance and compatibility. 3774 # Maybe implement a cache for libs that have already been checked (because a lot of software links against similar libs) 3775 3776 if {[catch {set otool_output [exec /usr/bin/otool -arch all -L [$b path]]} msg]} { 3777 ui_warn "Error running otool on file [$b path]: $msg" 3778 continue; 3779 } 3780 set otool_lines [split $otool_output "\n"] 3781 set arch "unknown" 3782 foreach otool_line $otool_lines { 3783 if {1 == [regexp -nocase {^Archive} $otool_line]} { 3784 ui_info "Ignoring archive file [$b path]" 3785 break; 3786 } 3787 if {1 == [regexp -nocase {\(architecture ([^\s]+)\)} $otool_line match arch]} { 3788 switch -glob $arch { 3789 x86_64 {} 3790 i386 {} 3791 ppc* {} 3792 default { 3793 ui_warn "Unknown architecture $arch" 3794 } 3795 } 3766 if {[llength $binaries] > 0} { 3767 set handle [machista::create_handle] 3768 if {$handle == "NULL"} { 3769 error "Error creating libmachista handle" 3770 } 3771 3772 set i 1 3773 foreach b $binaries { 3774 ui_debug "Scanning binary $i of [llength $binaries]: [$b path]" 3775 incr i 3776 3777 set resultlist [machista::parse_file $handle [$b path]] 3778 set returncode [lindex $resultlist 0] 3779 set result [lindex $resultlist 1] 3780 3781 if {$returncode != $machista::SUCCESS} { 3782 ui_warn "Error parsing file [$b path]: [machista::strerror $returncode]" 3796 3783 continue; 3797 3784 } 3798 if {$arch == "unknown"} { 3799 ui_warn "Unspecified architecture in file [$b path]" 3800 break; 3801 } 3802 if {1 == [regexp -nocase {^\t([^\s]+) \(compatibility version ([^,]+), current version ([^)]+)\)} $otool_line match file comp_version curr_version]} { 3803 if {$file == [$b path]} { 3804 # library files contain themselves as their first entry in the output of otool -L 3805 continue; 3806 } 3807 ui_debug "Linked against: $file, architecture $arch, version $curr_version, compatibility version $comp_version" 3808 if {[file exists $file]} { 3809 set lib_found false 3810 if {[catch {set lib_install_name [exec /usr/bin/otool -arch $arch -X -D $file]}] == 0} { 3811 if {[catch {set lib_otool_output [exec /usr/bin/otool -arch $arch -X -L $file]}] == 0} { 3812 set lib_otool_lines [split $lib_otool_output "\n"] 3813 foreach lib_otool_line $lib_otool_lines { 3814 if {1 == [regexp -nocase {^\t([^\s]+) \(compatibility version ([^,]+), current version ([^)]+)\)} $lib_otool_line match lib_file lib_comp_version lib_curr_version]} { 3815 # call with -D to get install name, search for install name in -L output 3816 if {$lib_install_name == $lib_file} { 3817 set lib_found true 3818 if {$curr_version != $lib_curr_version} { 3819 if {$comp_version != $lib_comp_version} { 3820 ui_warn "Incompatible library version of $file: Expected $comp_version, but $lib_comp_version is installed!" 3821 } 3822 } 3823 break; 3824 } 3825 } 3826 } 3785 3786 set architecture [$result cget -mt_archs] 3787 while {$architecture != "NULL"} { 3788 set loadcommand [$architecture cget -mat_loadcmds] 3789 3790 while {$loadcommand != "NULL"} { 3791 set libresultlist [machista::parse_file $handle [$loadcommand cget -mlt_install_name]] 3792 set libreturncode [lindex $libresultlist 0] 3793 set libresult [lindex $libresultlist 1] 3794 3795 if {$libreturncode != $machista::SUCCESS} { 3796 ui_info "Could not open `[$loadcommand cget -mlt_install_name]': [machista::strerror $libreturncode]" 3797 if {$libreturncode == $machista::EFILE} { 3798 ui_warn "Adding [$b path]" 3799 lappend broken_files [$b path] 3827 3800 } 3828 } 3829 if {$lib_found == false} { 3830 ui_warn "Missing architecture in file: $arch in $file!" 3831 } 3832 } else { 3833 ui_warn "Missing dependency: $file!" 3834 } 3835 continue; 3836 } 3837 ui_warn "Unparsable line in otool output: $otool_line" 3838 } 3839 } 3801 set loadcommand [$loadcommand cget -next] 3802 continue; 3803 } 3804 3805 set libarchitecture [$libresult cget -mt_archs] 3806 set libarch_found false; 3807 while {$libarchitecture != "NULL"} { 3808 if {[$architecture cget -mat_arch] != [$libarchitecture cget -mat_arch]} { 3809 set libarchitecture [$libarchitecture cget -next] 3810 continue; 3811 } 3812 3813 if {[$loadcommand cget -mlt_version] != [$libarchitecture cget -mat_version] && [$loadcommand cget -mlt_comp_version] != [$libarchitecture cget -mat_comp_version]} { 3814 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]" 3815 lappend broken_files [$architecture cget -mat_install_name] 3816 } 3817 3818 set libarch_found true; 3819 break; 3820 } 3821 3822 if {$libarch_found == false} { 3823 ui_info "Missing architecture [$architecture cget -mat_arch] in file `[$loadcommand cget -mlt_install_name]'" 3824 lappend broken_files [$architecture cget -mat_install_name] 3825 } 3826 set loadcommand [$loadcommand cget -next] 3827 } 3828 3829 set architecture [$architecture cget -next] 3830 } 3831 } 3832 machista::destroy_handle $handle 3833 3834 set broken_ports {} 3835 ui_msg "broken files: [llength $broken_files]" 3836 foreach file $broken_files { 3837 ui_msg " $file" 3838 set port [registry::file_registered $file] 3839 if {$port == 0} { 3840 ui_error "Broken file `$file' doesn't belong to any port." 3841 } 3842 lappend broken_ports $port 3843 } 3844 3845 ui_msg "broken ports: [llength $broken_ports]" 3846 foreach port $broken_ports { 3847 ui_msg " $port" 3848 } 3849 } 3850 3840 3851 return 0; 3841 3852 }
Note: See TracChangeset
for help on using the changeset viewer.

