Jhm

This patchset implements JHM in C++.

It also replaces our current build system (starsha) with JHM. Post-merge using starsha will be unsupported.

Two other PRs should land before this one (Or this one will implicitly land them), and one misc. task
- [x] #99 - Changes to our generic libraries.
- [x] #100 - Changes to `<base/json.h>`
- [ ] Update Jenkins (Has to happen at the same time as the merge)

#99 and #100 are pulled out because they should be reviewed more closely for not breaking old code than the full implementation of JHM needs to be / are relatively atomic.

## Core components 

- `jhm/job`: Describes some command that needs to be run, and keeps track fo both of what it needs as input, anything special it needs to run, and getting the command to run it.
- `jhm/env`: Maintains ownership / the collection of all jobs and files. Also maintains the job and file factories. 
- `jhm/work_finder`: 
- `jhm/job_runner`: A subprocess running queue. Rather than have n worker threads.

## Major design decisions

- There's only one thread which modifies jobs / files / etc. This eliminates a lot of locking.
- We just manage a pool of subprocesses rather than have n worker threads. See `jhm/job_runner`
- Configuration is all JSON based. See `jhm/config`.
- Files are dumb. A file is simply an entity in the JHM tree / container that lists various properties of the file (path, is source, etc). They don't know what produces them or what goes to output. Their main job is to exist, and to allow easy access to the config / various properties of the file.
- Jobs don't know about eachother. They can add attributes to their output files (Ex: list of includes as computed configuration of a file) to pass around configuration but that is it. There is no walking around the job graph.
- Work finder isolates keeping track of what we need to run to produce the requested files. It maintains sets of jobs which are currently Finished, Running (Submitted to the job runner), and Waiting (Needs 1+ other jobs to finish first). As jobs finish, it process the results of the job and asks a job if it's complete. If it is, it adds it to the Finished set, then queues any jobs which were waiting on it.

What all of this gives us is one foreground thread which queues jobs for what they need / does some fairly simple set computation to queue jobs inside a JobRunner, and then process the results (See `TWorkFinder::FinishAll`). A background thread which keeps as many subprocesses running as we have our worker count to, reading off a queue of jobs provided by the foreground thread, and storing back results for the foreground thread to grab in batches. There is a helper thread for the subprocess IO pumping (As is needed by `base/subprocess.h` in general).

## Things left TODO
There are lots of various todos in the code. Most just make things more usable. Various patches will likely appear over time.