Hi Kaz, On Tue, Jul 16, 2024 at 05:10:00PM GMT, Kaz Kylheku wrote: > On 2024-07-16 06:37, Alejandro Colomar wrote: > > Hi Paul! > > > > Usual compilation in a makefile is something like > > > > foo.o: foo.c; $(CC) $(CFLAGS) $< -o $@ > > You should only need: > > foo.o: foo.c > > because there is a built-in recipe for making .o files
Except that I do: MAKEFLAGS += --no-builtin-rules MAKEFLAGS += --no-builtin-variables MAKEFLAGS += --warn-undefined-variables Sorry for not mentioning that. > from .c which uses $(CC) and $(CFLAGS), almost identical > to yours, except that the built-in recipe also > references CPPFLAGS. Yep, my actual recipe also uses CPPFLAGS. I wrote it like that to keep it short. > > > If a project needs some CFLAGS, I guess it would do the following > > > > CFLAGS ?= $(shell pkgconf --cflags somedep) > > The problem with this that you're saying "if CFLAGS > isn't set, then define it with the options for a needed > dependency". > > You should only conditionally define CFLAGS to set > some basic options that are not strictly necessary. > > CFLAGS ?= -O2 # Optimize, unless told otherwise > > You should never be clobbering the CFLAGS. CFLAGS belongs > to the user building the program, which could be an entire > distro. > > Distros set certain things with CFLAGS, like tuning for > a particular CPU and whatnot. Thanks. I assumed that, although I didn't know the exact semantics when a user specifies CFLAGS. > > Programs should use CFLAGS, CPPFLAGS, LDFLAGS and LDLIBS if those > are set on the make command line or in the environment. Hmmmm, for the time being, I won't be able to use them from the environment, because that conflicts with MAKEFLAGS += --no-builtin-variables I'll need the next release of make(1) to be able to use an empty default CFLAGS ?= > If you want to use built-in recipes, and your code needs > certain cflags (like for instance C dialect selection), then > you can add that to CFLAGS: > > CFLAGS += -std=c17 -Wmy-favorite-warning-option There's a problem with that. My selection would have preference over the user, since it's specified later in the command line. It should be the user that has preference, so I need a way to prepend to CFLAGS, not append. I want this: CFLAGS ?= CFLAGS_ := -Wmy-fav-warn-opt $(CFLAGS) and then use CFLAGS_ instead of CFLAGS in recipes. > If you want your users to tweak some of your own flags without > having to edit your Makefile, you can use your own variables. > > FOO_LANG_FLAGS := -std=c17 > FOO_DIAG_FLAGS := -Wall -W > > CFLAGS += $(FOO_LANG_FLAGS) $(FOO_DIAG_FLAGS) > > Now the user can use "make FOO_DIAG_FLAGS=..." to add a diagnostic > option, without having to mess with CFLAGS. Since appending a different -std= or -Wno- overrides my selection, they should only need to append it to the command line, without using my internal variable names. > For instance, the user could be running a build recipe from a distro, > which specifies CFLAGS, so having to get between the distro and > the programs' build system to adjust CFLAGS is inconvenient. > > (If you ever have to do that, it's a good thing that GNU Make > supports the += syntax on the command line.) Not so good in this case, because of the need for prepending. In fact, I seldom use +=. Only in conditionals. $ find GNUmakefile share/mk/ -type f \ | grep '\.mk$' \ | xargs grep += \ | wc -l; 4 > > There are two variables LDFLAGS and LDLIBS because linker flags > like -Wl,-L/path/to/dir and library options like -lfoo are > separated on the compiler command line; the libraries come last. > > If you write your own recipe for linking an executable or shared > object, you should pull in $(LDFLAGS) and $(LDLIBS) in the > right places. > > Distros sometimes use both of these! > > CPPFLAGS is for C preprocessor flags that are independent of > language. In GNU Make, built-in recipes for different languages > bring in CPPFLAGS. > > CPPFLAGS could be used for something like passing a -DFOO=BAR > option everywhere the preprocessor is used, whether for C, or > Fortran or whatever. > > GNU CPP has some -W diagnostic options that make sense in CPPFLAGS. > For instance -Wundef: warn if an undefined identifier is > referenced in an #if directive, where it is treated as zero. > > In summary, a C project should use all of these if they are defined: > > CFLAGS, CPPFLAGS, LDFLAGS, LDLIBS. Yup, I use all of these. Thanks! > > The project should only add to these variables, never taken them over. > > Never do things like CFLAGS ?= --badly-needed-option where your program > breaks at build time or run time without --badly-needed-option. > Use this only to set up some some minimal optimization. > > If CFLAGS exist, The bad part is that CFLAGS _always_ exists (unless you remove it on the command line with -R, which is kind of nonsensical, because whoever runs make(1) already can override it by specifying a different value explicitly). Thankfully, the next version of make(1) will fix that historical bug. > assume that the user/distro is using that to > control optimization and possibly other code generation options. > You can disable optimization by adding -O0 after $(CFLAGS). That would be overriding the user's choice, which I don't think is a good idea. Thanks! Have a lovely day! Alex -- <https://www.alejandro-colomar.es/>
signature.asc
Description: PGP signature