~ubuntu-branches/ubuntu/natty/scons/natty

0.1.1 by Mark Brown
Import upstream version 0.95
1
"""SCons.Platform.posix
2
3
Platform-specific initialization for POSIX (Linux, UNIX, etc.) systems.
4
5
There normally shouldn't be any need to import this module directly.  It
6
will usually be imported through the generic SCons.Platform.Platform()
7
selection method.
8
"""
9
10
#
0.2.4 by Mark Brown
Import upstream version 0.96.96
11
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
0.1.1 by Mark Brown
Import upstream version 0.95
12
#
13
# Permission is hereby granted, free of charge, to any person obtaining
14
# a copy of this software and associated documentation files (the
15
# "Software"), to deal in the Software without restriction, including
16
# without limitation the rights to use, copy, modify, merge, publish,
17
# distribute, sublicense, and/or sell copies of the Software, and to
18
# permit persons to whom the Software is furnished to do so, subject to
19
# the following conditions:
20
#
21
# The above copyright notice and this permission notice shall be included
22
# in all copies or substantial portions of the Software.
23
#
24
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
25
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
26
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
#
32
0.2.6 by Michael Bienia
Import upstream version 0.97.0d20071203
33
__revision__ = "src/engine/SCons/Platform/posix.py 2509 2007/12/03 20:20:38 broonie"
0.1.1 by Mark Brown
Import upstream version 0.95
34
35
import os
36
import os.path
37
import popen2
38
import string
39
import sys
40
import select
41
42
import SCons.Util
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
43
from SCons.Platform import TempFileMunge
0.1.1 by Mark Brown
Import upstream version 0.95
44
45
exitvalmap = {
46
    2 : 127,
47
    13 : 126,
48
}
49
50
def escape(arg):
51
    "escape shell special characters"
52
    slash = '\\'
53
    special = '"$'
54
55
    arg = string.replace(arg, slash, slash+slash)
56
    for c in special:
57
        arg = string.replace(arg, c, slash+c)
58
59
    return '"' + arg + '"'
60
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
61
def exec_system(l, env):
62
    stat = os.system(string.join(l))
63
    if stat & 0xff:
64
        return stat | 0x80
65
    return stat >> 8
66
67
def exec_spawnvpe(l, env):
68
    stat = os.spawnvpe(os.P_WAIT, l[0], l, env)
69
    # os.spawnvpe() returns the actual exit code, not the encoding
70
    # returned by os.waitpid() or os.system().
71
    return stat
72
0.2.3 by Mark Brown
Import upstream version 0.96.93
73
def exec_fork(l, env): 
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
74
    pid = os.fork()
75
    if not pid:
76
        # Child process.
77
        exitval = 127
78
        try:
79
            os.execvpe(l[0], l, env)
80
        except OSError, e:
0.2.3 by Mark Brown
Import upstream version 0.96.93
81
            exitval = exitvalmap.get(e[0], e[0])
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
82
            sys.stderr.write("scons: %s: %s\n" % (l[0], e[1]))
83
        os._exit(exitval)
84
    else:
85
        # Parent process.
86
        pid, stat = os.waitpid(pid, 0)
87
        if stat & 0xff:
88
            return stat | 0x80
89
        return stat >> 8
90
0.1.1 by Mark Brown
Import upstream version 0.95
91
def _get_env_command(sh, escape, cmd, args, env):
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
92
    s = string.join(args)
0.1.1 by Mark Brown
Import upstream version 0.95
93
    if env:
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
94
        l = ['env', '-'] + \
95
            map(lambda t, e=escape: t[0]+'='+e(t[1]), env.items()) + \
96
            [sh, '-c', escape(s)]
97
        s = string.join(l)
0.1.1 by Mark Brown
Import upstream version 0.95
98
    return s
99
100
def env_spawn(sh, escape, cmd, args, env):
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
101
    return exec_system([_get_env_command( sh, escape, cmd, args, env)], env)
0.1.1 by Mark Brown
Import upstream version 0.95
102
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
103
def spawnvpe_spawn(sh, escape, cmd, args, env):
104
    return exec_spawnvpe([sh, '-c', string.join(args)], env)
0.1.1 by Mark Brown
Import upstream version 0.95
105
106
def fork_spawn(sh, escape, cmd, args, env):
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
107
    return exec_fork([sh, '-c', string.join(args)], env)
0.1.1 by Mark Brown
Import upstream version 0.95
108
109
def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr):
110
    stdout_eof = stderr_eof = 0
111
    while not (stdout_eof and stderr_eof):
112
        (i,o,e) = select.select([cmd_stdout, cmd_stderr], [], [])
113
        if cmd_stdout in i:
114
            str = cmd_stdout.read()
115
            if len(str) == 0:
116
                stdout_eof = 1
117
            elif stdout != None:
118
                stdout.write(str)
119
        if cmd_stderr in i:
120
            str = cmd_stderr.read()
121
            if len(str) == 0:
122
                #sys.__stderr__.write( "stderr_eof=1\n" )
123
                stderr_eof = 1
124
            else:
125
                #sys.__stderr__.write( "str(stderr) = %s\n" % str )
126
                stderr.write(str)
127
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
128
def exec_popen3(l, env, stdout, stderr):
129
    proc = popen2.Popen3(string.join(l), 1)
0.1.1 by Mark Brown
Import upstream version 0.95
130
    process_cmd_output(proc.fromchild, proc.childerr, stdout, stderr)
131
    stat = proc.wait()
132
    if stat & 0xff:
133
        return stat | 0x80
134
    return stat >> 8
