Projects
New Ticket     Wiki     Browse Source     Timeline     Roadmap     Bug Reports     Search

root/trunk/base/src/macports1.0/macports.tcl

Revision 42747, 84.0 KB (checked in by simon@…, 4 days ago)

base/src: Make sure the default port source is specified.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:filetype=tcl:et:sw=4:ts=4:sts=4
2# macports.tcl
3# $Id$
4#
5# Copyright (c) 2002 Apple Computer, Inc.
6# Copyright (c) 2004 - 2005 Paul Guyot, <pguyot@kallisys.net>.
7# Copyright (c) 2004 - 2006 Ole Guldberg Jensen <olegb@opendarwin.org>.
8# Copyright (c) 2004 - 2005 Robert Shaw <rshaw@opendarwin.org>
9# All rights reserved.
10#
11# Redistribution and use in source and binary forms, with or without
12# modification, are permitted provided that the following conditions
13# are met:
14# 1. Redistributions of source code must retain the above copyright
15#    notice, this list of conditions and the following disclaimer.
16# 2. Redistributions in binary form must reproduce the above copyright
17#    notice, this list of conditions and the following disclaimer in the
18#    documentation and/or other materials provided with the distribution.
19# 3. Neither the name of Apple Computer, Inc. nor the names of its contributors
20#    may be used to endorse or promote products derived from this software
21#    without specific prior written permission.
22#
23# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33# POSSIBILITY OF SUCH DAMAGE.
34#
35package provide macports 1.0
36package require macports_dlist 1.0
37package require macports_index 1.0
38package require macports_util 1.0
39
40namespace eval macports {
41    namespace export bootstrap_options user_options portinterp_options open_mports ui_priorities
42    variable bootstrap_options "\
43        portdbpath libpath binpath auto_path extra_env sources_conf prefix x11prefix portdbformat \
44        portinstalltype portarchivemode portarchivepath portarchivetype portautoclean \
45        porttrace portverbose destroot_umask variants_conf rsync_server rsync_options \
46        rsync_dir startupitem_type place_worksymlink xcodeversion xcodebuildcmd \
47        mp_remote_url mp_remote_submit_url configureccache configuredistcc configurepipe buildnicevalue buildmakejobs \
48        applications_dir frameworks_dir universal_target universal_sysroot universal_archs"
49    variable user_options "submitter_name submitter_email submitter_key"
50    variable portinterp_options "\
51        portdbpath porturl portpath portbuildpath auto_path prefix prefix_frozen x11prefix portsharepath \
52        registry.path registry.format registry.installtype portarchivemode portarchivepath \
53        portarchivetype portautoclean porttrace portverbose destroot_umask rsync_server \
54        rsync_options rsync_dir startupitem_type place_worksymlink \
55        mp_remote_url mp_remote_submit_url configureccache configuredistcc configurepipe buildnicevalue buildmakejobs \
56        applications_dir frameworks_dir universal_target universal_sysroot universal_archs $user_options"
57   
58    # deferred options are only computed when needed.
59    # they are not exported to the trace thread.
60    # they are not exported to the interpreter in system_options array.
61    variable portinterp_deferred_options "xcodeversion xcodebuildcmd"
62   
63    variable open_mports {}
64   
65    variable ui_priorities "debug info msg error warn"
66}
67
68# Provided UI instantiations
69# For standard messages, the following priorities are defined
70#     debug, info, msg, warn, error
71# Clients of the library are expected to provide ui_prefix and ui_channels with
72# the following prototypes.
73#     proc ui_prefix {priority}
74#     proc ui_channels {priority}
75# ui_prefix returns the prefix for the messages, if any.
76# ui_channels returns a list of channels to output the message to, empty for
77#     no message.
78# if these functions are not provided, defaults are used.
79# Clients of the library may optionally provide ui_init with the following
80# prototype.
81#     proc ui_init {priority prefix channels message}
82# ui_init needs to correctly define the proc ::ui_$priority {message} or throw
83# an error.
84# if this function is not provided or throws an error, default procedures for
85# ui_$priority are defined.
86
87# ui_options accessor
88proc macports::ui_isset {val} {
89    if {[info exists macports::ui_options($val)]} {
90        if {$macports::ui_options($val) == "yes"} {
91            return 1
92        }
93    }
94    return 0
95}
96
97
98# global_options accessor
99proc macports::global_option_isset {val} {
100    if {[info exists macports::global_options($val)]} {
101        if {$macports::global_options($val) == "yes"} {
102            return 1
103        }
104    }
105    return 0
106}
107
108
109proc macports::ui_init {priority message} {
110    # Get the list of channels.
111    try {
112        set channels [ui_channels $priority]
113    } catch * {
114        set channels [ui_channels_default $priority]
115    }
116
117    # Simplify ui_$priority.
118    set nbchans [llength $channels]
119    if {$nbchans == 0} {
120        proc ::ui_$priority {str} {}
121    } else {
122        try {
123            set prefix [ui_prefix $priority]
124        } catch * {
125            set prefix [ui_prefix_default $priority]
126        }
127
128        try {
129            ::ui_init $priority $prefix $channels $message
130        } catch * {
131            if {$nbchans == 1} {
132                set chan [lindex $channels 0]
133                proc ::ui_$priority {str} [subst { puts $chan "$prefix\$str" }]
134            } else {
135                proc ::ui_$priority {str} [subst {
136                    foreach chan \$channels {
137                        puts $chan "$prefix\$str"
138                    }
139                }]
140            }
141        }
142
143        # Call ui_$priority
144        ::ui_$priority $message
145    }
146}
147
148# Default implementation of ui_prefix
149proc macports::ui_prefix_default {priority} {
150    switch $priority {
151        debug {
152            return "DEBUG: "
153        }
154        error {
155            return "Error: "
156        }
157        warn {
158            return "Warning: "
159        }
160        default {
161            return ""
162        }
163    }
164}
165
166# Default implementation of ui_channels:
167# ui_options(ports_debug) - If set, output debugging messages
168# ui_options(ports_verbose) - If set, output info messages (ui_info)
169# ui_options(ports_quiet) - If set, don't output "standard messages"
170proc macports::ui_channels_default {priority} {
171    switch $priority {
172        debug {
173            if {[ui_isset ports_debug]} {
174                return {stderr}
175            } else {
176                return {}
177            }
178        }
179        info {
180            if {[ui_isset ports_verbose]} {
181                return {stdout}
182            } else {
183                return {}
184            }
185        }
186        msg {
187            if {[ui_isset ports_quiet]} {
188                return {}
189            } else {   
190                return {stdout}
191            }
192        }
193        error {
194            return {stderr}
195        }
196        default {
197            return {stdout}
198        }
199    }
200}
201
202foreach priority ${macports::ui_priorities} {
203    proc ui_$priority {str} [subst { macports::ui_init $priority \$str }]
204}
205
206# Replace puts to catch errors (typically broken pipes when being piped to head)
207rename puts tcl::puts
208proc puts {args} {
209    catch "tcl::puts $args"
210}
211
212# find a binary either in a path defined at MacPorts' configuration time
213# or in the PATH environment variable through macports::binaryInPath (fallback)
214proc macports::findBinary {prog {autoconf_hint ""}} {
215    if {${autoconf_hint} != "" && [file executable ${autoconf_hint}]} {
216        return ${autoconf_hint}
217    } else {
218        if {[catch {set cmd_path [macports::binaryInPath ${prog}]} result] == 0} {
219            return ${cmd_path}
220        } else {
221            return -code error "${result} or at its MacPorts configuration time location, did you move it?"
222        }
223    }
224}
225
226# check for a binary in the path
227# returns an error code if it can not be found
228proc macports::binaryInPath {prog} {
229    global env
230    foreach dir [split $env(PATH) :] {
231        if {[file executable [file join $dir $prog]]} {
232            return [file join $dir $prog]
233        }
234    }
235    return -code error [format [msgcat::mc "Failed to locate '%s' in path: '%s'"] $prog $env(PATH)];
236}
237
238# deferred option processing
239proc macports::getoption {name} {
240    global macports::$name
241    return [expr $$name]
242}
243
244# deferred and on-need extraction of xcodeversion and xcodebuildcmd.
245proc macports::setxcodeinfo {name1 name2 op} {
246    global macports::xcodeversion
247    global macports::xcodebuildcmd
248   
249    trace remove variable macports::xcodeversion read macports::setxcodeinfo
250    trace remove variable macports::xcodebuildcmd read macports::setxcodeinfo
251
252    if {[catch {set xcodebuild [binaryInPath "xcodebuild"]}] == 0} {
253        if {![info exists xcodeversion]} {
254            # Determine xcode version (<= 2.0 or 2.1)
255            if {[catch {set xcodebuildversion [exec xcodebuild -version]}] == 0} {
256                if {[regexp "DevToolsCore-(.*); DevToolsSupport-(.*)" $xcodebuildversion devtoolscore_v devtoolssupport_v] == 1} {
257                    if {$devtoolscore_v >= 620.0 && $devtoolssupport_v >= 610.0} {
258                        # for now, we don't need to distinguish 2.1 from 2.1 or higher.
259                        set macports::xcodeversion "2.1"
260                    } else {
261                        set macports::xcodeversion "2.0orlower"
262                    }
263                } else {
264                    set macports::xcodeversion "2.0orlower"
265                }
266            } else {
267                set macports::xcodeversion "2.0orlower"
268            }
269        }
270       
271        if {![info exists xcodebuildcmd]} {
272            set macports::xcodebuildcmd "xcodebuild"
273        }
274    } elseif {[catch {set pbxbuild [binaryInPath "pbxbuild"]}] == 0} {
275        if {![info exists xcodeversion]} {
276            set macports::xcodeversion "pb"
277        }
278        if {![info exists xcodebuildcmd]} {
279            set macports::xcodebuildcmd "pbxbuild"
280        }
281    } else {
282        if {![info exists xcodeversion]} {
283            set macports::xcodeversion "none"
284        }
285        if {![info exists xcodebuildcmd]} {
286            set macports::xcodebuildcmd "none"
287        }
288    }
289}
290
291# dportinit
292# Deprecated version of the new mportinit proc, listed here as backwards
293# compatibility glue for API clients that haven't updated to the new naming
294proc dportinit {{up_ui_options {}} {up_options {}} {up_variations {}}} {
295    ui_warn "The dportinit proc is deprecated and will be going away soon, please use mportinit in the future!"
296    mportinit $up_ui_options $up_options $up_variations
297}
298
299proc mportinit {{up_ui_options {}} {up_options {}} {up_variations {}}} {
300    if {$up_ui_options eq ""} {
301        array set macports::ui_options {}
302    } else {
303        upvar $up_ui_options temp_ui_options
304        array set macports::ui_options [array get temp_ui_options]
305    }
306    if {$up_options eq ""} {
307        array set macports::global_options {}
308    } else {
309        upvar $up_options temp_options
310        array set macports::global_options [array get temp_options]
311    }
312    if {$up_variations eq ""} {
313        array set variations {}
314    } else {
315        upvar $up_variations variations
316    }
317   
318    global auto_path env
319    global macports::autoconf::macports_conf_path
320    global macports::macports_user_dir
321    global macports::bootstrap_options
322    global macports::user_options
323    global macports::extra_env
324    global macports::portconf
325    global macports::portdbpath
326    global macports::portsharepath
327    global macports::registry.format
328    global macports::registry.path
329    global macports::sources
330    global macports::sources_default
331    global macports::sources_conf
332    global macports::destroot_umask
333    global macports::libpath
334    global macports::prefix
335    global macports::prefix_frozen
336    global macports::x11prefix
337    global macports::registry.installtype
338    global macports::rsync_dir
339    global macports::rsync_options
340    global macports::rsync_server
341    global macports::variants_conf
342    global macports::xcodebuildcmd
343    global macports::xcodeversion
344    global macports::configureccache
345    global macports::configuredistcc
346    global macports::configurepipe
347    global macports::buildnicevalue
348    global macports::buildmakejobs
349    global macports::universal_target
350    global macports::universal_sysroot
351    global macports::universal_archs
352
353    # Set the system encoding to utf-8
354    encoding system utf-8
355
356    # Ensure that the macports user directory exists if HOME is defined
357    if {[info exists env(HOME)]} {
358        set macports::macports_user_dir [file normalize $macports::autoconf::macports_user_dir]
359        if { ![file exists $macports_user_dir] } {
360        # If not, create it with ownership of the enclosing directory, rwx by the user only
361        file mkdir $macports_user_dir
362        file attributes $macports_user_dir -permissions u=rwx,go= \
363            -owner [file attributes $macports_user_dir/.. -owner] \
364            -group [file attributes $macports_user_dir/.. -group]
365        }
366    } else {
367        # Otherwise define the user directory as a direcotory that will never exist
368        set macports::macports_user_dir "/dev/null/NO_HOME_DIR"
369    }
370   
371    # Configure the search path for configuration files
372    set conf_files ""
373    lappend conf_files "${macports_conf_path}/macports.conf"
374    if { [file isdirectory $macports_user_dir] } {
375        lappend conf_files "${macports_user_dir}/macports.conf"
376    }
377    if {[info exists env(PORTSRC)]} {
378        set PORTSRC $env(PORTSRC)
379        lappend conf_files ${PORTSRC}
380    }
381   
382    # Process the first configuration file we find on conf_files list
383    foreach file $conf_files {
384        if [file exists $file] {
385            set portconf $file
386            set fd [open $file r]
387            while {[gets $fd line] >= 0} {
388                if {[regexp {^(\w+)([ \t]+(.*))?$} $line match option ignore val] == 1} {
389                    if {[lsearch $bootstrap_options $option] >= 0} {
390                        set macports::$option $val
391                        global macports::$option
392                    }
393                }
394            }           
395        }
396    }
397   
398    # Process per-user only settings
399    set per_user "${macports_user_dir}/user.conf"
400    if [file exists $per_user] {
401        set fd [open $per_user r]
402        while {[gets $fd line] >= 0} {
403            if {[regexp {^(\w+)([ \t]+(.*))?$} $line match option ignore val] == 1} {
404                if {[lsearch $user_options $option] >= 0} {
405                    set macports::$option $val
406                    global macports::$option
407                }
408            }
409        }
410    }
411   
412    if {![info exists sources_conf]} {
413        return -code error "sources_conf must be set in ${macports_conf_path}/macports.conf or in your ${macports_user_dir}/macports.conf file"
414    }
415    set fd [open $sources_conf r]
416    while {[gets $fd line] >= 0} {
417        set line [string trimright $line]
418        if {![regexp {^\s*#|^$} $line]} {
419            if {[regexp {^([\w-]+://\S+)(?:\s+\[(\w+(?:,\w+)*)\])?$} $line _ url flags]} {
420                set flags [split $flags ,]
421                foreach flag $flags {
422                    if {[lsearch -exact [list nosync default] $flag] == -1} {
423                        ui_warn "$sources_conf source '$line' specifies invalid flag '$flag'"
424                    }
425                    if {$flag == "default"} {
426                        set sources_default [concat [list $url] $flags]
427                    }
428                }
429                lappend sources [concat [list $url] $flags]
430            } else {
431                ui_warn "$sources_conf specifies invalid source '$line', ignored."
432            }
433        }
434    }
435    # Make sure the default port source is defined. Otherwise
436    # [macports::getportresourcepath] fails when the first source doesn't
437    # contain _resources.
438    if {![info exists sources_default]} {
439        return -code error "No default port source specified in $sources_conf"
440    }
441
442    if {![info exists sources]} {
443        if {[file isdirectory ports]} {
444            set sources "file://[pwd]/ports"
445        } else {
446            return -code error "No sources defined in $sources_conf"
447        }
448    }
449
450    if {[info exists variants_conf]} {
451        if {[file exist $variants_conf]} {
452            set fd [open $variants_conf r]
453            while {[gets $fd line] >= 0} {
454                set line [string trimright $line]
455                if {![regexp {^[\ \t]*#.*$|^$} $line]} {
456                    foreach arg [split $line " \t"] {
457                        if {[regexp {^([-+])([-A-Za-z0-9_+\.]+)$} $arg match sign opt] == 1} {
458                            if {![info exists variations($opt)]} {
459                                set variations($opt) $sign
460                            }
461                        } else {
462                            ui_warn "$variants_conf specifies invalid variant syntax '$arg', ignored."
463                        }
464                    }
465                }
466            }
467        } else {
468            ui_debug "$variants_conf does not exist, variants_conf setting ignored."
469        }
470    }
471
472    if {![info exists portdbpath]} {
473        return -code error "portdbpath must be set in ${macports_conf_path}/macports.conf or in your ${macports_user_dir}/macports.conf"
474    }
475    if {![file isdirectory $portdbpath]} {
476        if {![file exists $portdbpath]} {
477            if {[catch {file mkdir $portdbpath} result]} {
478                return -code error "portdbpath $portdbpath does not exist and could not be created: $result"
479            }
480        } else {
481            return -code error "$portdbpath is not a directory. Please create the directory $portdbpath and try again"
482        }
483    }
484
485    set registry.path $portdbpath
486
487    # Format for receipts, can currently be either "flat" or "sqlite"
488    if {[info exists portdbformat]} {
489        if { $portdbformat == "sqlite" } {
490            return -code error "SQLite is not yet supported for registry storage."
491        }
492        set registry.format receipt_${portdbformat}
493    } else {
494        set registry.format receipt_flat
495    }
496
497    # Installation type, whether to use port "images" or install "direct"
498    if {[info exists portinstalltype]} {
499        set registry.installtype $portinstalltype
500    } else {
501        set registry.installtype image
502    }
503   
504    # Autoclean mode, whether to automatically call clean after "install"
505    if {![info exists portautoclean]} {
506        set macports::portautoclean "yes"
507        global macports::portautoclean
508    }
509    # Check command line override for autoclean
510    if {[info exists macports::global_options(ports_autoclean)]} {
511        if {![string equal $macports::global_options(ports_autoclean) $portautoclean]} {
512            set macports::portautoclean $macports::global_options(ports_autoclean)
513        }
514    }
515    # Trace mode, whether to use darwintrace to debug ports.
516    if {![info exists porttrace]} {
517        set macports::porttrace "no"
518        global macports::porttrace
519    }
520    # Check command line override for trace
521    if {[info exists macports::global_options(ports_trace)]} {
522        if {![string equal $macports::global_options(ports_trace) $porttrace]} {
523            set macports::porttrace $macports::global_options(ports_trace)
524        }
525    }
526
527    # Duplicate prefix into prefix_frozen, so that port actions
528    # can always get to the original prefix, even if a portfile overrides prefix
529    set macports::prefix_frozen $prefix
530
531    # Export verbosity.
532    if {![info exists portverbose]} {
533        set macports::portverbose "no"
534        global macports::portverbose
535    }
536    if {[info exists macports::ui_options(ports_verbose)]} {
537        if {![string equal $macports::ui_options(ports_verbose) $portverbose]} {
538            set macports::portverbose $macports::ui_options(ports_verbose)
539        }
540    }
541
542    # Archive mode, whether to create/use binary archive packages
543    if {![info exists portarchivemode]} {
544        set macports::portarchivemode "yes"
545        global macports::portarchivemode
546    }
547
548    # Archive path, where to store/retrieve binary archive packages
549    if {![info exists portarchivepath]} {
550        set macports::portarchivepath [file join $portdbpath packages]
551        global macports::portarchivepath
552    }
553    if {$portarchivemode == "yes"} {
554        if {![file isdirectory $portarchivepath]} {
555            if {![file exists $portarchivepath]} {
556                if {[catch {file mkdir $portarchivepath} result]} {
557                    return -code error "portarchivepath $portarchivepath does not exist and could not be created: $result"
558                }
559            }
560        }
561        if {![file isdirectory $portarchivepath]} {
562            return -code error "$portarchivepath is not a directory. Please create the directory $portarchivepath and try again"
563        }
564    }
565
566    # Archive type, what type of binary archive to use (CPIO, gzipped
567    # CPIO, XAR, etc.)
568    if {![info exists portarchivetype]} {
569        set macports::portarchivetype "cpgz"
570        global macports::portarchivetype
571    }
572    # Convert archive type to a list for multi-archive support, colon or
573    # comma separators indicates to use multiple archive formats
574    # (reading and writing)
575    set macports::portarchivetype [split $portarchivetype {:,}]
576
577    # Set rync options
578    if {![info exists rsync_server]} {
579        set macports::rsync_server rsync.macports.org
580        global macports::rsync_server
581    }
582    if {![info exists rsync_dir]} {
583        set macports::rsync_dir release/base/
584        global macports::rsync_dir
585    }
586    if {![info exists rsync_options]} {
587        set rsync_options "-rtzv --delete-after"
588        global macports::rsync_options
589    }
590
591    set portsharepath ${prefix}/share/macports
592    if {![file isdirectory $portsharepath]} {
593        return -code error "Data files directory '$portsharepath' must exist"
594    }
595   
596    if {![info exists libpath]} {
597        set libpath "${prefix}/share/macports/Tcl"
598    }
599
600    if {![info exists binpath]} {
601        set env(PATH) "${prefix}/bin:${prefix}/sbin:/bin:/sbin:/usr/bin:/usr/sbin:${x11prefix}/bin"
602    } else {
603        set env(PATH) "$binpath"
604    }
605   
606    # Set startupitem default type (can be overridden by portfile)
607    if {![info exists macports::startupitem_type]} {
608        set macports::startupitem_type "default"
609    }
610
611    # Default place_worksymlink
612    if {![info exists macports::place_worksymlink]} {
613        set macports::place_worksymlink yes
614    }
615
616    # Default mp remote options
617    if {![info exists macports::mp_remote_url]} {
618        set macports::mp_remote_url "http://db.macports.org"
619    }
620    if {![info exists macports::mp_remote_submit_url]} {
621        set macports::mp_remote_submit_url "${macports::mp_remote_url}/submit"
622    }
623   
624    # Default mp configure options
625    if {![info exists macports::configureccache]} {
626        set macports::configureccache no
627    }
628    if {![info exists macports::configuredistcc]} {
629        set macports::configuredistcc no
630    }
631    if {![info exists macports::configurepipe]} {
632        set macports::configurepipe no
633    }
634
635    # Default mp build options
636    if {![info exists macports::buildnicevalue]} {
637        set macports::buildnicevalue 0
638    }
639    if {![info exists macports::buildmakejobs]} {
640        set macports::buildmakejobs 1
641    }
642
643    # Default mp universal options
644    if {![info exists macports::universal_target]} {
645        if {[file exists /Developer/SDKs/MacOSX10.5.sdk]} {
646            set macports::universal_target "10.5"
647        } else {
648            set macports::universal_target "10.4"
649        }
650    }
651    if {![info exists macports::universal_sysroot]} {
652        if {[file exists /Developer/SDKs/MacOSX10.5.sdk]} {
653            set macports::universal_sysroot "/Developer/SDKs/MacOSX10.5.sdk"
654        } else {
655            set macports::universal_sysroot "/Developer/SDKs/MacOSX10.4u.sdk"
656        }
657    }
658    if {![info exists macports::universal_archs]} {
659        set macports::universal_archs {ppc i386}
660    }
661   
662    # ENV cleanup.
663    set keepenvkeys {
664        DISPLAY DYLD_FALLBACK_FRAMEWORK_PATH
665        DYLD_FALLBACK_LIBRARY_PATH DYLD_FRAMEWORK_PATH
666        DYLD_LIBRARY_PATH DYLD_INSERT_LIBRARIES
667        HOME JAVA_HOME MASTER_SITE_LOCAL
668        PATCH_SITE_LOCAL PATH PORTSRC RSYNC_PROXY TMP TMPDIR
669        USER GROUP
670        http_proxy HTTPS_PROXY FTP_PROXY ALL_PROXY NO_PROXY
671        COLUMNS LINES
672    }
673    if {[info exists extra_env]} {
674        set keepenvkeys [concat ${keepenvkeys} ${extra_env}]
675    }
676   
677    foreach envkey [array names env] {
678        if {[lsearch $keepenvkeys $envkey] == -1} {
679            array unset env $envkey
680        }
681    }
682
683    if {![info exists xcodeversion] || ![info exists xcodebuildcmd]} {
684        # We'll resolve these later (if needed)
685        trace add variable macports::xcodeversion read macports::setxcodeinfo
686        trace add variable macports::xcodebuildcmd read macports::setxcodeinfo
687    }
688
689    # Set the default umask
690    if {![info exists destroot_umask]} {
691        set destroot_umask 022
692    }
693
694    if {[info exists master_site_local] && ![info exists env(MASTER_SITE_LOCAL)]} {
695        set env(MASTER_SITE_LOCAL) "$master_site_local"
696    }
697
698    if {[file isdirectory $libpath]} {
699        lappend auto_path $libpath
700        set macports::auto_path $auto_path
701
702        # XXX: not sure if this the best place, but it needs to happen
703        # early, and after auto_path has been set.  Or maybe Pextlib
704        # should ship with macports1.0 API?
705        package require Pextlib 1.0
706        package require registry 1.0
707    } else {
708        return -code error "Library directory '$libpath' must exist"
709    }
710
711    # unset environment an extra time, to work around bugs in Leopard Tcl
712    foreach envkey [array names env] {
713        if {[lsearch $keepenvkeys $envkey] == -1} {
714            unsetenv $envkey
715        }
716    }
717}
718
719proc macports::worker_init {workername portpath porturl portbuildpath options variations} {
720    global macports::portinterp_options macports::portinterp_deferred_options registry.installtype
721
722    # Hide any Tcl commands that should be inaccessible to port1.0 and Portfiles
723    # exit: It should not be possible to exit the interpreter
724    interp hide $workername exit
725
726    # cd: This is necessary for some code in port1.0, but should be hidden
727    interp eval $workername "rename cd _cd"
728
729    # Tell the sub interpreter about all the Tcl packages we already
730    # know about so it won't glob for packages.
731    foreach pkgName [package names] {
732        foreach pkgVers [package versions $pkgName] {
733            set pkgLoadScript [package ifneeded $pkgName $pkgVers]
734            $workername eval "package ifneeded $pkgName $pkgVers {$pkgLoadScript}"
735        }
736    }
737
738    # Create package require abstraction procedure
739    $workername eval "proc PortSystem \{version\} \{ \n\
740            package require port \$version \}"
741
742    # Clearly separate slave interpreters and the master interpreter.
743    $workername alias mport_exec mportexec
744    $workername alias mport_open mportopen
745    $workername alias mport_close mportclose
746    $workername alias mport_search mportsearch
747
748    # instantiate the UI call-backs
749    foreach priority ${macports::ui_priorities} {
750        $workername alias ui_$priority ui_$priority
751    }
752    $workername alias