On Tue, Feb 24, 2009 at 09:44:22AM +0100, Roland Illig wrote: [...] > We could surely avoid that by changing _all_ these files to the order > known from C header files: > > .ifndef BUILDLINK3_PKGNAME_MK > .define BUILDLINK3_PKGNAME_MK > > .include "../../dependency/one/buildlink3.mk" > .include "../../dependency/two/buildlink3.mk" > > BUILDLINK_PACKAGES+= pkgname > ... > > .endif > > That would be all. But this change involves lots of subtleties that only > jlam@ understands. I asked some years ago whether to make that change, > but didn't dare to start the whole work. So, I've looked at this, because the "only jlam knows about that stuff" hand waving only gets us so far. It's actually not that complicated, how scary the code might be. Your typical buildlink3.mk files does this: BUILDLINK_DEPTH:= ${BUILDLINK_DEPTH}+ GLIB2_BUILDLINK3_MK:= ${GLIB2_BUILDLINK3_MK}+ .if !empty(BUILDLINK_DEPTH:M+) BUILDLINK_DEPENDS+= glib2 .endif BUILDLINK_PACKAGES:= ${BUILDLINK_PACKAGES:Nglib2} BUILDLINK_PACKAGES+= glib2 BUILDLINK_ORDER:= ${BUILDLINK_ORDER} ${BUILDLINK_DEPTH}glib2 .if !empty(GLIB2_BUILDLINK3_MK:M+) BUILDLINK_API_DEPENDS.glib2+= glib2>=2.4.0 BUILDLINK_ABI_DEPENDS.glib2+= glib2>=2.14.3 BUILDLINK_PKGSRCDIR.glib2?= ../../devel/glib2 PRINT_PLIST_AWK+= /^@dirrm lib\/gio$$/ { next; } PRINT_PLIST_AWK+= /^@dirrm lib\/gio\/modules$$/ \ { print "@comment in glib2: " $$0; next; } .endif # GLIB2_BUILDLINK3_MK .include "../../converters/libiconv/buildlink3.mk" .include "../../devel/gettext-lib/buildlink3.mk" .include "../../devel/pcre/buildlink3.mk" .include "../../mk/pthread.buildlink3.mk" BUILDLINK_DEPTH:= ${BUILDLINK_DEPTH:S/+$//} There are a couple variables that are used with respect to multiple inclusions. The first one is BUILDLINK_DEPTH. The reason it exists is so that a "top-level" inclusion of a buildlink3 file will add to the BUILDLINK_DEPENDS variable. It is also used in BUILDLINK_ORDER, I'll get back to that later. Then there is <package>_BUILDLINK3_MK. It is used so that a few variables are only set/added to once. That's the only reason it exists. So what matters for a buildlink3.mk file is that its contents is parsed at least once entirely (duh) and that BUILDLINK_DEPENDS gets updated if we're at top-level, and that BUILDLINK_ORDER gets updated at every inclusion. You can invoke jlam-obfuscation as much as you want, there is nothing more to it. My first idea (thank you, insomnia) was that we can't naively protect against multiple inclusion, because of the use of BUILDLINK_DEPTH. The main issue is BUILDLINK_ORDER, because it gets updated with new information at each inclusion. But when you actually think about it, what information does that bring if a bl3.mk has already been included at a specific BUILDLINK_DEPTH? Nothing. So my idea was to add the following test: BUILDLINK_DEPTH:= ${BUILDLINK_DEPTH}+ GLIB2_BUILDLINK3_MK:= ${GLIB2_BUILDLINK3_MK}+ GLIB2_BUILDLINK_DEPTH?= ${BUILDLINK_DEPTH}+ .if empty(BUILDLINK_DEPTH:N${GLIB2_BUILDLINK_DEPTH}*) GLIB2_BUILDLINK_DEPTH:= ${BUILDLINK_DEPTH} ... .endif BUILDLINK_DEPTH:= ${BUILDLINK_DEPTH:S/+$//} That's about as good as you can get without changing the nature of the BUILDLINK_ORDER variable. Of course, I am here guilty of waving the magic jlam obfuscation wand, because I didn't even try to know what BUILDLINK_ORDER is about. Well, guess what? It's only used for "make show-buildlink3". So there is no point of caring specificly about it. So I don't see any reason why devel/glib2's bl3.mk file shouldn't look like that: BUILDLINK_DEPTH:= ${BUILDLINK_DEPTH}+ .if !empty(BUILDLINK_DEPTH:M+) BUILDLINK_DEPENDS+= glib2 .endif .if !defined(GLIB2_BUILDLINK3_MK) GLIB2_BUILDLINK3_MK= # defined BUILDLINK_PACKAGES+= glib2 BUILDLINK_ORDER:= ${BUILDLINK_ORDER} ${BUILDLINK_DEPTH}glib2 BUILDLINK_API_DEPENDS.glib2+= glib2>=2.4.0 BUILDLINK_ABI_DEPENDS.glib2+= glib2>=2.14.3 BUILDLINK_PKGSRCDIR.glib2?= ../../devel/glib2 PRINT_PLIST_AWK+= /^@dirrm lib\/gio$$/ { next; } PRINT_PLIST_AWK+= /^@dirrm lib\/gio\/modules$$/ \ { print "@comment in glib2: " $$0; next; } .include "../../converters/libiconv/buildlink3.mk" .include "../../devel/gettext-lib/buildlink3.mk" .include "../../devel/pcre/buildlink3.mk" .include "../../mk/pthread.buildlink3.mk" .endif BUILDLINK_DEPTH:= ${BUILDLINK_DEPTH:S/+$//} Same goes for every other bl3.mk file, of course. (Note the removal of the line that removes the package name from BUILDLINK_PACKAGES, too.) That should make pkgsrc's performance a bit less embarassing. It's a lot of work, though. Any volunteer? -- Quentin Garnier - cube%cubidou.net@localhost - cube%NetBSD.org@localhost "See the look on my face from staying too long in one place [...] every time the morning breaks I know I'm closer to falling" KT Tunstall, Saving My Face, Drastic Fantastic, 2007.
Attachment:
pgphpkXsFDKSj.pgp
Description: PGP signature