Compile multiple ** modified source files at once in GNU make

I know that there were several questions with similar names, but no one seems to give an answer to what I need (correct me if I am wrong).

Consider this make file:

SOURCES=file1.cpp file2.cpp file3.cpp OBJECTS=$(SOURCES:.cpp=.o) EXECUTABLE=myprog all: $(SOURCES) $(EXECUTABLE) $(EXECUTABLE): $(OBJECTS) $(CXX) -o $@ $(OBJECTS) file1.o: file1.cpp file1.h file2.o: file2.cpp file2.h file1.h file3.o: file3.cpp .cpp.o: $(CXX) $(CXXFLAGS) -c -o $@ $< 

If I modify the file1.h file, the following is executed:

 g++ -c -o file1.o file1.cpp g++ -c -o file2.o file2.cpp g++ -o myprog file1.o file2.o file3.o 

I would like to:

 g++ -c file1.cpp file2.cpp g++ -o myprog file1.o file2.o file3.o 

(I know that I cannot specify the output directory of the object with GCC, but I can live with it, and it is possible to work with some cd commands with it.)

In nmake, this is done using the double-colon output rule (the so-called " batch mode rule ). Basically, it groups the output rules (for example,". Obj.cpp: ") for several purposes and calls the compiler for all the dependencies, not one times for each file.The variable $< gets a list of dependencies, not just the first one.

Right now we are using concurrent creation (make -j), but it has its own problems, and the VC ++ compiler works much better in single-call mode, so I would prefer to use it.

+8
c gcc makefile nmake
source share
2 answers

I don’t understand why you want this effect, but here is how to get it (in GNUMake):

 SOURCES=file1.cpp file2.cpp file3.cpp OBJECTS=$(SOURCES:.cpp=.o) EXECUTABLE=myprog all: $(EXECUTABLE) $(EXECUTABLE): $(SOURCES) $(CXX) $(CXXFLAGS) -c $? $(CXX) -o $@ $(OBJECTS) 

EDIT:
I am surprised that this solution works - something is wrong with my idea of ​​what it does, but I don’t think it will work in your case with header dependencies without the following kludge. (There are one or two other approaches that may work if this doesn't turn off.)

 SOURCES=file1.cpp file2.cpp file3.cpp OBJECTS=$(SOURCES:.cpp=.o) EXECUTABLE=myprog all: $(EXECUTABLE) $(EXECUTABLE): $(OBJECTS) $(CXX) -o $@ $(OBJECTS) file1.cpp: file1.h file2.cpp: file2.h file1.h $(SOURCES): @touch $@ $(OBJECTS): $(SOURCES) $(CXX) $(CXXFLAGS) -c $? @touch $(OBJECTS) 
+1
source share

You can get GNUmake to do what you want by collecting the files you need to rebuild in the build rule, and then actually create them when you link:

 SOURCES=file1.cpp file2.cpp file3.cpp OBJECTS=$(SOURCES:.cpp=.o) EXECUTABLE=myprog all: $(EXECUTABLE) .PHONY: build_list build_list: -rm -f build_list $(OBJECTS): %.o: %.cpp | build_list echo $< >> build_list $(EXECUTABLE): build_list $(OBJECTS) if [ -r build_list ]; then $(CXX) $(CXXFLAGS) -c `cat build_list`; fi $(CXX) -o $@ $(OBJECTS) file1.o: file1.h file2.o: file2.h file1.h 
+1
source share

All Articles