At Sun, 2 Feb 2025 00:37:10 +0000, David Holland <dholland-tech%netbsd.org@localhost> wrote: Subject: Re: variable MAKEOBJDIR inside of Makefile > > 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. Well, yes, I think that was probably the idea in the first place, and I think that part of the design seems very good. > This makes the whole idea (of having an OBJDIR you chdir to) suspect. So, I disagree quite with that claim. > 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. I don't think the problem is with the tools -- as far as I know there hasn't been such a problem with mainline tools used in Makefiles for decades, though perhaps if you include any scripts defined within a Makefile as a "tool", well, yeah, but there's the rub -- either trying to teach Make to manipulate just and only the "right" paths within a rule to prepend .OBJDIR gets mighty ugly mighty fast -- it's just plain inelegant. Even with the ability to give non-local pathnames to tools "we" have been "taught" to write make rules such that the default is to assume products go in the "current" directory. And that's true across all "make" variants I've ever encountered. So I think it's far more elegant and "clean" to transform sources to have the .CURDIR prefix. The kicker though is that while Make does know about _a_ target product for each rule, it doesn't necessarily know about any intermediate or secondary products created by a given rule (nor does it always know about sibling products made by the same rule, e.g. by yacc, though arguably that's a bug in the Makefile). All those things are likely going to end up in the current working directory no matter how hard you try to convince Makefile writers to change their ways. One could argue that's a fault of the tool, but it's a common requirement, e.g. for linkers, to be able to do that, and forcing the Makefile writer to always remember to include the object directory (when they don't if it's a primary known target) just isn't going to cut it, ever. Meanwhile we've also been taught to specify all the sources for any given rule, and it's easy for most people to understand why this is necessary. Make can also safely always assume those sources can be found relative to the directory where it was invoked (.CURDIR). (And we mostly have well known ways to find other "hidden" dependencies that might be used by a rule, such as header files, etc. and we even have a well known pseudo-target to do this: "make depend") So, I think the initial part of the design that says: chdir(.OBJDIR) before doing anything is not just a good idea, but it is (nearly) ideal. So, what's actually wrong with .OBJDIR? Well I think the first main problem that it is hard, next to impossible given the current implementation, especially of MAKEOBJDIRPREFIX, to specify a relative directory structure that, say, might be beside the source tree, especially when there are subdirectories in the source tree. Related is the problem of having a relative MAKEOBJDIRPREFIX that works even if you invoke "make" from deeper in such a multi-level source tree. The other main problem is that Make doesn't insist on always having separate .OBJDIRs and that it doesn't automatically try to make them first. I would have bit that bullet and changed it decades ago. Having to have a separate initial "make obj" step, and having everything go horribly wrong if you forget it, is a major botch. Personally I would _never_ have .OBJDIR be relative to within each source directory (in multi-directory source trees) either -- always in a separate sub-tree, though possibly within the top level of the source directory. Of course it would also be nice if it were easier to write one top-level Makefile for a multi-directory source tree, and maybe even have Make look for the Makefile up the parent directory chain until it finds one (e.g. how git looks for its repo). Tangentially there's the ongoing difference between how different logical lines in a given rule are treated depending on whether Make is in "jobs mode" or not. That should have been stamped out decades ago too. Also the name .CURDIR is rather unfortunately confusing. .SRCDIR might have been less ambiguous. -- Greg A. Woods <gwoods%acm.org@localhost> Kelowna, BC +1 250 762-7675 RoboHack <woods%robohack.ca@localhost> Planix, Inc. <woods%planix.com@localhost> Avoncote Farms <woods%avoncote.ca@localhost>
Attachment:
pgpPuQj1n7_Rm.pgp
Description: OpenPGP Digital Signature