On Mon, 3 Jan 2022 11:16:48 +0100 Markus Wichmann <nullp...@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 $@ $(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 >