Pregunta

I was a little confused with the responses to Quick way to override -Werror flag?

So I ask my specific question here.

I have multiple Makefiles working together and CFLAGS has been set along the way to (-Werror -Wall .. and many others)

But in one of the Makefiles, I wish that the errors not be treated as warnings and so I would like to remove -Werror flag.

What would be the best way to achieve this, so that only for this Makefile, -Werror flag is removed and for the others normal execution takes place?

Thanks, Sunny

¿Fue útil?

Solución 2

Simpler way

It looks like you can invoke

gcc -c ... -Werror ... -Wno-error ...

without having GCC complain (GCC 4.7.1). So, you can add -Wno-error to the CFLAGS set up elsewhere in the one makefile where you need it. If you're using GNU make, in the one makefile, you can add:

CFLAGS += -Wno-error

possibly for just the single target that needs it.

Harder way

Otherwise, you need a system for building CFLAGS from components. What I have in the makefile I use for testing answers to questions on SO is:

WFLAG1 = -Wall 
WFLAG2 = -Wextra
WFLAG3 = -Wmissing-prototypes 
WFLAG4 = -Wstrict-prototypes 
WFLAG5 = -Wold-style-definition
WFLAG6 =
WFLAGS = ${WFLAG1} ${WFLAG2} ${WFLAG3} ${WFLAG4} ${WFLAG5} ${WFLAG6} 
SFLAGS = -std=c99
GFLAGS = -g
OFLAGS = -O3
UFLAGS =
IFLAG1 = -I${HOME}/inc
IFLAGS = # ${IFLAG1}

CFLAGS   = ${OFLAGS} ${GFLAGS} ${IFLAGS} ${SFLAGS} ${WFLAGS} ${UFLAGS}

The main point is that each flag is independently adjustable; I can control the warning flags by setting any of ${WFLAG1} to ${WFLAG6}, or by setting ${WFLAGS} wholesale on the command line, or (indeed) by setting ${CFLAGS}. But because each is individually adjustable, and can tune the warnings relatively easily (the main hassle being determining which WFLAGn needs clobbering).

The UFLAGS is 'user flags' and is only set on the command line; I can add more flags to my command line by setting it.

This way is 'harder' because it requires you to modify the central part of your makefile system where you set CFLAGS. It is also less likely to be understood by your colleagues at first sight.

Otros consejos

The right way to do this is with the filter-out function.

Put

CFLAGS := $(filter-out -Werror,$(CFLAGS))

in the Makefile where you want to override this, and the -Werror part of CFLAGS will be removed in that Makefile.

You can even use this to override flags for a single target by using target-specific variable values:

CFLAGS = -Werror

all: foo bar

foo:
        echo cc $(CFLAGS) -o $@

bar: CFLAGS := $(filter-out -Werror,$(CFLAGS))

bar:
        echo cc $(CFLAGS) -o $@

foo will be built with the default CFLAGS containing -Werror, but bar will be built without.

This is a general-purpose solution that works for all arguments to all programs, rather than requiring each program to supply a --no-foo for every --foo option. Because it can’t be done from Make command-line, it doesn’t directly answer the question you linked to. But overriding Make variables from the command-line to force stuff to build is a pretty good way to make your unbuildable code even less maintainable!

You can see an example of variable overriding in Git Makefile with CFLAGS which now can be tweaked when invoking Make while using DEVELOPER=YesPlease, with Git 2.22 (Q2 2019)

DEVELOPER (in Git Makefile) is a variable to group more compiler warning.

See commit 6d5d4b4, commit 71a7894, commit 8fb2a23, commit 65260a4, commit 9559f8f, commit 4f14a8c (22 Feb 2019) by Ævar Arnfjörð Bjarmason (avar).
(Merged by Junio C Hamano -- gitster -- in commit 3cef676, 20 Mar 2019)

Makefile: allow for combining DEVELOPER=1 and CFLAGS="..."

Ever since the DEVELOPER=1 facility introduced there's been no way to have custom CFLAGS (e.g. CFLAGS="-O0 -g -ggdb3") while still benefiting from the set of warnings and assertions DEVELOPER=1 enables.

This is because the semantics of variables in the Makefile are such that the user setting CFLAGS overrides anything we set, including what we're doing in config.mak.dev.

So let's introduce a "DEVELOPER_CFLAGS" variable in config.mak.dev and add it to ALL_CFLAGS. Before this the ALL_CFLAGS variable would (basically, there's some nuance we won't go into) be set to:

$(CPPFLAGS) [$(CFLAGS) *or* $(CFLAGS) in config.mak.dev] $(BASIC_CFLAGS) $(EXTRA_CPPFLAGS)

But will now be:

$(DEVELOPER_CFLAGS) $(CPPFLAGS) $(CFLAGS) $(BASIC_CFLAGS) $(EXTRA_CPPFLAGS)

The reason for putting DEVELOPER_CFLAGS first is to allow for selectively overriding something DEVELOPER=1 brings in.
On both GCC and Clang later settings override earlier ones.
E.g. "-Wextra -Wno-extra" will enable no "extra" warnings, but not if those two arguments are reversed.

Examples of things that weren't possible before, but are now:

# Use -O0 instead of -O2 for less painful debuggng
DEVELOPER=1 CFLAGS="-O0 -g"
# DEVELOPER=1 plus -Wextra, but disable some of the warnings
DEVELOPER=1 DEVOPTS="no-error extra-all" CFLAGS="-O0 -g -Wno-unused-parameter"

The reason for the patches leading up to this one re-arranged the various *FLAGS assignments and includes is just for readability.
The Makefile supports assignments out of order, e.g.:

$ cat Makefile
X = $(A) $(B) $(C)
A = A
B = B
include c.mak
all:
        @echo $(X)
$ cat c.mak
C=C
$ make
A B C
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top