[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: CFLAGS and other flag variables
From: |
Alejandro Colomar |
Subject: |
Re: CFLAGS and other flag variables |
Date: |
Wed, 17 Jul 2024 11:11:01 +0200 |
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