Avoid linking and compiling in Make if not needed

2019-05-10 04:08发布

问题:

As a follow-up question from here: My Makefile will do the linking, even if nothing is changed in the code. Why? How can I avoid that behaviour, so that make won't do anything if the code has not changed?

OBJS    = main_no_mkl.o
SOURCE  = main_no_mkl.cpp
HEADER =    IO.h
OUT     =       test
CXX     = ../../mpich-install/bin/mpic++
CXXFLAGS    =   -I../../intel/mkl/include   -Wl,--start-group    -Wl,--end-group    -lpthread   -lm -ldl    -Wall
LDFLAGS   =       ../../intel/mkl/lib/intel64/libmkl_scalapack_lp64.a       -Wl,--start-group       ../../intel/mkl/lib/intel64/libmkl_intel_lp64.a ../../intel/mkl/lib/intel64/libmkl_core.a  ../../intel/mkl/lib/intel64/libmkl_sequential.a    -Wl,--end-group ../../intel/mkl/lib/intel64/libmkl_blacs_intelmpi_lp64.a -lpthread       -lm     -ldl

all: $(OBJS)
    $(CXX)  $(OBJS) -o  $(OUT)  $(CXXFLAGS) $(LDFLAGS)

# create/compile the individual files >>separately<<
main_no_mkl.o:    main_no_mkl.cpp
    $(CXX)  -c  main_no_mkl.cpp $(CXXFLAGS)

.PHONY : all

回答1:

The problem is your all target. It doesn't generate an all (and is marked .PHONY as well) file. Check this answer for a reminder about .PHONY. (You are violating the second Rule of Makefiles.)

So the second/etc time you run make (assume the .PHONY marking wasn't present) make would look for an all file, not find it, and assume it must need to create it again.

With .PHONY you short-circuit that file-finding logic and make just always assumes it needs to run the recipe again.

So, essentially, you've told make to always run the linking step so make does that.

Use this instead to fix that problem.

all: $(OUT)

$(OUT): $(OBJS)
    $(CXX)  $(OBJS) -o  $(OUT)  $(CXXFLAGS) $(LDFLAGS)

For the record running make -d and reading through the output would have pointed this out to you.



回答2:

The objects are really the dependencies of your output, and your "all" target should depend on the output(s). So you should do something like this instead:

all: $(OUT)

$(OUT): $(OBJS)
    $(CXX)  $(OBJS) -o  $(OUT)  $(CXXFLAGS) $(LDFLAGS)