author | Benoit Girard <b56girard@gmail.com> |
Thu, 15 Dec 2011 15:10:35 +0000 | |
changeset 82657 | 329274bcfd57f3f68b20d1ccba7b255e8e5a7229 |
parent 82656 | 53a13d60eaf5d1e9d426be66e28475aaf3fac180 |
child 82658 | 49481d05bd7caaa6b4874263eb012e8815aff688 |
push id | 21693 |
push user | bmo@edmorley.co.uk |
push date | Fri, 16 Dec 2011 01:34:58 +0000 |
treeherder | mozilla-central@c8b8b310f27e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | cjones |
bugs | 629668 |
milestone | 11.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/ipc/ipdl/Makefile.in +++ b/ipc/ipdl/Makefile.in @@ -107,23 +107,27 @@ GARBAGE += $(CPPSRCS) LOCAL_INCLUDES += -I$(DEPTH)/ipc/ipdl/_ipdlheaders include $(topsrcdir)/config/config.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk include $(topsrcdir)/config/rules.mk +-include $(ALL_IPDLSRCS:.ipdl=.ipdl.depends) # NB: the IPDL compiler manages .ipdl-->.h/.cpp dependencies itself, # which is why we don't have explicit .h/.cpp targets here -export:: $(ALL_IPDLSRCS) +export:: $(CPPSRCS) + +$(CPPSRCS) : $(ALL_IPDLSRCS) $(PYTHON) $(topsrcdir)/config/pythonpath.py \ -I$(topsrcdir)/other-licenses/ply \ $(srcdir)/ipdl.py \ --outheaders-dir=_ipdlheaders \ --outcpp-dir=. \ + --dependencies \ $(IPDLDIRS:%=-I$(topsrcdir)/%) \ $^ # We #include some things in the dom/plugins/ directory that rely on # toolkit libraries. CXXFLAGS += $(TK_CFLAGS)
--- a/ipc/ipdl/ipdl.py +++ b/ipc/ipdl/ipdl.py @@ -54,22 +54,25 @@ op.add_option('-d', '--outheaders-dir', A protocol Foo in the namespace bar will cause the headers dir/bar/Foo.h, dir/bar/FooParent.h, and dir/bar/FooParent.h to be generated""") op.add_option('-o', '--outcpp-dir', dest='cppdir', default='.', help="""Directory into which C++ sources will be generated A protocol Foo in the namespace bar will cause the sources cppdir/FooParent.cpp, cppdir/FooChild.cpp to be generated""") +op.add_option('-m', '--dependencies', dest='emitdependencies', default=False, action='store_true', + help="Emit Makefile dependencies for incremental rebuilds") options, files = op.parse_args() _verbosity = options.verbosity headersdir = options.headersdir cppdir = options.cppdir +emitdependencies = options.emitdependencies includedirs = [ os.path.abspath(incdir) for incdir in options.includedirs ] if not len(files): op.error("No IPDL files specified") log(2, 'Generated C++ headers will be generated relative to "%s"', headersdir) log(2, 'Generated C++ sources will be generated in "%s"', cppdir) @@ -101,23 +104,26 @@ for f in files: if not ipdl.typecheck(ast): print >>sys.stderr, 'Specification is not well typed.' sys.exit(1) if _verbosity > 2: log(3, ' pretty printed code:') ipdl.genipdl(ast, codedir) + if emitdependencies == 1: + ipdl.genm(ast, cppdir, normalizedFilename(f)) + # Second pass: generate code for f in files: # Read from parser cache filename = normalizedFilename(f) ast = ipdl.parse(None, filename, includedirs=includedirs) ipdl.gencxx(filename, ast, headersdir, cppdir) - + allprotocols.append('%sMsgStart' % ast.protocol.name) allprotocols.sort() ipcmsgstart = StringIO() print >>ipcmsgstart, """ // CODE GENERATED by ipdl.py. Do not edit. @@ -135,10 +141,10 @@ print >>ipcmsgstart, """ LastMsgIndex }; COMPILE_ASSERT(LastMsgIndex <= 65536, need_to_update_IPC_MESSAGE_MACRO); #endif // ifndef IPCMessageStart_h """ -ipdl.writeifmodified(ipcmsgstart.getvalue(), +ipdl.writetofile(ipcmsgstart.getvalue(), os.path.join(headersdir, 'IPCMessageStart.h'))
--- a/ipc/ipdl/ipdl/__init__.py +++ b/ipc/ipdl/ipdl/__init__.py @@ -25,22 +25,23 @@ # use your version of this file under the terms of the MPL, indicate your # decision by deleting the provisions above and replace them with the notice # and other provisions required by the GPL or the LGPL. If you do not delete # the provisions above, a recipient may use your version of this file under # the terms of any one of the MPL, the GPL or the LGPL. # # ***** END LICENSE BLOCK ***** -__all__ = [ 'gencxx', 'genipdl', 'parse', 'typecheck', 'writeifmodified' ] +__all__ = [ 'gencxx', 'genipdl', 'parse', 'typecheck', 'writetofile' ] -import os, sys +import os, sys, errno from cStringIO import StringIO from ipdl.cgen import IPDLCodeGen +from ipdl.mgen import DependGen from ipdl.lower import LowerToCxx from ipdl.parser import Parser from ipdl.type import TypeCheck from ipdl.cxx.cgen import CxxCodeGen def parse(specstring, filename='/stdin', includedirs=[ ], errout=sys.stderr): @@ -67,28 +68,37 @@ def gencxx(ipdlfilename, ast, outheaders ] def resolveCpp(cpp): return [ cpp, os.path.join(outcppdir, cpp.name) ] for ast, filename in ([ resolveHeader(hdr) for hdr in headers ] + [ resolveCpp(cpp) for cpp in cpps ]): tempfile = StringIO() CxxCodeGen(tempfile).cgen(ast) - writeifmodified(tempfile.getvalue(), filename) + writetofile(tempfile.getvalue(), filename) def genipdl(ast, outdir): return IPDLCodeGen().cgen(ast) -def writeifmodified(contents, file): +def genm(ast, dir, filename): + tempfile = StringIO() + DependGen(tempfile).mgen(ast) + filename = dir + "/" + os.path.basename(filename) + ".depends" + writetofile(tempfile.getvalue(), filename) + + +def writetofile(contents, file): dir = os.path.dirname(file) - os.path.exists(dir) or os.makedirs(dir) - oldcontents = None - if os.path.exists(file): - fd = open(file, 'rb') - oldcontents = fd.read() - fd.close() - if oldcontents != contents: - fd = open(file, 'wb') - fd.write(contents) - fd.close() + # Guard against race condition by using Try instead + # of |os.path.exists(dir) or os.makedirs(dir)| + try: + os.makedirs(dir) + except OSError, ex: + if ex.errno != errno.EEXIST: + raise ex + # else directory already exists. silently ignore and continue + + fd = open(file, 'wb') + fd.write(contents) + fd.close()
new file mode 100644 --- /dev/null +++ b/ipc/ipdl/ipdl/mgen.py @@ -0,0 +1,54 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# Contributor(s): +# Benoit Girard <bgirard@mozilla.com> +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +import sys + +from ipdl.cgen import CodePrinter +from ipdl.cxx.ast import TypeArray, Visitor + +class DependGen(CodePrinter, Visitor): + def __init__(self, outf=sys.stdout, indentCols=4): + CodePrinter.__init__(self, outf, indentCols) + + def mgen(self, cxxfile): + cxxfile.accept(self) + + def visitTranslationUnit(self, tu): + self.write(tu.filename) + self.write(": ") + + for pinc in tu.protocolIncludes: + self.write(pinc.file) + self.write(" ") + + self.println(); +