Re: [dev] Special target ".POSIX" in Makefiles

From: Mattias Andrée <maandree_AT_kth.se>
Date: Mon, 3 Jan 2022 11:56:23 +0100

On Mon, 3 Jan 2022 11:16:48 +0100
Markus Wichmann <nullplan_AT_gmx.net> wrote:

> On Sat, Jan 01, 2022 at 08:09:38PM +0100, Mattias Andrée wrote:
> > .POSIX:
> >
> > CC = c99
> > # Required as POSIX doesn't mandate that it is defined by default
> >
> > OBJ =\
> > alpha.o\
> > beta.o\
> > gamma.o
> >
> > LINUX_AMD64_OBJ = $(OBJ:.o=.linux-amd64-o)
> > OPENBSD_AMD64_OBJ = $(OBJ:.o=.openbsd-amd64-o)
> >
> > all: myproj-linux-amd64 myproj-openbsd-amd64
> >
> > myproj-linux-amd64: $(LINUX_AMD64_OBJ)
> > $(CC) -o $_AT_ $(LINUX_AMD64_OBJ) $(LDFLAGS_LINUX_AMD64)
> >
> > myproj-openbsd-amd64: $(OPENBSD_AMD64_OBJ)
> > $(CC) -o $_AT_ $(OPENBSD_AMD64_OBJ) $(LDFLAGS_OPENBSD_AMD64)
> >
> > .c.linux-amd64-o:
> > $(CC) -c -o $_AT_ $< $(CFLAGS_LINUX_AMD64) $(CPPFLAGS_LINUX_AMD64)
> >
> > .c.openbsd-amd64-o:
> > $(CC) -c -o $_AT_ $< $(CFLAGS_OPENBSD_AMD64) $(CPPFLAGS_OPENBSD_AMD64)
> >
> > .SUFFIXES:
> > .SUFFIXES: .c .linux-amd64-o .openbsd-amd64-o
> >
> > # NB! Cannot use .linux-amd64.o and .openbsd-amd64.o
> > # as POSIX requires a dot at the beginning but
> > # forbids any additional dot
> >
> >
>
> OK, that is one way. I do wonder how you would handle configurable
> dependencies. I have always been partial to the Linux Kconfig way of
> doing it, but it requires +=:
>
> obj-y = alpha.o beta.o gamma.o
> obj-$(CONFIG_FOO) += foo.o
> obj-$(CONFIG_BAR) += bar.o
> obj-$(CONFIG_BAZ) += baz.o

You can always, although it may confuse people, especially if you
don't explain it, have ./Makefile be used to generate ./makefile.
It may be a bit messy, but this would allow you to anything, and
you can even build from ./makefile automatic once it has been
generated.

What I do, which unfortunately only work well when you have a
few options, and becomes messy when you have a lot of settings
(hopely that is a rarity), is:

./Makefile

        CONFIG_FOO=n
        include mk/foo=$(CONFIG_FOO).mk

        CONFIG_BAR=n
        include mk/bar=$(CONFIG_BAR).mk

        CONFIG_BAZ=n
        include mk/baz=$(CONFIG_BAZ).mk

        OBJ =\
                alpha.o\
                beta.o\
                gamma.o\
                $(OBJ_FOO)\
                $(OBJ_BAR)\
                $(OBJ_BAZ)

./mk/foo=y.mk

        OBJ_FOO = foo.o

Similar for ./mk/bar=y.mk and ./mk/baz=y.mk; and
./mk/foo=n.mk, ./mk/bar=n.mk, and ./mk/baz=n.mk are empty.

Another solution would be

./Makefile

        CONFIG_FOO = 0
        CONFIG_BAR = 0
        CONFIG_BAZ = 0

        CPPFLAGS = -DCONFIG_FOO=$(CONFIG_FOO)\
                   -DCONFIG_BAR=$(CONFIG_BAR)\
                   -DCONFIG_BAZ=$(CONFIG_BAZ)

        OBJ = alpha.o beta.o gamma.o dependencies.o

        dependencies.o: foo.c bar.c baz.c

./dependencies.c

        #if CONFIG_FOO != 0
        #include "foo.c"
        #endif

        #if CONFIG_BAR != 0
        #include "bar.c"
        #endif

        #if CONFIG_BAZ != 0
        #include "baz.c"
        #endif

Of course there are situations where this doesn't work well.

But extensions aren't always that bad, += clearly has it's
uses as these examples demonstrate. It is much cleaner, to
use your sample with += than mine. It's even much better
than using the if-statement extension.


>
> dir.o: $(obj-y)
> ld -r -o $_AT_ $^

$^ is non-POSIX, so you need $(obj-y)

>
> With your scheme, this one in particular would blow up due to
> combinatorics (need a list for none, FOO, BAR, BAZ, FOO+BAR, FOO+BAZ,
> BAR+BAZ, and FOO+BAR+BAZ. Now imagine this for the hundreds of options
> Linux has)
>
> But with the advent of ninja (yes, I know this list's opinion of C++ and
> Google in particular, but you cannot deny that Ninja is FAST), I have
> come around to the idea of configure scripts creating makefiles (or
> similar). And then you can generate makefiles in as complicated a manner
> as you like.
>
> Indeed, if the makefile is generated, there is little need for suffix
> rules at all. You can just make direct rules for everything. Repetition
> is no problem if the code generating the Makefile is readable. And then
> you can even build with make -r, because you don't need the default
> database, either. And -r saves time in some implementations.
>
> Ciao,
> Markus
>
Received on Mon Jan 03 2022 - 11:56:23 CET

This archive was generated by hypermail 2.3.0 : Mon Jan 03 2022 - 12:00:07 CET