changeset 0:4ad92f00bca5

initial commit
author John W. Eaton <jwe@octave.org>
date Tue, 05 Jun 2018 12:38:50 +0000
parents
children 97e7b7963dc9
files master.cfg server.tac slave.tac
diffstat 3 files changed, 835 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/master.cfg	Tue Jun 05 12:38:50 2018 +0000
@@ -0,0 +1,752 @@
+## -*- python -*-
+## ex: set syntax=python:
+
+## This is a sample buildmaster config file. It must be installed as
+## 'master.cfg' in your buildmaster's base directory.
+
+## This is the dictionary that the buildmaster pays attention to. We
+## also use a shorter alias to save typing.
+
+c = BuildmasterConfig = {}
+
+## WORKERS
+
+## The 'worker' list defines the set of recognized workers. Each
+## element is a Worker object, specifying a unique worker name and
+## password.  The same worker name and password must be configured on
+## the worker.
+
+from buildbot.worker import Worker
+
+## Not in hg archive because it contains password and system configuration info.
+import octave_buildbot_config
+
+c["workers"] = []
+
+for worker, info in octave_buildbot_config.workers.iteritems ():
+  c["workers"].append (Worker (worker, info["pass"], max_builds = info["max_builds"]))
+
+## 'protocols' contains information about protocols which master will
+## use for communicating with workers.  You must define at least 'port'
+## option that workers could connect to your master with this protocol.
+## 'port' must match the value configured into the workers (with
+## their --master option)
+
+c["protocols"] = { "pb" : { "port" : 9990 }}
+
+## SOURCES
+
+## The main mercurial repository server. This machines pings the
+## PBChangeSource. The workers should pull from it, to make
+## sure they are in sync.
+
+octave_hg_repo = "https://hg.savannah.gnu.org/hgweb/octave"
+## NOTE: We need this second URL for the Octave sources because
+## of a bug in buildbot that won't allow two hg poller instances
+## for the same URL.  If that were possible, then we could have
+## one URL for both the stable and default branches.
+stable_octave_hg_repo = "http://hg.octave.org/octave"
+mxe_octave_hg_repo = "http://hg.octave.org/mxe-octave"
+
+## CHANGESOURCES
+
+## the 'change_source' setting tells the buildmaster how it should
+## find out about source code changes.  Here we point to the buildbot
+## clone of Octave.
+
+from buildbot.changes.hgpoller import HgPoller
+
+c["change_source"] = []
+
+c["change_source"].append (HgPoller (project = "octave",
+                                     repourl = octave_hg_repo,
+                                     workdir = "octave-hg-repo",
+                                     pollinterval = 5*60))
+
+c["change_source"].append (HgPoller (project = "stable octave",
+                                     branch = "stable",
+                                     repourl = stable_octave_hg_repo,
+                                     workdir = "stable-octave-hg-repo",
+                                     pollinterval = 5*60))
+
+c["change_source"].append (HgPoller (project = "mxe-octave",
+                                     repourl = mxe_octave_hg_repo,
+                                     workdir = "mxe-octave-hg-repo",
+                                     pollinterval = 15*60))
+
+## FILTERS
+
+from buildbot.changes import filter
+
+octave_default_filter = filter.ChangeFilter (project = "octave", branch = "default")
+
+octave_stable_filter = filter.ChangeFilter (project = "stable octave", branch = "stable")
+
+mxe_octave_default_filter = filter.ChangeFilter (project = "mxe-octave", branch = "default")
+
+## SCHEDULERS
+
+## Configure the Schedulers, which decide how to react to incoming
+## changes.
+
+from buildbot.schedulers.basic import SingleBranchScheduler
+from buildbot.schedulers.forcesched import ForceScheduler
+from buildbot.schedulers import timed
+
+all_default_octave_builders = [];
+#all_default_octave_builders.append ("gcc-4.9-debian")
+#all_default_octave_builders.append ("gcc-5-debian")
+all_default_octave_builders.append ("gcc-6-debian") # mtmx
+all_default_octave_builders.append ("gcc-7-debian") # jwe
+all_default_octave_builders.append ("gcc-7-lto-debian") # jwe
+all_default_octave_builders.append ("gcc-fedora") # das
+all_default_octave_builders.append ("gcc-lto-fedora") # das
+all_default_octave_builders.append ("no-extras-debian") # jwe
+all_default_octave_builders.append ("clang-3.9-debian") # mtmx
+all_default_octave_builders.append ("clang-4.0-debian") # jwe
+all_default_octave_builders.append ("clang-5.0-debian") # jwe
+all_default_octave_builders.append ("clang-fedora") # das
+all_default_octave_builders.append ("clang-osx") # simone
+
+all_stable_octave_builders = [];
+all_stable_octave_builders.append ("stable-gcc-7-debian") # jwe
+all_stable_octave_builders.append ("stable-gcc-7-lto-debian") # jwe
+all_stable_octave_builders.append ("stable-gcc-fedora") # das
+all_stable_octave_builders.append ("stable-no-extras-debian") # jwe
+all_stable_octave_builders.append ("stable-clang-4.0-debian") # jwe
+all_stable_octave_builders.append ("stable-clang-5.0-debian") # jwe
+all_stable_octave_builders.append ("stable-clang-osx") # simone
+
+all_mxe_octave_builders = [];
+all_mxe_octave_builders.append ("w32-on-debian") # jwe
+all_mxe_octave_builders.append ("w64-32-on-debian") # jwe
+all_mxe_octave_builders.append ("w64-64-on-debian") # jwe
+all_mxe_octave_builders.append ("w32-stable-on-debian") # jwe
+all_mxe_octave_builders.append ("w64-32-stable-on-debian") # jwe
+all_mxe_octave_builders.append ("mxe-native-on-debian") # jwe
+all_mxe_octave_builders.append ("mxe-native-all-on-debian") # jwe
+
+c["schedulers"] = []
+
+c["schedulers"].append (SingleBranchScheduler (name = "default octave",
+                                               change_filter = octave_default_filter,
+                                               treeStableTimer = 5*60,
+                                               builderNames = all_default_octave_builders))
+
+c["schedulers"].append (ForceScheduler (name = "force_default_octave", builderNames = all_default_octave_builders))
+
+c["schedulers"].append (SingleBranchScheduler (name = "stable octave",
+                                               change_filter = octave_stable_filter,
+                                               treeStableTimer = 5*60,
+                                               builderNames = all_stable_octave_builders))
+
+c["schedulers"].append (ForceScheduler (name = "force_stable_octave", builderNames = all_stable_octave_builders))
+
+## Here, branch is the mxe-octave branch.
+c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w32",
+                                       branch = "default",
+                                       change_filter = mxe_octave_default_filter,
+                                       builderNames = ["w32-on-debian"],
+                                       hour = 0))
+
+## Here, branch is the mxe-octave branch.
+c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w64-32",
+                                       branch = "default",
+                                       change_filter = mxe_octave_default_filter,
+                                       builderNames = ["w64-32-on-debian"],
+                                       hour = 6))
+
+## Here, branch is the mxe-octave branch.
+c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w64-64",
+                                       branch = "default",
+                                       change_filter = mxe_octave_default_filter,
+                                       builderNames = ["w64-64-on-debian"],
+                                       hour = 12))
+
+## Here, branch is the mxe-octave branch.
+c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-native",
+                                       branch = "default",
+                                       change_filter = mxe_octave_default_filter,
+                                       builderNames = ["mxe-native-on-debian"],
+                                       hour = 18))
+
+## Here, branch is the mxe-octave branch.
+c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-native-all",
+                                       branch = "default",
+                                       change_filter = mxe_octave_default_filter,
+                                       builderNames = ["mxe-native-all-on-debian"],
+                                       hour = 0))
+
+## Here, branch is the mxe-octave branch.
+c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w32-stable",
+                                       branch = "default",
+                                       change_filter = mxe_octave_default_filter,
+                                       builderNames = ["w32-stable-on-debian"],
+                                       hour = 8))
+
+## Here, branch is the mxe-octave branch.
+c["schedulers"].append (timed.Nightly (name = "periodic mxe-octave-w64-32-stable",
+                                       branch = "default",
+                                       change_filter = mxe_octave_default_filter,
+                                       builderNames = ["w64-32-stable-on-debian"],
+                                       hour = 16))
+
+c["schedulers"].append (ForceScheduler (name = "force_mxe_octave", builderNames = all_mxe_octave_builders))
+
+## BUILDERS
+
+## The 'builders' list defines the Builders, which tell Buildbot how
+## to perform a build:  what steps, and which workers can execute them.
+## Note that any particular build will only take place on one worker.
+
+from buildbot.process.factory import BuildFactory
+from buildbot.steps.source.mercurial import Mercurial
+from buildbot.steps.shell import ShellCommand
+from buildbot.steps.shell import Configure
+from buildbot.steps.shell import Compile
+from buildbot.steps.shell import Test
+
+## Steps we may use in more than one build factory.
+
+def build_cmd_list (cmd, nice = 0, opts = []):
+  cmd_list = []
+
+  if nice != 0:
+    cmd_list.extend (["nice", "-n", str (nice)])
+
+  if isinstance (cmd, list):
+    cmd_list.extend (cmd)
+  else:
+    cmd_list.append (cmd)
+
+  if isinstance (opts, list):
+    cmd_list.extend (opts)
+  else:
+    cmd_list.append (opts)
+
+  return cmd_list
+
+
+build_env = { "PATH" : "${HOME}/bin:${PATH}" };
+
+def mk_octave_hg_update_step (repo, branch):
+  return Mercurial (repourl = repo,
+                    defaultBranch = branch, branchType = "inrepo",
+                    workdir = "src", mode = "full", method = "fresh",
+                    haltOnFailure = True)
+
+def mk_octave_bootstrap_step (nice = 0):
+  boot_cmd = build_cmd_list ("./bootstrap", nice = nice)
+  return ShellCommand (command = boot_cmd, workdir = "src", env = build_env,
+                       description = "bootstrap")
+
+sh_rm_build_dir = ShellCommand (command = ["rm", "-rf", "build"], workdir = ".",
+                                env = build_env, description = "clean build dir")
+
+sh_mk_build_dir = ShellCommand (command = ["mkdir", "build"],
+                                description = "create build dir")
+
+def mk_octave_configure_step (nice = 0, opts = []):
+  conf_cmd = build_cmd_list ("../src/configure", nice = nice, opts = opts)
+  return Configure (command = conf_cmd, workdir = "build", env = build_env)
+
+
+def mk_octave_compile_step (nice = 0, opts = []):
+  make_cmd = build_cmd_list (["make", "V=1"], nice = nice, opts = opts)
+  return Compile (command = make_cmd, workdir = "build", env = build_env,
+                  warningPattern = ":[0-9][0-9]*:[0-9][0-9]*:warning: ")
+
+import re
+from buildbot.process.results import SUCCESS
+from buildbot.process.results import FAILURE
+from buildbot.process.results import WARNINGS
+
+class octave_test (Test):
+
+  def evaluateCommand (self, cmd):
+    rc = SUCCESS
+    if cmd.didFail ():
+      rc = FAILURE
+
+    ## FIXME: return WARNINGS if there are skipped tests?
+    ## FIXME: should probably search for the "^Summary:$" line just
+    ## before the PASS/FAIL totals.
+
+    logtext = "".join(self.getLog('stdio').readlines())
+
+    m = re.search (r"^ *FAIL +([0-9]+) *$", logtext,
+                   flags = re.MULTILINE)
+
+    ## There should always be a line with FAIL, so m should always be a
+    ## valid match object.  But if it is not, then that is also a
+    ## failure because there must be something wrong with the log file.
+    if not m or int (m.group (1)) != 0:
+      rc = FAILURE
+    else:
+      m = re.search (r"^ *REGRESSION +([0-9]+) *$", logtext,
+                     flags = re.MULTILINE)
+      ## If REGRESSION does not appear in the output, then there were none.
+      ## If it is present, then there should be some regressions, but we'll
+      ## check anyway.
+      if m and int (m.group (1)) != 0:
+        rc = FAILURE
+
+    return rc
+
+def mk_octave_test_step (nice = 0, xvfb = True):
+  if xvfb:
+    cmd = ["xvfb-run", "-a", "-s", "-screen 0 640x480x24"]
+  else:
+    cmd = []
+  cmd.extend (["make", "V=1", "check"])
+  test_cmd = build_cmd_list (cmd, nice = nice)
+  return octave_test (command = test_cmd, workdir = "build", env = build_env)
+
+def mk_octave_factory (nice, configure_opts, compile_opts, branch, xvfb = True):
+  factory = BuildFactory ()
+
+  factory.addStep (mk_octave_hg_update_step (octave_hg_repo, branch))
+  factory.addStep (mk_octave_bootstrap_step (nice = nice))
+  factory.addStep (sh_rm_build_dir)
+  factory.addStep (sh_mk_build_dir)
+  factory.addStep (mk_octave_configure_step (nice = nice, opts = configure_opts))
+  factory.addStep (mk_octave_compile_step (nice = nice, opts = compile_opts))
+  factory.addStep (mk_octave_test_step (nice = nice, xvfb = xvfb))
+
+  return factory
+
+def mk_gcc_factory (nice, compile_opts, branch):
+  return mk_octave_factory (nice, [], compile_opts, branch)
+
+
+def mk_gcc_4_9_factory (nice, compile_opts, branch):
+  return mk_octave_factory (nice,
+                            ["CC=gcc-4.9", "CXX=g++-4.9", "F77=gfortran-4.9", "--without-magick"],
+                            compile_opts, branch)
+
+
+## Default build.
+def mk_gcc_5_factory (nice, compile_opts, branch):
+  return mk_octave_factory (nice,
+                            ["CC=gcc-5", "CXX=g++-5", "F77=gfortran-5"],
+                            compile_opts, branch)
+
+
+def mk_gcc_6_factory (nice, compile_opts, branch):
+  return mk_octave_factory (nice,
+                            ["CC=gcc-6", "CXX=g++-6", "F77=gfortran-6"],
+                            compile_opts, branch)
+                                   
+
+def mk_gcc_7_factory (nice, compile_opts, branch):
+  return mk_octave_factory (nice,
+                            ["CC=gcc-7", "CXX=g++-7", "F77=gfortran-7"],
+                            compile_opts, branch)
+                                   
+
+def mk_gcc_7_lto_factory (nice, compile_opts, branch):
+  return mk_octave_factory (nice,
+                            ["CC=gcc-7", "CXX=g++-7", "F77=gfortran-7",
+                             "CFLAGS=-O2 -flto=4 -ffat-lto-objects",
+                             "CXXFLAGS=-O2 -flto=4 -ffat-lto-objects",
+                             "FFLAGS=-O2 -flto=4 -ffat-lto-objects",
+                             "LDFLAGS=-flto=4",
+                             "NM=gcc-nm-7", "AR=gcc-ar-7", "RANLIB=gcc-ranlib-7"],
+                            compile_opts, branch)
+                                   
+
+def mk_gcc_lto_factory (nice, compile_opts, branch):
+  return mk_octave_factory (nice,
+                            ["CFLAGS=-O2 -flto=4 -ffat-lto-objects",
+                             "CXXFLAGS=-O2 -flto=4 -ffat-lto-objects",
+                             "FFLAGS=-O2 -flto=4 -ffat-lto-objects",
+                             "LDFLAGS=-flto=4",
+                             "NM=gcc-nm", "AR=gcc-ar", "RANLIB=gcc-ranlib"],
+                            compile_opts, branch)
+                                   
+
+no_extras = ["--disable-docs",
+             "--disable-fftw-threads",
+             "--disable-java",
+             "--disable-jit",
+             "--disable-openmp",
+             "--disable-readline",
+             "--without-osmesa",
+             "--without-amd",
+             "--without-arpack",
+             "--without-bz2",
+             "--without-camd",
+             "--without-ccolamd",
+             "--without-cholmod",
+             "--without-colamd",
+             "--without-curl",
+             "--without-cxsparse",
+             "--without-fftw3",
+             "--without-fftw3f",
+             "--without-fltk",
+             "--without-framework-opengl",
+             "--without-glpk",
+             "--without-hdf5",
+             "--without-klu",
+             "--without-sundials-ida",
+             "--without-sundials_nvecserial",
+             "--without-magick",
+             "--without-opengl",
+             "--without-openssl",
+             "--without-portaudio",
+             "--without-qhull",
+             "--without-qrupdate",
+             "--without-qscintilla",
+             "--without-qt",
+             "--without-sndfile",
+             "--without-sundials_ida",
+             "--without-sundials_nvecserial",
+             "--without-umfpack",
+             "--without-x",
+             "--without-z"]
+
+def mk_no_extras_factory (nice, compile_opts, branch):
+  return mk_octave_factory (nice, no_extras, compile_opts, branch)
+
+
+def mk_clang_3_8_factory (nice, compile_opts, branch):
+  return mk_octave_factory (nice,
+                            ["CC=clang-3.8", "CXX=clang++-3.8"],
+                            compile_opts, branch)
+
+
+def mk_clang_3_9_factory (nice, compile_opts, branch):
+  return mk_octave_factory (nice,
+                            ["CC=clang-3.9", "CXX=clang++-3.9"],
+                            compile_opts, branch)
+
+def mk_clang_4_0_factory (nice, compile_opts, branch):
+  return mk_octave_factory (nice,
+                            ["CC=clang-4.0", "CXX=clang++-4.0"],
+                            compile_opts, branch)
+
+def mk_clang_5_0_factory (nice, compile_opts, branch):
+  return mk_octave_factory (nice,
+                            ["CC=clang-5.0", "CXX=clang++-5.0"],
+                            compile_opts, branch)
+
+def mk_clang_factory (nice, compile_opts, branch):
+  return mk_octave_factory (nice,
+                            ["CC=clang", "CXX=clang++"],
+                            compile_opts, branch)
+
+def mk_clang_osx_factory (nice, compile_opts, branch):
+  ## The linker does search /usr/local/lib, but it does so after
+  ## searching /usr/lib.  That selects a readline library that is not
+  ## fully compatible with GNU readline.
+  return mk_octave_factory (nice,
+                            ["CC=clang",
+                             "CXX=clang++",
+                             "CPPFLAGS=-I/opt/X11/include -I/usr/local/opt/gettext/include -I/usr/local/opt/icu4c/include -I/usr/local/opt/openssl/include -I/usr/local/opt/readline/include -I/usr/local/opt/sqlite/include",
+                             "LDFLAGS=-L/usr/local/lib -L/opt/X11/lib -L/usr/local/opt/qt/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/texinfo/lib -L/usr/local/opt/bison/lib -L/usr/local/opt/gettext/lib -L/usr/local/opt/icu4c/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/openblas/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/sqlite/lib",
+                             "PKG_CONFIG_PATH=/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/qt/lib/pkgconfig",
+                             "--enable-link-all-dependencies",
+                             "--with-x=no",
+                             "--without-osmesa",
+                             "--with-blas=openblas"],
+                            compile_opts, branch, xvfb = False)
+
+from buildbot.config import BuilderConfig
+
+c["builders"] = []
+
+#c["builders"].append (BuilderConfig (name = "gcc-4.9-debian",
+#                                     workernames = ["jwe-debian-x86_64-0"],
+#                                     factory = mk_gcc_4_9_factory (19, "-j8", "default")))
+
+#c["builders"].append (BuilderConfig (name = "gcc-5-debian",
+#                                     workernames = ["jwe-debian-x86_64-0"],
+#                                     factory = mk_gcc_5_factory (19, "-j8", "default")))
+
+c["builders"].append (BuilderConfig (name = "gcc-6-debian",
+                                     workernames = ["mtmx-debian-x86_64"],
+                                     factory = mk_gcc_6_factory (10, "-j2", "default")))
+
+c["builders"].append (BuilderConfig (name = "gcc-7-debian",
+                                     workernames = ["jwe-debian-x86_64-1"],
+                                     factory = mk_gcc_7_factory (19, "-j8", "default")))
+
+c["builders"].append (BuilderConfig (name = "stable-gcc-7-debian",
+                                     workernames = ["jwe-debian-x86_64-1"],
+                                     factory = mk_gcc_7_factory (19, "-j8", "stable")))
+
+c["builders"].append (BuilderConfig (name = "gcc-7-lto-debian",
+                                     workernames = ["jwe-debian-x86_64-2"],
+                                     factory = mk_gcc_7_lto_factory (19, "-j8", "default")))
+
+c["builders"].append (BuilderConfig (name = "stable-gcc-7-lto-debian",
+                                     workernames = ["jwe-debian-x86_64-2"],
+                                     factory = mk_gcc_7_lto_factory (19, "-j8", "stable")))
+
+c["builders"].append (BuilderConfig (name = "gcc-fedora",
+                                     workernames = ["das_fc25-x86_64"],
+                                     factory = mk_gcc_factory (0, "-j8", "default")))
+
+c["builders"].append (BuilderConfig (name = "stable-gcc-fedora",
+                                     workernames = ["das_fc25-x86_64"],
+                                     factory = mk_gcc_factory (0, "-j8", "stable")))
+
+c["builders"].append (BuilderConfig (name = "gcc-lto-fedora",
+                                     workernames = ["das_fc25-x86_64"],
+                                     factory = mk_gcc_lto_factory (10, "-j8", "default")))
+
+c["builders"].append (BuilderConfig (name = "no-extras-debian",
+                                     workernames = ["jwe-debian-x86_64-1"],
+                                     factory = mk_no_extras_factory (19, "-j8", "default")))
+
+c["builders"].append (BuilderConfig (name = "stable-no-extras-debian",
+                                     workernames = ["jwe-debian-x86_64-1"],
+                                     factory = mk_no_extras_factory (19, "-j8", "stable")))
+
+##c["builders"].append (BuilderConfig (name = "clang-3.8-debian",
+##                                     workernames = ["jwe-debian-x86_64-2"],
+##                                     factory = mk_clang_3_8_factory (19, "-j8", "default")))
+
+c["builders"].append (BuilderConfig (name = "clang-3.9-debian",
+                                     workernames = ["mtmx-debian-x86_64"],
+                                     factory = mk_clang_3_9_factory (19, "-j2", "default")))
+
+c["builders"].append (BuilderConfig (name = "clang-4.0-debian",
+                                     workernames = ["jwe-debian-x86_64-0"],
+                                     factory = mk_clang_4_0_factory (19, "-j8", "default")))
+
+c["builders"].append (BuilderConfig (name = "stable-clang-4.0-debian",
+                                     workernames = ["jwe-debian-x86_64-0"],
+                                     factory = mk_clang_4_0_factory (19, "-j8", "stable")))
+
+c["builders"].append (BuilderConfig (name = "clang-5.0-debian",
+                                     workernames = ["jwe-debian-x86_64-2"],
+                                     factory = mk_clang_5_0_factory (19, "-j8", "default")))
+
+c["builders"].append (BuilderConfig (name = "stable-clang-5.0-debian",
+                                     workernames = ["jwe-debian-x86_64-2"],
+                                     factory = mk_clang_5_0_factory (19, "-j8", "stable")))
+
+c["builders"].append (BuilderConfig (name = "clang-fedora",
+                                     workernames = ["das_fc25-x86_64"],
+                                     factory = mk_clang_factory (19, "-j8", "default")))
+
+
+c["builders"].append (BuilderConfig (name = "clang-osx",
+                                     workernames = ["epfl-elcapitan-x86_64"],
+                                     factory = mk_clang_osx_factory (0, "-j4", "default")))
+
+c["builders"].append (BuilderConfig (name = "stable-clang-osx",
+                                     workernames = ["epfl-elcapitan-x86_64"],
+                                     factory = mk_clang_osx_factory (0, "-j4", "stable")))
+
+
+def mk_mxe_octave_hg_update_step (repo):
+  return Mercurial (repourl = repo,
+                    defaultBranch = "default", branchType = "inrepo",
+                    workdir = "src", mode = "full", method = "fresh",
+                    haltOnFailure = True)
+
+
+def mk_mxe_octave_bootstrap_step (nice = 0):
+  boot_cmd = build_cmd_list ("autoconf", nice = nice)
+  return ShellCommand (command = boot_cmd, workdir = "src", env = build_env,
+                       description = "bootstrap")
+
+
+def mk_mxe_octave_configure_step (nice = 0, branch = "default", opts = []):
+  conf_cmd = build_cmd_list (["./configure",
+                              "--with-pkg-dir=../../mxe-pkg-src",
+                              "--with-ccache", "--enable-octave=" + branch,
+                              "--enable-binary-packages"],
+                             nice = nice, opts = opts)
+  return Configure (command = conf_cmd, workdir = "src", env = build_env)
+
+
+def mk_mxe_octave_clean_step (nice = 0):
+  boot_cmd = build_cmd_list (["make", "clean"], nice = nice)
+  return ShellCommand (command = boot_cmd, workdir = "src", env = build_env,
+                       description = "clean")
+
+
+## Timeout is large for these steps because mxe-octave currently only
+## prints a status update for each package, not detailed output from
+## make.  The way the dependencies currently work, making
+## hg-octave-dist will also cause all the build tools to be updated,
+## and some of those make take significant time to build, especially
+## if the build is running on a heavily loaded system and this step
+## has a high nice value.
+
+def mk_mxe_octave_hg_tarball_step (nice = 0, jobs = 8, branch = "default"):
+  make_cmd = build_cmd_list (["make", "JOBS=" + str (jobs), "hg-octave-dist", "hg-octave-branch=" + branch],
+                             nice = nice)
+  return Compile (command = make_cmd, workdir = "src", env = build_env,
+                  timeout = 14400)
+
+
+def mk_mxe_octave_compile_step (nice = 0, jobs = 8, opts = []):
+  make_cmd = build_cmd_list (["make", "JOBS=" + str (jobs)],
+                             nice = nice, opts = opts)
+  return Compile (command = make_cmd, workdir = "src", env = build_env,
+                  timeout = 14400)
+
+
+def mk_mxe_octave_factory (nice, jobs, branch, configure_opts, compile_opts):
+  factory = BuildFactory ()
+
+  factory.addStep (mk_mxe_octave_hg_update_step (mxe_octave_hg_repo))
+  factory.addStep (mk_mxe_octave_bootstrap_step (nice = nice))
+  ## Must run configure to ensure clean target will work, then must
+  ## run configure again to recreate makefile.
+  factory.addStep (mk_mxe_octave_configure_step (nice = nice, branch = branch,
+                                                 opts = configure_opts))
+  factory.addStep (mk_mxe_octave_clean_step (nice = nice))
+  factory.addStep (mk_mxe_octave_configure_step (nice = nice, branch = branch,
+                                                 opts = configure_opts))
+  ## Create a tarball file from an hg checkout, then build from that.
+  ## This also builds all dependencies for Octave, so it can take a
+  ## while.  Using ccache should help us significantly since we are
+  ## typically rebuilding the same sets of packages repeatedly.
+  factory.addStep (mk_mxe_octave_hg_tarball_step (nice = nice, jobs = jobs,
+                                                  branch = branch))
+  factory.addStep (mk_mxe_octave_compile_step (nice = nice, jobs = jobs,
+                                               opts = compile_opts))
+  ## factory.addStep (mk_mxe_octave_test_step (nice = nice))
+
+  return factory
+
+
+def mk_w32_factory (nice, jobs, branch, compile_opts):
+  return mk_mxe_octave_factory (nice, jobs, branch,
+                                ["--enable-qt5",
+                                 "--enable-devel-tools",
+                                 "--disable-windows-64",
+                                 "--disable-system-opengl"],
+                                compile_opts)
+
+
+def mk_w64_32_factory (nice, jobs, branch, compile_opts):
+  configure_opts = ["--enable-qt5",
+                    "--enable-devel-tools",
+                    "--disable-system-opengl"]
+  if branch == "stable":
+    configure_opts.extend (["--disable-64"])
+
+  return mk_mxe_octave_factory (nice, jobs, branch,
+                                configure_opts,
+                                compile_opts)
+
+
+def mk_w64_64_factory (nice, jobs, branch, compile_opts):
+  return mk_mxe_octave_factory (nice, jobs, branch,
+                                ["--enable-qt5",
+                                 "--enable-devel-tools",
+                                 "--enable-fortran-int64",
+                                 "--disable-system-opengl",
+                                 "--enable-64"],
+                                compile_opts)
+
+
+def mk_native_factory (nice, jobs, branch, compile_opts):
+  return mk_mxe_octave_factory (nice, jobs, branch,
+                                ["--enable-native-build",
+                                 "--enable-qt5",
+                                 "--enable-lib64-directory",
+                                 "--enable-pic-flag",
+                                 "--disable-devel-tools",
+                                 "--enable-system-x11-libs",
+                                 "--enable-system-fontconfig",
+                                 "--enable-system-gcc",
+                                 "gnu-linux"],
+                                compile_opts)
+
+
+def mk_native_all_factory (nice, jobs, branch, compile_opts):
+  return mk_mxe_octave_factory (nice, jobs, branch,
+                                ["--enable-native-build",
+                                 "--enable-qt5",
+                                 "--enable-lib64-directory",
+                                 "--enable-pic-flag",
+                                 "--disable-devel-tools",
+                                 "--disable-system-x11-libs",
+                                 "--disable-system-fontconfig",
+                                 "--disable-system-gcc",
+                                 "--disable-system-opengl",
+                                 "gnu-linux"],
+                                compile_opts)
+
+
+c["builders"].append (BuilderConfig (name = "w32-on-debian",
+                                     workernames = ["jwe-debian-x86_64-0"],
+                                     factory = mk_w32_factory (19, 8, "default", "nsis-installer")))
+
+c["builders"].append (BuilderConfig (name = "w64-32-on-debian",
+                                     workernames = ["jwe-debian-x86_64-0"],
+                                     factory = mk_w64_32_factory (19, 8, "default", "nsis-installer")))
+
+c["builders"].append (BuilderConfig (name = "w64-64-on-debian",
+                                     workernames = ["jwe-debian-x86_64-0"],
+                                     factory = mk_w64_64_factory (19, 8, "default", "nsis-installer")))
+
+
+c["builders"].append (BuilderConfig (name = "mxe-native-on-debian",
+                                     workernames = ["jwe-debian-x86_64-0"],
+                                     factory = mk_native_factory (19, 8, "default", "tar-dist")))
+
+c["builders"].append (BuilderConfig (name = "mxe-native-all-on-debian",
+                                     workernames = ["jwe-debian-x86_64-3"],
+                                     factory = mk_native_all_factory (19, 8, "default", "tar-dist")))
+
+
+c["builders"].append (BuilderConfig (name = "w32-stable-on-debian",
+                                     workernames = ["jwe-debian-x86_64-3"],
+                                     factory = mk_w32_factory (19, 8, "stable", "nsis-installer")))
+
+c["builders"].append (BuilderConfig (name = "w64-32-stable-on-debian",
+                                     workernames = ["jwe-debian-x86_64-3"],
+                                     factory = mk_w64_32_factory (19, 8, "stable", "nsis-installer")))
+
+## PROJECT IDENTITY
+
+## the 'title' string will appear at the top of this buildbot
+## installation's html.WebStatus home page (linked to the 'titleURL')
+## and is embedded in the title of the waterfall HTML page.
+
+c["title"] = "GNU Octave Buildbot"
+c["titleURL"] = "https://octave.org"
+
+# The 'buildbotURL' string should point to the location where the buildbot's
+# internal web server is visible. This typically uses the port number set in
+# the 'www' entry below, but with an externally-visible host name which the
+# buildbot cannot figure out without some help.
+
+c['buildbotURL'] = "http://buildbot.octave.org:8011/"
+
+## Minimalistic config to activate new web UI
+
+from buildbot.plugins import util
+
+c['www'] = {
+  "port" : 8011,
+  "auth" : util.UserPasswordAuth ({"octave" : "8avete$t$"}),
+  "plugins" : { "waterfall_view" : True }
+}
+
+## DB URL
+
+## This specifies what database buildbot uses to store its state.  You
+## can leave this at its default for all but the largest installations.
+
+c["db"] = { "db_url" : "sqlite:///state.sqlite" }
+
+## NOTIFICATIONS
+
+from buildbot.plugins import reporters
+
+c["services"] = []
+
+m = reporters.MailNotifier (fromaddr = "NO-REPLY@octave.org",
+                            sendToInterestedUsers = False,
+                            extraRecipients = ["octave-buildbot@gnu.org"],
+                            mode = "failing")
+c["services"].append (m)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server.tac	Tue Jun 05 12:38:50 2018 +0000
@@ -0,0 +1,38 @@
+import os
+
+from twisted.application import service
+from buildbot.master import BuildMaster
+
+basedir = '.'
+rotateLength = 10000000
+maxRotatedFiles = 10
+configfile = 'master.cfg'
+
+## Default umask for server
+
+umask = None
+
+## if this is a relocatable tac file, get the directory containing the TAC
+
+if basedir == '.':
+    import os.path
+    basedir = os.path.abspath(os.path.dirname(__file__))
+
+## note: this line is matched against to check that this is a
+## buildmaster directory; do not edit it.
+application = service.Application('buildmaster')
+
+from twisted.python.logfile import LogFile
+from twisted.python.log import ILogObserver
+from twisted.python.log import FileLogObserver
+
+logfile = LogFile.fromFullPath(os.path.join(basedir, 'twistd.log'),
+                               rotateLength = rotateLength,
+                               maxRotatedFiles = maxRotatedFiles)
+
+application.setComponent(ILogObserver, FileLogObserver(logfile).emit)
+
+m = BuildMaster (basedir, configfile, umask)
+m.setServiceParent(application)
+m.log_rotation.rotateLength = rotateLength
+m.log_rotation.maxRotatedFiles = maxRotatedFiles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/slave.tac	Tue Jun 05 12:38:50 2018 +0000
@@ -0,0 +1,45 @@
+
+import os
+
+from buildbot_worker.bot import Worker
+from twisted.application import service
+
+basedir = '.'
+rotateLength = 10000000
+maxRotatedFiles = 10
+
+# if this is a relocatable tac file, get the directory containing the TAC
+if basedir == '.':
+    import os.path
+    basedir = os.path.abspath(os.path.dirname(__file__))
+
+# note: this line is matched against to check that this is a buildbot worker
+# directory; do not edit it.
+application = service.Application('buildbot-worker')
+
+try:
+    from twisted.python.logfile import LogFile
+    from twisted.python.log import ILogObserver, FileLogObserver
+    logfile = LogFile.fromFullPath(os.path.join(basedir, "twistd.log"), rotateLength=rotateLength,
+                                   maxRotatedFiles=maxRotatedFiles)
+    application.setComponent(ILogObserver, FileLogObserver(logfile).emit)
+except ImportError:
+    # probably not yet twisted 8.2.0 and beyond, can't set log yet
+    pass
+
+buildmaster_host = 'buildbot.octave.org'
+port = 9990
+workername = 'your-worker-name'
+passwd = 'your-worker-password'
+keepalive = 600
+maxdelay = 300
+numcpus = None
+allow_shutdown = None
+maxretries = None
+
+s = Worker(buildmaster_host, port, workername, passwd, basedir,
+           keepalive, maxdelay=maxdelay,
+           numcpus=numcpus, allow_shutdown=allow_shutdown,
+           maxRetries=maxretries)
+s.setServiceParent(application)
+