[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: CFLAGS and other flag variables
From: |
Kaz Kylheku |
Subject: |
Re: CFLAGS and other flag variables |
Date: |
Tue, 16 Jul 2024 17:10:00 -0700 |
User-agent: |
Roundcube Webmail/1.4.15 |
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
from .c which uses $(CC) and $(CFLAGS), almost identical
to yours, except that the built-in recipe also
references CPPFLAGS.
> 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.
Programs should use CFLAGS, CPPFLAGS, LDFLAGS and LDLIBS if those
are set on the make command line or in the environment.
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
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.
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.)
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.
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, 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).