Some work to enable incremental compilation

Introducing inputs/outputs to compile task. So `protoc` is called when `*.proto` files really changed or generated files changed.
This can prevent unnecessary compilation during build process.
Unfortunately was unable to create sufficient unit test for this.