Makefile (Auto-Dependency Generation) - makefile

just for quick terminology:
#basic makefile rule
target: dependencies
recipe
The Problem: I want to generate the dependencies automatically.
For example, I am hoping to turn this:
#one of my targets
file.o: file.cpp 1.h 2.h 3.h 4.h 5.h 6.h 7.h 8.h another.h lots.h evenMore.h
$(COMPILE)
Into this:
#one of my targets
file.o: $(GENERATE)
$(COMPILE)
and I'm not too sure if it's possible..
What I do know:
I can use this compiler flag:
g++ -MM file.cpp
and it will return the proper target and dependency.
so from the example, it would return:
file.o: file.cpp 1.h 2.h 3.h 4.h 5.h 6.h 7.h 8.h another.h lots.h evenMore.h
however, 'make' does NOT allow me to explicitly write shell code in the target or dependency section of a rule :(
I know there is a 'make' function called shell
but I can't quite plug this in as dependency and do parsing magic because it relies on the macro $# which represents the target.. or at least I think that’s what the problem is
I've even tried just replacing the "file.cpp" dependency with this makefile function and that won't work either..
#it's suppose to turn the $# (file.o) into file.cpp
THE_CPP := $(addsuffix $(.cpp),$(basename $#))
#one of my targets
file.o: $(THE_CPP) 1.h 2.h 3.h 4.h 5.h 6.h 7.h 8.h another.h lots.h evenMore.h
$(COMPILE)
#this does not work
So all over google, there appear to be two solutions. both of which I don't fully grasp.
From GNU Make Manual
Some Site that says the GNU Make Manual one is out-of-date
So my ultimate question is: Is it possible to do it the way I want to do it,
and if not, can somebody break down the code from one of these sites and explain to me in detail how they work. I'll implement it one of these ways if I have to, but I'm weary to just paste a chunk of code into my makefile before understanding it

Newer versions of GCC have an -MP option which can be used with -MD. I simply added -MP and -MD to the CPPFLAGS variable for my project (I did not write a custom recipe for compiling C++) and added an "-include $(SRC:.cpp=.d)" line.
Using -MD and -MP gives a dependency file which includes both the dependencies (without having to use some weird sed) and dummy targets (so that deleting header files will not cause errors).

To manipulate the filenames when you already know what the dependencies should be, you can use a pattern rule:
file.o: %.o : %.cpp 1.h 2.h 3.h 4.h 5.h 6.h 7.h 8.h another.h lots.h evenMore.h
$(COMPILE)
And you can reuse the rule for other targets:
# Note these two rules without recipes:
file.o: 1.h 2.h 3.h 4.h 5.h 6.h 7.h 8.h another.h lots.h evenMore.h
anotherFile.o: 4.h 9.h yetAnother.h
file.o anotherFile.o: %.o : %.cpp
$(COMPILE)
But if you want Make to figure out the list of dependencies automatically, the best way (that I know of) is Advanced Auto-Dependency Generation. It looks like this:
%.o : %.cc
#g++ -MD -c -o $# $<
#cp $*.d $*.P; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \
rm -f $*.d
-include *.P
Basically, when it builds file.o, it also builds file.d. Then it runs file.d through a bewildering sed command that turns the list of dependencies into a rule with no recipes. The last line is an instruction to include any such rules that exist. The logic here is subtle and ingenious: you don't actually need the dependencies the first time you build foo.o, because Make already knows that foo.o must be built, because it doesn't exist. The next time you run Make, it will use the dependency list it created last time. If you change one of the files so that there is actually a new dependency which is not in the list, Make will still rebuild foo.o because you changed a file which was a dependency. Try it, it really works!

Excellent answers but in my build I put the .obj files in a subdirectory based on build type (ie: debug vs. release). So for example, if I'm building debug, I put all the object files in a build/debug folder. It was a mind-numbing task to try to get the multiline sed command above to use the correct destination folder, but after some experimentation, I stumbled on a solution that works great for my build. Hopefully it'll help someone else as well.
Here's a snippet:
# List my sources
CPP_SOURCES := foo.cpp bar.cpp
# If I'm debugging, change my output location
ifeq (1,$(DEBUG))
OBJ_DIR:=./obj/debug
CXXFLAGS+= -g -DDEBUG -O0 -std=c++0x
else
CXXFLAGS+= -s -O2
OBJ_DIR:=./obj/release
endif
# destination path macro we'll use below
df = $(OBJ_DIR)/$(*F)
# create a list of auto dependencies
AUTODEPS:= $(patsubst %.cpp,$(OBJ_DIR)/%.d,$(CPP_SOURCES))
# include by auto dependencies
-include $(AUTODEPS)
.... other rules
# and last but not least my generic compiler rule
$(OBJ_DIR)/%.o: %.cpp
## Build the dependency file
#$(CXX) -MM -MP -MT $(df).o -MT $(df).d $(CXXFLAGS) $< > $(df).d
## Compile the object file
#echo " C++ : " $< " => " $#
#$(CXX) -c $< $(CXXFLAGS) -o $#
Now for the details:
The first execution of CXX in my generic build rule is the interesting one. Note that I'm not using any "sed" commands. Newer versions of gcc do everything I needed (I'm using gcc 4.7.2).
-MM builds the main dependency rule including project headers but not system headers. If I left it like this, my .obj file would NOT have the correct path. So I use the -MT option to specify the "real" path to my .obj destination. (using the "df" macro I created).
I also use a second -MT option to make sure the resulting dependency file (ie: .d file) has the correct path, and that it is included in the target list and therefor has the same dependencies as the source file.
Last but not least is the inclusion of the -MP option. This tell gcc to also make stubbed rules for each header solving the problem that occurs if I delete a header causing make to generate an error.
I suspect that since I'm using gcc for all the dependency generation instead of piping out to sed, my build is faster (although I've yet to prove that since my build is relatively small at this point). If you see ways I can improve upon this, I'm always open to suggestions. Enjoy

For the record, this is how I generate dependencies automatically now:
CPPFLAGS = -std=c++1y -MD -MP
SRC = $(wildcard *.cpp)
all: main
main: $(SRC:%.cpp=%.o)
g++ $(CPPFLAGS) -o $# $^
-include $(SRC:%.cpp=%.d)
The compiler flags -MD and -MP help do the trick.

First, you can have THE_CPP=$(patsubst %.o,%.cpp,$#)
Then you can run make -p to understand the builtin rules of make
A usual way of doing could be to generate the makefile dependencies into *.md files:
%.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $< -MMD -MF $(patsubst %.c,%.md,$#)
and later in your Makefile including them with something like
-include $(wildcard *.md)
But you can also consider using other builders like omake and many many others

WOOO! I did manage to get the code in Beta's post to work on a small test project.
I should note, for anyone else who may come across this,
If you're using the bash shell(which I was), you will need to add an escape character in front of the pound sign to escape from making the rest of the expression a comment. (see 4th line of code)
%.o : %.cpp
g++ -c -MD -o $# $<
cp $*.d $*.P; \
sed -e 's/\#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \
rm -f $*.d
-include *.P
Now I want to share information that I found in Managing Projects with GNU Make, 3rd Edition. because it's points out some important issues on this matter, and supplies code that I still don't fully grasp yet.
A method appears in the book that is similar to the method found on the Make manual page.
It looks like this:
include $(subst .c,.d,$(SOURCES))
%.d: %.c
$(CC) -M $(CPPFLAGS) $< > $#.$$$$; \
sed 's,\($*\).o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
This is what I believe is happening.
Right away, 'make' wants to include a ".d" file for every source file.
Because no .d files initially exist, the chunk of code is ran again and again in order to create all the missing .d files.
This means make will start over again and again until every .d file is created and included in the makefile.
Each ".d" file is what Beta said: a target with a set of dependencies and NO recipe.
If a header file is ever changed, those rules that are included in, will need the dependencies updated first. This is what throws me off a bit, how is it that the chunk of code is able to be called again? It is used to update .d files, so if a .h file changes how does it get called? Aside from this, I realize that the default rule is used to compile the object. Any clarifications/misconceptions to this explanation are appreciated.
Later in the book it points out problems with this method, and problems that I believe also exist in the Advanced Auto-Dependency Generation implementation.
Problem 1: It's inefficient. 'make' must restart every time it makes a .d file
Problem 2: make generates warning messages for all the missing .d files- Which is mostly just a nuisance and can be hidden by adding a "-" in front of the include statement.
Problem 3: If you delete a src file because it's no longer needed, 'make' will crash the next time you try to compile because some .d file has the missing src as a dependency, and because there is no rule to recreate that src, make will refuse to go any further.
They say a fix to these issues is Tromey's method, but the code looks very different from the code on the website. Perhaps it's just because they used some macros, made it a function call, and wrote it slightly different. I'm still looking into it, but wanted to share some discoveries I've made so far. Hopefully this opens up a little bit more discussion, and gets me closer to the bottom of all this.

A simple and elegant solution, inclusive of a detailed explanation of how it works, is available here.
DEPDIR := .deps
DEPFLAGS = -MT $# -MMD -MP -MF $(DEPDIR)/$*.d
%.o : %.cpp
%.o : %.cpp $(DEPDIR)/%.d | $(DEPDIR)
g++ -c $(DEPFLAGS) $(CFLAGS) $<
$(DEPDIR): ; #mkdir -p $#
DEPFILES := $(SRCS:%.c=$(DEPDIR)/%.d)
$(DEPFILES):
include $(wildcard $(DEPFILES))

I prefer to use $(shell ...) function with find. Here is a sample of one of my Makefiles:
SRCDIR = src
OBJDIR = obj
LIBDIR = lib
DOCDIR = doc
# Get Only the Internal Structure of Directories from SRCDIR
STRUCTURE := $(shell find $(SRCDIR) -type d)
#Filter-out hidden directories
STRUCTURE := $(filter-out $(shell find $(SRCDIR)/.* -type d),$(STRUCTURE))
# Get All Files From STRUCTURE
CODEFILES := $(addsuffix /*,$(STRUCTURE))
CODEFILES := $(wildcard $(CODEFILES))
## Filter Only Specific Files
SRCFILES := $(filter %.c,$(CODEFILES))
HDRFILES := $(filter %.h,$(CODEFILES))
OBJFILES := $(subst $(SRCDIR),$(OBJDIR),$(SRCFILES:%.c=%.o))
DOCFILES := $(addprefix $(DOCDIR)/, \
$(addsuffix .md, \
$(basename $(SRCFILES))))
# Filter Out Function main for Libraries
LIBDEPS := $(filter-out $(OBJDIR)/main.o,$(OBJFILES))
In this approach, I first get all the internal directory structure, with any depth. Then I get all files inside the Structure. At this time, I can use filter, filter-out, addsuffix, etc, to get exactly what I need at each time.
This example covers *.c files, but you can change it to *.cpp as well.

Building on the content of the Auto-Dependency Generation article referenced in comments on a previous post at I've created an annotated makefile project which includes a generic Makefile annotated with comments and implemented for a simple project with 3 .c files and 2 .h files. See full Makefile content below. Simple projects should be able to just customize the TODO section
# See http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
# for the template used to start this file
# -- TODO: customize the list below for your project ---
# List of source .c files used with the project
SRCS := main.c file1.c file2.c
# The aplication generated
APPNAME = depend-generation-test
# -- End of customization section ---
# Replace .c extension on SRCS to get objfiles using gnu make pattern rules and substitution references.
# See https://www.gnu.org/software/make/manual/html_node/Pattern-Intro.html#Pattern-Intro for pattern rules and
# https://www.gnu.org/software/make/manual/html_node/Substitution-Refs.html#Substitution-Refs for substitution references overview
OBJFILES := $(SRCS:%.c=%.o)
# Build the app you've specified in APPNAME for the "all" or "default" target
all : $(APPNAME)
default : $(APPNAME)
# Remove all build intermediates and output file
clean : ; #rm -rf $(APPNAME) *.o
# Build the application by running the link step with all objfile inputs
$(APPNAME) : $(OBJFILES)
$(CC) $(LDFLAGS) $^ -o $(APPNAME)
# Add all warnings/errors to cflags default. This is not required but is a best practice
CFLAGS += -Wall -Werror
# The below content is from http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
# with the following changes:
# 1) Added comments
# 2) Removed TARGET_ARCH from COMPILE.c since it's no longer listed in the [default rules](https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html#Catalogue-of-Rules) and [isn't documented](https://lists.gnu.org/archive/html/help-make/2010-06/msg00005.html)
# Original content below is:
# Copyright © 1997-2019 Paul D. Smith Verbatim copying and distribution is permitted in any medium, provided this notice is preserved.
# The directory (hidden) where dependency files will be stored
DEPDIR := .deps
# Flags passed to gcc to automatically build dependencies when compiling
# See https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html for detail about variable names
# $# references the target file of the rule and will be "main.o" when compiling "main.c"
# $* references the stem of the rule, and will be "main" when target is "main.o"
DEPFLAGS = -MT $# -MMD -MP -MF $(DEPDIR)/$*.d
# Rules for compiling a C file, including DEPFLAGS along with Implicit GCC variables.
# See https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
# and see https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html#Catalogue-of-Rules
# for the default c rule
COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c
# Delete the built-in rules for building object files from .c files
%.o : %.c
# Define a rule to build object files based on .c or dependency files by making the associated dependency file
# a prerequisite of the target. Make the DEPDIR an order only prerequisite of the target, so it will be created when needed, meaning
# the targets won't get rebuilt when the timestamp on DEPDIR changes
# See https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html for order only prerequesites overview.
%.o : %.c $(DEPDIR)/%.d | $(DEPDIR)
$(COMPILE.c) $(OUTPUT_OPTION) $<
# Create the DEPDIR when it doesn't exist
$(DEPDIR): ; #mkdir -p $#
# Use pattern rules to build a list of DEPFILES
DEPFILES := $(SRCS:%.c=$(DEPDIR)/%.d)
# Mention each of the dependency files as a target, so make won't fail if the file doesn't exist
$(DEPFILES):
# Include all dependency files which exist, to include the relevant targets.
# See https://www.gnu.org/software/make/manual/html_node/Wildcard-Function.html for wildcard function documentation
include $(wildcard $(DEPFILES))

Related

Gnu Make auto-dependency generation

Based on this famous link and adapted from this gist, and supposing that all of your source files are .cpp, you get easily a solution like this to have auto-dependence generation:
SRCS := $(wildcard *.cpp */*.cpp)
DEPDIR := .d
DEPS := $(SRCS:%.cpp=$(DEPDIR)/%.d)
# Temporary .Td dependence file... ?
DEPFLAGS = -MT $# -MD -MP -MF $(DEPDIR)/$*.Td
# Isn't it better a order-only prerequisite?
$(shell mkdir -p $(dir $(DEPS)) >/dev/null)
%.o: %.cpp # Removal of implicit rules... ? Twice?
%.o: %.cpp $(DEPDIR)/%.d # Dependency on .d... ?
g++ -o $# $(DEPFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c $<
# Avoid some bugs?
mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $#
# If the `%.d` dependency is removed, is this still necessary?
.PRECIOUS = $(DEPDIR)/%.d
$(DEPDIR)/%.d: ;
-include $(DEPS)
To don't make this question too long discussing deeply why I think that all of the lines commented in the snippet above are innecesary, I will ask it in a short form; is there any difference in behaviour if I just change this snippet to:
SRCS := $(wildcard *.cpp */*.cpp)
DEPDIR := .d
DEPS := $(SRCS:%.cpp=$(DEPDIR)/%.d)
DEPFLAGS := -MT $# -MD -MP -MF $(DEPDIR)/$*.d
$(DEPDIR)/%:
mkdir -p $#
%.o: %.cpp | $(DEPDIR)/$(dir %)
g++ -o $(DEPFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c $<
# touch $(DEPDIR)/$.d # ??
-include $(DEPS)
I have still two extra doubts; in the first link above, it says that
it’s been reported that some versions of GCC may leave the object file
older than the dependency file, which causes unnecessary rebuilds.
However, in the gist (second link above), the touch command is removed, and since the dependence file is no longer prerequisite of any rule, is there any reason to keep including it? Does this "gcc bug" still apply in any form?
The second doubt is related to the directory creation, moved to an order-only rule; do I need to make the "order-only" $(DEPDIR)/% rule .PRECIOUS? I don't know if make will attempt to remove the directory if the %.o recipe fails, because I don't know the concrete features of order-only rules.
You cannot remove the %.d prerequisite. The reason this is needed is explained in the page you linked.
I don't know what you mean by your comment Removal of implicit rules... ? Twice?. The removal of the implicit rule is needed, to ensure that our new implicit rule is used, and we only remove it once.
The temporary file .Td is used in case someone uses ^C or similar to kill their make job right in the middle of creating this file. By writing to a temporary file then only atomically replacing the real file once we know it's complete, we never have to worry about partial files which could cause the next invocation of make to generate an error or, worse, not recompile source files that should be recompiled.
Regarding the comment about object files older than the dependency file, first the gist you link to uses clang not GCC and perhaps Clang doesn't have this issue (or perhaps it does but people don't realize it). Second that update to the blog post is relatively recent as people have reported this issue to me with GCC. I've not seen it myself (I only use GCC) so maybe it's only an issue with some versions of GCC.
Regarding .PRECIOUS, make never (currently) recursively deletes directories so it won't delete any non-empty directory regardless of that setting.

Forcing the order of implicit rule/pattern rule evaluation in GNU Make

I have a domain specific language compiler (homemade) which takes a file x.inflow and generates two files: x.c and x.h. The C file is compiled in the conventional manner and the generated header file has to be included into any file that calls the functions defined within it.
The header files therefore have to be generated before any C files that use them are compiled. My current Makefile, below, works fine except for the first build from clean where it can try and compile main.c before the header file that it includes has been created.
NAME = simplest
OBJ = $(patsubst %.c,%.o,$(wildcard *.c)) \
$(patsubst %.inflow,%.o,$(wildcard *.inflow))
CC = gcc
CFLAGS = -g -Wall
$(NAME): $(OBJ)
$(CC) $(CFLAGS) -o $# $^ $(CLIBS)
# Dependencies for existing .o files.
-include $(OBJ:.o=.d)
# Compile an inflow file into both a .c and .h file.
# Note that this rule has two targets.
%.c %.h: %.inflow
inflow $<
# Compile object files and generate dependency information.
%.o: %.c
$(CC) -MD -MP -c $(CFLAGS) -o $# $<
Obviously, I can fix this for specific cases by adding, for example (where simplest.h is a generated header):
main.o: simplest.h
But is there a general way to force one type of pattern rule (%.c %.h: %.inflow) to be run before any invokations of another (%.o: %.c)?
Well, you can force any target to be run before any other target with order-only prerequisites. So for example, you can write:
%.o : %.c | simplest.h
$(CC) -MD -MP -c $(CFLAGS) -o $# $<
which will ensure that no target that uses this pattern rule to build will be invoked before the target simplest.h is created. However, I don't think you can put patterns in an order-only prerequisite. To be honest, I've never tried it so it's possible that it works, I'm not sure.
If not, you could just list all the order-only prerequisites in the %.o pattern rule; this would ensure that all the inflow files are generated before any of the object files are built. That's probably OK.
It seems the problem is twofold:
Make doesn't know that it needs to generate simplest.h before compiling main.c.
You don't want to have to explicitly tell Make about the dependency (and remember to update it when it changes).
Rather than force Make to evaluate rules in a set order, you can solve your problem by letting Make create the dependencies for you. Check out this section of the Gnu Make manual: http://www.gnu.org/software/make/manual/make.html#Automatic-Prerequisites
When you run Make, it will scan your source files and gather their dependencies for you (and you won't have to explicitly list that main.o depends on simplest.h).

Automatically generating dependency in make and including them in dependency list

Here this tutorial explains it quite beautifully and most of it works fine. The following is the final Makefile from the tutorial which assumes that you have a directory structure like the following:
root-----Makefile
|-----All source files here.
Results of compilation are to be in the root directory. The following is the Makefile:
OBJS := foo.o bar.o
# link
proggie: $(OBJS)
gcc $(OBJS) -o proggie
# pull in dependency info for *existing* .o files
-include $(OBJS:.o=.d) #NOTE THIS
%.o: %.c #NOTE THIS
gcc -c $(CFLAGS) $*.c -o $*.o
gcc -MM $(CFLAGS) $*.c > $*.d
#cp -f $*.d $*.d.tmp
#sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | \
sed -e 's/^ *//' -e 's/$$/:/' >> $*.d
#rm -f $*.d.tmp
# remove compilation products
clean:
rm -f proggie *.o *.dOBJS := foo.o bar.o
I do not understand only one thing in tutorial. It says pull in dependency info for *existing* .o files and the corresponding .d files are made but how are these taken care of as no change has been made in the dependency list of the targets which still remain %.o: %.c.
In fact from what I have noticed it just does not work for me. Can anybody explain what is going on here. If this tutorial is wrong(which I highly doubt) then please mention how can we include dependency from .d files to the dependency list.
The dependency files created with gcc MM will contain rules like:
foo.o: stdio.h myinc.h # ...
and this line here includes dependency file for each object in the list:
-include $(OBJS:.o=.d)
just look at the foo.d for example.
According to this:
One file can be the target of several rules. All the prerequisites mentioned in all the rules are merged into one list of prerequisites for the target. If the target is older than any prerequisite from any rule, the recipe is executed.
So even if you have the rule %.o: %.c, the include statement imports rules that expand this rule with dependencies.

Problem generating dependencies in Makefile using -MM

I am new to Makefiles and g++ and i am struck with a problem while generating dependencies of the project files using -MM flag. I'm posting the Makefile i am using for your consideration. Please take a look.
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 sooo many times. I googled for the solution but couldn't find any.
Is using "-MM" flag to generate dependencies the right option?? If not please suggest me the right way to generate the dependencies. I wanted to generated dependencies automatically because my project will have sooo many files. I thought it is the better option than to write down evey dependency manually.
These are the errors i am getting
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.
It looks like you are trying to generate a dependency file (called *.d, by your makefile rules) for each .cpp file. This is not my understanding of how a dependencies file is used.
Use the -M option to generate a single dependencies file for your project and then include the dependencies file.
DEPS = $(OUR_DIR)/make.dep
$(DEPS): $(SOURCE_TARGET)
#$(CC) -M $(SOURCE_TARGET) > $(DEPS)
include $(DEPS)
edit Your dependency file should also depend on your headers
$(DEPS): $(SOURCE_TARGET) $(HEADER_TARGET)
#$(CC) -M $(SOURCE_TARGET) > $(DEPS)
where HEADER_TARGET is defined the same as SOURCE_TARGET. That way, when a header file is changed the dependency file is rebuilt.
For a beginner, you are doing some exotic stuff. You should start simple and only use code in your Makefile that you 100% understand and trust. Even on a large project with hundreds of files you will not spend much time maintaining the Makefile.
Variables assigned with := are immediately expanded--all the $(VAR) values are substituted into the variable's value during assignment. Variables assigned with = are expanded when they are used, so they can do things like refer to variables that aren't defined yet.
The -MM flag for g++ will generate a Makefile dependency line, e.g. foo.o: foo.cc foo.hh, but I've never found it useful. I had a phony "dependency" target that generated a single dependency file. Your idea of making a bunch of *.d files with those one line dependencies might work, but you'll end up with a lot of those files.
The error you are getting is from g++, not from make. It's because you are using $(DEPS) as if it were a single file when it's the entire list of *.d files. What happens is this line:
#$(CC) -c -MM $< > $(DEPS)
gets expanded to:
g++ -c -MM MyFile.cpp > MyFile.d stdAfx.d Main.cpp
mcdave just posted the code I have used to generate a dependency file. You can either switch to the single dependency file style, or change your -MM command to this:
#$(CC) -MM $< > $#
You may also have to fix the -include statement because I don't think it supports a list of files to include.

How can I have a Makefile automatically rebuild source files that include a modified header file? (In C/C++)

I have the following makefile that I use to build a program (a kernel, actually) that I'm working on. Its from scratch and I'm learning about the process, so its not perfect, but I think its powerful enough at this point for my level of experience writing makefiles.
AS = nasm
CC = gcc
LD = ld
TARGET = core
BUILD = build
SOURCES = source
INCLUDE = include
ASM = assembly
VPATH = $(SOURCES)
CFLAGS = -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions \
-nostdinc -fno-builtin -I $(INCLUDE)
ASFLAGS = -f elf
#CFILES = core.c consoleio.c system.c
CFILES = $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
SFILES = assembly/start.asm
SOBJS = $(SFILES:.asm=.o)
COBJS = $(CFILES:.c=.o)
OBJS = $(SOBJS) $(COBJS)
build : $(TARGET).img
$(TARGET).img : $(TARGET).elf
c:/python26/python.exe concat.py stage1 stage2 pad.bin core.elf floppy.img
$(TARGET).elf : $(OBJS)
$(LD) -T link.ld -o $# $^
$(SOBJS) : $(SFILES)
$(AS) $(ASFLAGS) $< -o $#
%.o: %.c
#echo Compiling $<...
$(CC) $(CFLAGS) -c -o $# $<
#Clean Script - Should clear out all .o files everywhere and all that.
clean:
-del *.img
-del *.o
-del assembly\*.o
-del core.elf
My main issue with this makefile is that when I modify a header file that one or more C files include, the C files aren't rebuilt. I can fix this quite easily by having all of my header files be dependencies for all of my C files, but that would effectively cause a complete rebuild of the project any time I changed/added a header file, which would not be very graceful.
What I want is for only the C files that include the header file I change to be rebuilt, and for the entire project to be linked again. I can do the linking by causing all header files to be dependencies of the target, but I cannot figure out how to make the C files be invalidated when their included header files are newer.
I've heard that GCC has some commands to make this possible (so the makefile can somehow figure out which files need to be rebuilt) but I can't for the life of me find an actual implementation example to look at. Can someone post a solution that will enable this behavior in a makefile?
EDIT: I should clarify, I'm familiar with the concept of putting the individual targets in and having each target.o require the header files. That requires me to be editing the makefile every time I include a header file somewhere, which is a bit of a pain. I'm looking for a solution that can derive the header file dependencies on its own, which I'm fairly certain I've seen in other projects.
As already pointed out elsewhere on this site, see this page:
Auto-Dependency Generation
In short, gcc can automatically create .d dependency files for you, which are mini makefile fragments containing the dependencies of the .c file you compiled.
Every time you change the .c file and compile it, the .d file will be updated.
Besides adding the -M flag to gcc, you'll need to include the .d files in the makefile (like Chris wrote above).
There are some more complicated issues in the page which are solved using sed, but you can ignore them and do a "make clean" to clear away the .d files whenever make complains about not being able to build a header file that no longer exists.
You could add a 'make depend' command as others have stated but why not get gcc to create dependencies and compile at the same time:
DEPS := $(COBJS:.o=.d)
-include $(DEPS)
%.o: %.c
$(CC) -c $(CFLAGS) -MM -MF $(patsubst %.o,%.d,$#) -o $# $<
The '-MF' parameter specifies a file to store the dependencies in.
The dash at the start of '-include' tells Make to continue when the .d file doesn't exist (e.g. on first compilation).
Note there seems to be a bug in gcc regarding the -o option. If you set the object filename to say obj/_file__c.o then the generated _file_.d will still contain _file_.o, not obj/_file_c.o.
This is equivalent to Chris Dodd's answer, but uses a different naming convention (and coincidentally doesn't require the sed magic. Copied from a later duplicate.
If you are using a GNU compiler, the compiler can assemble a list of dependencies for you. Makefile fragment:
depend: .depend
.depend: $(SOURCES)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^>>./.depend;
include .depend
There is also the tool makedepend, but I never liked it as much as gcc -MM
You'll have to make individual targets for each C file, and then list the header file as a dependency. You can still use your generic targets, and just place the .h dependencies afterwards, like so:
%.o: %.c
#echo Compiling $<...
$(CC) $(CFLAGS) -c -o $# $<
foo.c: bar.h
# And so on...
Basically, you need to dynamically create the makefile rules to rebuild the object files when the header files change. If you use gcc and gnumake, this is fairly easy; just put something like:
$(OBJDIR)/%.d: %.c
$(CC) -MM -MG $(CPPFLAGS) $< | sed -e 's,^\([^:]*\)\.o[ ]*:,$(#D)/\1.o $(#D)/\1.d:,' >$#
ifneq ($(MAKECMDGOALS),clean)
include $(SRCS:%.c=$(OBJDIR)/%.d)
endif
in your makefile.
Over and above what #mipadi said, you can also explore the use of the '-M' option to generate a record of the dependencies. You might even generate those into a separate file (perhaps 'depend.mk') which you then include in the makefile. Or you can find a 'make depend' rule which edits the makefile with the correct dependencies (Google terms: "do not remove this line" and depend).
Simpler solution: Just use the Makefile to have the .c to .o compilation rule be dependent on the header file(s) and whatever else is relevant in your project as a dependency.
E.g., in the Makefile somewhere:
DEPENDENCIES=mydefs.h yourdefs.h Makefile GameOfThrones.S07E01.mkv
::: (your other Makefile statements like rules
::: for constructing executables or libraries)
# Compile any .c to the corresponding .o file:
%.o: %.c $(DEPENDENCIES)
$(CC) $(CFLAGS) -c -o $# $<
None of the answers worked for me. E.g. Martin Fido's answer suggests gcc can create dependency file, but when I tried that it was generating empty (zero bytes) object files for me without any warnings or errors. It might be a gcc bug. I am on
$ gcc --version gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16)
So here's my complete Makefile that works for me; it's a combination of solutions + something that wasn't mentioned by anyone else (e.g. "suffix replacement rule" specified as .cc.o:):
CC = g++
CFLAGS = -Wall -g -std=c++0x
INCLUDES = -I./includes/
# LFLAGS = -L../lib
# LIBS = -lmylib -lm
# List of all source files
SRCS = main.cc cache.cc
# Object files defined from source files
OBJS = $(SRCS:.cc=.o)
# # define the executable file
MAIN = cache_test
#List of non-file based targets:
.PHONY: depend clean all
## .DEFAULT_GOAL := all
# List of dependencies defined from list of object files
DEPS := $(OBJS:.o=.d)
all: $(MAIN)
-include $(DEPS)
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
#suffix replacement rule for building .o's from .cc's
#build dependency files first, second line actually compiles into .o
.cc.o:
$(CC) $(CFLAGS) $(INCLUDES) -c -MM -MF $(patsubst %.o,%.d,$#) $<
$(CC) $(CFLAGS) $(INCLUDES) -c -o $# $<
clean:
$(RM) *.o *~ $(MAIN) *.d
Notice I used .cc .. The above Makefile is easy to adjust for .c files.
Also notice importance of these two lines :
$(CC) $(CFLAGS) $(INCLUDES) -c -MM -MF $(patsubst %.o,%.d,$#) $<
$(CC) $(CFLAGS) $(INCLUDES) -c -o $# $<
so gcc is called once to build a dependency file first, and then actually compiles a .cc file. And so on for each source file.
I believe the mkdep command is what you want. It actually scans .c files for #include lines and creates a dependency tree for them. I believe Automake/Autoconf projects use this by default.

Resources