2

What I need:

all: release debug

release: compile

debug: compile

compile: 
    if parent_target_name = release: 
        $(CXXFLAGS) = for rel
    else: $(CXXFLAGS) = for deb

The problem: How to check the name of the target which invoked the current target?

I've seen this question GNU Make get parent target name but it didn't help.

Sergei Shumilin
  • 411
  • 5
  • 17
  • What you are probably looking for is [Target-specific Variable Values](https://www.gnu.org/software/make/manual/make.html#Target_002dspecific). If you carefully read this section of the manual you'll see how they propagate to the prerequisites. – Renaud Pacalet Dec 11 '18 at 10:47
  • I've read this section. As I understood Target-specific variables only give me the ability to locally change a global variable. – Sergei Shumilin Dec 11 '18 at 10:55

1 Answers1

3

What you are probably looking for is Target-specific Variable Values. If you carefully read this section of the manual you'll see how they propagate to the prerequisites.

Just to illustrate how they work:

.PHONY: all release debug compile

all:
    $(MAKE) release
    $(MAKE) debug

release: CXXFLAGS = for rel
debug: CXXFLAGS = for deb

release debug: compile
    @echo 'building $@ with CXXFLAGS = $(CXXFLAGS)'

compile: a b c
    @echo 'building $@ with CXXFLAGS = $(CXXFLAGS)'

a b c:
    @echo 'building $@ with CXXFLAGS = $(CXXFLAGS)'

Demo:

$ make --no-print-directory all
make release
building a with CXXFLAGS = for rel
building b with CXXFLAGS = for rel
building c with CXXFLAGS = for rel
building compile with CXXFLAGS = for rel
building release with CXXFLAGS = for rel
make debug
building a with CXXFLAGS = for deb
building b with CXXFLAGS = for deb
building c with CXXFLAGS = for deb
building compile with CXXFLAGS = for deb
building debug with CXXFLAGS = for deb
Renaud Pacalet
  • 25,260
  • 3
  • 34
  • 51
  • Thank you!) It's perfect – Sergei Shumilin Dec 11 '18 at 11:23
  • 1
    Note that this example works because all targets are phony (either explicitly or not). They are always rebuilt. If (as is likely the case) your final targets are files you will encounter a new problem: once a file has been built make will not rebuild it just because flags changed... – Renaud Pacalet Dec 11 '18 at 11:25
  • Ok. One more question: how to add new variables here `release: CXXFLAGS = for rel` – Sergei Shumilin Dec 11 '18 at 11:27
  • 1
    If you want to define new target-specific variables just add one new `target: variable = value` line per target/variable pair. – Renaud Pacalet Dec 11 '18 at 11:31
  • Hmm) And then how to make `a` launched every time? – Sergei Shumilin Dec 11 '18 at 13:31
  • Just to note: in the above you have no default setting for `CXXFLAGS`, so if you attempt to build a single target such as `make a`, or you even run `make compile` to build them all but without `debug` or `release`, then `CXXFLAGS` will be empty. – MadScientist Dec 11 '18 at 13:49
  • 1
    @SergeiShumilin: "_how to make `a` launched every time_". Either `make clean` between `make debug` and `make release` or have different targets for the different cases (e.g. `a_debug` and `a_release`). These different targets can have the same sources but different rules. Look for instance at [this recent question and its answers](https://stackoverflow.com/questions/53709886/how-to-force-gnu-make-to-recompile-the-same-object-file-used-in-two-targets-with). – Renaud Pacalet Dec 11 '18 at 14:26