User:Gszorc/Build frontend shootout
This article examines alternatives to Makefile's for containing mozilla-central's build system definition. See discussion at https://groups.google.com/forum/?fromgroups=#!topic/mozilla.dev.platform/SACOnl-avMs
Contents
Goals
We want a frontend language whose output is a giant data structure. The data structure will be consumed by a generator to produce files that actually build the tree.
The produced data structure can come about many different ways. The frontend files themselves could be a data structure (e.g. JSON). They could be scripts that call built-in functions which register elements with the data structure. They could be scripts that populate specific variables whose values are read post execution.
Comparison
Makefile
This is what things would look like in a Makefile.in today in mozilla-central. This example is abbreviated from dom/base/Makefile.in.
DEPTH := @DEPTH@
topsrcdir := @top_srcdir@
srcdir := @srcdir@
VPATH := @srcdir@
FAIL_ON_WARNINGS := 1
include $(DEPTH)/config/autoconf.mk
MODULE = dom
LIBRARY_NAME = jsdombase_s
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
DIRS = \
test \
$(NULL)
EXTRA_PP_COMPONENTS = \
ConsoleAPI.js \
ConsoleAPI.manifest \
$(NULL)
EXTRA_JS_MODULES = ConsoleAPIStorage.jsm \
$(NULL)
EXTRA_JS_MODULES += \
DOMRequestHelper.jsm \
IndexedDBHelper.jsm \
ObjectWrapper.jsm \
$(NULL)
XPIDLSRCS = \
nsIDOMDOMError.idl \
nsIDOMDOMRequest.idl \
nsIEntropyCollector.idl \
nsIScriptChannel.idl \
$(NULL)
EXPORTS = \
nsDOMCID.h \
nsDOMClassInfoClasses.h \
nsDOMClassInfoID.h \
nsDOMJSUtils.h \
$(NULL)
EXPORTS_NAMESPACES = mozilla/dom
EXPORTS_mozilla/dom = \
DOMError.h \
DOMRequest.h \
StructuredCloneTags.h \
ScreenOrientation.h \
$(NULL)
CPPSRCS = \
nsBarProps.cpp \
nsDOMException.cpp \
nsDOMWindowUtils.cpp \
nsJSEnvironment.cpp \
$(NULL)
include $(topsrcdir)/dom/dom-config.mk
ifdef MOZ_JSDEBUGGER
DEFINES += -DMOZ_JSDEBUGGER
endif
ifdef MOZ_B2G_RIL
DEFINES += -DMOZ_B2G_RIL
endif
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += \
-I$(topsrcdir)/js/xpconnect/src \
-I$(topsrcdir)/js/xpconnect/wrappers \
-I$(topsrcdir)/xpcom/ds \
$(NULL)
ifdef MOZ_X11
CXXFLAGS += $(TK_CFLAGS)
LDFLAGS += $(TK_LIBS)
endif
XPIDL_FLAGS += \
-I$(topsrcdir)/dom/interfaces/events \
$(NULL)
Python (data oriented)
We use Python as the frontend language. We try to make it is *data oriented* as possible. By that, we mean we value static data structures over function calls.
FAIL_ON_WARNINGS = True
MODULE = {
'name': 'dom',
'library_name': 'jsdombase_s',
'libxul': True,
'static': True,
}
DIRS = ['test']
EXTRA_PP_COMPONENTS = [
'ConsoleAPI.js',
'ConsoleAPI.manifest'
]
EXTRA_JS_MODULES = ['ConsoleAPIStorage.jsm']
EXTRA_JS_MODULES += [
'DOMRequestHelper.jsm',
'IndexedDBHelper.jsm',
'ObjectWrapper.jsm',
]
XPIDLSRCS = [
'nsIDOMDOMError.idl',
'nsIDOMDOMRequest.idl',
'nsIEntropyCollector.idl',
'nsIScriptChannel.idl',
]
EXPORTS['__main__'] = [
'nsDOMCID.h',
'nsDOMClassInfoClasses.h',
'nsDOMClassInfoID.h',
'nsDOMJSUtils.h',
]
EXPORTS['mozilla/dom'] = [
'DOMError.h,
'DOMRequest.h,
'StructuredCloneTags.h',
'ScreenOrientation.h',
]
CPPSRCS = [
'nsBarProps.cpp',
'nsDOMException.cpp',
'nsDOMWindowUtils.cpp',
'nsJSEnvironment.cpp',
]
if ENV.MOZ_JSDEBUGGER:
DEFINES += ['MOZ_JSDEBUGGER']
if ENV.MOZ_B2G_RIL:
DEFINES += ['MOZ_B2G_RIL']
LOCAL_SRCDIR_INCLUDES = [
'js/xpconnect/src',
'js/xpconnect/wrappers',
'xpcom/ds',
]
if ENV.MOZ_X11:
CXXFLAGS += ENV.TK_CFLAGS
LDFLAGS += ENV.TK_LIBS
XPIDL_SRCDIR_INCLUDES = ['dom/interfaces/events']
Python (procedural oriented)
In this flavor of Python, all relevant tasks are done with calls to built-in functions. The style of this example is purposefully mixed. There is no shortage of bike shedding regarding naming, argument values, etc.
fail_on_warnings(True)
module('dom', library_name='jsdombase_s', libxul=True, static=True)
test_dir('test')
preprocess_files('ConsoleAPI.js', 'ConsoleAPI.manifest')
extra_js_module('ConsoleAPIStorage.jsm')
extra_js_module('DOMRequestHelper.jsm')
extra_js_module('IndexedDBHelper.jsm')
extra_js_module('ObjectWrapper.jsm')
xpidl_source('nsIDOMDOMError.idl')
xpidl_source('nsIDOMDOMRequest.idl')
xpidl_source('nsIEntropyCollector.idl')
xpidl_source('nsIScriptChannel.idl')
exports(None, [
'nsDOMCID.h',
'nsDOMClassInfoClasses.h',
'nsDOMClassInfoID.h',
'nsDOMJSUtils.h',
])
exports('mozilla/dom', [
'DOMError.h,
'DOMRequest.h,
'StructuredCloneTags.h',
'ScreenOrientation.h',
])
cpp_sources(
'nsBarProps.cpp',
'nsDOMException.cpp',
'nsDOMWindowUtils.cpp',
'nsJSEnvironment.cpp'
)
if not ENV.MOZ_JSDEBUGGER:
add_define('MOZ_JSDEBUGGER')
if not ENV.MOZ_B2G_RIL:
add_define('MOZ_B2G_RIL')
add_include_dirs(
'js/xpconnect/src',
'js/xpconnect/wrappers',
'xpcom/ds'
)
if ENV.MOZ_X11:
add_cxxflags(ENV.TOK_CFLAGS)
add_ldflags(ENV.TK_LIBS)
add_xpidl_includes('dom/interfaces/events')
Ini-like
This is what an ini-like syntax could look like. The syntax could certainly be adjusted (flags could be handled in a better manner, probably)
[module "dom"]
FAIL_ON_WARNINGS = True
library_name = jsdombase_s
libxul = True
static = True
[dirs]
test
[pp_components]
ConsoleAPI.js
ConsoleAPI.manifest
[js_modules]
ConsoleAPIStorage.jsm
DOMRequestHelper.jsm
IndexedDBHelper.jsm
ObjectWrapper.jsm
[xpidl]
nsIDOMDOMError.idl
nsIDOMDOMRequest.idl
nsIEntropyCollector.idl
nsIScriptChannel.idl
[exports]
nsDOMCID.h
nsDOMClassInfoClasses.h
nsDOMClassInfoID.h
nsDOMJSUtils.h
[exports "mozilla/dom"]
DOMError.h
DOMRequest.h
StructuredCloneTags.h
ScreenOrientation.h
[sources]
nsBarProps.cpp
nsDOMException.cpp
nsDOMWindowUtils.cpp
nsJSEnvironment.cpp
[defines]
#ifdef MOZ_JSDEBUGGER
MOZ_JSDEBUGGER
#endif
#ifdef MOZ_B2G_RIL
MOZ_B2G_RIL
#endif
[includes]
js/xpconnect/src
js/xpconnect/wrappers
xpcom/ds
#ifdef MOZ_X11
[cxxflags]
@TK_CFLAGS@
[ldflags]
@TK_LIBS@
#endif
[xpidl_includes]
dom/interfaces/events
An extension to the syntax, borrowed from jar.mn, would be to indicate preprocessing by prepending the file name with an asterisk.
[components]
*ConsoleAPI.js
ConsoleAPI.manifest
SCons
TODO
WAF
TODO
Lua
TODO
GYP
TODO