Bug 629668 - Don't rebuild IPDL files when not necessary; r=cjones

This commit is contained in:
Benoit Girard 2011-12-15 15:10:35 +00:00
Родитель 5baad23d88
Коммит 1ac32258fc
4 изменённых файлов: 92 добавлений и 18 удалений

Просмотреть файл

@ -112,15 +112,19 @@ include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk
-include $(ALL_IPDLSRCS:.ipdl=.ipdl.depends)
# NB: the IPDL compiler manages .ipdl-->.h/.cpp dependencies itself, # NB: the IPDL compiler manages .ipdl-->.h/.cpp dependencies itself,
# which is why we don't have explicit .h/.cpp targets here # 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 \ $(PYTHON) $(topsrcdir)/config/pythonpath.py \
-I$(topsrcdir)/other-licenses/ply \ -I$(topsrcdir)/other-licenses/ply \
$(srcdir)/ipdl.py \ $(srcdir)/ipdl.py \
--outheaders-dir=_ipdlheaders \ --outheaders-dir=_ipdlheaders \
--outcpp-dir=. \ --outcpp-dir=. \
--dependencies \
$(IPDLDIRS:%=-I$(topsrcdir)/%) \ $(IPDLDIRS:%=-I$(topsrcdir)/%) \
$^ $^

Просмотреть файл

@ -59,12 +59,15 @@ op.add_option('-o', '--outcpp-dir', dest='cppdir', default='.',
A protocol Foo in the namespace bar will cause the sources A protocol Foo in the namespace bar will cause the sources
cppdir/FooParent.cpp, cppdir/FooChild.cpp cppdir/FooParent.cpp, cppdir/FooChild.cpp
to be generated""") 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() options, files = op.parse_args()
_verbosity = options.verbosity _verbosity = options.verbosity
headersdir = options.headersdir headersdir = options.headersdir
cppdir = options.cppdir cppdir = options.cppdir
emitdependencies = options.emitdependencies
includedirs = [ os.path.abspath(incdir) for incdir in options.includedirs ] includedirs = [ os.path.abspath(incdir) for incdir in options.includedirs ]
if not len(files): if not len(files):
@ -106,6 +109,9 @@ for f in files:
log(3, ' pretty printed code:') log(3, ' pretty printed code:')
ipdl.genipdl(ast, codedir) ipdl.genipdl(ast, codedir)
if emitdependencies == 1:
ipdl.genm(ast, cppdir, normalizedFilename(f))
# Second pass: generate code # Second pass: generate code
for f in files: for f in files:
# Read from parser cache # Read from parser cache
@ -140,5 +146,5 @@ COMPILE_ASSERT(LastMsgIndex <= 65536, need_to_update_IPC_MESSAGE_MACRO);
#endif // ifndef IPCMessageStart_h #endif // ifndef IPCMessageStart_h
""" """
ipdl.writeifmodified(ipcmsgstart.getvalue(), ipdl.writetofile(ipcmsgstart.getvalue(),
os.path.join(headersdir, 'IPCMessageStart.h')) os.path.join(headersdir, 'IPCMessageStart.h'))

Просмотреть файл

@ -30,12 +30,13 @@
# #
# ***** END LICENSE BLOCK ***** # ***** 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 cStringIO import StringIO
from ipdl.cgen import IPDLCodeGen from ipdl.cgen import IPDLCodeGen
from ipdl.mgen import DependGen
from ipdl.lower import LowerToCxx from ipdl.lower import LowerToCxx
from ipdl.parser import Parser from ipdl.parser import Parser
from ipdl.type import TypeCheck from ipdl.type import TypeCheck
@ -72,23 +73,32 @@ def gencxx(ipdlfilename, ast, outheadersdir, outcppdir):
+ [ resolveCpp(cpp) for cpp in cpps ]): + [ resolveCpp(cpp) for cpp in cpps ]):
tempfile = StringIO() tempfile = StringIO()
CxxCodeGen(tempfile).cgen(ast) CxxCodeGen(tempfile).cgen(ast)
writeifmodified(tempfile.getvalue(), filename) writetofile(tempfile.getvalue(), filename)
def genipdl(ast, outdir): def genipdl(ast, outdir):
return IPDLCodeGen().cgen(ast) return IPDLCodeGen().cgen(ast)
def writeifmodified(contents, file): def genm(ast, dir, filename):
dir = os.path.dirname(file) tempfile = StringIO()
os.path.exists(dir) or os.makedirs(dir) DependGen(tempfile).mgen(ast)
filename = dir + "/" + os.path.basename(filename) + ".depends"
writetofile(tempfile.getvalue(), filename)
oldcontents = None
if os.path.exists(file): def writetofile(contents, file):
fd = open(file, 'rb') dir = os.path.dirname(file)
oldcontents = fd.read()
fd.close() # Guard against race condition by using Try instead
if oldcontents != contents: # of |os.path.exists(dir) or os.makedirs(dir)|
fd = open(file, 'wb') try:
fd.write(contents) os.makedirs(dir)
fd.close() 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()

54
ipc/ipdl/ipdl/mgen.py Normal file
Просмотреть файл

@ -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();