custom.py revision f8aeb1c990b6e127497da1e46e0e4cdcb67ce9b3
197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca"""custom
297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé FonsecaCustom builders and methods.
497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca"""
697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca#
897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# All Rights Reserved.
1097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca#
1197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# Permission is hereby granted, free of charge, to any person obtaining a
1297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# copy of this software and associated documentation files (the
1397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# "Software"), to deal in the Software without restriction, including
1497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# without limitation the rights to use, copy, modify, merge, publish,
1597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# distribute, sub license, and/or sell copies of the Software, and to
1697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# permit persons to whom the Software is furnished to do so, subject to
1797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# the following conditions:
1897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca#
1997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# The above copyright notice and this permission notice (including the
2097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# next paragraph) shall be included in all copies or substantial portions
2197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# of the Software.
2297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca#
2397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
2797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca#
3197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
3297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
3397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport os
3497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport os.path
3597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport re
36235225ec935002b4669d14a48c9c20864a5496f8José Fonsecaimport sys
37235225ec935002b4669d14a48c9c20864a5496f8José Fonsecaimport subprocess
3897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
3997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport SCons.Action
4097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport SCons.Builder
4197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport SCons.Scanner
4297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
4397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport fixes
4497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
45582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wuimport source_list
4697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
4797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef quietCommandLines(env):
4897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # Quiet command lines
4997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # See also http://www.scons.org/wiki/HidingCommandLinesInOutput
5097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['ASCOMSTR'] = "  Assembling $SOURCE ..."
5197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['ASPPCOMSTR'] = "  Assembling $SOURCE ..."
5297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['CCCOMSTR'] = "  Compiling $SOURCE ..."
5397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['SHCCCOMSTR'] = "  Compiling $SOURCE ..."
5497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['CXXCOMSTR'] = "  Compiling $SOURCE ..."
5597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['SHCXXCOMSTR'] = "  Compiling $SOURCE ..."
5697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['ARCOMSTR'] = "  Archiving $TARGET ..."
5797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['RANLIBCOMSTR'] = "  Indexing $TARGET ..."
5897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['LINKCOMSTR'] = "  Linking $TARGET ..."
5997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['SHLINKCOMSTR'] = "  Linking $TARGET ..."
6097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['LDMODULECOMSTR'] = "  Linking $TARGET ..."
6197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['SWIGCOMSTR'] = "  Generating $TARGET ..."
6254d8c5e3c2fc7db643a2bae61be203ab9cbb1efaJosé Fonseca    env['LEXCOMSTR'] = "  Generating $TARGET ..."
6354d8c5e3c2fc7db643a2bae61be203ab9cbb1efaJosé Fonseca    env['YACCCOMSTR'] = "  Generating $TARGET ..."
642311e2adf0db3c46a1054d94cdfcd2ec0badbfd3José Fonseca    env['CODEGENCOMSTR'] = "  Generating $TARGET ..."
6537058c3497850f452bdaf70a5dda07ee4840b6b9José Fonseca    env['INSTALLSTR'] = "  Installing $TARGET ..."
6697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
6797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
6897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef createConvenienceLibBuilder(env):
6997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    """This is a utility function that creates the ConvenienceLibrary
7097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    Builder in an Environment if it is not there already.
7197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
7297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    If it is already there, we return the existing one.
7397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
7497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    Based on the stock StaticLibrary and SharedLibrary builders.
7597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    """
7697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
7797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    try:
7897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        convenience_lib = env['BUILDERS']['ConvenienceLibrary']
7997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    except KeyError:
8097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ]
8197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        if env.Detect('ranlib'):
8297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca            ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR")
8397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca            action_list.append(ranlib_action)
8497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
8597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        convenience_lib = SCons.Builder.Builder(action = action_list,
8697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                                  emitter = '$LIBEMITTER',
8797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                                  prefix = '$LIBPREFIX',
8897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                                  suffix = '$LIBSUFFIX',
8997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                                  src_suffix = '$SHOBJSUFFIX',
9097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                                  src_builder = 'SharedObject')
9197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        env['BUILDERS']['ConvenienceLibrary'] = convenience_lib
9297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
9397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    return convenience_lib
9497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
9597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
9697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# TODO: handle import statements with multiple modules
9797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# TODO: handle from import statements
9897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport_re = re.compile(r'^import\s+(\S+)$', re.M)
9997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
10097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef python_scan(node, env, path):
10197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789
10297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    contents = node.get_contents()
10397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    source_dir = node.get_dir()
10497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    imports = import_re.findall(contents)
10597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    results = []
10697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    for imp in imports:
10797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        for dir in path:
10897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca            file = os.path.join(str(dir), imp.replace('.', os.sep) + '.py')
10997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca            if os.path.exists(file):
11097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                results.append(env.File(file))
11197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                break
11297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca            file = os.path.join(str(dir), imp.replace('.', os.sep), '__init__.py')
11397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca            if os.path.exists(file):
11497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                results.append(env.File(file))
11597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                break
11697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    return results
11797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
11897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecapython_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py'])
11997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
12097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
12197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef code_generate(env, script, target, source, command):
12297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    """Method to simplify code generation via python scripts.
12397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
12497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    http://www.scons.org/wiki/UsingCodeGenerators
12597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    http://www.scons.org/doc/0.98.5/HTML/scons-user/c2768.html
12697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    """
12797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
12897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # We're generating code using Python scripts, so we have to be
12997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # careful with our scons elements.  This entry represents
13097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # the generator file *in the source directory*.
13197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    script_src = env.File(script).srcnode()
13297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
13397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # This command creates generated code *in the build directory*.
13497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    command = command.replace('$SCRIPT', script_src.path)
1352311e2adf0db3c46a1054d94cdfcd2ec0badbfd3José Fonseca    action = SCons.Action.Action(command, "$CODEGENCOMSTR")
1362311e2adf0db3c46a1054d94cdfcd2ec0badbfd3José Fonseca    code = env.Command(target, source, action)
13797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
13897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # Explicitly mark that the generated code depends on the generator,
13997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # and on implicitly imported python modules
14097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    path = (script_src.get_dir(),)
14197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    deps = [script_src]
14297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    deps += script_src.get_implicit_deps(env, python_scanner, path)
14397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env.Depends(code, deps)
14497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
14597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # Running the Python script causes .pyc files to be generated in the
14697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # source directory.  When we clean up, they should go too. So add side
14797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # effects for .pyc files
14897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    for dep in deps:
14997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        pyc = env.File(str(dep) + 'c')
15097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        env.SideEffect(pyc, code)
15197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
15297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    return code
15397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
15497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
15597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef createCodeGenerateMethod(env):
15697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env.Append(SCANNERS = python_scanner)
15797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env.AddMethod(code_generate, 'CodeGenerate')
15897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
15997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
160235225ec935002b4669d14a48c9c20864a5496f8José Fonsecadef _pkg_check_modules(env, name, modules):
161235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    '''Simple wrapper for pkg-config.'''
162235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
163235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env['HAVE_' + name] = False
164235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
165235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    # For backwards compatability
166235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env[name.lower()] = False
167235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
168235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    if env['platform'] == 'windows':
169235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        return
170235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
171235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    if not env.Detect('pkg-config'):
172235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        return
173235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
174235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    if subprocess.call(["pkg-config", "--exists", ' '.join(modules)]) != 0:
175235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        return
176235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
177235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    # Other flags may affect the compilation of unrelated targets, so store
178235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    # them with a prefix, (e.g., XXX_CFLAGS, XXX_LIBS, etc)
179235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    try:
180235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        flags = env.ParseFlags('!pkg-config --cflags --libs ' + ' '.join(modules))
181235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    except OSError:
182235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        return
183235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    prefix = name + '_'
184235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    for flag_name, flag_value in flags.iteritems():
185235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        assert '_' not in flag_name
186235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        env[prefix + flag_name] = flag_value
187235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
188235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env['HAVE_' + name] = True
189235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
190235225ec935002b4669d14a48c9c20864a5496f8José Fonsecadef pkg_check_modules(env, name, modules):
191235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
192235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    sys.stdout.write('Checking for %s...' % name)
193235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    _pkg_check_modules(env, name, modules)
194235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    result = env['HAVE_' + name]
195235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    sys.stdout.write(' %s\n' % ['no', 'yes'][int(bool(result))])
196235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
197235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    # XXX: For backwards compatability
198235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env[name.lower()] = result
199235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
200235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
201235225ec935002b4669d14a48c9c20864a5496f8José Fonsecadef pkg_use_modules(env, names):
202235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    '''Search for all environment flags that match NAME_FOO and append them to
203235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    the FOO environment variable.'''
204235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
205235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    names = env.Flatten(names)
206235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
207235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    for name in names:
208235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        prefix = name + '_'
209235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
210235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        if not 'HAVE_' + name in env:
211f8aeb1c990b6e127497da1e46e0e4cdcb67ce9b3José Fonseca            raise Exception('Attempt to use unknown module %s' % name)
212235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
213235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        if not env['HAVE_' + name]:
214f8aeb1c990b6e127497da1e46e0e4cdcb67ce9b3José Fonseca            raise Exception('Attempt to use unavailable module %s' % name)
215235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
216235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        flags = {}
217235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        for flag_name, flag_value in env.Dictionary().iteritems():
218235225ec935002b4669d14a48c9c20864a5496f8José Fonseca            if flag_name.startswith(prefix):
219235225ec935002b4669d14a48c9c20864a5496f8José Fonseca                flag_name = flag_name[len(prefix):]
220235225ec935002b4669d14a48c9c20864a5496f8José Fonseca                if '_' not in flag_name:
221235225ec935002b4669d14a48c9c20864a5496f8José Fonseca                    flags[flag_name] = flag_value
222235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        if flags:
223235225ec935002b4669d14a48c9c20864a5496f8José Fonseca            env.MergeFlags(flags)
224235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
225235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
226235225ec935002b4669d14a48c9c20864a5496f8José Fonsecadef createPkgConfigMethods(env):
227235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env.AddMethod(pkg_check_modules, 'PkgCheckModules')
228235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env.AddMethod(pkg_use_modules, 'PkgUseModules')
229235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
230235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
231582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wudef parse_source_list(env, filename, names=None):
232582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    # parse the source list file
233582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    parser = source_list.SourceListParser()
234582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    src = env.File(filename).srcnode()
235582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    sym_table = parser.parse(src.abspath)
236582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
237582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    if names:
238582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        if isinstance(names, basestring):
239582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu            names = [names]
240582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
241582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        symbols = names
242582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    else:
243582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        symbols = sym_table.keys()
244582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
245582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    # convert the symbol table to source lists
246582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    src_lists = {}
247582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    for sym in symbols:
248582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        val = sym_table[sym]
249582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        src_lists[sym] = [f for f in val.split(' ') if f]
250582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
251582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    # if names are given, concatenate the lists
252582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    if names:
253582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        srcs = []
254582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        for name in names:
255582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu            srcs.extend(src_lists[name])
256582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
257582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        return srcs
258582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    else:
259582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        return src_lists
260582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
261582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wudef createParseSourceListMethod(env):
262582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    env.AddMethod(parse_source_list, 'ParseSourceList')
263582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
264582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
26597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef generate(env):
26697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    """Common environment generation code"""
26797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
268c7bd0fa4851187c3102948f5f4d70c26d1b55a5eJosé Fonseca    verbose = env.get('verbose', False) or not env.get('quiet', True)
269c7bd0fa4851187c3102948f5f4d70c26d1b55a5eJosé Fonseca    if not verbose:
27097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        quietCommandLines(env)
27197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
27297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # Custom builders and methods
27397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    createConvenienceLibBuilder(env)
27497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    createCodeGenerateMethod(env)
275235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    createPkgConfigMethods(env)
276582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    createParseSourceListMethod(env)
27797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
27897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # for debugging
27997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    #print env.Dump()
28097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
28197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
28297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef exists(env):
28397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    return 1
284