0
votes

What I need: make LAUNCHMAKES target dependent on something in order to not invoke sub makefiles when no source file has been changed.

SUB MakeFile contains collecting of all .cpp files in the dir and stores them to the obj/. Then no src file changed it still invokes and engenders "Entering directory - Leaving directory". I need to get rid of it when there is no need. I've read about --no-print-directory but it's not the case.

The project's structure:

Project
|----project
|    |----dir1
|    |    |----src1.cpp
|    |    `----Makefile
|    |----dir2
|    |    |----src2.cpp
|    |    `----Makefile
     `----main.cpp
|----obj
|    |----src1.o
|    |----src2.o
|    `----main.o
|----MakeFile

The code:

release: LAUNCHMAKES obj/main.o
    $(CXX) $(CXXFLAGS) main.o src1.o src2.o -o result

LAUNCHMAKES: (?)
    for i in $(SUBDIRS); do \
    $(MAKE) -C $$i CXXFLAGS=$(CXXFLAGS);  \
    done

obj/main.o: project/main.cpp
    $(CXX) $(CXXFLAGS) -c $< -o $@
1
What you ask for is a bit contradictory: if you delegate the build of sub-directories to sub-makes, then you tell make which files to watch in the sub-Makefiles, not in the main Makefile. But if you want the main Makefile to be sufficient for make to decide whether a sub-directory is up-to-date or not, then, you must put in the main Makefile all the dependencies you declared in the sub-Makefiles. In other words, you should probably decide once for all between flat or hierarchical organization. Note: your for loop iterates on the CXXFLAGS (probably not what you want). - Renaud Pacalet
Thanks, I've edited. If makefile checks whether is the dependency up-to-date why I can't (sorry if it naive) put the sourse files to the dependencies of LAUNCHMAKES. e.g. LAUNCHMAKES: src1.cpp src2.cpp. If they are changed then the recepi of iterating is launched. - Sergei Shumilin
The problem is that a file is not up-to-date or outdated by itself. It is by reference to another file. And your LAUNCHMAKES target is not a file which last modification time could be compared by make with that of the source files to decide whether it is up-to-date or outdated. So, in your main Makefile you will have to replicate the complete dependencies that you declared in the sub-Makefiles. And replicating code is usually a very bad idea... - Renaud Pacalet
Inclusions of sub-Makefiles could be used to avoid code replications but as the paths would probably be relative to different directories this would open new issues. Sincerely, most projects I know that use make for their build system don't do what you want. They either don't use recursive make at all or run the sub-makes systematically, even if there is nothing to do. They don't try to save the (usually negligible) time it takes to uselessly run sub-makes. - Renaud Pacalet

1 Answers

1
votes

Not a solution to your problem but an example of a non-recursive Makefile, just to show you how simple it could be for your simple example project:

SUBDIRS := dir1 dir2
OBJDIR  := obj
SRCS    := $(shell find . -type f -name '*.cpp')
OBJS    := $(patsubst %.cpp,$(OBJDIR)/%.o,$(notdir $(SRCS)))
VPATH   := $(SUBDIRS)

.PHONY: release clean

release: result

result: $(OBJS)
    $(CXX) $(LDFLAGS) $^ -o $@

$(OBJDIR)/%.o: %.cpp
    $(CXX) $(CXXFLAGS) -c $< -o $@

clean:
    rm -f $(OBJDIR)/*.o result

Demo:

$ make
g++  -c dir2/src2.cpp -o obj/src2.o
g++  -c dir1/src1.cpp -o obj/src1.o
g++  -c main.cpp -o obj/main.o
g++  obj/src2.o obj/src1.o obj/main.o -o result