| # 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/. |
| |
| STANDALONE_MAKEFILE := 1 |
| |
| include $(topsrcdir)/config/rules.mk |
| |
| # Building XPIDLs effectively consists of two steps: |
| # |
| # 1) Staging all .idl files to a common directory. |
| # 2) Doing everything with the .idl files. |
| # |
| # Each .idl file is processed into a .h file and typelib information. |
| # The .h file shares the same stem as the input file and is installed |
| # in the common headers include directory. |
| # |
| # XPIDL files are logically grouped together by modules. The typelib |
| # information for all XPIDLs in the same module is linked together into |
| # an .xpt file having the name of the module. |
| # |
| # As an optimization to reduce overall CPU usage, we process all .idl |
| # belonging to a module with a single command invocation. This prevents |
| # redundant parsing of .idl files and significantly reduces CPU cycles. |
| |
| # For dependency files. |
| idl_deps_dir := .deps |
| |
| dist_idl_dir := $(DIST)/idl |
| dist_include_dir := $(DIST)/include |
| process_py := $(topsrcdir)/python/mozbuild/mozbuild/action/xpidl-process.py |
| |
| # TODO we should use py_action, but that would require extra directories to be |
| # in the virtualenv. |
| %.xpt: |
| @echo "$(@F)" |
| $(PYTHON_PATH) $(PLY_INCLUDE) -I$(IDL_PARSER_DIR) -I$(IDL_PARSER_CACHE_DIR) \ |
| $(process_py) --cache-dir $(IDL_PARSER_CACHE_DIR) --depsdir $(idl_deps_dir) \ |
| $(dist_idl_dir) $(dist_include_dir) $(@D) $(libxul_sdk_includes) \ |
| $(basename $(notdir $@)) $($(basename $(notdir $@))_deps) |
| # When some IDL is added or removed, if the actual IDL file was already, or |
| # still is, in the tree, simple dependencies can't detect that the XPT needs |
| # to be rebuilt. |
| # Add the current value of $($(xpidl_module)_deps) in the depend file, such that |
| # we can later check if the value has changed since last build, which will |
| # indicate whether IDLs were added or removed. |
| # Note that removing previously built files is not covered. |
| @echo $(basename $(notdir $@))_deps_built = $($(basename $(notdir $@))_deps) >> $(idl_deps_dir)/$(basename $(notdir $@)).pp |
| |
| # Chrome manifests may be written from several Makefiles at various times during |
| # the build. The 'buildlist' action adds to the file if it already exists, but |
| # if it does exist, make considers it to be up-to-date (as we have no inputs to |
| # depend on). We use FORCE to ensure that we always add the interface manifest, |
| # whether or not the chrome manifest already exists. |
| %/chrome.manifest: FORCE |
| $(call py_action,buildlist,$@ 'manifest components/interfaces.manifest') |
| |
| chrome_manifests := @chrome_manifests@ |
| |
| %/interfaces.manifest: Makefile |
| $(call py_action,buildlist,$@ $(foreach xpt,$(filter $*/%,$(registered_xpt_files)),'interfaces $(notdir $(xpt))')) |
| |
| interfaces_manifests := @interfaces_manifests@ |
| |
| xpidl_modules := @xpidl_modules@ |
| registered_xpt_files := @registered_xpt_files@ |
| xpt_files := $(registered_xpt_files) @xpt_files@ |
| |
| @xpidl_rules@ |
| |
| depends_files := $(foreach root,$(xpidl_modules),$(idl_deps_dir)/$(root).pp) |
| |
| GARBAGE += $(xpt_files) $(depends_files) |
| |
| xpidl:: $(xpt_files) $(chrome_manifests) $(interfaces_manifests) |
| |
| $(xpt_files): $(process_py) $(call mkdir_deps,$(idl_deps_dir) $(dist_include_dir)) |
| |
| -include $(depends_files) |
| |
| define xpt_deps |
| $(1): $(call mkdir_deps,$(dir $(1))) |
| $(1): $(addsuffix .idl,$(addprefix $(dist_idl_dir)/,$($(basename $(notdir $(1)))_deps))) |
| ifneq ($($(basename $(notdir $(1)))_deps),$($(basename $(notdir $(1)))_deps_built)) |
| $(1): FORCE |
| endif |
| endef |
| |
| $(foreach xpt,$(xpt_files),$(eval $(call xpt_deps,$(xpt)))) |
| |
| .PHONY: xpidl |