[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lmi] Copying compiler run-time files in the makefiles
From: |
Vadim Zeitlin |
Subject: |
Re: [lmi] Copying compiler run-time files in the makefiles |
Date: |
Thu, 21 Jul 2022 23:10:12 +0200 |
On Thu, 21 Jul 2022 15:02:27 +0000 Greg Chicares <gchicares@sbcglobal.net>
wrote:
GC> On 6/28/22 13:47, Vadim Zeitlin wrote:
GC> > On Tue, 28 Jun 2022 00:23:15 +0000 Greg Chicares
<gchicares@sbcglobal.net> wrote:
GC> >
GC> > GC> On 6/27/22 20:45, Vadim Zeitlin wrote:
GC> > GC> [...]
GC> > GC> > I am not sure I
GC> > GC> > understand why should build_dir depend on $(gpl_files)
GC> > GC>
GC> > GC> $(build_dir) is a prerequisite for everything:
GC> > GC>
GC> > GC> % :: $(build_dir) ; @:
GC> >
GC> > Ah, I've missed this, sorry. But it's still not totally clear to me how
GC> > does this work because, quoting GNU make manual[1]:
GC> >
GC> > One choice is to mark the match-anything rule as terminal by
GC> > defining it with a double colon. When a rule is terminal, it does
GC> > not apply unless its prerequisites actually exist. Prerequisites
GC> > that could be made with other implicit rules are not good enough.
GC> > In other words, no further chaining is allowed beyond a terminal
GC> > rule.
GC> >
GC> > Doesn't this mean that $(build_dir) must already exist for this to work?
GC>
GC> I was going to respond claiming that $(build_dir) is a target here,
GC> rather than a prerequisite, but that would have been incorrect.
GC>
GC> Applying the terminological example from section 2.1:
GC>
GC> target … : prerequisites …
GC> recipe
GC>
GC> to the rule at hand:
GC>
GC> % :: $(build_dir) ; @:
GC>
GC> the 'target' is "%"; "$(build_dir)" is a prerequisite; and the recipe
GC> is apparently "; @:", which I don't quite understand, though I'm pretty
GC> sure it does nothing. Normally, ";" would suffice for doing nothing.
GC> The "@:" looks like it might mean something special to 'make', but I
GC> can't find it in the manual, so I think the recipe is the shell command
GC> ':', and the "@" prefix tells make not to print that shell command.
Yes, this is how I parsed it too when looking at it: execute the "do
nothing" command ":" while suppressing its display using "@" -- so this is
the case of a tree not falling in a forest and nobody being there to (not?)
hear it, which should be enough to safely conclude that will be no sound^W
output here.
GC> So your question is deep, at least from my perspective. Stepping back
GC> to include more context...
GC>
GC> .PHONY: $(build_dir)
GC> $(build_dir): $(gpl_files)
GC> +@[ -d $@ ] || $(MKDIR) --parents $@
GC> [...]
GC> % :: $(build_dir) ; @:
GC>
GC> I believe the resolution is that the .PHONYness of $(build_dir)
GC> creates an implicit exception to the paragraph quoted from the
GC> manual, which might be amended thus:
GC>
GC> One choice is to mark the match-anything rule as terminal by
GC> defining it with a double colon. When a rule is terminal, it does
GC> - not apply unless its prerequisites actually exist. Prerequisites
GC> + not apply unless its prerequisites actually exist (or are .PHONY,
GC> + in which case they are deemed not to name a real file). Prerequisites
GC> that could be made with other implicit rules are not good enough.
GC> In other words, no further chaining is allowed beyond a terminal
GC> rule.
Thanks, it would indeed make sense if gmake behaved like this...
GC> But I think it's clear that the answer to your question is "No":
GC> the build directory needn't already exist. Indeed, 'make clean'
GC> removes the build directory, and it always gets recreated.
... and, empirically, it does seem to. I couldn't find any further
discussions of this, but experimenting with this makefile:
---------------------------------- >8 --------------------------------------
% cat terminal.make
.PHONY: always
always:
@echo Always made.
sometimes:
@echo Sometimes made.
% :: $(dep)
@echo $@ made.
---------------------------------- >8 --------------------------------------
confirms that it works as you say, i.e.
% make -f terminal.make dep=always foo
Always made.
terminal.make made.
foo made.
% make -f terminal.make dep=sometimes foo
Sometimes made.
terminal.make made.
foo made.
% touch sometimes
% make -f terminal.make dep=sometimes foo
foo made.
GC> > GC> I'll try to specify the desired behavior here, in case you can see a
GC> > GC> better way to accomplish it. To run any msw binary, the compiler
runtime
GC> > GC> libraries must be on $WINEPATH; specifically, $localbindir must
contain
GC> > GC> copies of them.
GC> >
GC> > Sorry but I have to point that the implication indicated by the use of
GC> > semicolon here is not correct. You could also just add the directory
GC> > containing the files to WINEPATH, which is what I typically do and which
GC> > seems both simpler and more robust to me.
GC>
GC> Okay, so you'd add something like this to $WINEPATH:
GC> /usr/lib/gcc/x86_64-w64-mingw32/10-win32/
GC> (not tested, but that's what 'mlocate' suggests)--i.e., the place
GC> where 'apt' put it. The canonical way to get that is:
GC>
GC> $ dirname $(x86_64-w64-mingw32-g++ -print-libgcc-file-name)
GC> /usr/lib/gcc/x86_64-w64-mingw32/10-win32
Yes, so I used to just start all the commands with
% WINEPATH=$(dirname $(x86_64-w64-mingw32-g++ -print-libgcc-file-name))
...
Now that we don't have to juggle between 32 and 64 bit builds any more, I
could also simply put this WINEPATH in the environment.
GC> But I still think it's more important for us to eat our own dogfood.
Well, as long as you don't meant it literally (as, apparently, Mars
employees do), I don't have any real objections.
GC> > On Tue, 28 Jun 2022 11:32:58 +0000 Greg Chicares
<gchicares@sbcglobal.net> wrote:
[...]
GC> > GC> Let me mention the reasons for a couple of particulars:
GC> > GC> - The 'install' command uses a shell for-loop, because
GC> > GC> $(compiler_runtime_files) might be empty, and I see no
GC> > GC> better way to deal with that possibility.
GC> >
GC> > The old (removed in the above-mentioned 19c09468c8) idea of simply using
GC> >
GC> > @[ -z "$(compiler_runtime_files)" ] || cp ...
GC> >
GC> > seems better to me because it's both more clear (i.e. you can see at a
GC> > glance that the possibility of compiler_runtime_files being empty has been
GC> > considered and handled, instead of wondering whether it's normal for it to
GC> > be empty) and uses one cp command instead of N calls to it. But it's
hardly
GC> > critically important, of course.
GC>
GC> Yet commit f760e3df2823 says:
GC>
GC> running `make -n fardel` through shellcheck elicits:
GC> SC2157: Argument to -z is always false due to literal strings.
GC> for the controlling condition here:
GC> [ -z "$(compiler_runtime_files)" ]
GC> because of a trailing blank.
Oh, I totally failed to notice this, sorry.
GC> There's a trailing blank because of this definition:
GC> compiler_runtime_files := \
GC> $(wildcard $(compiler_sysroot)/libgcc*.dll) \
GC> $(wildcard $(compiler_sysroot)/libstdc++*.dll) \
GC> That's how I like to define 'make' variables, and I don't want to
GC> change it in a special case that I might break later. I could use
GC> 'sed' to remove extraneous leading or trailing spaces, but that
GC> seems worse than the for-loop. I could try '${param// }', but
GC> that's a ksh-ism that's not POSIX,
And POSIX solution (https://unix.stackexchange.com/a/147362/20551) is much
longer (although, arguably, more clear).
GC> and $(compiler_runtime_files) is a 'make' variable anyway.
GC>
GC> Maybe
GC> [ -z "$(strip $(compiler_runtime_files))" ]
GC> would work (although I'm not sure I can do that in a recipe),
Make functions can be applied anywhere and this looks like a perfectly
reasonable solution to me.
GC> but then I'd want to explain why the $(strip ...) function is used.
FWIW, I think using strip for the -z argument is rather self-explanatory.
GC> I think I'll just leave well enough alone.
But, it's hard to argue with this solution too.
VZ
pgplUAejU9rZc.pgp
Description: PGP signature