I'm currently evaluating Olivier Sessinks jailkit to maintain a small cvsd CHROOT with an included SSH server. The cvsd-buildroot command e.g. doesn't handle the libpam-modules dependency in the CHROOT. So I tried to update the Debian packaging files included in the jailkit source. During this work I found some issues with the build environment - e.g. no DESTDIR support and some other stuff (another user already complained, that there might be problems with the SUID installation part for jk_chrootsh, jk_uchroot and jk_procmailwrapper of the Makefiles).
So I began to check and “fix” the Makefiles and the configure script and then sent everything to Olivier. I did not only add the DESTDIR variables. I also made use of built-in rules, common variables (also for implicit rules), ... and such stuff to make the Makefiles shorter and easier to maintain. My fault: I tested everything with GNU make. Now Olivier complained, that BSDs make doesn't work anymore. So we began a short hack session to check for the problems.
My first issue: I had to find some BSD make to test it myself. I found it in the freebsd5-buildutils, that contains the freebsd-make command. Then we began to check for incompatibilities and that's the result:
ifdef
statements differ in syntax- GNU make uses
ifdef VAR
- BSD make uses
.ifdef VAR
solution: We replaced the statement with a construct similar to
AM_CONDITIONAL
. But we do not use this macro, because it would need to be shipped in aclocal.m4, which is currently not necessary. The code simply sets a variable foo_TRUE to ‘#
‘, if the condition is wrong, or the variable is left empty, if the condition is true:if test "x$my_condition" != "xno" ; then AC_SUBST([foo_TRUE], []) else AC_SUBST([foo_TRUE], [# ]) fi
FILES = bar @foo_TRUE@FILES += foo
- GNU make uses
- prerequisite variables differ in syntax
- GNU make uses
$<
,$^
,$@
, ... - BSD make uses
${.IMPSRC}
,${.ALLSRC}
,${.TARGET}
, ... (note, that both *SRC variables hold a list of source files)
Unfortunately both make implementations don't seem to share a variable for the list of prerequisites. So the only solution is to list all prerequisites in the rule again. A variable would be much more comfortable. Maybe one could write a function, that first tests
${.IMPSRC}
and falls back to$^
. Maybe that's an alternative, but it's IMHO not a very good solution. We've chosen to write down all prerequisites in a rule instead of using a variable. This is a little bit harder to maintain, but it works. - GNU make uses
- built-in rules are not shared and do not use the same variables
- GNU make ships built-in rules to build objects from sources and link them; rules consider CPPFLAGS
- BSD make ships built-in rules to build objects from sources, but there are no rules to link them; rules do not consider CPPFLAGS
In the case of GNU make, one can simply write:
myprog: foo.o bar.o
and GNU make will automatically create foo.o from foo.c (
.c.o:
, ditto for bar.o) and at least link myprog (.o:
). But BSD make will only create the object files. There is no final link-step. So we had to include the rule to link the program in the Makefile.
Finally we got it and it looks good now. I/We learned a lot of new things (I learnd a lot about BSD make) ;), but it took us 1-2 hours to understand and fix the problems.
Here a list of URLs that might give some more information about the programs, their syntax and limitations: