author Wes Kocher <>
Mon, 09 Dec 2013 20:45:54 -0800
changeset 159631 cd37573496575d867f6951fba24584da42787081
parent 158016 11b3857b72cb2d17e53d4c2d29af816d83fd24e7
child 160360 f9614eb176adce6995f4c26afc125e804ba065c2
permissions -rw-r--r--
Merge m-c to inbound

# 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

webidl_base = $(topsrcdir)/dom/webidl
# Generated by

binding_include_path := mozilla/dom
webidl_files += $(generated_events_webidl_files)
all_webidl_files = $(webidl_files) $(generated_webidl_files) $(preprocessed_webidl_files)

# Set exported_binding_headers before adding the test IDL to the mix
exported_binding_headers := $(subst .webidl,Binding.h,$(all_webidl_files))
exported_generated_events_headers := $(subst .webidl,.h,$(generated_events_webidl_files))

# Set linked_binding_cpp_files before adding the test IDL to the mix
linked_binding_cpp_files := $(subst .webidl,Binding.cpp,$(all_webidl_files))
linked_generated_events_cpp_files := $(subst .webidl,.cpp,$(generated_events_webidl_files))

all_webidl_files += $(test_webidl_files) $(preprocessed_test_webidl_files)

generated_header_files := $(subst .webidl,Binding.h,$(all_webidl_files)) $(exported_generated_events_headers)
generated_cpp_files := $(subst .webidl,Binding.cpp,$(all_webidl_files)) $(linked_generated_events_cpp_files)

# We want to be able to only regenerate the .cpp and .h files that really need
# to change when a .webidl file changes.  We do this by making the
# binding_dependency_trackers targets have dependencies on the right .webidl
# files via generated .pp files, having a .BindingGen target that depends on the
# binding_dependency_trackers and which has all the generated binding .h/.cpp
# depending on it, and then in the make commands for that target being able to
# check which exact binding_dependency_trackers changed.
binding_dependency_trackers := $(subst .webidl,Binding,$(all_webidl_files))

globalgen_targets := \
  GeneratedAtomList.h \
  PrototypeList.h \
  RegisterBindings.h \
  RegisterBindings.cpp \
  UnionTypes.h \
  UnionTypes.cpp \
  UnionConversions.h \

# Nasty hack: when the test/ invokes us to do codegen, it
# uses a target of
# "export TestExampleInterface-example TestExampleProxyInterface-example".
# We don't actually need to load our .o.pp files in that case, so just
# pretend like we have no CPPSRCS if that's the target.  It makes the
# test cycle much faster, which is why we're doing it.
# XXXbz We could try to cheat even more and only include our CPPSRCS
# when $(MAKECMDGOALS) contains libs, so that we can skip loading all
# those .o.pp when trying to make a single .cpp file too, but that
# would break |make FooBinding.o(bj)|.  Ah, well.
ifneq (export TestExampleInterface-example TestExampleProxyInterface-example,$(MAKECMDGOALS))
  $(unified_binding_cpp_files) \
  $(linked_generated_events_cpp_files) \
  $(filter %.cpp, $(globalgen_targets)) \

ABS_DIST := $(abspath $(DIST))

EXTRA_EXPORT_MDDEPEND_FILES := $(addsuffix .pp,$(binding_dependency_trackers))

EXPORTS_GENERATED_FILES := $(exported_binding_headers) $(exported_generated_events_headers)
EXPORTS_GENERATED_DEST := $(ABS_DIST)/include/$(binding_include_path)

# Install auto-generated GlobalGen files. The rules for the install must
# be in the same target/subtier as, otherwise the files will not
# get installed into the appropriate location as they are generated.
globalgen_headers_FILES := \
  GeneratedAtomList.h \
  PrototypeList.h \
  RegisterBindings.h \
  UnionConversions.h \
  UnionTypes.h \
globalgen_headers_DEST = $(ABS_DIST)/include/mozilla/dom
globalgen_headers_TARGET := export
INSTALL_TARGETS += globalgen_headers

include $(topsrcdir)/config/

ifdef GNU_CC
CXXFLAGS += -Wno-uninitialized

# If you change bindinggen_dependencies here, change it in
# dom/bindings/test/ too.
bindinggen_dependencies := \ \
  Bindings.conf \ \ \
  ParserResults.pkl \
  parser/ \

CSS2Properties.webidl: $(topsrcdir)/layout/style/nsCSSPropList.h \
                       $(topsrcdir)/layout/style/nsCSSPropAliasList.h \
                       $(webidl_base)/ \
                       $(webidl_base)/CSS2PropertiesProps.h \
                       $(srcdir)/ \
	$(CPP) $(DEFINES) $(ACDEFINES) -I$(topsrcdir)/layout/style $(webidl_base)/CSS2PropertiesProps.h | \
	  $(srcdir)/ $(webidl_base)/ > CSS2Properties.webidl

