Build runners
=============

Edalize will by default create a Makefile which it subsequently executes to offload the process of keeping track of what needs to be rebuilt when source files change. In Edalize we call make a build runner since it runs the build process.

In some cases it can be necessary to augment or completely replace the makefile generation, e.g. to initialize some environment before launching or to integrate with a custom build system.

It is therefore possible to replace the default build runner with a custom tool by creating a new module under the `edalize.build_runner` namespace. In this module Edalize expects to find a class with the same name as the module but capitalized. This class should have the following three functions defined.

**__init__(self, flow_options)** Constructor that also receives the flow_options defined.

**get_build_command(self)** Returns a tuple where the first element is the command to launch (e.g. `make` if we are executing a Makefile) and the second element is a list of options to send to the command (e.g. `["-j4", "-d"]` for a `make` process).

**write(self, commands: EdaCommands, work_root: Path)** Write any required files needed for building. For the `make` build runner, this creates the actual Makefile.

Below is an example of a build runner that extends the `make` build runner to copy the build tree to a server over ssh and the execute it from there.


Build runner examplee::

  from typing import List
  from pathlib import Path
  
  from edalize.build_runners.make import Make
  from edalize.utils import EdaCommands
  
  class Sshmake(Make):
  
      def __init__(self, flow_options):
          super().__init__(flow_options)
          self.build_host = "5446.54.40.138"
  
      def get_build_command(self):
          return ("sh", ["launchme.sh"])
  
      def write(self, commands: EdaCommands, work_root: Path):
          # Write Makefile
          super().write(commands, work_root)
  
          # Write launcher script that copies files to build host and runs it
          outfile = work_root / Path("launchme.sh")
          with open(outfile, "w") as f:
              f.write("#Auto generated by Edalize\n\n")
              f.write(f"scp -r {work_root} {self.build_host}\n")
              f.write(f"ssh {self.build_host} make " + ' '.join(self.build_options)+ "\n")
