Re: [dev] Special target ".POSIX" in Makefiles
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
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
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
Re: [dev] Special target ".POSIX" in Makefiles
On Sat, 1 Jan 2022 23:30:39 +0100 Ralph Eastwood wrote: Dear Ralph, > Those are both useful suggestions! Thank you! you're very welcome! :) With best regards Laslo
Re: [dev] Special target ".POSIX" in Makefiles
Hi Laslo and Mattias, On Sat, 1 Jan 2022 at 19:05, Laslo Hunhold wrote: > If you think about it, a better approach in this case would be to pack > these things into a static library (which is basically a collection of > object files). So you would have a target On Sat, 1 Jan 2022 at 20:10, Mattias Andrée wrote: > .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) Those are both useful suggestions! Thank you! -- Tai Chi Minh Ralph Eastwood tcmreastw...@gmail.com
Re: [dev] Special target ".POSIX" in Makefiles
.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 On Sat, 1 Jan 2022 14:08:24 +0100 Ralph Eastwood wrote: > Hi Mattias, > > Happy New Year! > > > But I also like makel, but I will give it some more though before I > rename it a second time. > > So... makellint? :D > I like it; it seems 'makel' is unused as a project name. > > Are there any suggestions for handling out-of-source builds using > POSIX makefiles? I recently had a project where we needed to > support multiple platforms and so output-ing object files and binaries > into platform-specific directories was needed. > I know that GNU's pattern matching rules support this behaviour, i.e.: > > $(OBJDIR)/%.o: $(SRCDIR)/%.c > $(CC) $(CFLAGS) -c $< -o $@ > > Perhaps just listing all of the object files and source + > dependencies would be the easiest way in this instance? > > Best regards, > Ralph > > -- > Tai Chi Minh Ralph Eastwood > tcmreastw...@gmail.com >
Re: [dev] Special target ".POSIX" in Makefiles
On Sat, 1 Jan 2022 17:03:41 +0100 Ralph Eastwood wrote: Dear Ralph, > Thanks for pointing out that technique, I've utilised it in the past > and it's a shame that it's not more well-known... I've seen many a > GNUism in its place... yeah, it makes a lot of sense and is nice and simple. > The idea was to build all the platforms' binaries out of the source > tree. For example, having an 'obj' directory separate from the 'src' > directory and then dumping the built objects into there. In the > context of multiple platforms, then you would have 'obj/x86', > 'obj/arm' etc. So taking your example: > > make TARGET=x86 # obj/x86 is populated with *.o, bins > make TARGET=arm # obj/arm is populated with *.o, bins > > The benefit of having it out of tree is so that you do not need to > `make clean` and lose previously built object files. > > As far as I'm aware, suffix intrinsic rules like: > > .c.o: >$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< > > only allow you to implicitly define rules that have the target suffix > (.o) and the source suffix (.c) as long as the prefix is the same. > > My thoughts have always been to not have this as part of the > make-step, and that platform (or generally configuration) specific > building should be done in an external step (be it a shell script or > some overly-sophisticated CI [another topic]). > An alternative could be a script or even make step that can > 'save' and 'restore the build state of a particular platform into the > 'obj/$(TARGET)' directory. If you think about it, a better approach in this case would be to pack these things into a static library (which is basically a collection of object files). So you would have a target library-$(TARGET).a: $(SRC:.c=.o) $(AR) rc $@ $? $(RANLIB) $@ (where AR and RANLIB are defined in config.mk) that you could rely on in higher levels of the program. This single file also allows you to easily move it around and swap it. The make-clean-matter can be resolved insofar that you only cleanup the static library of the current target, i.e. clean: rm library-$TARGET.a $(SRC:.c=.o) which then yields a build environment where you can work on the arch that matters at hand without having to recompile the other stuff (which stays "stale" and can be linked into your program without issues). However, if you want to clean everything up and rebuild everything, you just have to remove all the static libraries and regenerate them (either automatically by invocation from a higher layer or manually). With best regards Laslo
Re: [dev] Special target ".POSIX" in Makefiles
Hi Laslo, > and then in config.mk have a variable > >TARGET = arm > > and then in the Makefile have a line > >include target/$TARGET.mk Thanks for pointing out that technique, I've utilised it in the past and it's a shame that it's not more well-known... I've seen many a GNUism in its place... > So did you build all of the platforms or would it need to be > selectable? If you have multiple platform sources e.g. in folders "x86" > and "arm", I would create a folder "target" that contains the files The idea was to build all the platforms' binaries out of the source tree. For example, having an 'obj' directory separate from the 'src' directory and then dumping the built objects into there. In the context of multiple platforms, then you would have 'obj/x86', 'obj/arm' etc. So taking your example: make TARGET=x86 # obj/x86 is populated with *.o, bins make TARGET=arm # obj/arm is populated with *.o, bins The benefit of having it out of tree is so that you do not need to `make clean` and lose previously built object files. As far as I'm aware, suffix intrinsic rules like: .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< only allow you to implicitly define rules that have the target suffix (.o) and the source suffix (.c) as long as the prefix is the same. My thoughts have always been to not have this as part of the make-step, and that platform (or generally configuration) specific building should be done in an external step (be it a shell script or some overly-sophisticated CI [another topic]). An alternative could be a script or even make step that can 'save' and 'restore the build state of a particular platform into the 'obj/$(TARGET)' directory. Best regards, Ralph -- Tai Chi Minh Ralph Eastwood tcmreastw...@gmail.com
Re: [dev] Special target ".POSIX" in Makefiles
On Sat, 1 Jan 2022 14:08:24 +0100 Ralph Eastwood wrote: Dear Ralph, > So... makellint? :D > I like it; it seems 'makel' is unused as a project name. and even if, it's not like names are reserved. When some 13-year-old kid dumps some Rust-crap with a name on GitHub I wouldn't see it as reserved. The threshold is if a program or library gets packaged, because then you may have namespace-conflicts. > Are there any suggestions for handling out-of-source builds using > POSIX makefiles? I recently had a project where we needed to > support multiple platforms and so output-ing object files and binaries > into platform-specific directories was needed. > I know that GNU's pattern matching rules support this behaviour, i.e.: > > $(OBJDIR)/%.o: $(SRCDIR)/%.c > $(CC) $(CFLAGS) -c $< -o $@ > > Perhaps just listing all of the object files and source + > dependencies would be the easiest way in this instance? So did you build all of the platforms or would it need to be selectable? If you have multiple platform sources e.g. in folders "x86" and "arm", I would create a folder "target" that contains the files --- x86.mk --- SRC =\ x86/util.c\ x86/dump.c\ x86/foo.c\ -- --- arm.mk --- SRC =\ arm/util.c\ arm/dump.c\ arm/foo.c\ -- and then in config.mk have a variable TARGET = arm and then in the Makefile have a line include target/$TARGET.mk (this works according to the standard, see [0] under "Include Lines") The nice thing about this is that you can do all kinds of things within these mk-files apart from defining SRC-files. You can also change CFLAGS or whatnot, but do as little as possible to ensure that maximum control is retained within the config.mk. Within the Makefile, you can then easily just work with the $SRC-variable that is automatically set, and if you want to build for certain architectures, you simply run make TARGET=arm It also "breaks" elegantly because it would output an error that target/itanium.mk (or something) could not be found, which is pretty easy to understand. You can also, if you have shared source files, only define a variable $TARGET_SRC in the target files that is then appended to SRC in the Makefile itself. I think that should work out in your case, but let me know if it is different from how I understood it. With best regards Laslo [0]:https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html
Re: [dev] Special target ".POSIX" in Makefiles
Hi Mattias, Happy New Year! > But I also like makel, but I will give it some more though before I rename it a second time. So... makellint? :D I like it; it seems 'makel' is unused as a project name. Are there any suggestions for handling out-of-source builds using POSIX makefiles? I recently had a project where we needed to support multiple platforms and so output-ing object files and binaries into platform-specific directories was needed. I know that GNU's pattern matching rules support this behaviour, i.e.: $(OBJDIR)/%.o: $(SRCDIR)/%.c $(CC) $(CFLAGS) -c $< -o $@ Perhaps just listing all of the object files and source + dependencies would be the easiest way in this instance? Best regards, Ralph -- Tai Chi Minh Ralph Eastwood tcmreastw...@gmail.com
Re: [dev] Special target ".POSIX" in Makefiles
On Sat, 1 Jan 2022 13:22:48 +0100 Mattias Andrée wrote: Dear Mattias, > libzahl is my only project with a German name, and it's was called > libzahl because the bold Z used represent the integers stands for > Zahl, but I do have projects with names in different languages (I > also have libskrift (Swedish), libruun (librún; Old Norse, Icelandic, > and Faroese; this one is not published yet), radharc (Irish and > Gaelic), and libcantara (Spanish, Protuguese, Galician, and Asturian; > this one hasn't been published yet, and the rate it is being > developed at it I'm doubtful it ever will be))), so giving it a > non-English name wouldn't be out of character. thanks for the overview. > But I also like makel, but I will give it some more though before I > rename it a second time. Yeah, take your time. :) More important than the name is the code, but under all conditions the name must contain "make" at best so it is easy to associate. With best regards Laslo
Re: [dev] Special target ".POSIX" in Makefiles
On Sat, 1 Jan 2022 13:01:05 +0100 Laslo Hunhold wrote: > On Sat, 1 Jan 2022 10:33:22 +0100 > Mattias Andrée wrote: > > Dear Mattias, > > first off, happy new year to all of you! > > > Thanks for pointing that it, I didn't find it in my search. > > I renamed it to mklint. > > This is also confusing as mk(1) by plan9 exists, but you explicitly > target POSIX make(1). Your right, that wasn't really a good idea. > > makelint is a really great name and it clearly shows what it does, the > linked project seems to be dead after the initial commit and nobody > talks about it. > > Here are some suggestions for a different name: > >- makel ("Makel" means "flaw" in Germany, and it fits so well > because you want to find flaws in Makefiles) >- makeorbreak (english idiom, meaning a situation that either brings > success or complete failure, might be a nod towards > the fact that you either are POSIX compliant or not) >- shakenmake (like Shake'n'Bake) > > I really like "makel" to be honest, which also fits your theme of > naming some of your projects after German nouns (e.g. libzahl). libzahl is my only project with a German name, and it's was called libzahl because the bold Z used represent the integers stands for Zahl, but I do have projects with names in different languages (I also have libskrift (Swedish), libruun (librún; Old Norse, Icelandic, and Faroese; this one is not published yet), radharc (Irish and Gaelic), and libcantara (Spanish, Protuguese, Galician, and Asturian; this one hasn't been published yet, and the rate it is being developed at it I'm doubtful it ever will be))), so giving it a non-English name wouldn't be out of character. But I also like makel, but I will give it some more though before I rename it a second time. > > With best regards > > Laslo >
Re: [dev] Special target ".POSIX" in Makefiles
> I'd definitely be interested in such a tool. Weather it be in form of > a make implementation or linter doesn't matter a whole lot to me as > long as the end goal of having a tool to help write portable makefile > is achieved. This is my take, too --- I'd get plenty of use out of either version, though I'd probably prefer just a linter. While POSIX is theoretically the least common denominator, in (most) practice, GNU make is the expectation, and upholding that expectation *in addition to* the standard is usually my ideal make situation. A POSIX linter that does not necessarily include an implementation would fit well into the GNU environments I find myself in. Anyway, if anyone gets around to implementing anything along these lines, maybe send an email here; I'd be very interested in looking at and using either version! -- Lincoln Auster They/Them
Re: [dev] Special target ".POSIX" in Makefiles
On Sat, 1 Jan 2022 10:33:22 +0100 Mattias Andrée wrote: Dear Mattias, first off, happy new year to all of you! > Thanks for pointing that it, I didn't find it in my search. > I renamed it to mklint. This is also confusing as mk(1) by plan9 exists, but you explicitly target POSIX make(1). makelint is a really great name and it clearly shows what it does, the linked project seems to be dead after the initial commit and nobody talks about it. Here are some suggestions for a different name: - makel ("Makel" means "flaw" in Germany, and it fits so well because you want to find flaws in Makefiles) - makeorbreak (english idiom, meaning a situation that either brings success or complete failure, might be a nod towards the fact that you either are POSIX compliant or not) - shakenmake (like Shake'n'Bake) I really like "makel" to be honest, which also fits your theme of naming some of your projects after German nouns (e.g. libzahl). With best regards Laslo
Re: [dev] Special target ".POSIX" in Makefiles
Thanks for pointing that it, I didn't find it in my search. I renamed it to mklint. Regards, Mattias Andrée On Sat, 1 Jan 2022 14:43:15 +0600 NRK wrote: > On Fri, Dec 31, 2021 at 11:29:11PM +0100, Mattias Andrée wrote: > > I just started implementing a linter[0]. Even though I just > > started it today, I think that's enough for this year. > > > > Happy New Year! > > Mattias Andrée > > > > [0] https://github.com/maandree/makelint/ > > Thank you very much, I'll keep an eye on this. > > Also as for the name, while looking it up I noticed that there's another > project by the exact same name [0]. Funny enough, this project's goal > seems to be complete opposite of ours, it advices usage of non-posix > implicit variables like $(RM) in it's README. > > Might be a good idea to use a different name to avoid potential > confusion. Something like `makecheck` should be fine, I cannot find any > other project with that name. > > [0]: https://github.com/christianhujer/makelint > > - NRK >
Re: [dev] Special target ".POSIX" in Makefiles
On Fri, Dec 31, 2021 at 11:29:11PM +0100, Mattias Andrée wrote: > I just started implementing a linter[0]. Even though I just > started it today, I think that's enough for this year. > > Happy New Year! > Mattias Andrée > > [0] https://github.com/maandree/makelint/ Thank you very much, I'll keep an eye on this. Also as for the name, while looking it up I noticed that there's another project by the exact same name [0]. Funny enough, this project's goal seems to be complete opposite of ours, it advices usage of non-posix implicit variables like $(RM) in it's README. Might be a good idea to use a different name to avoid potential confusion. Something like `makecheck` should be fine, I cannot find any other project with that name. [0]: https://github.com/christianhujer/makelint - NRK
Re: [dev] Special target ".POSIX" in Makefiles
I just started implementing a linter[0]. Even though I just started it today, I think that's enough for this year. Happy New Year! Mattias Andrée [0] https://github.com/maandree/makelint/ On Thu, 30 Dec 2021 21:17:32 +0100 Mattias Andrée wrote: > On Thu, 30 Dec 2021 21:07:06 +0100 > Laslo Hunhold wrote: > > > On Thu, 30 Dec 2021 17:49:23 +0100 > > crae...@gmail.com wrote: > > > > Dear craekz, > > > > > As far as I can see, we could add `.POSIX` to the following programs: > > > dwm, dmenu, dwmstatus, sent and tabbed > > > I've just looked over the Makefiles very briefly, so I may have > > > overseen something. Note: I just picked out the "biggest" programs. > > > > sadly the make-implementations out there don't offer a "strict" mode to > > warn you about non-compliance or undefined behaviour. GNU make (as > > I've actually being thinking of writing a makefile linter. > How interested would people be in such a tool? > > The reason to have a linter separate from a make utility itself > is that it would not have to reject non-standard features that > you don't want to implement in make. And I also think it would for > cleaner implementation of both projects. Additionally, I would > suspect that a lot of people would just stay with GNU make because > it's in every distro, so having it as a separate project would > probably give it wider adoption. > > > > usual with GNU products) added a lot of GNU-extensions and poisoned the > > entire ecosystem. It's really easy to write non-compliant makefiles and > > have things silently break or behave slightly different across > > implementations. > > > > Adding a .POSIX target is one thing, it's another to actually verify > > the makefiles are POSIX-compliant. > > > > It would be a cool project-idea to write a very strict POSIX-compliant > > make-implementation that, if it includes extensions, marks them as such > > and prints a warning if desired. mk by plan9 is also very nice, of > > course, but makefiles are the common denominator in the scene and it > > might be a cool incentive to have such a validating make. > > > > A lot of new systems are used all over the place, like cmake, ninja and > > whatnot, so it might be cool to show how zen it is to just work with a > > make-based build-system. One example is the really trivial way to > > package suckless-projects, e.g. libgrapheme[0]. It doesn't get simpler > > than that. > > > > With best regards > > > > Laslo > > > > [0]:https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=libgrapheme > > > >
Re: [dev] Special target ".POSIX" in Makefiles
On 2021-12-30, NRK wrote: > 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. It is accepted for the upcoming POSIX issue 8: https://austingroupbugs.net/view.php?id=330
Re: [dev] Special target ".POSIX" in Makefiles
On Fri, 31 Dec 2021 12:53:59 +0100 crae...@gmail.com wrote: > > Yeah you make a strong argument. I too think a linting tool would be > > useful. I imagine it would function like shellcheck does for shells. If > > nothing else it would really help people identify GNU extensions vs > > portable behavior. > Something like shellcheck would be awesome! Given that the POSIX > Makefile syntax isn't very large or complicated, the implementation of > such a tool could be pretty simple (in the manner of suckless). > Although I wouldn't mind a strict POSIX compliant make(1) without any > extensions. There a far too few programs that could be used to > verify compliance with standards (and buying a test suite isn't a > great solution). > > -- > craekz > I think a make(1) implementation without any extensions isn't the best idea. There are a lot of makefiles out there that rely on extensions, and its not always that bad, it could be that it just uses +=. I would much rather have a make implementation with a sane set of commonly used extensions, that nags me if I use extensions, than a minimal[0] implementation that I use for many own projects and a garbage implementation for when I compile software I download (of course the minimal would do in some cases, but if I build from the AUR, what would happen is that it would be used for every AUR package I download). Regards, Mattias Andrée [0] Minimal only run when building from a makefile. When building for a makefile, optional stuff like default rules for compiling C code would be omitted, but there is no reason to not allow such stuff, even for languages that POSIX does not specify, when running without a makefile.
Re: [dev] Special target ".POSIX" in Makefiles
> Yeah you make a strong argument. I too think a linting tool would be > useful. I imagine it would function like shellcheck does for shells. If > nothing else it would really help people identify GNU extensions vs > portable behavior. Something like shellcheck would be awesome! Given that the POSIX Makefile syntax isn't very large or complicated, the implementation of such a tool could be pretty simple (in the manner of suckless). Although I wouldn't mind a strict POSIX compliant make(1) without any extensions. There a far too few programs that could be used to verify compliance with standards (and buying a test suite isn't a great solution). -- craekz
Re: [dev] Special target ".POSIX" in Makefiles
On Fri, Dec 31, 2021 at 11:33:21AM +0100, Laslo Hunhold wrote: > On Fri, 31 Dec 2021 11:16:18 +0100 > Hiltjo Posthuma wrote: > > Dear Hiltjo, > > > In my opinion a practical way is to really test it on different > > systems (bleeding edge Linux, older Debian stable, NetBSD, OpenBSD) > > and GNU/Make, different BSD make programs. > > > > This doesn't cover the POSIX compatibility, but some make > > implementations are not fully POSIX either and this also finds other > > issues. > To clarify, I did not mean to say this makes a POSIX make lint tool useless. > yes, this also helped me identify some issues, but as far as I know all > of them implement e.g. ":=" and "?=" and macros in target rules. Of > course one might say that it's enough to cover multiple > implementations, but given there's often no reason to use extensions, > something like Mattias proposed would really come in handy. > > With best regards > > Laslo > -- Kind regards, Hiltjo
Re: [dev] Special target ".POSIX" in Makefiles
On Fri, 31 Dec 2021 11:16:18 +0100 Hiltjo Posthuma wrote: Dear Hiltjo, > In my opinion a practical way is to really test it on different > systems (bleeding edge Linux, older Debian stable, NetBSD, OpenBSD) > and GNU/Make, different BSD make programs. > > This doesn't cover the POSIX compatibility, but some make > implementations are not fully POSIX either and this also finds other > issues. yes, this also helped me identify some issues, but as far as I know all of them implement e.g. ":=" and "?=" and macros in target rules. Of course one might say that it's enough to cover multiple implementations, but given there's often no reason to use extensions, something like Mattias proposed would really come in handy. With best regards Laslo
Re: [dev] Special target ".POSIX" in Makefiles
On Fri, 31 Dec 2021 01:52:42 -0800 Arthur Williams wrote: Dear Arthur, > I too fell victim to the GNU trap and thought "?=" was standard and > actually useful. hehe this thread here feels like a self-help-thread of the newly POSIX-make-awakened! > Completely forgot about the -e flag. Now I need to go update all my > projects and who knows what other GNU-isms I'm unknowingly using. Just be careful that the standard explicitly states that environment variables with null values also override macro assignments. Additionally, you don't want some variables to be silently overridden (e.g. file lists like SRC or something) by an unknown environment which might as well just have this defined. It's better to just explicitly override certain variables and stay within the "usual" naming schemes (DESTDIR, PREFIX, CFLAGS, etc.). > > that is exactly what I meant earlier on that the POSIX-intended good > > practices get destroyed by the retarded GNU extensions. > > Yeah you make a strong argument. I too think a linting tool would be > useful. I imagine it would function like shellcheck does for shells. > If nothing else it would really help people identify GNU extensions vs > portable behavior. Exactly! With best regards Laslo
Re: [dev] Special target ".POSIX" in Makefiles
On Fri, Dec 31, 2021 at 01:52:42AM -0800, Arthur Williams wrote: > I too fell victim to the GNU trap and thought "?=" was standard and > actually useful. > > > and want to "dynamically" override it (e.g. in a build system context) > > when the environment already specifies PREFIX, you either do > > > >make -e > > Completely forgot about the -e flag. Now I need to go update all my > projects and who knows what other GNU-isms I'm unknowingly using. > Hi, In my opinion a practical way is to really test it on different systems (bleeding edge Linux, older Debian stable, NetBSD, OpenBSD) and GNU/Make, different BSD make programs. This doesn't cover the POSIX compatibility, but some make implementations are not fully POSIX either and this also finds other issues. > > that is exactly what I meant earlier on that the POSIX-intended good > > practices get destroyed by the retarded GNU extensions. > > Yeah you make a strong argument. I too think a linting tool would be > useful. I imagine it would function like shellcheck does for shells. If > nothing else it would really help people identify GNU extensions vs > portable behavior. > -- Kind regards / Happy new year, Hiltjo
Re: [dev] Special target ".POSIX" in Makefiles
I too fell victim to the GNU trap and thought "?=" was standard and actually useful. > and want to "dynamically" override it (e.g. in a build system context) > when the environment already specifies PREFIX, you either do > >make -e Completely forgot about the -e flag. Now I need to go update all my projects and who knows what other GNU-isms I'm unknowingly using. > that is exactly what I meant earlier on that the POSIX-intended good > practices get destroyed by the retarded GNU extensions. Yeah you make a strong argument. I too think a linting tool would be useful. I imagine it would function like shellcheck does for shells. If nothing else it would really help people identify GNU extensions vs portable behavior.
Re: [dev] Special target ".POSIX" in Makefiles
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. "?=" sets a variable only if it doesn't have a value. However, you really don't need that and should go the other way around by specifying override variables (those following after "make" in the command line) instead. They will override any variable within the Makefile. Alternatively pass the "-e" flag to set all environment variables as overrides, but this is less clean. GNU of course complicated it again by _then_ offering an "override" directive which really really overrides even override variables[0]. I hate GNU so much. So what is the replacement? Usually you have a context where e.g. in a config.mk you have PREFIX=/usr/local and want to "dynamically" override it (e.g. in a build system context) when the environment already specifies PREFIX, you either do make -e or explicitly set make PREFIX=/usr/local and are bloody done. What more do you want? It was ingenious by POSIX to really not give in to any stupid extensions which poison this beautifully simple environment handling. With best regards Laslo [0]:https://www.gnu.org/software/make/manual/html_node/Override-Directive.html
Re: [dev] Special target ".POSIX" in Makefiles
On Fri, Dec 31, 2021 at 12:49:46PM +0600, NRK wrote: > What would be a posix replacement for `?=` ? I assume something like: > > VAR = $$(if test -n "$$VAR"; then printf "%s" "$$VAR"; else printf > "fallback"; fi) > Now that I think about it, posix shell has parameter expansion that could be used here for a more compact assignment: VAR = $${VAR:-fallback} should also do the trick. I guess it could also be double quoted to protect against word splitting as well. But I don't think that'd be a good idea for things like CFLAGS where word splitting is desired. - NRK
Re: [dev] Special target ".POSIX" in Makefiles
On Thu, Dec 30, 2021 at 09:17:32PM +0100, Mattias Andrée wrote: > I've actually being thinking of writing a makefile linter. > How interested would people be in such a tool? > > The reason to have a linter separate from a make utility itself > is that it would not have to reject non-standard features that > you don't want to implement in make. And I also think it would for > cleaner implementation of both projects. Additionally, I would > suspect that a lot of people would just stay with GNU make because > it's in every distro, so having it as a separate project would > probably give it wider adoption. I'd definitely be interested in such a tool. Weather it be in form of a make implementation or linter doesn't matter a whole lot to me as long as the end goal of having a tool to help write portable makefile is achieved. On Thu, Dec 30, 2021 at 11:07:35PM +0100, Laslo Hunhold wrote: >$ snake -l >Makefile:1:1: warning: Missing ".POSIX" target. >config.mk:2:4: warning: "?=" is a GNU-extension. >Makefile:20:34: warning: A prerequisite must not contain a macro. >$ 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
Re: [dev] Special target ".POSIX" in Makefiles
On Thu, 30 Dec 2021 23:07:35 +0100 Laslo Hunhold wrote: > On Thu, 30 Dec 2021 21:17:32 +0100 > Mattias Andrée wrote: > > Dear Mattias, > > > I've actually being thinking of writing a makefile linter. > > How interested would people be in such a tool? > > very interested! Even though, when you implement the logic, you might > as well go all the way and offer a make(1) that also offers linting > (comparable to mandoc(1)). Yes, of course you could add it to make(1) also, but for the explained reasons I think it would be useful as a standalone implementation. However, a linter could do thinks that I do not want to do in make(1) itself. For example, it could do analysis to and find a portable solution (e.g. just removing "$(@:.o=.c)"), or explain that an non-standard feature is being used in vain (e.g. "PREFIX ?= /usr/local"). make(1) should of course tell you when you are not being POSIX compliant, but ultimately to what extent it would hold you hand and how pedantic it be would be determined at time of implementation. It would probably be very little. For example, I think that the linker could warn about bugs in other implementations or about potential whitespace issues which are probably just fine in every implementation people use, but I do not want to do this in make(1) itself. > > > The reason to have a linter separate from a make utility itself > > is that it would not have to reject non-standard features that > > you don't want to implement in make. And I also think it would for > > cleaner implementation of both projects. Additionally, I would > > suspect that a lot of people would just stay with GNU make because > > it's in every distro, so having it as a separate project would > > probably give it wider adoption. > > You wouldn't have to reject non-standard features, but offer printing a > warning for undefined behaviour and non-standard extensions while still > supporting them to a certain extent, something like: > >$ snake -l >Makefile:1:1: warning: Missing ".POSIX" target. >config.mk:2:4: warning: "?=" is a GNU-extension. >Makefile:20:34: warning: A prerequisite must not contain a macro. >$ > > Optionally you could also choose to always print warnings and turn > them into hard errors with the l-flag. > > It would be necessary to assess how many extensions are necessary > to implement. With sbase/ubase we found out that while GNU-extensions > are used, they are not all too widespread and only a small subset of > the entire GNU bloat. > > With Makefiles you don't really need the GNU extensions and they, > as usual with GNU extensions, seem to originate from a misunderstanding > or caving in to simply wrong usage-patterns (just think of cat -v) by > users who probably don't know it better or about the right tools for the > job. I think there are situations where some of the extensions offered by GNU are useful as they can make things cleaner, but they are hardly necessary, and often they are inappropriately used, and of course there are some features I cannot find an inappropriate use case for at all. GNU's strategy is to make things as easy for users as possible, and offer “more value” than the software they are replacing, which naturally lead to it's current miserable situation. They just haven't learned to say No. Which is probably to toughest but most valuable lesson for any programmer to learn. > > Anyway, tl;dr: Such a strict POSIX-compliant make would be really awesome! > I'm sure many would pick it up. Null program wrote a great post[0] > about this topic, indicating that there's no tool out there that is > explicit about standard conformance, _especially_ undefined behaviour. A few month ago I started writing a POSIX-like shell[0], it has requirements that makes it impossible to be fully POSIX, but it if you start it as sh it will be strictly POSIX and if it, in this mode, encounters an extension it will warn you that it will not be recognising it. It will also warn you in some situations that look like mistakes, and yell at you (in lower case) if you are using backquotes (read up on the backquote syntax in sh and you will understand why). > > With best regards > > Laslo > > [0]:https://nullprogram.com/blog/2017/08/20/ > Regards, Mattias Andrée [0] https://github.com/maandree/apsh
Re: [dev] Special target ".POSIX" in Makefiles
On Thu, 30 Dec 2021 21:17:32 +0100 Mattias Andrée wrote: Dear Mattias, > I've actually being thinking of writing a makefile linter. > How interested would people be in such a tool? very interested! Even though, when you implement the logic, you might as well go all the way and offer a make(1) that also offers linting (comparable to mandoc(1)). > The reason to have a linter separate from a make utility itself > is that it would not have to reject non-standard features that > you don't want to implement in make. And I also think it would for > cleaner implementation of both projects. Additionally, I would > suspect that a lot of people would just stay with GNU make because > it's in every distro, so having it as a separate project would > probably give it wider adoption. You wouldn't have to reject non-standard features, but offer printing a warning for undefined behaviour and non-standard extensions while still supporting them to a certain extent, something like: $ snake -l Makefile:1:1: warning: Missing ".POSIX" target. config.mk:2:4: warning: "?=" is a GNU-extension. Makefile:20:34: warning: A prerequisite must not contain a macro. $ Optionally you could also choose to always print warnings and turn them into hard errors with the l-flag. It would be necessary to assess how many extensions are necessary to implement. With sbase/ubase we found out that while GNU-extensions are used, they are not all too widespread and only a small subset of the entire GNU bloat. With Makefiles you don't really need the GNU extensions and they, as usual with GNU extensions, seem to originate from a misunderstanding or caving in to simply wrong usage-patterns (just think of cat -v) by users who probably don't know it better or about the right tools for the job. Anyway, tl;dr: Such a strict POSIX-compliant make would be really awesome! I'm sure many would pick it up. Null program wrote a great post[0] about this topic, indicating that there's no tool out there that is explicit about standard conformance, _especially_ undefined behaviour. With best regards Laslo [0]:https://nullprogram.com/blog/2017/08/20/
Re: [dev] Special target ".POSIX" in Makefiles
On Thu, 30 Dec 2021 21:07:06 +0100 Laslo Hunhold wrote: > On Thu, 30 Dec 2021 17:49:23 +0100 > crae...@gmail.com wrote: > > Dear craekz, > > > As far as I can see, we could add `.POSIX` to the following programs: > > dwm, dmenu, dwmstatus, sent and tabbed > > I've just looked over the Makefiles very briefly, so I may have > > overseen something. Note: I just picked out the "biggest" programs. > > sadly the make-implementations out there don't offer a "strict" mode to > warn you about non-compliance or undefined behaviour. GNU make (as I've actually being thinking of writing a makefile linter. How interested would people be in such a tool? The reason to have a linter separate from a make utility itself is that it would not have to reject non-standard features that you don't want to implement in make. And I also think it would for cleaner implementation of both projects. Additionally, I would suspect that a lot of people would just stay with GNU make because it's in every distro, so having it as a separate project would probably give it wider adoption. > usual with GNU products) added a lot of GNU-extensions and poisoned the > entire ecosystem. It's really easy to write non-compliant makefiles and > have things silently break or behave slightly different across > implementations. > > Adding a .POSIX target is one thing, it's another to actually verify > the makefiles are POSIX-compliant. > > It would be a cool project-idea to write a very strict POSIX-compliant > make-implementation that, if it includes extensions, marks them as such > and prints a warning if desired. mk by plan9 is also very nice, of > course, but makefiles are the common denominator in the scene and it > might be a cool incentive to have such a validating make. > > A lot of new systems are used all over the place, like cmake, ninja and > whatnot, so it might be cool to show how zen it is to just work with a > make-based build-system. One example is the really trivial way to > package suckless-projects, e.g. libgrapheme[0]. It doesn't get simpler > than that. > > With best regards > > Laslo > > [0]:https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=libgrapheme >
Re: [dev] Special target ".POSIX" in Makefiles
On Thu, 30 Dec 2021 17:49:23 +0100 crae...@gmail.com wrote: Dear craekz, > As far as I can see, we could add `.POSIX` to the following programs: > dwm, dmenu, dwmstatus, sent and tabbed > I've just looked over the Makefiles very briefly, so I may have > overseen something. Note: I just picked out the "biggest" programs. sadly the make-implementations out there don't offer a "strict" mode to warn you about non-compliance or undefined behaviour. GNU make (as usual with GNU products) added a lot of GNU-extensions and poisoned the entire ecosystem. It's really easy to write non-compliant makefiles and have things silently break or behave slightly different across implementations. Adding a .POSIX target is one thing, it's another to actually verify the makefiles are POSIX-compliant. It would be a cool project-idea to write a very strict POSIX-compliant make-implementation that, if it includes extensions, marks them as such and prints a warning if desired. mk by plan9 is also very nice, of course, but makefiles are the common denominator in the scene and it might be a cool incentive to have such a validating make. A lot of new systems are used all over the place, like cmake, ninja and whatnot, so it might be cool to show how zen it is to just work with a make-based build-system. One example is the really trivial way to package suckless-projects, e.g. libgrapheme[0]. It doesn't get simpler than that. With best regards Laslo [0]:https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=libgrapheme
Re: [dev] Special target ".POSIX" in Makefiles
>I agree that it shall be added to all Makefile, because >otherwise the behavior of make is unspecified. >(Quote from the POSIX specifications) I'm sure you meant it like that, but just to clarify it: It is only unspecified if it doesn't appear as the first non-comment line, has prerequisites or commands. >.POSIX can be used as long a the makefile does not >use any feature that conflicts with POSIX. But I think >it would mislead people into thinking the non-POSIX >features are POSIX feature, so it would be best skip >it in that case. I agree with that. As far as I can see, we could add `.POSIX` to the following programs: dwm, dmenu, dwmstatus, sent and tabbed I've just looked over the Makefiles very briefly, so I may have overseen something. Note: I just picked out the "biggest" programs. >I do however think some Makefile here that use the @ >macro in the prerequisite. This is not a POSIX feature, >is seldom needed, and should be removed assuming it >is redundant given the inferred prerequisite of >inference rules. sbase does it but I haven't looked closer. -- craekz
Re: [dev] Special target ".POSIX" in Makefiles
I agree that it shall be added to all Makefile, because “otherwise, the behavior of make is unspecified.” (Quote from the POSIX specifications) Probably missing because people don't usually learn make(1) by reading the entire manual. .POSIX can be used as long a the makefile does not use any feature that conflicts with POSIX. But I think it would mislead people into thinking the non-POSIX features are POSIX feature, so it would be best skip it in that case. I do however think some Makefile here that use the @ macro in the prerequisite. This is not a POSIX feature, is seldom needed, and should be removed assuming it is redundant given the inferred prerequisite of inference rules. Regards, Mattias Andrée On Thu, 30 Dec 2021 15:58:33 +0100 crae...@gmail.com wrote: > Hi, > > I'm wondering why the Makefiles of some suckless programs (and libs) have the > special target `.POSIX` in them and some don't. > For example, dwm doesn't have it in it's Makefile but there isn't a single > non-POSIX feature used. I think it would be better to include the `.POSIX` > target > simply to follow the standard and guarantee portability. > If there is a good reason why it isn't included, please let me know. > > -- > craekz >
[dev] Special target ".POSIX" in Makefiles
Hi, I'm wondering why the Makefiles of some suckless programs (and libs) have the special target `.POSIX` in them and some don't. For example, dwm doesn't have it in it's Makefile but there isn't a single non-POSIX feature used. I think it would be better to include the `.POSIX` target simply to follow the standard and guarantee portability. If there is a good reason why it isn't included, please let me know. -- craekz