Bug 1620133 - Move MIDL handling to moz.build. r=firefox-build-system-reviewers,rstewart
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 28 Aug 2020 01:58:50 +0000
changeset 546735 478edcb2dc6e57d6ed4fae1db26d562f794e2e19
parent 546734 3f6d140abf16111a7ad5a9633a202803bb68e707
child 546736 fdb0f33f3b56fa70106a937dc00888223c23ac4e
push id125184
push usermh@glandium.org
push dateFri, 28 Aug 2020 02:04:40 +0000
treeherderautoland@478edcb2dc6e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfirefox-build-system-reviewers, rstewart
bugs1620133
milestone82.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
Bug 1620133 - Move MIDL handling to moz.build. r=firefox-build-system-reviewers,rstewart The `register` rules are dropped at the same time because nothing actually uses them. Differential Revision: https://phabricator.services.mozilla.com/D88390
accessible/interfaces/gecko/Makefile.in
accessible/interfaces/gecko/moz.build
accessible/interfaces/ia2/Makefile.in
accessible/interfaces/ia2/moz.build
accessible/interfaces/msaa/Makefile.in
accessible/interfaces/msaa/moz.build
accessible/ipc/win/handler/Makefile.in
accessible/ipc/win/handler/moz.build
accessible/ipc/win/typelib/Makefile.in
accessible/ipc/win/typelib/moz.build
build/midl.py
deleted file mode 100644
--- a/accessible/interfaces/gecko/Makefile.in
+++ /dev/null
@@ -1,35 +0,0 @@
-# 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/.
-
-GARBAGE += $(MIDL_GENERATED_FILES) done_gen
-
-MIDL_GENERATED_FILES = \
-  dlldata.c \
-  IGeckoCustom.h \
-  IGeckoCustom_p.c \
-  IGeckoCustom_i.c \
-  IGeckoCustom.tlb \
-  $(NULL)
-
-# Bug 1420119: We need the trailing semicolon here to generate a recipe for the
-# midl targets to avoid timestamp caching issues.
-$(MIDL_GENERATED_FILES): done_gen ;
-
-done_gen: $(srcdir)/IGeckoCustom.idl
-	$(call WINEWRAP,$(MIDL)) $(MIDL_FLAGS) -I $(srcdir_rel) -Oicf $(srcdir_rel)/IGeckoCustom.idl
-	touch $@
-
-export:: done_gen
-
-midl_exports := \
-    IGeckoCustom.h \
-    IGeckoCustom_i.c \
-    $(NULL)
-
-INSTALL_TARGETS += midl_exports
-midl_exports_FILES := $(midl_exports)
-midl_exports_DEST = $(DIST)/include
-midl_exports_TARGET := midl
-
-export:: midl
--- a/accessible/interfaces/gecko/moz.build
+++ b/accessible/interfaces/gecko/moz.build
@@ -1,26 +1,29 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
+GeneratedFile('IGeckoCustom.h', 'IGeckoCustom_p.c', 'IGeckoCustom_i.c',
+              'IGeckoCustom_dlldata.c', 'IGeckoCustom.tlb',
+              inputs=['IGeckoCustom.idl'],
+              script='/build/midl.py', entry_point='midl',
+              flags=['-dlldata', OBJDIR + '/IGeckoCustom_dlldata.c'])
+
 SOURCES += [
-    '!dlldata.c',
+    '!IGeckoCustom_dlldata.c',
     '!IGeckoCustom_i.c',
     '!IGeckoCustom_p.c',
 ]
 
