Merge pull request #3922 from lightmare/sconf-try-action

Sconf TryAction replacement
This commit is contained in:
Artem Pavlenko 2018-07-02 09:53:02 +02:00 committed by GitHub
commit ba0e13c812
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -34,6 +34,20 @@ try:
except:
HAS_DISTUTILS = False
try:
# Python 3.3+
from shlex import quote as shquote
except:
# Python 2.7
from pipes import quote as shquote
try:
# Python 3.3+
from subprocess import DEVNULL
except:
# Python 2.7
DEVNULL = open(os.devnull, 'w')
LIBDIR_SCHEMA_DEFAULT='lib'
severities = ['debug', 'warn', 'error', 'none']
@ -157,12 +171,66 @@ def regular_print(color,text,newline=True):
else:
print (text)
def call(cmd, silent=False):
stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
if not stderr:
return stdin.strip()
elif not silent:
color_print(1,'Problem encounted with SCons scripts, please post bug report to: https://github.com/mapnik/mapnik/issues \nError was: %s' % stderr)
def shell_command(cmd, *args, **kwargs):
""" Run command through shell.
`cmd` should be a valid, properly shell-quoted command.
Additional positional arguments, if provided, will each
be individually quoted as necessary and appended to `cmd`,
separated by spaces.
`logstream` optional keyword argument should be either:
- a file-like object, into which the command-line
and the command's STDERR output will be written; or
- None, in which case STDERR will go to DEVNULL.
Additional keyword arguments will be passed to `Popen`.
Returns a tuple `(result, output)` where:
`result` = True if the command completed successfully,
False otherwise
`output` = captured STDOUT with trailing whitespace removed
"""
# `cmd` itself is intentionally not wrapped in `shquote` here
# in order to support passing user-provided commands that may
# include arguments. For example:
#
# ret, out = shell_command(env['CXX'], '--version')
#
# needs to work even if `env['CXX'] == 'ccache c++'`
#
if args:
cmdstr = ' '.join([cmd] + [shquote(a) for a in args])
else:
cmdstr = cmd
# redirect STDERR to `logstream` if provided
try:
logstream = kwargs.pop('logstream')
except KeyError:
logstream = None
else:
if logstream is not None:
logstream.write(cmdstr + '\n')
kwargs['stderr'] = logstream
else:
kwargs['stderr'] = DEVNULL
# execute command and capture output
proc = Popen(cmdstr, shell=True, stdout=PIPE, **kwargs)
out, err = proc.communicate()
try:
outtext = out.decode(sys.stdout.encoding or 'UTF-8').rstrip()
except UnicodeDecodeError:
outtext = out.decode('UTF-8', errors='replace').rstrip()
if logstream is not None and outtext:
logstream.write('->\t' + outtext.replace('\n', '\n->\t') + '\n')
return proc.returncode == 0, outtext
def silent_command(cmd, *args):
return shell_command(cmd, *args, stderr=DEVNULL)
def config_command(cmd, *args):
return shell_command(cmd, *args, logstream=conf.logstream)
def strip_first(string,find,replace=''):
if string.startswith(find):
@ -578,19 +646,22 @@ def prioritize_paths(context, silent=True):
def CheckPKGConfig(context, version):
context.Message( 'Checking for pkg-config... ' )
ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
context.sconf.cached = False
ret, _ = config_command('pkg-config --atleast-pkgconfig-version', version)
context.Result( ret )
return ret
def CheckPKG(context, name):
context.Message( 'Checking for %s... ' % name )
ret = context.TryAction('pkg-config --exists \'%s\'' % name)[0]
context.sconf.cached = False
ret, _ = config_command('pkg-config --exists', name)
context.Result( ret )
return ret
def CheckPKGVersion(context, name, version):
context.Message( 'Checking for at least version %s for %s... ' % (version,name) )
ret = context.TryAction('pkg-config --atleast-version=%s \'%s\'' % (version,name))[0]
context.sconf.cached = False
ret, _ = config_command('pkg-config --atleast-version', version, name)
context.Result( ret )
return ret
@ -601,8 +672,9 @@ def parse_config(context, config, checks='--libs --cflags'):
if config in ('GDAL_CONFIG'):
toolname += ' %s' % checks
context.Message( 'Checking for %s... ' % toolname)
context.sconf.cached = False
cmd = '%s %s' % (env[config], checks)
ret = context.TryAction(cmd)[0]
ret, value = config_command(cmd)
parsed = False
if ret:
try:
@ -613,7 +685,6 @@ def parse_config(context, config, checks='--libs --cflags'):
# and thus breaks knowledge below that gdal worked
# TODO - upgrade our scons logic to support Framework linking
if env['PLATFORM'] == 'Darwin':
value = call(cmd,silent=True)
if value and '-framework GDAL' in value:
env['LIBS'].append('gdal')
if os.path.exists('/Library/Frameworks/GDAL.framework/unix/lib'):
@ -643,12 +714,11 @@ def get_pkg_lib(context, config, lib):
libname = None
env = context.env
context.Message( 'Checking for name of %s library... ' % lib)
cmd = '%s --libs' % env[config]
ret = context.TryAction(cmd)[0]
context.sconf.cached = False
ret, value = config_command(env[config], '--libs')
parsed = False
if ret:
try:
value = call(cmd, silent=True).decode("utf8")
if ' ' in value:
parts = value.split(' ')
if len(parts) > 1:
@ -671,10 +741,10 @@ def parse_pg_config(context, config):
env = context.env
tool = config.lower()
context.Message( 'Checking for %s... ' % tool)
ret = context.TryAction(env[config])[0]
context.sconf.cached = False
ret, lib_path = config_command(env[config], '--libdir')
ret, inc_path = config_command(env[config], '--includedir')
if ret:
lib_path = call('%s --libdir' % env[config]).decode("utf8")
inc_path = call('%s --includedir' % env[config]).decode("utf8")
env.AppendUnique(CPPPATH = fix_path(inc_path))
env.AppendUnique(LIBPATH = fix_path(lib_path))
lpq = env['PLUGINS']['postgis']['lib']
@ -688,7 +758,10 @@ def parse_pg_config(context, config):
def ogr_enabled(context):
env = context.env
context.Message( 'Checking if gdal is ogr enabled... ')
ret = context.TryAction('%s --ogr-enabled' % env['GDAL_CONFIG'])[0]
context.sconf.cached = False
ret, out = config_command(env['GDAL_CONFIG'], '--ogr-enabled')
if ret and out:
ret = (out == 'yes')
if not ret:
if 'ogr' not in env['SKIPPED_DEPS']:
env['SKIPPED_DEPS'].append('ogr')
@ -833,10 +906,10 @@ int main() {
context.Result('u_getDataDirectory returned %s' % ret[1])
return ret[1].strip()
else:
ret = call("icu-config --icudatadir", silent=True)
ret, value = config_command('icu-config --icudatadir')
if ret:
context.Result('icu-config returned %s' % ret.decode("utf8"))
return ret.decode('utf8')
context.Result('icu-config returned %s' % value)
return value
else:
context.Result('Failed to detect (mapnik-config will have null value)')
return ''
@ -1274,11 +1347,11 @@ if not preconfigured:
env['PLATFORM'] = platform.uname()[0]
color_print(4,"Configuring on %s in *%s*..." % (env['PLATFORM'],mode))
cxx_version = call("%s --version" % env["CXX"] ,silent=True)
if cxx_version:
color_print(5, "CXX %s" % cxx_version.decode("utf8"))
ret, cxx_version = config_command(env['CXX'], '--version')
if ret:
color_print(5, "C++ compiler: %s" % cxx_version)
else:
color_print(5, "Could not detect CXX compiler")
color_print(5, "Could not detect C++ compiler")
env['MISSING_DEPS'] = []
env['SKIPPED_DEPS'] = []