Last week I sent out a broad last-rite email for a number of gkrellm plugins that my tinderbox reported warnings about that shows that they have been broken for a long time. This has been particularly critical because the current maintainer of all the gkrellm packages, Jim (lack), seems not to be very active on them.
The plugins I scheduled for removal are mostly showing warnings related to the gdk_string_width()
function called with a completely different object than it should have been called with, which will result in unpredictable behaviour at runtime (most likely, it’ll crash). A few more were actually buffer overflows, or packages failing because their dependencies changed. If you care about a plugin that is scheduled for removal, you’re suggested to look into it yourself and start proxy-maintain it.
I originally though I was able to catch all of the broken packages; but since then, another one appeared with the same gdk_string_width()
error, so I decided running the tinderbox specifically against the gkrellm plugins; there was another one missing and then I actually found all of them. A few more were reported ignoring LDFLAGS, but nothing especially bad turned up on my tinderbox.
What it did show though, is that the ignored LDFLAGS are just a symptom of a deeper problem: most of the plugins have broken Makefile
that are very poorly written. This could be seen in a number of small things, but the obvious one is the usual ”job server unavailable” message that I have written about last year.
So here’s a good checklist of things that shows that your Makefile
is broken:
- you call directly the
make
command — while this works perfectly fine on GNU systems, where you almost always use the GNUmake
implementation, this is not the case in most BSD systems, and almost always theMakefile
is good enough only to work with the GNU implemenation; the solution is to call$(MAKE)
which is replaced with the name of themake
implementation you’re actually using; - it takes you more than one command to run
make
in a subdirectory (this can also be true for ebuilds, mind you) — things likecd foo && make
or even worse(cd foo; make; cd ..; )
are mostly silly to look at and, besides, will cause the usual jobserver unavailable warning; what you might not know here is thatmake
is (unfortunately) designed to allow for recursive build, and provides an option to do so without requiring changing the working directory beforehand:make -C foo
(which actually should be, taking the previous point into consideration,$(MAKE) -C foo
) does just that, and only changes the working directory for themake
process and its children rather than for the current process as well; - it doesn’t use the builtin rules — why keep writing the same rules to build object files?
make
already knows how to compile.c
files into relocatable objects; instead of writing your rules to inject parameters, just use theCFLAGS
variable likemake
is designed to do! Bonus points if, for final executables, you also use the built-in linking rule (for shared objects I don’t think there is one); - it doesn’t use the “standard” variable names — for years I have seen projects written in C++ insisting on using
CPP
andCPPFLAGS
variables, well that’s wrong, as here “cpp” refers to the C Pre-Processor; the correct variables areCXX
andCXXFLAGS
; inventing your own variable names to express parameters that can be passed by the user tends to be a vary bad choice, as you break the expectations of the developers and packagers using your software.
Now, taking this into consideration, can you please clean up your packages? Pretty please with sugar on top?
I am certainly not an expert, but I think the “using builtin rules” isn’t always such a great idea, e.g. you might want to customize the output (e.g. kernel style), you need some parts to be compiled with a cross-compiler and others with the host compiler which might make the builtin rules confusing.But if you don’t use (some of) the builtin (suffix-)rules I suggest you disable them, that speeds up processing quite a bit, particularly on Windows and seems to avoid some cases where make confuses itself and fails to compile (compiling .rc files with some make versions somehow manage to convince make that everything is up-to-date despite the destination file not even existing).
Obviously, the usual rule of “if you do know what you’re doing, keep doing it” applies.The problem is that _most_ people who don’t use the builtin rules will get them wrong in one way or another.
Saw a great example of that final point the other day. D2X-XL uses the ARCH variable for arch-specific CFLAGS. Obviously it didn’t agree with Portage!
Just to clarify 2nd point in the checklist about “recursion”:http://www.gnu.org/software… :@cd subdir && $(MAKE)@ is also fine and equivalent to @$(MAKE) -C subdir@
Right, without subshell it works; on the other hand, why using two commands when one suffices? 🙂
Another point about recursion. As far as I understand “$(MAKE) -C” is a gnu-ism.With that in mind I was thinking it was better to go with “cd subdir && $(MAKE)” if you intended to support a wider range of make utilities.
Might have to look deeper into that later on today, but I’m pretty sure that @$(MAKE) -C@ is quite standard, as at least BSD supports it.
I don’t see a -C reference in http://www.opengroup.org/on…
Actually, it can by now be a good option to simply rely on GNU make instead of a generic make, because it can save you so many other dependencies that would be needed to work around broken or incomplete implementations (Perl etc.). Also in a modern build one should never need to recurse, but have one build process handling all the dependencies.(1)<shameless plug>see the new OpenOffice.org build system for example:http://www.ooocon.org/index…</shameless>(1) see also: http://miller.emu.id.au/pmi…
I don’t know if FreeBSD supports $(MAKE) -C, but I do know that NetBSD does not. From what I understand, the officially correct and portable way to recurse actually is “cd dir && $(MAKE)”. But I agree with Peter Miller who was just referenced by Bjoern recursive make should definitely be avoided for reasons that Diego has gone over many times.
Just to shamelessly plug some more, the talk is now available as video (and there is a lot in the talk that is not on the slides):http://users2.ooodev.org/~o…
I cannot watch it right now but I’ll make sure to watch it tomorrow, since it really is in my area of interest, thanks!
What we need here is more discussion on make -C! According to the online man pages, (Free|Dragonfly|Net)BSD all support it, while OpenBSD does not. Though I never find the need to make recursive builds, I will do it the non-GNU way. GNU has too much glut. Hmmm, maybe ‘Glut, Not Usability’.I was looking at some broken make files today, and noticed some CPPFLAGS garbage, CC=g++, a static archive depending directly on headers…After an overhaul, writing ‘make’ actually uses dependency information correctly.