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
1772470e918cc29e5d057a28551ce9c15e7d83fab7eJosé Fonseca    # Strip version expressions from modules
1782470e918cc29e5d057a28551ce9c15e7d83fab7eJosé Fonseca    modules = [module.split(' ', 1)[0] for module in modules]
1792470e918cc29e5d057a28551ce9c15e7d83fab7eJosé Fonseca
180235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    # Other flags may affect the compilation of unrelated targets, so store
181235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    # them with a prefix, (e.g., XXX_CFLAGS, XXX_LIBS, etc)
182235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    try:
183235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        flags = env.ParseFlags('!pkg-config --cflags --libs ' + ' '.join(modules))
184235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    except OSError:
185235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        return
186235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    prefix = name + '_'
187235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    for flag_name, flag_value in flags.iteritems():
188235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        assert '_' not in flag_name
189235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        env[prefix + flag_name] = flag_value
190235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
191235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env['HAVE_' + name] = True
192235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
193235225ec935002b4669d14a48c9c20864a5496f8José Fonsecadef pkg_check_modules(env, name, modules):
194235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
1952470e918cc29e5d057a28551ce9c15e7d83fab7eJosé Fonseca    sys.stdout.write('Checking for %s (%s)...' % (name, ' '.join(modules)))
196235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    _pkg_check_modules(env, name, modules)
197235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    result = env['HAVE_' + name]
198235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    sys.stdout.write(' %s\n' % ['no', 'yes'][int(bool(result))])
199235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
200235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    # XXX: For backwards compatability
201235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env[name.lower()] = result
202235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
203235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
204235225ec935002b4669d14a48c9c20864a5496f8José Fonsecadef pkg_use_modules(env, names):
205235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    '''Search for all environment flags that match NAME_FOO and append them to
206235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    the FOO environment variable.'''
207235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
208235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    names = env.Flatten(names)
209235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
210235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    for name in names:
211235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        prefix = name + '_'
212235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
213235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        if not 'HAVE_' + name in env:
214f8aeb1c990b6e127497da1e46e0e4cdcb67ce9b3José Fonseca            raise Exception('Attempt to use unknown module %s' % name)
215235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
216235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        if not env['HAVE_' + name]:
217f8aeb1c990b6e127497da1e46e0e4cdcb67ce9b3José Fonseca            raise Exception('Attempt to use unavailable module %s' % name)
218235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
219235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        flags = {}
220235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        for flag_name, flag_value in env.Dictionary().iteritems():
221235225ec935002b4669d14a48c9c20864a5496f8José Fonseca            if flag_name.startswith(prefix):
222235225ec935002b4669d14a48c9c20864a5496f8José Fonseca                flag_name = flag_name[len(prefix):]
223235225ec935002b4669d14a48c9c20864a5496f8José Fonseca                if '_' not in flag_name:
224235225ec935002b4669d14a48c9c20864a5496f8José Fonseca                    flags[flag_name] = flag_value
225235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        if flags:
226235225ec935002b4669d14a48c9c20864a5496f8José Fonseca            env.MergeFlags(flags)
227235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
228235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
229235225ec935002b4669d14a48c9c20864a5496f8José Fonsecadef createPkgConfigMethods(env):
230235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env.AddMethod(pkg_check_modules, 'PkgCheckModules')
231235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env.AddMethod(pkg_use_modules, 'PkgUseModules')
232235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
233235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
234582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wudef parse_source_list(env, filename, names=None):
235582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    # parse the source list file
236582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    parser = source_list.SourceListParser()
237582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    src = env.File(filename).srcnode()
238ea8dcfc90d5abbf699cd64be4dccd1e69fe82d75José Fonseca
23950dec637909cfe8fa53582f2f64ab261b123f092José Fonseca    cur_srcdir = env.Dir('.').srcnode().abspath
24050dec637909cfe8fa53582f2f64ab261b123f092José Fonseca    top_srcdir = env.Dir('#').abspath
24150dec637909cfe8fa53582f2f64ab261b123f092José Fonseca    top_builddir = os.path.join(top_srcdir, env['build_dir'])
24250dec637909cfe8fa53582f2f64ab261b123f092José Fonseca
24350dec637909cfe8fa53582f2f64ab261b123f092José Fonseca    # Populate the symbol table of the Makefile parser.
24450dec637909cfe8fa53582f2f64ab261b123f092José Fonseca    parser.add_symbol('top_srcdir', top_srcdir)
24550dec637909cfe8fa53582f2f64ab261b123f092José Fonseca    parser.add_symbol('top_builddir', top_builddir)
246ea8dcfc90d5abbf699cd64be4dccd1e69fe82d75José Fonseca
247582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    sym_table = parser.parse(src.abspath)
248582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
249582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    if names:
250582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        if isinstance(names, basestring):
251582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu            names = [names]
252582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
253582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        symbols = names
254582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    else:
255582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        symbols = sym_table.keys()
256582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
257582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    # convert the symbol table to source lists
258582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    src_lists = {}
259582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    for sym in symbols:
260582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        val = sym_table[sym]
26150dec637909cfe8fa53582f2f64ab261b123f092José Fonseca        srcs = []
26250dec637909cfe8fa53582f2f64ab261b123f092José Fonseca        for f in val.split():
26350dec637909cfe8fa53582f2f64ab261b123f092José Fonseca            if f:
26450dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                # Process source paths
26550dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                if f.startswith(top_builddir + '/src'):
26650dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                    # Automake puts build output on a `src` subdirectory, bue
26750dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                    # SCons does no, so strip it here.
26850dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                    f = top_builddir + f[len(top_builddir + '/src'):]
26950dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                if f.startswith(cur_srcdir + '/'):
27050dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                    # Prefer relative source paths, as absolute files tend to
27150dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                    # cause duplicate actions.
27250dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                    f = f[len(cur_srcdir + '/'):]
27350dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                srcs.append(f)
27450dec637909cfe8fa53582f2f64ab261b123f092José Fonseca
27550dec637909cfe8fa53582f2f64ab261b123f092José Fonseca        src_lists[sym] = srcs
276582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
277582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    # if names are given, concatenate the lists
278582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    if names:
279582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        srcs = []
280582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        for name in names:
281582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu            srcs.extend(src_lists[name])
282582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
283582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        return srcs
284582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    else:
285582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        return src_lists
286582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
287582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wudef createParseSourceListMethod(env):
288582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    env.AddMethod(parse_source_list, 'ParseSourceList')
289582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
290582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
29197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef generate(env):
29297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    """Common environment generation code"""
29397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
294c7bd0fa4851187c3102948f5f4d70c26d1b55a5eJosé Fonseca    verbose = env.get('verbose', False) or not env.get('quiet', True)
295c7bd0fa4851187c3102948f5f4d70c26d1b55a5eJosé Fonseca    if not verbose:
29697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        quietCommandLines(env)
29797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
29897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # Custom builders and methods
29997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    createConvenienceLibBuilder(env)
30097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    createCodeGenerateMethod(env)
301235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    createPkgConfigMethods(env)
302582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    createParseSourceListMethod(env)
30397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
30497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # for debugging
30597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    #print env.Dump()
30697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
30797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
30897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef exists(env):
30997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    return 1
310