[65087] trunk/base/src/macports1.0/macports.tcl
Jeremy Huddleston
jeremyhu at macports.org
Fri Apr 2 13:39:17 PDT 2010
This patch assumes that ports are binary. Non-binary ports do not have the universal variant and are set 'universal_variant no'. This makes it impossible to install anything using X11 with recent base.
--Jeremy
On Mar 21, 2010, at 09:00, jmr at macports.org wrote:
> Revision: 65087
> http://trac.macports.org/changeset/65087
> Author: jmr at macports.org
> Date: 2010-03-21 09:00:34 -0700 (Sun, 21 Mar 2010)
> Log Message:
> -----------
> check archs in dependencies when installing ports, and in case of a mismatch, upgrade/install the deps with +universal if possible, otherwise print an appropriate error message
>
> Modified Paths:
> --------------
> trunk/base/src/macports1.0/macports.tcl
>
> Modified: trunk/base/src/macports1.0/macports.tcl
> ===================================================================
> --- trunk/base/src/macports1.0/macports.tcl 2010-03-21 14:54:27 UTC (rev 65086)
> +++ trunk/base/src/macports1.0/macports.tcl 2010-03-21 16:00:34 UTC (rev 65087)
> @@ -1644,11 +1644,14 @@
> # upgrade any dependencies of mport that are installed and needed for target
> proc macports::_upgrade_mport_deps {mport target} {
> set options [ditem_key $mport options]
> + set workername [ditem_key $mport workername]
> set deptypes [macports::_deptypes_for_target $target]
> array set portinfo [mportinfo $mport]
> set depends {}
> array set depscache {}
>
> + set required_archs [$workername eval get_canonical_archs]
> +
> foreach deptype $deptypes {
> # Add to the list of dependencies if the option exists and isn't empty.
> if {[info exists portinfo($deptype)] && $portinfo($deptype) != ""} {
> @@ -1656,11 +1659,66 @@
> }
> }
>
> + if {[string equal ${macports::registry.installtype} "image"]} {
> + set test _portnameactive
> + } else {
> + set test registry::entry_exists_for_name
> + }
> +
> foreach depspec $depends {
> - set workername [ditem_key $mport workername]
> set dep_portname [$workername eval _get_dep_port $depspec]
> - if {$dep_portname != "" && ![info exists depscache(port:$dep_portname)] && [registry::entry_exists_for_name $dep_portname]} {
> - set status [macports::upgrade $dep_portname "port:$dep_portname" {} $options depscache]
> + if {$dep_portname != "" && ![info exists depscache(port:$dep_portname)] && [$test $dep_portname]} {
> + set variants {}
> +
> + # check that the dep has the required archs
> + set active_archs [_get_registry_archs $dep_portname]
> + if {$active_archs != "" && $active_archs != "noarch" && $required_archs != "noarch"} {
> + set missing {}
> + foreach arch $required_archs {
> + if {[lsearch -exact $active_archs $arch] == -1} {
> + lappend missing $arch
> + }
> + }
> + if {[llength $missing] > 0} {
> + set res [mportlookup $dep_portname]
> + array unset dep_portinfo
> + array set dep_portinfo [lindex $res 1]
> + if {[lsearch $dep_portinfo(variants) universal] != -1} {
> + # dep offers a universal variant
> + if {[llength $active_archs] == 1} {
> + # not installed universal
> + set missing {}
> + foreach arch $required_archs {
> + if {[lsearch -exact $macports::universal_archs $arch] == -1} {
> + lappend missing $arch
> + }
> + }
> + if {[llength $missing] > 0} {
> + ui_error "Cannot install [_mportkey $mport name] for the arch(s) '$required_archs' because"
> + ui_error "its dependency $dep_portname is only installed for the arch '$active_archs'"
> + ui_error "and the configured universal_archs '$macports::universal_archs' are not sufficient."
> + return -code error "architecture mismatch"
> + } else {
> + # upgrade the dep with +universal
> + lappend variants universal +
> + lappend options ports_upgrade_enforce-variants yes
> + }
> + } else {
> + # already universal
> + ui_error "Cannot install [_mportkey $mport name] for the arch(s) '$required_archs' because"
> + ui_error "its dependency $dep_portname is only installed for the archs '$active_archs'."
> + return -code error "architecture mismatch"
> + }
> + } else {
> + ui_error "Cannot install [_mportkey $mport name] for the arch(s) '$required_archs' because"
> + ui_error "its dependency $dep_portname is only installed for the arch '$active_archs'"
> + ui_error "and does not have a universal variant."
> + return -code error "architecture mismatch"
> + }
> + }
> + }
> +
> + set status [macports::upgrade $dep_portname "port:$dep_portname" $variants $options depscache]
> # status 2 means the port was not found in the index
> if {$status != 0 && $status != 2 && ![macports::ui_isset ports_processall]} {
> return -code error "upgrade $dep_portname failed"
> @@ -1669,6 +1727,18 @@
> }
> }
>
> +# get the archs with which the active version of portname is installed
> +proc macports::_get_registry_archs {portname} {
> + set ilist [registry::active $portname]
> + set i [lindex $ilist 0]
> + set regref [registry::open_entry [lindex $i 0] [lindex $i 1] [lindex $i 2] [lindex $i 3] [lindex $i 5]]
> + set archs [registry::property_retrieve $regref archs]
> + if {$archs == 0} {
> + set archs ""
> + }
> + return $archs
> +}
> +
> proc macports::getsourcepath {url} {
> global macports::portdbpath
>
> @@ -2289,8 +2359,11 @@
> }
>
> set subPorts {}
> - set options [ditem_key $mport options]
> - set variations [ditem_key $mport variations]
> + if {[llength $depends] > 0} {
> + set options [ditem_key $mport options]
> + set variations [ditem_key $mport variations]
> + set required_archs [[ditem_key $mport workername] eval get_canonical_archs]
> + }
>
> foreach depspec $depends {
> # Is that dependency satisfied or this port installed?
> @@ -2324,6 +2397,33 @@
> if {$subport == {}} {
> # We haven't opened this one yet.
> set subport [mportopen $portinfo(porturl) $options $variations]
> +
> + # check archs
> + if {![macports::_mport_supports_archs $subport $required_archs]} {
> + set supported_archs [_mportkey $subport supported_archs]
> + mportclose $subport
> + set arch_mismatch 1
> + set has_universal 0
> + if {[lsearch -exact $portinfo(variants) universal] != -1} {
> + # a universal variant is offered
> + set has_universal 1
> + array unset variation_array
> + array set variation_array $variations
> + if {![info exists variation_array(universal)] || $variation_array(universal) != "+"} {
> + set variation_array(universal) +
> + # try again with +universal
> + set subport [mportopen $portinfo(porturl) $options [array get variation_array]]
> + if {[macports::_mport_supports_archs $subport $required_archs]} {
> + set arch_mismatch 0
> + }
> + }
> + }
> + if {$arch_mismatch} {
> + macports::_explain_arch_mismatch [_mportkey $mport name] $dep_portname $required_archs $supported_archs $has_universal
> + return -code error "architecture mismatch"
> + }
> + }
> +
> if {$recurseDeps} {
> # Add to the list we need to recurse on.
> lappend subPorts $subport
> @@ -2349,6 +2449,54 @@
> return 0
> }
>
> +# check if the given mport can support dependents with the given archs
> +proc macports::_mport_supports_archs {mport required_archs} {
> + if {$required_archs == "noarch"} {
> + return 1
> + }
> + set workername [ditem_key $mport workername]
> + set provided_archs [$workername eval get_canonical_archs]
> + if {$provided_archs == "noarch"} {
> + return 1
> + }
> + foreach arch $required_archs {
> + if {[lsearch -exact $provided_archs $arch] == -1} {
> + return 0
> + }
> + }
> + return 1
> +}
> +
> +# print an error message explaining why a port's archs are not provided by a dependency
> +proc macports::_explain_arch_mismatch {port dep required_archs supported_archs has_universal} {
> + global macports::universal_archs
> + if {![macports::ui_isset ports_debug]} {
> + ui_msg ""
> + }
> + ui_error "Cannot install $port for the arch(s) '$required_archs' because"
> + if {$supported_archs != ""} {
> + foreach arch $required_archs {
> + if {[lsearch -exact $supported_archs $arch] == -1} {
> + ui_error "its dependency $dep only supports the arch(s) '$supported_archs'."
> + return
> + }
> + }
> + }
> + if {$has_universal} {
> + foreach arch $required_archs {
> + if {[lsearch -exact $universal_archs $arch] == -1} {
> + ui_error "its dependency $dep does not build for the required arch(s) by default"
> + ui_error "and the configured universal_archs '$universal_archs' are not sufficient."
> + return
> + }
> + }
> + ui_error "its dependency $dep cannot build for the required arch(s)."
> + return
> + }
> + ui_error "its dependency $dep does not build for the required arch(s) by default"
> + ui_error "and does not have a universal variant."
> +}
> +
> # Determine dependency types required for target
> proc macports::_deptypes_for_target {target} {
> switch $target {
> _______________________________________________
> macports-changes mailing list
> macports-changes at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/macports-changes
More information about the macports-dev
mailing list