make install

When the DESTDIR support was originally introduced 3.5 years ago, I tried to keep it as non-intrusive in the infrastructure as possible.
The reason was simply, that it is very easy to introduce bugs in the complex make rules and DESTDIR support would need quite a bit of work before it is ready for main stream consumption. My initial goal for 2006Q4 was 50% or so I wrote in my EuroBSDCon slides. I was waaaay too optimistic.

Fast forward 3 years to the current time. DESTDIR support is now supported by almost all packages. 384 package locations without DESTDIR support remains (compared to 8302 with). To avoid unnecessary regressions from developers not testing it, I made USE_DESTDIR=yes the default for PKG_DEVELOPER a while ago. That's when the complains and insults started.

Due to the change, "make install" now suddenly doesn't modify /usr/pkg any longer. The other direct consequence is that "DEPENDS_TARGET=package" breaks as well.
The former is reasonable to fix by finally pushing the originally planed intrusive changes. The latter is more difficult to do without second guessing and more a case of Update your config, please. So, what was needed to change the install target to behave the same from a user perspective?

First of all, a bit of search and replace. Second, dealing with the surprises. Just renaming install to stage-install -- fails. The install-vars target has be renamed as well, as the necessary files are created. More fun was the addition of the new target. Just adding

.PHONY: install
.if ${_USE_DESTDIR} == "no"
install: stage-install
install: package-install

...doesn't work. It surprisingly does nothing. What happened?

pkgsrc computes a number of variables based on the dependencies. For example, BUILDLINK_PREFIX depends on whether the package is builtin and if not, where it is found. This got quite expensive when pkgviews was introduced. A long time ago, pkgsrc therefore run a new make instance for every major build phase (depends, extract, build, install). This was changed later with the introduction of the pkgsrc barrier. Essentially, the build phases are separated into pre-barrier and post-barrier phases, with a separate make invocation in between.

How does this affect the install target above? install has to be a post-barrier operation otherwise it ends up effectively invocing build, but not the desired install rule.
Black magic. Why do I know? The same problem occured with package-install a long time ago...