Another problem with how Debian builds from source packages
When I wrote my first entry on this I didn't realize one more significant problem with the way Debian builds packages from source (because I hadn't run into it my own package building). This is that Debian builds binary packages in the source package working area.
It's easy to see how this came about. Since the unpacked, working form of a Debian source package is a directory tree with the source code and some extra information, doing an in-place build when compiling and building binary packages is both trivial and the obvious and simple approach. And usually everything works fine.
The problem is that this has the same failure mode as patching your source code in place during the build. You are crucially dependent on the software's build and cleanup processes actually cleaning everything up, both routinely and especially when things go wrong. If things do not completely clean up, always, then your working area for the actual package gets contaminated with artifacts of the build process, artifacts which you will have to disentangle from your own changes to the package and then remove by hand. You're also dependent on the build process not modifying anything in the original source tree; if it makes modifications itself, you're again going to have to disentangle and revert things by hand.
But wait, we're not done. There's another worry: reproduceable builds. Suppose that you are repeatedly building versions of the package (for example, you're testing a change). How sure are you that the build process has not contaminated the source tree such that your repeated rebuilds are producing a different result than what you'd get if you started from a just-unpacked tree? After all, the same source tree is being reused over and over again for each rebuild.
(In theory the package's cleanup process is not supposed to leave anything behind. Practice may be different from theory.)
Contrast this to the situation with a separate build tree. When you use a separate build tree, you can clean it up simply by deleting it all and you can always start from a known state by recreating it every time you build the package. The software being built can do whatever bizarre things it wants to inside its source tree (including patching its source code on the fly) and it won't contaminate anything else or get confused with your changes.
(The downside to a separate build tree is that you have to set it up every time. This slows down building packages as you copy and/or extract a potentially large source tree into your new build tree.)