135
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
136
def exec_piped_fork(l, env, stdout, stderr):
0.1.1 by Mark Brown
Import upstream version 0.95
137
    # spawn using fork / exec and providing a pipe for the command's
138
    # stdout / stderr stream
139
    if stdout != stderr:
140
        (rFdOut, wFdOut) = os.pipe()
141
        (rFdErr, wFdErr) = os.pipe()
142
    else:
143
        (rFdOut, wFdOut) = os.pipe()
144
        rFdErr = rFdOut
145
        wFdErr = wFdOut
146
    # do the fork
147
    pid = os.fork()
148
    if not pid:
149
        # Child process
150
        os.close( rFdOut )
151
        if rFdOut != rFdErr:
152
            os.close( rFdErr )
153
        os.dup2( wFdOut, 1 ) # is there some symbolic way to do that ?
154
        os.dup2( wFdErr, 2 )
155
        os.close( wFdOut )
156
        if stdout != stderr:
157
            os.close( wFdErr )
158
        exitval = 127
159
        try:
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
160
            os.execvpe(l[0], l, env)
0.1.1 by Mark Brown
Import upstream version 0.95
161
        except OSError, e:
0.2.3 by Mark Brown
Import upstream version 0.96.93
162
            exitval = exitvalmap.get(e[0], e[0])
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
163
            stderr.write("scons: %s: %s\n" % (l[0], e[1]))
0.1.1 by Mark Brown
Import upstream version 0.95
164
        os._exit(exitval)
165
    else:
166
        # Parent process
167
        pid, stat = os.waitpid(pid, 0)
168
        os.close( wFdOut )
169
        if stdout != stderr:
170
            os.close( wFdErr )
171
        childOut = os.fdopen( rFdOut )
172
        if stdout != stderr:
173
            childErr = os.fdopen( rFdErr )
174
        else:
175
            childErr = childOut
176
        process_cmd_output(childOut, childErr, stdout, stderr)
177
        os.close( rFdOut )
178
        if stdout != stderr:
179
            os.close( rFdErr )
180
        if stat & 0xff:
181
            return stat | 0x80
182
        return stat >> 8
183
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
184
def piped_env_spawn(sh, escape, cmd, args, env, stdout, stderr):
185
    # spawn using Popen3 combined with the env command
186
    # the command name and the command's stdout is written to stdout
187
    # the command's stderr is written to stderr
188
    return exec_popen3([_get_env_command(sh, escape, cmd, args, env)],
189
                       env, stdout, stderr)
190
191
def piped_fork_spawn(sh, escape, cmd, args, env, stdout, stderr):
192
    # spawn using fork / exec and providing a pipe for the command's
193
    # stdout / stderr stream
194
    return exec_piped_fork([sh, '-c', string.join(args)],
195
                           env, stdout, stderr)
196
0.1.1 by Mark Brown
Import upstream version 0.95
197
198
199
def generate(env):
200
    # If os.spawnvpe() exists, we use it to spawn commands.  Otherwise
201
    # if the env utility exists, we use os.system() to spawn commands,
202
    # finally we fall back on os.fork()/os.exec().  
203
    #
204
    # os.spawnvpe() is prefered because it is the most efficient.  But
205
    # for Python versions without it, os.system() is prefered because it
206
    # is claimed that it works better with threads (i.e. -j) and is more
207
    # efficient than forking Python.
208
    #
209
    # NB: Other people on the scons-users mailing list have claimed that
210
    # os.fork()/os.exec() works better than os.system().  There may just
211
    # not be a default that works best for all users.
212
213
    if os.__dict__.has_key('spawnvpe'):
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
214
        spawn = spawnvpe_spawn
0.1.1 by Mark Brown
Import upstream version 0.95
215
    else:
216
        spawn = fork_spawn
217
6 by Michael Bienia, Mark Brown, Michael Bienia
[ Mark Brown ]
218
    pspawn = piped_fork_spawn
0.1.1 by Mark Brown
Import upstream version 0.95
219
220
    if not env.has_key('ENV'):
221
        env['ENV']        = {}
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
222
    env['ENV']['PATH']    = '/usr/local/bin:/opt/bin:/bin:/usr/bin'
0.1.1 by Mark Brown
Import upstream version 0.95
223
    env['OBJPREFIX']      = ''
224
    env['OBJSUFFIX']      = '.o'
225
    env['SHOBJPREFIX']    = '$OBJPREFIX'
226
    env['SHOBJSUFFIX']    = '$OBJSUFFIX'
227
    env['PROGPREFIX']     = ''
228
    env['PROGSUFFIX']     = ''
229
    env['LIBPREFIX']      = 'lib'
230
    env['LIBSUFFIX']      = '.a'
231
    env['SHLIBPREFIX']    = '$LIBPREFIX'
232
    env['SHLIBSUFFIX']    = '.so'
233
    env['LIBPREFIXES']    = '$LIBPREFIX'
234
    env['LIBSUFFIXES']    = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ]
235
    env['PSPAWN']         = pspawn
236
    env['SPAWN']          = spawn
237
    env['SHELL']          = 'sh'
238
    env['ESCAPE']         = escape
0.2.2 by Daniel T Chen
Import upstream version 0.96.92
239
    env['TEMPFILE']       = TempFileMunge
240
    env['TEMPFILEPREFIX'] = '@'
241
    #Based on LINUX: ARG_MAX=ARG_MAX=131072 - 3000 for environment expansion
242
    #Note: specific platforms might rise or lower this value
243
    env['MAXLINELENGTH']  = 128072
0.2.1 by Mark Brown
Import upstream version 0.96.1
244
245
    # This platform supports RPATH specifications.
246
    env['__RPATH'] = '$_RPATH'