-GENERATED_FILES += [
-    'dlldata.c',
-    'IGeckoCustom.h',
-    'IGeckoCustom.tlb',
-    'IGeckoCustom_i.c',
-    'IGeckoCustom_p.c',
+EXPORTS += [
+    '!IGeckoCustom.h',
+    '!IGeckoCustom_i.c',
 ]
 
 FINAL_LIBRARY = 'xul'
 
 # Suppress warnings from the MIDL generated code.
 if CONFIG['CC_TYPE'] == 'clang-cl':
     CFLAGS += [
         '-Wno-extern-initializer',
deleted file mode 100644
--- a/accessible/interfaces/ia2/Makefile.in
+++ /dev/null
@@ -1,107 +0,0 @@
-# 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/.
-
-IA2DIR        = $(srcdir_rel)/$(DEPTH)/other-licenses/ia2
-
-GARBAGE       += $(MIDL_GENERATED_FILES) \
-                 $(MIDL_UNUSED_GENERATED_FILES) \
-                 midl_done \
-                 typelib_done \
-                 $(NULL)
-
-# Please keep this list in sync with the moz.build file until the rest of this
-# Makefile is ported over.
-MIDL_INTERFACES = \
-  Accessible2.idl \
-  Accessible2_2.idl \
-  Accessible2_3.idl \
-  AccessibleAction.idl \
-  AccessibleApplication.idl \
-  AccessibleComponent.idl \
-  AccessibleDocument.idl \
-  AccessibleEditableText.idl \
-  AccessibleHyperlink.idl \
-  AccessibleHypertext.idl \
-  AccessibleHypertext2.idl \
-  AccessibleImage.idl \
-  AccessibleRelation.idl \
-  AccessibleTable.idl \
-  AccessibleTable2.idl \
-  AccessibleTableCell.idl \
-  AccessibleText.idl \
-  AccessibleText2.idl \
-  AccessibleValue.idl \
-  $(NULL)
-
-# Please keep this list in sync with the moz.build file until the rest of this
-# Makefile is ported over.
-MIDL_ENUMS = \
-  AccessibleEventId.idl \
-  AccessibleRole.idl \
-  AccessibleStates.idl \
-  IA2CommonTypes.idl \
-  $(NULL)
-
-MIDL_LIBRARIES = \
-  IA2Typelib.idl \
-  $(NULL)
-
-MIDL_GENERATED_FILES = \
-  dlldata.c \
-  $(MIDL_ENUMS:%.idl=%.h) \
-  $(MIDL_INTERFACES:%.idl=%_p.c) \
-  $(MIDL_INTERFACES:%.idl=%_i.c) \
-  $(MIDL_INTERFACES:%.idl=%.h) \
-  $(MIDL_LIBRARIES:%.idl=%.tlb) \
-  $(NULL)
-
-# We want to generate a .tlb from MIDL_LIBRARIES, but midl also generates
-# a bunch of .h and .c files that we're not interested in.
-MIDL_UNUSED_GENERATED_FILES = \
-  $(MIDL_LIBRARIES:%.idl=%_p.c) \
-  $(MIDL_LIBRARIES:%.idl=%_i.c) \
-  $(MIDL_LIBRARIES:%.idl=%.h) \
-  $(MIDL_LIBRARIES:%.idl=%.c) \
-  $(NULL)
-
-INSTALL_TARGETS += midl
-midl_FILES := $(filter %.h %_i.c,$(MIDL_GENERATED_FILES))
-midl_DEST = $(DIST)/include
-midl_TARGET := midl
-
-export:: midl
-
-include $(topsrcdir)/config/rules.mk
-
-# generate list of to-be-generated files that are missing
-# but ignore special file dlldata.c and .tlb files
-missing:=$(strip $(foreach onefile,$(strip $(patsubst %.tlb,,$(subst dlldata.c,,$(MIDL_GENERATED_FILES)))),$(if $(wildcard $(onefile)),,$(onefile))))
-
-missing_base:=$(sort $(basename $(subst _p.c,,$(subst _i.c,,$(missing)))))
-
-# Bug 1420119: We need the trailing semicolon here to generate a recipe for the
-# midl targets to avoid timestamp caching issues.
-$(MIDL_GENERATED_FILES) : midl_done typelib_done ;
-
-ifneq ("$(missing)","")
-midl_done : FORCE
-endif
-
-midl_done : $(addprefix $(IA2DIR)/,$(MIDL_INTERFACES) $(MIDL_ENUMS))
-	for idl in $(sort $(subst FORCE,,$?) $(addsuffix .idl,$(addprefix $(IA2DIR)/,$(missing_base)))); do \
-	  $(call WINEWRAP,$(MIDL)) $(MIDL_FLAGS) -app_config -I $(IA2DIR) -Oicf $$idl; \
-	done
-	touch $@
-
-# The intent of this rule is to generate the .tlb file that is referenced in the
-# .rc file for IA2Marshal.dll
-typelib_done : $(addprefix $(srcdir_rel)/,$(MIDL_LIBRARIES))
-	for idl in $?; do \
-	  $(call WINEWRAP,$(MIDL)) $(MIDL_FLAGS) -app_config -I $(IA2DIR) -D _MIDL_DECLARE_WIREM_HANDLE -dlldata `basename $$idl .idl`.c -Oicf $$idl; \
-	done
-	touch $@
-
-# This marshall dll is NOT registered in the installer (agreed to by IA2 participants)
-register::
-	regsvr32 -s $(DIST)/bin/$(SHARED_LIBRARY)
--- a/accessible/interfaces/ia2/moz.build
+++ b/accessible/interfaces/ia2/moz.build
@@ -13,92 +13,83 @@ DEFFILE = 'IA2Marshal.def'
 OS_LIBS += [
     'uuid',
     'kernel32',
     'rpcrt4',
     'ole32',
     'oleaut32',
 ]
 
-GENERATED_FILES += [
-    'Accessible2.h',
-    'Accessible2_2.h',
-    'Accessible2_2_i.c',
-    'Accessible2_2_p.c',
-    'Accessible2_3.h',
-    'Accessible2_3_i.c',
-    'Accessible2_3_p.c',
-    'Accessible2_i.c',
-    'Accessible2_p.c',
-    'AccessibleAction.h',
-    'AccessibleAction_i.c',
-    'AccessibleAction_p.c',
-    'AccessibleApplication.h',
-    'AccessibleApplication_i.c',
-    'AccessibleApplication_p.c',
-    'AccessibleComponent.h',
-    'AccessibleComponent_i.c',
-    'AccessibleComponent_p.c',
-    'AccessibleDocument.h',
-    'AccessibleDocument_i.c',
-    'AccessibleDocument_p.c',
-    'AccessibleEditableText.h',
-    'AccessibleEditableText_i.c',
-    'AccessibleEditableText_p.c',
-    'AccessibleEventId.h',
-    'AccessibleHyperlink.h',
-    'AccessibleHyperlink_i.c',
-    'AccessibleHyperlink_p.c',
-    'AccessibleHypertext.h',
-    'AccessibleHypertext2.h',
-    'AccessibleHypertext2_i.c',
-    'AccessibleHypertext2_p.c',
-    'AccessibleHypertext_i.c',
-    'AccessibleHypertext_p.c',
-    'AccessibleImage.h',
-    'AccessibleImage_i.c',
-    'AccessibleImage_p.c',
-    'AccessibleRelation.h',
-    'AccessibleRelation_i.c',
-    'AccessibleRelation_p.c',
-    'AccessibleRole.h',
-    'AccessibleStates.h',
-    'AccessibleTable.h',
-    'AccessibleTable2.h',
-    'AccessibleTable2_i.c',
-    'AccessibleTable2_p.c',
-    'AccessibleTable_i.c',
-    'AccessibleTable_p.c',
-    'AccessibleTableCell.h',
-    'AccessibleTableCell_i.c',
-    'AccessibleTableCell_p.c',
-    'AccessibleText.h',
-    'AccessibleText2.h',
-    'AccessibleText2_i.c',
-    'AccessibleText2_p.c',
-    'AccessibleText_i.c',
-    'AccessibleText_p.c',
-    'AccessibleValue.h',
-    'AccessibleValue_i.c',
-    'AccessibleValue_p.c',
-    'dlldata.c',
-    'IA2CommonTypes.h',
-    'IA2Typelib.tlb',
+midl_enums = [
+    'AccessibleEventId',
+    'AccessibleRole',
+    'AccessibleStates',
+    'IA2CommonTypes',
 ]
 
-for p in GENERATED_FILES:
-    if p.endswith('.c'):
+midl_interfaces = [
+    'Accessible2',
+    'Accessible2_2',
+    'Accessible2_3',
+    'AccessibleAction',
+    'AccessibleApplication',
+    'AccessibleComponent',
+    'AccessibleDocument',
+    'AccessibleEditableText',
+    'AccessibleHyperlink',
+    'AccessibleHypertext',
+    'AccessibleHypertext2',
+    'AccessibleImage',
+    'AccessibleRelation',
+    'AccessibleTable',
+    'AccessibleTable2',
+    'AccessibleTableCell',
+    'AccessibleText',
+    'AccessibleText2',
+    'AccessibleValue',
+]
+
+for enum in midl_enums:
+    GeneratedFile(enum + '.h', inputs=['/other-licenses/ia2/' + enum + '.idl'],
+                  script='/build/midl.py', entry_point='midl',
+                  flags=['-app_config', '-I', TOPSRCDIR + '/other-licenses/ia2'])
+
+    EXPORTS += ['!' + enum + '.h']
+
+for iface in midl_interfaces:
+    GeneratedFile(iface + '.h', iface + '_p.c', iface + '_i.c', iface + '_dlldata.c',
+                  inputs=['/other-licenses/ia2/' + iface + '.idl'],
+                  script='/build/midl.py', entry_point='midl',
+                  flags=['-app_config', '-I', TOPSRCDIR + '/other-licenses/ia2',
+                         '-dlldata', OBJDIR + '/' + iface + '_dlldata.c'])
+
+    EXPORTS += ['!' + iface + '.h', '!' + iface + '_i.c']
+
+    for p in [iface + '_p.c', iface + '_i.c']:
         SOURCES += ['!%s' % p]
 
         # Give some symbols a unique name in each translation unit, to avoid
         # collisions caused by https://llvm.org/pr41817.
         if CONFIG['CC_TYPE'] == 'clang-cl':
             SOURCES['!%s' % p].flags += ['-DObject_StubDesc=Object_StubDesc__%s' % p[:-2]]
             SOURCES['!%s' % p].flags += ['-DUserMarshalRoutines=UserMarshalRoutines__%s' % p[:-2]]
 
+# Warning: the build system doesn't know about the dependency of IA2Marshal.rc on
+# IA2Typelib.tlb. We rely on the IA2Typelib.h output forcing the command to run
+# during export, before rc files are treated during compile.
+GeneratedFile('IA2Typelib.h', 'IA2Typelib_i.c', 'IA2Typelib.tlb',
+              inputs=['IA2Typelib.idl'], script='/build/midl.py', entry_point='midl',
+              flags=['-app_config', '-I', TOPSRCDIR + '/other-licenses/ia2',
+                     '-D', '_MIDL_DECLARE_WIREM_HANDLE'])
+
+GeneratedFile('dlldata.c', inputs=['!' + iface + '_dlldata.c' for iface in midl_interfaces],
+              script='/build/midl.py', entry_point='merge_dlldata')
+
+SOURCES += ['!dlldata.c']
+
 RCINCLUDE = 'IA2Marshal.rc'
 
 # Suppress warnings from the MIDL generated code.
 if CONFIG['CC_TYPE'] == 'clang-cl':
     CFLAGS += [
         '-Wno-extern-initializer',
         '-Wno-incompatible-pointer-types',
         '-Wno-missing-braces',
deleted file mode 100644
--- a/accessible/interfaces/msaa/Makefile.in
+++ /dev/null
@@ -1,42 +0,0 @@
-# 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/.
-
-GARBAGE += $(MIDL_GENERATED_FILES) done_gen
-
-MIDL_GENERATED_FILES = \
-  dlldata.c \
-  ISimpleDOM.h \
-  ISimpleDOM_i.c \
-  ISimpleDOM_p.c \
-  ISimpleDOM.tlb \
-  $(NULL)
-
-# Bug 1420119: We need the trailing semicolon here to generate a recipe for the
-# midl targets to avoid timestamp caching issues.
-$(MIDL_GENERATED_FILES): done_gen ;
-
-done_gen: $(srcdir)/ISimpleDOM.idl \
-          $(srcdir)/ISimpleDOMNode.idl \
-          $(srcdir)/ISimpleDOMDocument.idl \
-          $(srcdir)/ISimpleDOMText.idl
-	$(call WINEWRAP,$(MIDL)) $(MIDL_FLAGS) -I $(srcdir_rel) -robust -Oicf $(srcdir_rel)/ISimpleDOM.idl
-	touch $@
-
-export:: done_gen
-
-# This marshall dll is also registered in the installer
-register::
-	regsvr32 -s $(DIST)/bin/$(SHARED_LIBRARY)
-
-midl_exports := \
-    ISimpleDOM.h \
-    ISimpleDOM_i.c \
-    $(NULL)
-
-INSTALL_TARGETS += midl_exports
-midl_exports_FILES := $(midl_exports)
-midl_exports_DEST = $(DIST)/include
-midl_exports_TARGET := midl
-
-export:: midl
--- a/accessible/interfaces/msaa/moz.build
+++ b/accessible/interfaces/msaa/moz.build
@@ -1,44 +1,49 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 GeckoSharedLibrary('AccessibleMarshal', linkage=None)
 
+# Missing here, is the notion that changes to the idl files included by
+# ISimpleDOM.idl (e.g. ISimpleDOMNode.idl) should rebuild the outputs.
+GeneratedFile('ISimpleDOM.h', 'ISimpleDOM_p.c', 'ISimpleDOM_i.c',
+              'ISimpleDOM_dlldata.c', 'ISimpleDOM.tlb',
+              inputs=['ISimpleDOM.idl'],
+              script='/build/midl.py', entry_point='midl',
+              flags=['-I', SRCDIR, '-robust', '-dlldata', OBJDIR + '/ISimpleDOM_dlldata.c'])
+
 SOURCES += [
-    '!dlldata.c',
+    '!ISimpleDOM_dlldata.c',
     '!ISimpleDOM_i.c',
     '!ISimpleDOM_p.c',
     'AccessibleMarshalThunk.c',
 ]
 
+EXPORTS += [
+    '!ISimpleDOM.h',
+    '!ISimpleDOM_i.c',
+]
+
 DEFINES['REGISTER_PROXY_DLL'] = True
 # The following line is required to preserve compatibility with older versions
 # of AccessibleMarshal.dll.
 DEFINES['PROXY_CLSID'] = 'IID_ISimpleDOMNode'
 
 DEFFILE = 'AccessibleMarshal.def'
 
 OS_LIBS += [
     'kernel32',
     'rpcrt4',
     'oleaut32',
 ]
 
-GENERATED_FILES += [
-    'dlldata.c',
-    'ISimpleDOM.h',
-    'ISimpleDOM.tlb',
-    'ISimpleDOM_i.c',
-    'ISimpleDOM_p.c',
-]
-
 RCINCLUDE = 'AccessibleMarshal.rc'
 
 # Suppress warnings from the MIDL generated code.
 if CONFIG['CC_TYPE'] == 'clang-cl':
     CFLAGS += [
         '-Wno-extern-initializer',
         '-Wno-incompatible-pointer-types',
         '-Wno-missing-braces',
deleted file mode 100644
--- a/accessible/ipc/win/handler/Makefile.in
+++ /dev/null
@@ -1,40 +0,0 @@
-# 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/.
-
-IA2DIR = $(srcdir_rel)/$(DEPTH)/other-licenses/ia2
-MSAADIR = $(srcdir_rel)/$(DEPTH)/accessible/interfaces/msaa
-GARBAGE += $(MIDL_GENERATED_FILES) midl_done
-
-MIDL_GENERATED_FILES = \
-  dlldata.c \
-  HandlerData.h \
-  HandlerData_c.c \
-  HandlerData_i.c \
-  HandlerData_p.c \
-  HandlerData.tlb \
-  $(NULL)
-
-export:: $(MIDL_GENERATED_FILES)
-
-# Bug 1420119: We need the trailing semicolon here to generate a recipe for the
-# midl targets to avoid timestamp caching issues.
-$(MIDL_GENERATED_FILES): midl_done ;
-
-midl_done: $(srcdir)/HandlerData.acf $(srcdir)/HandlerData.idl
-	$(call WINEWRAP,$(MIDL)) $(MIDL_FLAGS) $(DEFINES) -I $(DEPTH) -I $(DEPTH)/dist/include -I $(IA2DIR) -I $(MSAADIR) -Oicf -acf $(srcdir_rel)/HandlerData.acf $(srcdir_rel)/HandlerData.idl
-	touch $@
-
-INSTALL_TARGETS += midl
-midl_FILES := HandlerData.h \
-              HandlerData_i.c \
-              $(NULL)
-midl_DEST := $(DIST)/include
-midl_TARGET := midl
-
-export:: midl
-
-register::
-	regsvr32 -s $(DIST)/bin/$(SHARED_LIBRARY)
-
-include $(topsrcdir)/config/rules.mk
--- a/accessible/ipc/win/handler/moz.build
+++ b/accessible/ipc/win/handler/moz.build
@@ -11,45 +11,59 @@ EXPORTS.mozilla.a11y += [
     'HandlerDataCleanup.h',
 ]
 
 LOCAL_INCLUDES += [
     '/accessible/interfaces/ia2',
     '/ipc/mscom/oop',
 ]
 
+# We want to generate distinct UUIDs on a per-channel basis, so we need
+# finer granularity than the standard preprocessor definitions offer.
+# These defines allow us to separate local builds from automated builds,
+# as well as separate beta from release.
+flags = []
+if CONFIG['MOZ_UPDATE_CHANNEL'] == 'default':
+    flags += ['-DUSE_LOCAL_UUID']
+elif CONFIG['MOZ_UPDATE_CHANNEL'] == 'beta':
+    flags += ['-DUSE_BETA_UUID']
+
+GeneratedFile('HandlerData.h', 'HandlerData_p.c', 'HandlerData_i.c', 'HandlerData_c.c',
+              'HandlerData_dlldata.c', 'HandlerData.tlb',
+              inputs=['HandlerData.idl'],
+              script='/build/midl.py', entry_point='midl',
+              flags=flags + ['-I', TOPOBJDIR, '-I', TOPOBJDIR + '/dist/include',
+                             '-I', TOPSRCDIR + '/other-licenses/ia2', '-I', SRCDIR,
+                             '-acf', SRCDIR + '/HandlerData.acf',
+                             '-dlldata', OBJDIR + '/HandlerData_dlldata.c'])
+
 SOURCES += [
-    '!dlldata.c',
     '!HandlerData_c.c',
+    '!HandlerData_dlldata.c',
     '!HandlerData_i.c',
     '!HandlerData_p.c',
     'AccessibleHandler.cpp',
     'AccessibleHandlerControl.cpp',
     'HandlerChildEnumerator.cpp',
     'HandlerRelation.cpp',
     'HandlerTextLeaf.cpp',
 ]
 
-GENERATED_FILES += [
-    'dlldata.c',
-    'HandlerData.h',
-    'HandlerData.tlb',
-    'HandlerData_c.c',
-    'HandlerData_i.c',
-    'HandlerData_p.c',
+EXPORTS += [
+    '!HandlerData.h',
+    '!HandlerData_i.c',
 ]
 
 # Give some symbols a unique name in each translation unit, to avoid
 # collisions caused by https://llvm.org/pr41817.
 if CONFIG['CC_TYPE'] == 'clang-cl':
     SOURCES['!HandlerData_p.c'].flags += ['-DHandlerData__MIDL_ProcFormatString=HandlerData__MIDL_ProcFormatString__HandlerData_p']
     SOURCES['!HandlerData_p.c'].flags += ['-DHandlerData__MIDL_TypeFormatString=HandlerData__MIDL_TypeFormatString__HandlerData_p']
-    for p in GENERATED_FILES:
-        if p.endswith('.c'):
-            SOURCES['!%s' % p].flags += ['-DUserMarshalRoutines=UserMarshalRoutines__%s' % p[:-2]]
+    for p in ('dlldata', 'c', 'i', 'p'):
+        SOURCES['!HandlerData_%s.c' % p].flags += ['-DUserMarshalRoutines=UserMarshalRoutines__HandlerData_%s' % p]
 
 DEFFILE = 'AccessibleHandler.def'
 
 USE_LIBS += [
     'mscom_oop',
 ]
 
 OS_LIBS += [
@@ -70,25 +84,16 @@ if CONFIG['CC_TYPE'] == 'clang-cl':
 
 # Since we are defining our own COM entry points (DllRegisterServer et al),
 # but we still want to be able to delegate some work to the generated code,
 # we add the prefix "Proxy" to all of the generated counterparts.
 DEFINES['ENTRY_PREFIX'] = 'Proxy'
 DEFINES['REGISTER_PROXY_DLL'] = True
 LIBRARY_DEFINES['MOZ_MSCOM_REMARSHAL_NO_HANDLER'] = True
 
-# We want to generate distinct UUIDs on a per-channel basis, so we need
-# finer granularity than the standard preprocessor definitions offer.
-# These defines allow us to separate local builds from automated builds,
-# as well as separate beta from release.
-if CONFIG['MOZ_UPDATE_CHANNEL'] == 'default':
-  DEFINES['USE_LOCAL_UUID'] = True
-elif CONFIG['MOZ_UPDATE_CHANNEL'] == 'beta':
-  DEFINES['USE_BETA_UUID'] = True
-
 # This DLL may be loaded into other processes, so we need static libs for
 # Windows 7 and Windows 8.
 USE_STATIC_LIBS = True
 
 LIBRARY_DEFINES['UNICODE'] = True
 LIBRARY_DEFINES['_UNICODE'] = True
 LIBRARY_DEFINES['MOZ_NO_MOZALLOC'] = True
 DisableStlWrapping()
deleted file mode 100644
--- a/accessible/ipc/win/typelib/Makefile.in
+++ /dev/null
@@ -1,33 +0,0 @@
-# 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/.
-
-GARBAGE += $(MIDL_GENERATED_FILES) done_gen dlldata.c
-
-MIDL_GENERATED_FILES = \
-  Accessible.h \
-  Accessible_i.c \
-  Accessible_p.c \
-  Accessible.tlb \
-  $(NULL)
-
-# Bug 1420119: We need the trailing semicolon here to generate a recipe for the
-# midl targets to avoid timestamp caching issues.
-$(MIDL_GENERATED_FILES): done_gen ;
-
-done_gen: $(srcdir)/Accessible.idl
-	$(call WINEWRAP,$(MIDL)) $(MIDL_FLAGS) -Oicf $(srcdir_rel)/Accessible.idl
-	touch $@
-
-export:: done_gen
-
-midl_exports := \
-  Accessible.tlb \
-  $(NULL)
-
-INSTALL_TARGETS += midl_exports
-midl_exports_FILES := $(midl_exports)
-midl_exports_DEST = $(DIST)/bin
-midl_exports_TARGET := export
-
-include $(topsrcdir)/config/rules.mk
--- a/accessible/ipc/win/typelib/moz.build
+++ b/accessible/ipc/win/typelib/moz.build
@@ -3,9 +3,11 @@
 # 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/.
 
 FINAL_TARGET_FILES += [
     '!Accessible.tlb',
 ]
 
-GeneratedFile('Accessible.tlb')
+GeneratedFile('Accessible.tlb',
+              inputs=['Accessible.idl'],
+              script='/build/midl.py', entry_point='midl')
new file mode 100644
--- /dev/null
+++ b/build/midl.py
@@ -0,0 +1,73 @@
+# 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 buildconfig
+import subprocess
+import os
+import sys
+
+
+# Windows program run via Wine don't like Unix absolute paths (they look
+# like command line arguments). So when needed, create relative paths
+# from absolute paths.
+def relativize(path):
+    if path.startswith('/'):
+        return os.path.relpath(path)
+    return path
+
+
+def midl(out, input, *flags):
+    out.avoid_writing_to_file()
+    midl = buildconfig.substs['MIDL']
+    wine = buildconfig.substs.get('WINE')
+    if midl.lower().endswith('.exe') and wine:
+        command = [wine, midl]
+    else:
+        command = [midl]
+    command.extend(buildconfig.substs['MIDL_FLAGS'])
+    command.extend([relativize(f) for f in flags])
+    command.append('-Oicf')
+    command.extend(['-out', relativize(os.path.dirname(out.name) or '.')])
+    command.append(relativize(input))
+    print('Executing:', ' '.join(command))
+    result = subprocess.run(command)
+    return result.returncode
+
+
+# midl outputs dlldata to a single dlldata.c file by default. This prevents running
+# midl in parallel in the same directory for idl files that would generate dlldata.c
+# because of race conditions updating the file. Instead, we ask midl to create
+# separate files, and we merge them manually.
+def merge_dlldata(out, *inputs):
+    inputs = [open(i) for i in inputs]
+    read_a_line = [True] * len(inputs)
+    while True:
+        lines = [f.readline() if read_a_line[n] else '\n' for n, f in enumerate(inputs)]
+        unique_lines = set(lines)
+        if len(unique_lines) == 1:
+            # All the lines are identical
+            if not lines[0]:
+                break
+            out.write(lines[0])
+            read_a_line = [True] * len(inputs)
+        elif len(unique_lines) == 2 and '\n' in unique_lines:
+            # Most lines are identical, except for some that are empty.
+            # In this case, we print out the line, but on next iteration, don't read
+            # a new line from the inputs that had nothing. This typically happens when
+            # some files have #defines that others don't.
+            unique_lines.remove('\n')
+            out.write(unique_lines.pop())
+            read_a_line = [l != '\n' for l in lines]
+        elif len(unique_lines) != len(lines):
+            # If for some reason, we don't get lines that are entirely different
+            # from each other, we have some unexpected input.
+            print('Error while merging dlldata. Last lines read: {}'.format(lines),
+                  file=sys.stderr)
+            return 1
+        else:
+            for line in lines:
+                out.write(line)
+            read_a_line = [True] * len(inputs)
+
+    return 0