Re: variable MAKEOBJDIR inside of Makefile
David Holland <[email protected]> Sun, 2 Feb 2025 00:37:10 +0000
| Newsgroups | gmane.os.netbsd.devel.toolchain |
|---|---|
| Message-ID | <[email protected]> |
On Thu, Jan 30, 2025 at 02:23:11PM -0800, Greg A. Woods wrote: > > Everything about make's magic objdir behavior is a bug. > > Indeed, but I think the problem is in implementing a feature like > .OBJDIR support in any way that is sufficiently simple for a human > programmer to understand and manage. Not really. I mean, it's certainly easy to make messes but in the case of language and semantic stuff like this, the trouble arises from implementing without first designing. The core problem is that chdir changes the meaning of relative paths, and (a) make lives on paths and (b) relative paths are strongly preferred to absolute paths so that the location of your checkout doesn't get entangled into the build. This makes the whole idea (of having an OBJDIR you chdir to) suspect. It's perfectly reasonable to not chdir but still put your build output into an object directory; tools that don't work correctly in that style are broken should be fixed regardless. This is what I'd recommend if designing a new build system, or new build tools. In the current scheme, relative paths are implicitly relative to .OBJDIR. This means that if you change .OBJDIR partway through reading the makefile, it changes the meaning of the rules you've already read and partially processed. It also invalidates the results of any lookups via .PATH you've done. So it doesn't work, can't work (regardless of other implementation issues that may exist), and is prohibited. There are several ways that one might improve this. One relatively easy one is to stick say $(.OBJDIR.CWD) in front of every relative path while loading the makefile, and then allow changing .OBJDIR up until the point where $(.OBJDIR.CWD) is first evaluated; that point is when you actually chdir. (And $(.OBJDIR.CWD) always expands to "./".) Doing much better than that requires improving make's internal phase structure. In a world where make parsed first, you could set .OBJDIR after parsing and before interpreting any string other than an include name as a path. In that world includes would be relative to the source directory rather than the object directory and that'd be fine, probably even desirable. (I started trying to move make to that world at one point, a long time back now, but didn't get very far and rillig's gone off in other directions since.) All schemes that involve chdiring will result in injecting absolute paths where it's better to have relative ones, though, so it's always going to be a second-best method. -- David A. Holland [email protected]