Closes https://github.com/pyodide/pyodide/issues/604

This creates an installable `pyodide-build` Python package that we can also upload to PyPi under https://pypi.org/project/pyodide-build/ (currently uploaded the dev version to reserve the name).

There is also the identically named `pyodide-build` CLI command which replaces `bin/pyodide`.

The short term goals is to use fewer hacks with `PATH` and `PYTHONPATH`. Long term goal make it a user facing interface for building packages instead of the Makefile.
Create an installable pyodide-build package. Closes https://github.com/pyodide/pyodide/issues/604

This creates an installable `pyodide-build` Python package that we can also upload to PyPi under https://pypi.org/project/pyodide-build/ (currently uploaded the dev version to reserve the name).

There is also the identically named `pyodide-build` CLI command which replaces `bin/pyodide`.

The short term goals is to use fewer hacks with `PATH` and `PYTHONPATH`. Long term goal make it a user facing interface for building packages instead of the Makefile.
# setup: import numpy as np ; grid_shape = (512, 512) ; grid = np.zeros(grid_shape) ; block_low = int(grid_shape[0] * .4) ; block_high = int(grid_shape[0] * .5) ; grid[block_low:block_high, block_low:block_high] = 0.005  # noqa
# run: evolve(grid, 0.1)
# from: High Performance Python by Micha Gorelick and Ian Ozsvald,
# http://shop.oreilly.com/product/0636920028963.do

# pythran export evolve(float64[][], float)

import numpy as np


def laplacian(grid):
    return (
        np.roll(grid, +1, 0)
        + np.roll(grid, -1, 0)
        + np.roll(grid, +1, 1)
        + np.roll(grid, -1, 1)
        - 4 * grid
    )


def evolve(grid, dt, D=1):
    return grid + dt * D * laplacian(grid)

# setup: import numpy as np ; grid_shape = (512, 512) ; grid = np.zeros(grid_shape) ; block_low = int(grid_shape[0] * .4) ; block_high = int(grid_shape[0] * .5) ; grid[block_low:block_high, block_low:block_high] = 0.005  # noqa
# run: evolve(grid, 0.1)
# from: High Performance Python by Micha Gorelick and Ian Ozsvald,
# http://shop.oreilly.com/product/0636920028963.do

# pythran export evolve(float64[][], float)

import numpy as np


def laplacian(grid):
    return (
        np.roll(grid, +1, 0)
        + np.roll(grid, -1, 0)
        + np.roll(grid, +1, 1)
        + np.roll(grid, -1, 1)
        - 4 * grid
    )


def evolve(grid, dt, D=1):
    return grid + dt * D * laplacian(grid)
