1

I have the following in my GNU makefile:

# CXXFLAGS ?= -DNDEBUG -g2 -O3
CXXFLAGS ?=

# Add -DNDEBUG if nothing specified
ifeq ($(filter -DDEBUG -DNDEBUG,$(CXXFLAGS)),)
$(info Adding -DNDEBUG to CXXFLAGS)
CXXFLAGS += -DNDEBUG
endif

# Add a symolize if nothing specified
ifeq ($(filter -g -g1 -g2 -g3 -Oz,$(CXXFLAGS)),)
$(info Adding -g2 to CXXFLAGS)
CXXFLAGS += -g2
endif

# Add an optimize if nothing specified
$(info Adding -O3 to CXXFLAGS)
ifeq ($(filter -O -O0 -O1 -O2 -O3 -Og -Os -Oz -Ofast,$(CXXFLAGS)),)
CXXFLAGS += -O3
endif

When I run it:

$ make CXXFLAGS="-g3"
Adding -DNDEBUG to CXXFLAGS
Adding -O3 to CXXFLAGS
g++ -g3 -c foo.cpp
...

In fact, if I uncomment the CXXFLAGS ?= -DNDEBUG ..., then I can append again. But that's not very helpful since I'm trying to make arguments optional (but with sane defaults).

And if I type just make, then it works (-fPIC -march=native -Wall -Wextra -pipe is added later by the same makefile, and it has always worked):

$ make
Adding -DNDEBUG to CXXFLAGS
Adding -g2 to CXXFLAGS
Adding -O3 to CXXFLAGS
g++  -DNDEBUG -g2 -O3 -fPIC -march=native -Wall -Wextra -pipe -c serpent.cpp
...

According to the manual and 6.6 Appending More Text to Variables:

Often it is useful to add more text to the value of a variable already defined. You do this with a line containing ‘+=’, like this:

     objects += another.o

Why is make not adding the values to the variable? How can I achieve the behavior I want?

jww
  • 97,681
  • 90
  • 411
  • 885

1 Answers1

1

By passing a variable via command-line, you're telling make that you are overriding any definitions in the file, which allows a user to compile as they intend rather than as you intend. Ignoring the restriction of user freedom, you can use the override directive:

To append more text to a variable defined on the command line, use:

override variable += more text

Variable assignments marked with the override flag have a higher priority than all other assignments, except another override. Subsequent assignments or appends to this variable which are not marked override will be ignored.

I would discourage you from using override when possible because it's annoying to realize that -O0 was needed to disable the optimizations that you enabled when I don't want them enabled (after all, I specify my own flags for a reason). Of course, if no flags were specified at all, then defaults are perfectly reasonable. In fact, Automake projects seem to default to -g -O2 when no compilation flags are specified.

There are exceptions to this advice of course, such as adding a directory to search for includes/libs or preprocessor definitions for compiling a conditional section of code on a certain platform.

  • Here's the full makefile: [GNUmakefile](https://github.com/weidai11/cryptopp/blob/master/GNUmakefile). We try not to step on user settings. We append a lot goodness to `CXXFLAGS`, but have never needed to use `override`. Any ideas why we have to use it now? And why would you claim we are infringing on a user's freedom??? My god, you sound as bad as Stallman.... – jww Jul 25 '15 at 08:19
  • @jww Because you used `make CXXFLAGS=-g3`, which requires the `override` directive to be used. [More info can be found here](http://stackoverflow.com/a/2826178/539810) –  Jul 25 '15 at 08:28
  • As for the user freedom bit, it's simply courtesy to allow others to specify the flags they wish and not be surprised when things don't work as expected. For example, `gdb` on some platforms will not work nearly as well with optimizations enabled, repeatedly printing the same source line as you step through code, which makes debugging a bit of a nightmare. I meant no offense. I merely suggested avoiding `override` when possible. In any case, it's your code. :-) –  Jul 25 '15 at 08:34