J.R.
J.R.

Reputation: 809

how can the make infer what kind of compiler it needs for the final target?

I've got a simple makefile here. It's a minimum c++ project and I'd like the make to do the correct behavior with the implicit rules. with the following makefile, it will report error. Then I type "make -n", it seems the make uses the cc rather than the cxx. But when I checked the GNU page it says the CXX is a implicit variable: https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html

So can I say for the final target. The implicit tool is always cc?

objects = test.o main.o
CXX=g++
CFLAGS=-std=c++11

test: $(objects)

.PHONY: clean
clean:
    rm -f *.o test

Upvotes: 0

Views: 87

Answers (1)

Toby Speight
Toby Speight

Reputation: 30969

It's likely that your object files are being linked with Make's default linker, which is $(CC). We can see that, if we look in the output of make --print-data-base -f /dev/null - in particular:

%: %.o
#  recipe to execute (built-in):
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@

If we look at the definition of LINK.o, we see:

# default
LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)

Luckily for us, Make provides LINK.cc for exactly our purpose:

# default
LINK.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

So all we need to do is redefine LINK.o to be the the value of LINK.cc, and the linking will be done by our C++ compiler:

LINK.o = $(LINK.cc)

If we had several targets, to be linked differently, we might use a target-dependent variable to localise the effect:

test: LINK.o = $(LINK.cc)

Other comments on the makefile:

  • test is a poor name for the program - it's easy to run the standard /usr/bin/test by mistake.
  • You probably meant CXXFLAGS=-std=c++11 (not CFLAGS).
  • All makefiles should contain a .DELETE_ON_ERROR: target, so that interrupted commands don't leave partial output that appears up-to-date.

Upvotes: 1

Related Questions