197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca"""custom
297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé FonsecaCustom builders and methods.
497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca"""
697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca#
8877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca# Copyright 2008 VMware, Inc.
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.
26877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca# IN NO EVENT SHALL VMWARE 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.path
34235225ec935002b4669d14a48c9c20864a5496f8José Fonsecaimport sys
35235225ec935002b4669d14a48c9c20864a5496f8José Fonsecaimport subprocess
36c521f2d7373a241a69238b95a8c0f3725a9da5adJosé Fonsecaimport modulefinder
3797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
3897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport SCons.Action
3997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport SCons.Builder
4097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport SCons.Scanner
4197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
4297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport fixes
4397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
44582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wuimport source_list
4597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
461b62b47f6fcaf5a825a5a909c91e802bffae3b1dGiuseppe Bilotta# the get_implicit_deps() method changed between 2.4 and 2.5: now it expects
471b62b47f6fcaf5a825a5a909c91e802bffae3b1dGiuseppe Bilotta# a callable that takes a scanner as argument and returns a path, rather than
481b62b47f6fcaf5a825a5a909c91e802bffae3b1dGiuseppe Bilotta# a path directly. We want to support both, so we need to detect the SCons version,
491b62b47f6fcaf5a825a5a909c91e802bffae3b1dGiuseppe Bilotta# for which no API is provided by SCons 8-P
501b62b47f6fcaf5a825a5a909c91e802bffae3b1dGiuseppe Bilotta
511b62b47f6fcaf5a825a5a909c91e802bffae3b1dGiuseppe Bilottascons_version = tuple(map(int, SCons.__version__.split('.')))
521b62b47f6fcaf5a825a5a909c91e802bffae3b1dGiuseppe Bilotta
5397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef quietCommandLines(env):
5497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # Quiet command lines
5597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # See also http://www.scons.org/wiki/HidingCommandLinesInOutput
5697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['ASCOMSTR'] = "  Assembling $SOURCE ..."
5797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['ASPPCOMSTR'] = "  Assembling $SOURCE ..."
5897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['CCCOMSTR'] = "  Compiling $SOURCE ..."
5997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['SHCCCOMSTR'] = "  Compiling $SOURCE ..."
6097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['CXXCOMSTR'] = "  Compiling $SOURCE ..."
6197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['SHCXXCOMSTR'] = "  Compiling $SOURCE ..."
6297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['ARCOMSTR'] = "  Archiving $TARGET ..."
6397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['RANLIBCOMSTR'] = "  Indexing $TARGET ..."
6497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['LINKCOMSTR'] = "  Linking $TARGET ..."
6597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['SHLINKCOMSTR'] = "  Linking $TARGET ..."
6697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['LDMODULECOMSTR'] = "  Linking $TARGET ..."
6797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env['SWIGCOMSTR'] = "  Generating $TARGET ..."
6854d8c5e3c2fc7db643a2bae61be203ab9cbb1efaJosé Fonseca    env['LEXCOMSTR'] = "  Generating $TARGET ..."
6954d8c5e3c2fc7db643a2bae61be203ab9cbb1efaJosé Fonseca    env['YACCCOMSTR'] = "  Generating $TARGET ..."
702311e2adf0db3c46a1054d94cdfcd2ec0badbfd3José Fonseca    env['CODEGENCOMSTR'] = "  Generating $TARGET ..."
7137058c3497850f452bdaf70a5dda07ee4840b6b9José Fonseca    env['INSTALLSTR'] = "  Installing $TARGET ..."
7297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
7397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
7497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef createConvenienceLibBuilder(env):
7597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    """This is a utility function that creates the ConvenienceLibrary
7697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    Builder in an Environment if it is not there already.
7797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
7897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    If it is already there, we return the existing one.
7997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
8097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    Based on the stock StaticLibrary and SharedLibrary builders.
8197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    """
8297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
8397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    try:
8497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        convenience_lib = env['BUILDERS']['ConvenienceLibrary']
8597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    except KeyError:
8697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ]
8797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        if env.Detect('ranlib'):
8897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca            ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR")
8997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca            action_list.append(ranlib_action)
9097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
9197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        convenience_lib = SCons.Builder.Builder(action = action_list,
9297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                                  emitter = '$LIBEMITTER',
9397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                                  prefix = '$LIBPREFIX',
9497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                                  suffix = '$LIBSUFFIX',
9597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                                  src_suffix = '$SHOBJSUFFIX',
9697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca                                  src_builder = 'SharedObject')
9797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        env['BUILDERS']['ConvenienceLibrary'] = convenience_lib
9897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
9997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    return convenience_lib
10097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
10197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
10297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef python_scan(node, env, path):
10397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789
104c521f2d7373a241a69238b95a8c0f3725a9da5adJosé Fonseca    # https://docs.python.org/2/library/modulefinder.html
10597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    contents = node.get_contents()
106b12606b693210fb6b327ec7cc7be6d9f79940198José Fonseca
107b12606b693210fb6b327ec7cc7be6d9f79940198José Fonseca    # Tell ModuleFinder to search dependencies in the script dir, and the glapi
108b12606b693210fb6b327ec7cc7be6d9f79940198José Fonseca    # dirs
109b12606b693210fb6b327ec7cc7be6d9f79940198José Fonseca    source_dir = node.get_dir().abspath
110b12606b693210fb6b327ec7cc7be6d9f79940198José Fonseca    GLAPI = env.Dir('#src/mapi/glapi/gen').abspath
111b12606b693210fb6b327ec7cc7be6d9f79940198José Fonseca    path = [source_dir, GLAPI] + sys.path
112b12606b693210fb6b327ec7cc7be6d9f79940198José Fonseca
113b12606b693210fb6b327ec7cc7be6d9f79940198José Fonseca    finder = modulefinder.ModuleFinder(path=path)
114c521f2d7373a241a69238b95a8c0f3725a9da5adJosé Fonseca    finder.run_script(node.abspath)
11597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    results = []
116c521f2d7373a241a69238b95a8c0f3725a9da5adJosé Fonseca    for name, mod in finder.modules.iteritems():
117c521f2d7373a241a69238b95a8c0f3725a9da5adJosé Fonseca        if mod.__file__ is None:
118c521f2d7373a241a69238b95a8c0f3725a9da5adJosé Fonseca            continue
119c521f2d7373a241a69238b95a8c0f3725a9da5adJosé Fonseca        assert os.path.exists(mod.__file__)
120c521f2d7373a241a69238b95a8c0f3725a9da5adJosé Fonseca        results.append(env.File(mod.__file__))
12197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    return results
12297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
12397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecapython_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py'])
12497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
12597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
12697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef code_generate(env, script, target, source, command):
12797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    """Method to simplify code generation via python scripts.
12897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
12997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    http://www.scons.org/wiki/UsingCodeGenerators
13097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    http://www.scons.org/doc/0.98.5/HTML/scons-user/c2768.html
13197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    """
13297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
13397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # We're generating code using Python scripts, so we have to be
13497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # careful with our scons elements.  This entry represents
13597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # the generator file *in the source directory*.
13697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    script_src = env.File(script).srcnode()
13797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
13897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # This command creates generated code *in the build directory*.
13997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    command = command.replace('$SCRIPT', script_src.path)
1402311e2adf0db3c46a1054d94cdfcd2ec0badbfd3José Fonseca    action = SCons.Action.Action(command, "$CODEGENCOMSTR")
1412311e2adf0db3c46a1054d94cdfcd2ec0badbfd3José Fonseca    code = env.Command(target, source, action)
14297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
14397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # Explicitly mark that the generated code depends on the generator,
14497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # and on implicitly imported python modules
1451b62b47f6fcaf5a825a5a909c91e802bffae3b1dGiuseppe Bilotta    path = (script_src.get_dir(),) if scons_version < (2, 5, 0) else lambda x: script_src
14697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    deps = [script_src]
14797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    deps += script_src.get_implicit_deps(env, python_scanner, path)
14897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env.Depends(code, deps)
14997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
15097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # Running the Python script causes .pyc files to be generated in the
15197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # source directory.  When we clean up, they should go too. So add side
15297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # effects for .pyc files
15397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    for dep in deps:
15497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        pyc = env.File(str(dep) + 'c')
15597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        env.SideEffect(pyc, code)
15697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
15797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    return code
15897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
15997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
16097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef createCodeGenerateMethod(env):
16197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env.Append(SCANNERS = python_scanner)
16297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    env.AddMethod(code_generate, 'CodeGenerate')
16397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
16497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
165235225ec935002b4669d14a48c9c20864a5496f8José Fonsecadef _pkg_check_modules(env, name, modules):
166235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    '''Simple wrapper for pkg-config.'''
167235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
168235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env['HAVE_' + name] = False
169235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
170235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    # For backwards compatability
171235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env[name.lower()] = False
172235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
173235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    if env['platform'] == 'windows':
174235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        return
175235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
176235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    if not env.Detect('pkg-config'):
177235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        return
178235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
179235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    if subprocess.call(["pkg-config", "--exists", ' '.join(modules)]) != 0:
180235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        return
181235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
1822470e918cc29e5d057a28551ce9c15e7d83fab7eJosé Fonseca    # Strip version expressions from modules
1832470e918cc29e5d057a28551ce9c15e7d83fab7eJosé Fonseca    modules = [module.split(' ', 1)[0] for module in modules]
1842470e918cc29e5d057a28551ce9c15e7d83fab7eJosé Fonseca
185235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    # Other flags may affect the compilation of unrelated targets, so store
186235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    # them with a prefix, (e.g., XXX_CFLAGS, XXX_LIBS, etc)
187235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    try:
188235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        flags = env.ParseFlags('!pkg-config --cflags --libs ' + ' '.join(modules))
189235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    except OSError:
190235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        return
191235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    prefix = name + '_'
192235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    for flag_name, flag_value in flags.iteritems():
193235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        assert '_' not in flag_name
194235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        env[prefix + flag_name] = flag_value
195235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
196235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env['HAVE_' + name] = True
197235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
198235225ec935002b4669d14a48c9c20864a5496f8José Fonsecadef pkg_check_modules(env, name, modules):
199235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
2002470e918cc29e5d057a28551ce9c15e7d83fab7eJosé Fonseca    sys.stdout.write('Checking for %s (%s)...' % (name, ' '.join(modules)))
201235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    _pkg_check_modules(env, name, modules)
202235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    result = env['HAVE_' + name]
203235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    sys.stdout.write(' %s\n' % ['no', 'yes'][int(bool(result))])
204235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
205235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    # XXX: For backwards compatability
206235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env[name.lower()] = result
207235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
208235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
209235225ec935002b4669d14a48c9c20864a5496f8José Fonsecadef pkg_use_modules(env, names):
210235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    '''Search for all environment flags that match NAME_FOO and append them to
211235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    the FOO environment variable.'''
212235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
213235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    names = env.Flatten(names)
214235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
215235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    for name in names:
216235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        prefix = name + '_'
217235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
218235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        if not 'HAVE_' + name in env:
219f8aeb1c990b6e127497da1e46e0e4cdcb67ce9b3José Fonseca            raise Exception('Attempt to use unknown module %s' % name)
220235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
221235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        if not env['HAVE_' + name]:
222f8aeb1c990b6e127497da1e46e0e4cdcb67ce9b3José Fonseca            raise Exception('Attempt to use unavailable module %s' % name)
223235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
224235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        flags = {}
225235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        for flag_name, flag_value in env.Dictionary().iteritems():
226235225ec935002b4669d14a48c9c20864a5496f8José Fonseca            if flag_name.startswith(prefix):
227235225ec935002b4669d14a48c9c20864a5496f8José Fonseca                flag_name = flag_name[len(prefix):]
228235225ec935002b4669d14a48c9c20864a5496f8José Fonseca                if '_' not in flag_name:
229235225ec935002b4669d14a48c9c20864a5496f8José Fonseca                    flags[flag_name] = flag_value
230235225ec935002b4669d14a48c9c20864a5496f8José Fonseca        if flags:
231235225ec935002b4669d14a48c9c20864a5496f8José Fonseca            env.MergeFlags(flags)
232235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
233235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
234235225ec935002b4669d14a48c9c20864a5496f8José Fonsecadef createPkgConfigMethods(env):
235235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env.AddMethod(pkg_check_modules, 'PkgCheckModules')
236235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    env.AddMethod(pkg_use_modules, 'PkgUseModules')
237235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
238235225ec935002b4669d14a48c9c20864a5496f8José Fonseca
239582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wudef parse_source_list(env, filename, names=None):
240582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    # parse the source list file
241582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    parser = source_list.SourceListParser()
242582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    src = env.File(filename).srcnode()
243ea8dcfc90d5abbf699cd64be4dccd1e69fe82d75José Fonseca
24450dec637909cfe8fa53582f2f64ab261b123f092José Fonseca    cur_srcdir = env.Dir('.').srcnode().abspath
24550dec637909cfe8fa53582f2f64ab261b123f092José Fonseca    top_srcdir = env.Dir('#').abspath
24650dec637909cfe8fa53582f2f64ab261b123f092José Fonseca    top_builddir = os.path.join(top_srcdir, env['build_dir'])
24750dec637909cfe8fa53582f2f64ab261b123f092José Fonseca
24806424376065a4a1e44920a29497936691d88598fJosé Fonseca    # Normalize everything to / slashes
24906424376065a4a1e44920a29497936691d88598fJosé Fonseca    cur_srcdir = cur_srcdir.replace('\\', '/')
25006424376065a4a1e44920a29497936691d88598fJosé Fonseca    top_srcdir = top_srcdir.replace('\\', '/')
25106424376065a4a1e44920a29497936691d88598fJosé Fonseca    top_builddir = top_builddir.replace('\\', '/')
25206424376065a4a1e44920a29497936691d88598fJosé Fonseca
25350dec637909cfe8fa53582f2f64ab261b123f092José Fonseca    # Populate the symbol table of the Makefile parser.
25450dec637909cfe8fa53582f2f64ab261b123f092José Fonseca    parser.add_symbol('top_srcdir', top_srcdir)
25550dec637909cfe8fa53582f2f64ab261b123f092José Fonseca    parser.add_symbol('top_builddir', top_builddir)
256ea8dcfc90d5abbf699cd64be4dccd1e69fe82d75José Fonseca
257582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    sym_table = parser.parse(src.abspath)
258582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
259582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    if names:
260582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        if isinstance(names, basestring):
261582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu            names = [names]
262582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
263582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        symbols = names
264582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    else:
265582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        symbols = sym_table.keys()
266582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
267582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    # convert the symbol table to source lists
268582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    src_lists = {}
269582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    for sym in symbols:
270582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        val = sym_table[sym]
27150dec637909cfe8fa53582f2f64ab261b123f092José Fonseca        srcs = []
27250dec637909cfe8fa53582f2f64ab261b123f092José Fonseca        for f in val.split():
27350dec637909cfe8fa53582f2f64ab261b123f092José Fonseca            if f:
27450dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                # Process source paths
27550dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                if f.startswith(top_builddir + '/src'):
27606424376065a4a1e44920a29497936691d88598fJosé Fonseca                    # Automake puts build output on a `src` subdirectory, but
27706424376065a4a1e44920a29497936691d88598fJosé Fonseca                    # SCons does not, so strip it here.
27850dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                    f = top_builddir + f[len(top_builddir + '/src'):]
27950dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                if f.startswith(cur_srcdir + '/'):
28050dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                    # Prefer relative source paths, as absolute files tend to
28150dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                    # cause duplicate actions.
28250dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                    f = f[len(cur_srcdir + '/'):]
283d4a1f3fd270001b2fb0684dc981340391df8fb64José Fonseca                # do not include any headers
2842da28dbd11e835ddc17e7656087b6f84c6f950baGeorge Kyriazis                if f.endswith(tuple(['.h','.hpp'])):
285d4a1f3fd270001b2fb0684dc981340391df8fb64José Fonseca                    continue
28650dec637909cfe8fa53582f2f64ab261b123f092José Fonseca                srcs.append(f)
28750dec637909cfe8fa53582f2f64ab261b123f092José Fonseca
28850dec637909cfe8fa53582f2f64ab261b123f092José Fonseca        src_lists[sym] = srcs
289582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
290582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    # if names are given, concatenate the lists
291582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    if names:
292582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        srcs = []
293582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        for name in names:
294582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu            srcs.extend(src_lists[name])
295582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
296582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        return srcs
297582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    else:
298582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu        return src_lists
299582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
300582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wudef createParseSourceListMethod(env):
301582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    env.AddMethod(parse_source_list, 'ParseSourceList')
302582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
303582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu
30497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef generate(env):
30597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    """Common environment generation code"""
30697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
307c7bd0fa4851187c3102948f5f4d70c26d1b55a5eJosé Fonseca    verbose = env.get('verbose', False) or not env.get('quiet', True)
308c7bd0fa4851187c3102948f5f4d70c26d1b55a5eJosé Fonseca    if not verbose:
30997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca        quietCommandLines(env)
31097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
31197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # Custom builders and methods
31297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    createConvenienceLibBuilder(env)
31397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    createCodeGenerateMethod(env)
314235225ec935002b4669d14a48c9c20864a5496f8José Fonseca    createPkgConfigMethods(env)
315582b5d869c0f05814d4d567636a743d3fdddf431Chia-I Wu    createParseSourceListMethod(env)
31697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
31797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    # for debugging
31897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    #print env.Dump()
31997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
32097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca
32197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef exists(env):
32297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca    return 1
323