1

Situation

I am using a handwritten GNUmakefile in which CXXFLAGS, CPPFLAGS and LDFLAGS are appended to by the += assignment, as in:

CXXFLAGS    += -std=c++11 $(MODENV) $(WARNINGS) $(OPTIMS)
CPPFLAGS    += $(DMACROS) $(INCDIRS)
LDFLAGS     += $(MODENV) $(LIBDIRS) $(EXTRA_LIBS)

Problem

When the user defines his own flags at the command-line, the appending in the Makefile will be ignored. This leaves the variables to exactly what the user set them. (And in my case, the build will fail.) The generic solution for this problem is to override the variables, as in:

override CXXFLAGS   += -std=c++11 $(MODENV) $(WARNINGS) $(OPTIMS)
override CPPFLAGS   += $(DMACROS) $(INCDIRS)
override LDFLAGS    += $(MODENV) $(LIBDIRS) $(EXTRA_LIBS)

This way, the necessary content will be appended to the user's variable.

Questions

  1. Is overriding variables considered bad practice?
  2. Is setting the above flags inside the Makefile considered bad practice?
  3. If "yes" to both questions above, then where do I put -std=c++11, if not in CXXFLAGS?
user7023624
  • 571
  • 5
  • 14
  • If your build fails without a given flag then it's perfectly acceptable, although if someone is messing around with build flags you might as well require them to edit the makefile itself if they want to make changes. – user657267 Aug 12 '18 at 05:39

3 Answers3

1

If a user overrides the variables, assume the user knows what they're doing. The system they're working on may have very different requirements and need to override the variables. Don't make the difficult impossible.

shawnhcorey
  • 3,545
  • 1
  • 15
  • 17
  • 1
    I've [reached the same conclusion](https://stackoverflow.com/a/51806613/7023624) on my own: appending things to the user-supplied flags for an easier build is the good intention that will pave the road to Makefile patching hell. – user7023624 Aug 12 '18 at 15:28
1

As the use cases for build management with make are so diverse, there simply is no ground to objectively judge this as "bad practice". If you are writing OSS for a multitude of platforms and for an unknown audience and timeframe, the POLA/POLS should be applied. That said, a user who is surprised to find more flags than the ones she gave on the command line is a rather unrealistic corner case, so -override has its place. In the end the values you add are absolutely necessary for the build, aren't they?

PS: the POLA should be applied to all engineering activities of course - its just that the definition of "surprise" shifts with the task in question.

Vroomfondel
  • 2,704
  • 1
  • 15
  • 29
1

I'm not going to comment on good/bad practice, as it depends on the use case (who are the users of this makefile? Do they all work with you, so you could just tell them how it's meant to be used? Can you just document your conventions, in the makefile comments or a project README?)

But ...

where do I put -std=c++11, if not in CXXFLAGS?

If you have flags that are essential and must not be overridden by the user, you can find another way to put them in the compilation command.

For example:

CXX := g++ -std=c++11

Or:

foo.o: foo.cc
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) -std=c++11 -o $@ $^

Even better might be to use a variable so that it can still be set by the user (e.g. to use -std=c++14 instead) but isn't set by CXXFLAGS:

STD := -std=c++11
foo.o: foo.cc
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(STD) -o $@ $^

(Or just put the -std option before CXXFLAGS so that a different std option in CXXFLAGS will take precedence).

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521