X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=scons%2Fcustom.py;h=277c05b67975e43d8cbe851df9eaa80c6f0c83d4;hb=bcfd51f8c45be2ee99f302ed3310c34998b19ff6;hp=572b963388a8819fd4ed3c8adcbf5c9640ee3104;hpb=3e18bad36d90255dca6cb519eb7ecfc540c292c1;p=mesa.git diff --git a/scons/custom.py b/scons/custom.py index 572b963388a..277c05b6797 100644 --- a/scons/custom.py +++ b/scons/custom.py @@ -33,6 +33,8 @@ Custom builders and methods. import os import os.path import re +import sys +import subprocess import SCons.Action import SCons.Builder @@ -40,6 +42,7 @@ import SCons.Scanner import fixes +import source_list def quietCommandLines(env): # Quiet command lines @@ -56,6 +59,10 @@ def quietCommandLines(env): env['SHLINKCOMSTR'] = " Linking $TARGET ..." env['LDMODULECOMSTR'] = " Linking $TARGET ..." env['SWIGCOMSTR'] = " Generating $TARGET ..." + env['LEXCOMSTR'] = " Generating $TARGET ..." + env['YACCCOMSTR'] = " Generating $TARGET ..." + env['CODEGENCOMSTR'] = " Generating $TARGET ..." + env['INSTALLSTR'] = " Installing $TARGET ..." def createConvenienceLibBuilder(env): @@ -125,7 +132,8 @@ def code_generate(env, script, target, source, command): # This command creates generated code *in the build directory*. command = command.replace('$SCRIPT', script_src.path) - code = env.Command(target, source, command) + action = SCons.Action.Action(command, "$CODEGENCOMSTR") + code = env.Command(target, source, action) # Explicitly mark that the generated code depends on the generator, # and on implicitly imported python modules @@ -149,15 +157,149 @@ def createCodeGenerateMethod(env): env.AddMethod(code_generate, 'CodeGenerate') +def _pkg_check_modules(env, name, modules): + '''Simple wrapper for pkg-config.''' + + env['HAVE_' + name] = False + + # For backwards compatability + env[name.lower()] = False + + if env['platform'] == 'windows': + return + + if not env.Detect('pkg-config'): + return + + if subprocess.call(["pkg-config", "--exists", ' '.join(modules)]) != 0: + return + + # Strip version expressions from modules + modules = [module.split(' ', 1)[0] for module in modules] + + # Other flags may affect the compilation of unrelated targets, so store + # them with a prefix, (e.g., XXX_CFLAGS, XXX_LIBS, etc) + try: + flags = env.ParseFlags('!pkg-config --cflags --libs ' + ' '.join(modules)) + except OSError: + return + prefix = name + '_' + for flag_name, flag_value in flags.iteritems(): + assert '_' not in flag_name + env[prefix + flag_name] = flag_value + + env['HAVE_' + name] = True + +def pkg_check_modules(env, name, modules): + + sys.stdout.write('Checking for %s (%s)...' % (name, ' '.join(modules))) + _pkg_check_modules(env, name, modules) + result = env['HAVE_' + name] + sys.stdout.write(' %s\n' % ['no', 'yes'][int(bool(result))]) + + # XXX: For backwards compatability + env[name.lower()] = result + + +def pkg_use_modules(env, names): + '''Search for all environment flags that match NAME_FOO and append them to + the FOO environment variable.''' + + names = env.Flatten(names) + + for name in names: + prefix = name + '_' + + if not 'HAVE_' + name in env: + raise Exception('Attempt to use unknown module %s' % name) + + if not env['HAVE_' + name]: + raise Exception('Attempt to use unavailable module %s' % name) + + flags = {} + for flag_name, flag_value in env.Dictionary().iteritems(): + if flag_name.startswith(prefix): + flag_name = flag_name[len(prefix):] + if '_' not in flag_name: + flags[flag_name] = flag_value + if flags: + env.MergeFlags(flags) + + +def createPkgConfigMethods(env): + env.AddMethod(pkg_check_modules, 'PkgCheckModules') + env.AddMethod(pkg_use_modules, 'PkgUseModules') + + +def parse_source_list(env, filename, names=None): + # parse the source list file + parser = source_list.SourceListParser() + src = env.File(filename).srcnode() + + cur_srcdir = env.Dir('.').srcnode().abspath + top_srcdir = env.Dir('#').abspath + top_builddir = os.path.join(top_srcdir, env['build_dir']) + + # Populate the symbol table of the Makefile parser. + parser.add_symbol('top_srcdir', top_srcdir) + parser.add_symbol('top_builddir', top_builddir) + + sym_table = parser.parse(src.abspath) + + if names: + if isinstance(names, basestring): + names = [names] + + symbols = names + else: + symbols = sym_table.keys() + + # convert the symbol table to source lists + src_lists = {} + for sym in symbols: + val = sym_table[sym] + srcs = [] + for f in val.split(): + if f: + # Process source paths + if f.startswith(top_builddir + '/src'): + # Automake puts build output on a `src` subdirectory, bue + # SCons does no, so strip it here. + f = top_builddir + f[len(top_builddir + '/src'):] + if f.startswith(cur_srcdir + '/'): + # Prefer relative source paths, as absolute files tend to + # cause duplicate actions. + f = f[len(cur_srcdir + '/'):] + srcs.append(f) + + src_lists[sym] = srcs + + # if names are given, concatenate the lists + if names: + srcs = [] + for name in names: + srcs.extend(src_lists[name]) + + return srcs + else: + return src_lists + +def createParseSourceListMethod(env): + env.AddMethod(parse_source_list, 'ParseSourceList') + + def generate(env): """Common environment generation code""" - if env.get('quiet', True): + verbose = env.get('verbose', False) or not env.get('quiet', True) + if not verbose: quietCommandLines(env) # Custom builders and methods createConvenienceLibBuilder(env) createCodeGenerateMethod(env) + createPkgConfigMethods(env) + createParseSourceListMethod(env) # for debugging #print env.Dump()