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

2022-01-03 Thread Ismael Luceno
El vie, 31 dic 2021 a la(s) 09:30, Laslo Hunhold (d...@frign.de) escribió:
>
> On Fri, 31 Dec 2021 12:49:46 +0600
> NRK  wrote:
>
> Dear NRK,
>
> > Hmm, I was under the impression that `?=` was accepted into POSIX.
> > But I cannot find any mention of it in the posix manpage (man 1p
> > make) so I guess I was wrong.
> >
> > What would be a posix replacement for `?=` ? I assume something like:
> >
> >   VAR = $$(if test -n "$$VAR"; then printf "%s" "$$VAR"; else
> > printf "fallback"; fi)
> >
> > - NRK
>
> that is exactly what I meant earlier on that the POSIX-intended good
> practices get destroyed by the retarded GNU extensions.

Actually, many of those extensions come from SunPro Make, so not
really GNU extensions, and I guess they were implemented in GNU make
mainly for compatibility reasons, as at the time SunOS was probably
the most relevant platform for the development of GNU (remember, this
was a long time before autoconf/automake).

Also, "?=" is meant to provide a default value for something you want
to take from the environment into the makefile for substitution, but
where otherwise you really want the environment value, so it has its
uses; and it's fairly widespread.



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

2022-01-03 Thread Mattias Andrée
On Mon, 3 Jan 2022 11:16:48 +0100
Markus Wichmann  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 $@ $(LINUX_AMD64_OBJ) $(LDFLAGS_LINUX_AMD64)
> >
> > myproj-openbsd-amd64: $(OPENBSD_AMD64_OBJ)
> > $(CC) -o $@ $(OPENBSD_AMD64_OBJ) $(LDFLAGS_OPENBSD_AMD64)
> >
> > .c.linux-amd64-o:
> > $(CC) -c -o $@ $< $(CFLAGS_LINUX_AMD64) $(CPPFLAGS_LINUX_AMD64)
> >
> > .c.openbsd-amd64-o:
> > $(CC) -c -o $@ $< $(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 $@ $^

$^ 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
> 




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

2022-01-03 Thread Markus Wichmann
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 $@ $(LINUX_AMD64_OBJ) $(LDFLAGS_LINUX_AMD64)
>
> myproj-openbsd-amd64: $(OPENBSD_AMD64_OBJ)
>   $(CC) -o $@ $(OPENBSD_AMD64_OBJ) $(LDFLAGS_OPENBSD_AMD64)
>
> .c.linux-amd64-o:
>   $(CC) -c -o $@ $< $(CFLAGS_LINUX_AMD64) $(CPPFLAGS_LINUX_AMD64)
>
> .c.openbsd-amd64-o:
>   $(CC) -c -o $@ $< $(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

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

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