PageRenderTime 14ms CodeModel.GetById 3ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

Python | 144 lines | 118 code | 9 blank | 17 comment | 5 complexity | 065049d5518db045e70c9d2bf1bd2242 MD5 | raw file
  1#!/usr/bin/env python
  4@author Nat Goodspeed
  5@date   2009-09-03
  6@brief  Helper script to allow CMake to run some command after setting
  7        environment variables.
  9CMake has commands to run an external program. But remember that each CMake
 10command must be backed by multiple build-system implementations. Unfortunately
 11it seems CMake can't promise that every target build system can set specified
 12environment variables before running the external program of interest.
 14This helper script is a workaround. It simply sets the requested environment
 15variables and then executes the program specified on the rest of its command
 20python -DFOO=bar myprog somearg otherarg
 22sets environment variable FOO=bar, then runs:
 23myprog somearg otherarg
 26Second Life Viewer Source Code
 27Copyright (C) 2009-2010, Linden Research, Inc.
 29This library is free software; you can redistribute it and/or
 30modify it under the terms of the GNU Lesser General Public
 31License as published by the Free Software Foundation;
 32version 2.1 of the License only.
 34This library is distributed in the hope that it will be useful,
 35but WITHOUT ANY WARRANTY; without even the implied warranty of
 37Lesser General Public License for more details.
 39You should have received a copy of the GNU Lesser General Public
 40License along with this library; if not, write to the Free Software
 41Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 43Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 47import os
 48import sys
 49import subprocess
 51def main(command, libpath=[], vars={}):
 52    """Pass:
 53    command is a sequence (e.g. a list) of strings. The first item in the list
 54    must be the command name, the rest are its arguments.
 56    libpath is a sequence of directory pathnames. These will be appended to
 57    the platform-specific dynamic library search path environment variable.
 59    vars is a dict of arbitrary (var, value) pairs to be added to the
 60    environment before running 'command'.
 62    This function runs the specified command, waits for it to terminate and
 63    returns its return code. This will be negative if the command terminated
 64    with a signal, else it will be the process's specified exit code.
 65    """
 66    # Handle platform-dependent libpath first.
 67    if sys.platform == "win32":
 68        lpvars = ["PATH"]
 69    elif sys.platform == "darwin":
 70        lpvars = ["LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH"]
 71    elif sys.platform.startswith("linux"):
 72        lpvars = ["LD_LIBRARY_PATH"]
 73    else:
 74        # No idea what the right pathname might be! But only crump if this
 75        # feature is requested.
 76        if libpath:
 77            raise NotImplemented("run_build_test: unknown platform %s" % sys.platform)
 78        lpvars = []
 79    for var in lpvars:
 80        # Split the existing path. Bear in mind that the variable in question
 81        # might not exist; instead of KeyError, just use an empty string.
 82        dirs = os.environ.get(var, "").split(os.pathsep)
 83        # Append the sequence in libpath
 84        print "%s += %r" % (var, libpath)
 85        for dir in libpath:
 86            # append system paths at the end
 87            if dir in ('/lib', '/usr/lib'):
 88                dirs.append(dir)
 89            # prepend non-system paths
 90            else:
 91                dirs.insert(0, dir)
 93        # Filter out some useless pieces
 94        clean_dirs = []
 95        for dir in dirs:
 96            if dir and dir not in ('', '.'):
 97                clean_dirs.append(dir)
 99        # Now rebuild the path string. This way we use a minimum of separators
100        # -- and we avoid adding a pointless separator when libpath is empty.
101        os.environ[var] = os.pathsep.join(clean_dirs)
102        print "%s = %r" % (var, os.environ[var])
103    # Now handle arbitrary environment variables. The tricky part is ensuring
104    # that all the keys and values we try to pass are actually strings.
105    if vars:
106         print "Setting:"
107         for key, value in vars.iteritems():
108             print "%s=%s" % (key, value)
109    os.environ.update(dict([(str(key), str(value)) for key, value in vars.iteritems()]))
110    # Run the child process.
111    print "Running: %s" % " ".join(command)
112    # Make sure we see all relevant output *before* child-process output.
113    sys.stdout.flush()
114    return
116if __name__ == "__main__":
117    from optparse import OptionParser
118    parser = OptionParser(usage="usage: %prog [options] command args...")
119    # We want optparse support for the options we ourselves handle -- but we
120    # DO NOT want it looking at options for the executable we intend to run,
121    # rejecting them as invalid because we don't define them. So configure the
122    # parser to stop looking for options as soon as it sees the first
123    # positional argument (traditional Unix syntax).
124    parser.disable_interspersed_args()
125    parser.add_option("-D", "--define", dest="vars", default=[], action="append",
126                      metavar="VAR=value",
127                      help="Add VAR=value to the env variables defined")
128    parser.add_option("-l", "--libpath", dest="libpath", default=[], action="append",
129                      metavar="DIR",
130                      help="Add DIR to the platform-dependent DLL search path")
131    opts, args = parser.parse_args()
132    # What we have in opts.vars is a list of strings of the form "VAR=value"
133    # or possibly just "VAR". What we want is a dict. We can build that dict by
134    # constructing a list of ["VAR", "value"] pairs -- so split each
135    # "VAR=value" string on the '=' sign (but only once, in case we have
136    # "VAR=some=user=string"). To handle the case of just "VAR", append "" to
137    # the list returned by split(), then slice off anything after the pair we
138    # want.
139    rc = main(command=args, libpath=opts.libpath,
140              vars=dict([(pair.split('=', 1) + [""])[:2] for pair in opts.vars]))
141    if rc not in (None, 0):
142        print >>sys.stderr, "Failure running: %s" % " ".join(args)
143        print >>sys.stderr, "Error: %s" % rc
144    sys.exit((rc < 0) and 255 or rc)