tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: variable MAKEOBJDIR inside of Makefile



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



Home | Main Index | Thread Index | Old Index