dom/bindings/BindingGen.py
author Boris Zbarsky <bzbarsky@mit.edu>
Thu, 09 May 2013 13:05:33 -0400
changeset 143187 712d3684efe44cff7d6963ba3d8af0d58e80f802
parent 139393 4f857bd3df51e8f1c1a20331d8d090a470ae34e8
child 143188 59c279d93f8e268449e5153b1330e9d254ea4f8a
permissions -rw-r--r--
Bug 861587. Rejigger the WebIDL binding build system to do all binding codegen in a single python process while still using our dependency tracking for bindings to minimize the number of bindings we try to regenerate. r=khuey

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.

import os
import cPickle
from Configuration import Configuration
from Codegen import CGBindingRoot, replaceFileIfChanged

def generate_binding_files(config, outputprefix, srcprefix, webidlfile):
    """
    |config| Is the configuration object.
    |outputprefix| is a prefix to use for the header guards and filename.
    """

    depsname = ".deps/" + outputprefix + ".pp"
    root = CGBindingRoot(config, outputprefix, webidlfile)
    replaceFileIfChanged(outputprefix + ".h", root.declare())
    replaceFileIfChanged(outputprefix + ".cpp", root.define())

    with open(depsname, 'wb') as f:
        # Sort so that our output is stable
        f.write("\n".join(outputprefix + ": " + os.path.join(srcprefix, x) for
                          x in sorted(root.deps())))

def main():
    # Parse arguments.
    from optparse import OptionParser
    usagestring = "usage: %prog [header|cpp] configFile outputPrefix srcPrefix webIDLFile"
    o = OptionParser(usage=usagestring)
    o.add_option("--verbose-errors", action='store_true', default=False,
                 help="When an error happens, display the Python traceback.")
    (options, args) = o.parse_args()

    configFile = os.path.normpath(args[0])
    srcPrefix = os.path.normpath(args[1])

    # Load the parsing results
    f = open('ParserResults.pkl', 'rb')
    parserData = cPickle.load(f)
    f.close()

    # Create the configuration data.
    config = Configuration(configFile, parserData)

    def readFile(f):
        file = open(f, 'rb')
        try:
            contents = file.read()
        finally:
            file.close()
        return contents
    allWebIDLFiles = readFile(args[2]).split()
    changedDeps = readFile(args[3]).split()

    if all(f.endswith("Binding") or f == "ParserResults.pkl" for f in changedDeps):
        toRegenerate = filter(lambda f: f.endswith("Binding"), changedDeps)
        toRegenerate = map(lambda f: f[:-len("Binding")] + ".webidl", toRegenerate)
    else:
        toRegenerate = allWebIDLFiles

    for webIDLFile in toRegenerate:
        assert webIDLFile.endswith(".webidl")
        outputPrefix = webIDLFile[:-len(".webidl")] + "Binding"
        generate_binding_files(config, outputPrefix, srcPrefix, webIDLFile);

if __name__ == '__main__':
    main()