$(webidl_files): %: $(webidl_base)/%
	$(INSTALL) $(IFLAGS1) $(webidl_base)/$* .

$(test_webidl_files): %: $(srcdir)/test/%
	$(INSTALL) $(IFLAGS1) $(srcdir)/test/$* .

# We can't easily use PP_TARGETS here because it insists on outputting targets
# that look like "$(CURDIR)/foo" whereas we want our target to just be "foo".
# Make sure to include $(GLOBAL_DEPS) so we pick up changes to what symbols are
# defined.  Also make sure to remove $@ before writing to it, because otherwise
# if a file goes from non-preprocessed to preprocessed we can end up writing to
# a symlink, which will clobber files in the srcdir, which is bad.
$(preprocessed_webidl_files): %: $(webidl_base)/% $(GLOBAL_DEPS)
	$(RM) $@
	$(call py_action,preprocessor, \
          $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $(webidl_base)/$* -o $@)

# See the comment about PP_TARGETS for $(preprocessed_webidl_files)
$(preprocessed_test_webidl_files): %: $(srcdir)/test/% $(GLOBAL_DEPS)
	$(RM) $@
	$(call py_action,preprocessor, \
          $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $(srcdir)/test/$* -o $@)

# Make is dumb and can get confused between "foo" and "$(CURDIR)/foo".  Make
# sure that the latter depends on the former, since the latter gets used in .pp
# files.
all_webidl_files_absolute = $(addprefix $(CURDIR)/,$(all_webidl_files))
$(all_webidl_files_absolute): $(CURDIR)/%: %

$(generated_header_files): .BindingGen

$(generated_cpp_files): .BindingGen

# $(binding_dependency_trackers) pick up additional dependencies via .pp files
# The rule: just brings the tracker up to date, if it's out of date, so that
# we'll know that we have to redo binding generation and flag this prerequisite
# there as being newer than the bindinggen target.
	@$(TOUCH) $@

$(globalgen_targets): ParserResults.pkl

%-example: .BindingGen
	PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/ \
	  $(PLY_INCLUDE) -I$(srcdir)/parser \
	  $(srcdir)/ \
	  $(srcdir)/Bindings.conf $*

CACHE_DIR = _cache

globalgen_dependencies := \ \
  Bindings.conf \ \ \
  parser/ \ \
  $(all_webidl_files) \
  $(CACHE_DIR)/.done \

	@$(TOUCH) $@

# Running updates ParserResults.pkl as a side-effect
ParserResults.pkl: $(globalgen_dependencies)
	$(info Generating global WebIDL files)
	PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/ \
	  $(PLY_INCLUDE) -I$(srcdir)/parser \
	  $(srcdir)/ $(srcdir)/Bindings.conf . \
	  --cachedir=$(CACHE_DIR) \

$(globalgen_headers_FILES): ParserResults.pkl

# Make sure .deps actually exists, since we'll try to write to it from
# but we're typically running in the export phase, which is
# before anyone has bothered creating .deps.
# Then, pass our long lists through files to try to avoid blowing out the
# command line.
# Next, will examine the changed dependency list to figure out
# what it really needs to regenerate.
# Finally, touch the .BindingGen file so that we don't have to keep redoing
# all that until something else actually changes.
.BindingGen: $(bindinggen_dependencies) $(binding_dependency_trackers)
	$(info Generating WebIDL bindings)
	$(MKDIR) -p .deps
	echo $(all_webidl_files) > .all-webidl-file-list
	echo $(generated_events_webidl_files) > .generated-events-webidl-files
	echo $? > .changed-dependency-list
	PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/ \
	  $(PLY_INCLUDE) -I$(srcdir)/parser \
	  $(srcdir)/ \
	  $(srcdir)/Bindings.conf \
	  $(CURDIR) \
	  .all-webidl-file-list \
	  .generated-events-webidl-files \
	@$(TOUCH) $@

GARBAGE += \ \
  parser.out \
  $(wildcard *-example.h) \
  $(wildcard *-example.cpp) \
  .BindingGen \
  .all-webidl-file-list \
  .generated-events-webidl-files \
  .changed-dependency-list \
  $(binding_dependency_trackers) \

# Make sure all binding header files are created during the export stage, so we
# don't have issues with .cpp files being compiled before we've generated the
# headers they depend on.  This is really only needed for the test files, since
# the non-test headers are all exported above anyway.  Note that this means that
# we do all of our codegen during export.
export:: $(generated_header_files)

	-$(RM) \
        $(generated_header_files) \
        $(generated_cpp_files) \
        $(all_webidl_files) \
        $(globalgen_targets) \
        ParserResults.pkl \