The problem of creating dependencies in a Makefile using -MM

I am new to Makefiles and g ++, and I am facing a problem when creating project file dependencies using the -MM flag. I submit a Makefile which I use for your consideration. Take a look, please.

OUTPUT_ROOT := output/ SOURCE_ROOT := source/ TITLE_NAME := TestProj SOURCES := \ MyFile.cpp \ stdAfx.cpp \ Main.cpp \ OUT_DIR := $(OUTPUT_ROOT) OUT_O_DIR := $(OUT_DIR) OBJS = $(SOURCES:%.cpp=$(OUT_O_DIR)%.o) DEPS = $(OBJS:%.o=%.d) DIRS = $(subst /,/,$(sort $(dir $(OBJS)))) SOURCE_TARGET = $(SOURCES:%.cpp=$(SOURCE_ROOT)%.cpp) OUTPUT_TARGET = $(OUT_DIR)$(TITLE_NAME) #--------------------------------------------------------------------- # executables #--------------------------------------------------------------------- MD := mkdir -p RM := rm CC := g++ #--------------------------------------------------------------------- # rules #--------------------------------------------------------------------- .PHONY: clean directories objects title all: directories objects title directories: @$(MD) $(DIRS) clean: $(RM) -rf $(OUT_DIR) $(OBJS): $(SOURCE_TARGET) @$(CC) -c $< -o $@ $(DEPS): $(SOURCE_TARGET) @$(CC) -c -MM $< > $(DEPS) -include $(DEPS) objects:$(OBJS) $(DEPS) title: $(OBJS) @$(CC) $< -o $@ 

I tried several options and many times. I googled for a solution, but could not find.

Use the -MM flag to generate the dependencies of the right option? If not, suggest me the correct way to generate dependencies. I wanted to create the generated dependencies automatically, because there will be many files in my project. I thought this was a better option than writing the evey dependency manually.

These are the errors that I get

 g++: stdAfx.d: No such file or directory g++: Main.d: No such file or directory make: *** No rule to make target `stdAfx.d', needed by `objects'. Stop. 

Thanks in advance.

+6
makefile
source share
2 answers

It looks like you are trying to create a dependency file (called * .d, by your makefile rules) for each .cpp file. This is not my understanding of how the dependency file is used.

Use the -M option to create one dependency file for your project, and then include the dependency file.

 DEPS = $(OUR_DIR)/make.dep $(DEPS): $(SOURCE_TARGET) @$(CC) -M $(SOURCE_TARGET) > $(DEPS) include $(DEPS) 

change . Your dependency file should also depend on your headers.

 $(DEPS): $(SOURCE_TARGET) $(HEADER_TARGET) @$(CC) -M $(SOURCE_TARGET) > $(DEPS) 

where HEADER_TARGET is defined in the same way as SOURCE_TARGET. Thus, when the header file changes, the dependency file is rebuilt.

+8
source share

For beginners, you do exotic things. You should start simple and use only the code in the Makefile, which you 100% understand and trust. Even with a large project with hundreds of files, you won’t spend much time saving the Makefile.

Variables assigned with: = are expanded immediately - all $ (VAR) values ​​are substituted into the variable value at the time of assignment. Variables assigned with = expand when they are used, so they can do things like references to variables that are not yet defined.

The -MM flag for g ++ will generate a Makefile dependency line, for example. foo.o: foo.cc foo.hh, but I never found this useful. I had a false “dependency” target that generated one dependency file. Your idea of ​​creating a bunch of * .d files with these single line dependencies might work, but you end up with a lot of these files.

The error you get is from g ++, not from make. This is because you use $ (DEPS), as if it were the only file when it has the entire list of * .d files. What happens is this line:

 @$(CC) -c -MM $< > $(DEPS) 

expands to:

 g++ -c -MM MyFile.cpp > MyFile.d stdAfx.d Main.cpp 

mcdave just posted the code that I used to create the dependency file. You can either switch to one dependency file style, or change the -MM command to this:

 @$(CC) -MM $< > $@ 

You may also need to fix the -include statement because I don't think it maintains a list of files to include.

+3
source share

All Articles