make include directive and dependency generation with -MM - c++

I want a build rule to be triggered by an include directive if the target of the include is out of date or doesn't exist.
Currently the makefile looks like this:
program_NAME := wget++
program_H_SRCS := $(wildcard *.h)
program_CXX_SRCS := $(wildcard *.cpp)
program_CXX_OBJS := ${program_CXX_SRCS:.cpp=.o}
program_OBJS := $(program_CXX_OBJS)
DEPS = make.deps
.PHONY: all clean distclean
all: $(program_NAME) $(DEPS)
$(program_NAME): $(program_OBJS)
$(LINK.cc) $(program_OBJS) -o $(program_NAME)
clean:
#- $(RM) $(program_NAME)
#- $(RM) $(program_OBJS)
#- $(RM) make.deps
distclean: clean
make.deps: $(program_CXX_SRCS) $(program_H_SRCS)
$(CXX) $(CPPFLAGS) -MM $(program_CXX_SRCS) > make.deps
include $(DEPS)
The problem is that it seems like the include directive is executing before the rule to build make.deps which effectively means that make is either getting no dependency list if make.deps doesn't exist or always getting the make.deps from the previous build and not the current one.
For example:
$ make clean
$ make
makefile:32: make.deps: No such file or directory
g++ -MM addrCache.cpp connCache.cpp httpClient.cpp wget++.cpp > make.deps
g++ -c -o addrCache.o addrCache.cpp
g++ -c -o connCache.o connCache.cpp
g++ -c -o httpClient.o httpClient.cpp
g++ -c -o wget++.o wget++.cpp
g++ addrCache.o connCache.o httpClient.o wget++.o -o wget++
Edit
I read the docs for the include directive, and it sounds like if the include target doesn't exist it will continue processing the parent makefile try and build the target, but it's not completely clear to me how this works:
If an included makefile cannot be
found in any of these directories, a
warning message is generated, but it
is not an immediately fatal error;
processing of the makefile containing
the include continues. Once it has
finished reading makefiles, make will
try to remake any that are out of date
or don't exist. See section How
Makefiles Are Remade. Only after it
has tried to find a way to remake a
makefile and failed, will make
diagnose the missing makefile as a
fatal error.
ANSWER
This is a modification of the answer I accepted. The one thing missing was that the dependency files also depend on the sources, and won't get regenerated unless they are added to the deps files which are being included:
%.d: $(program_CXX_SRCS)
# $(CXX) $(CPPFLAGS) -MM $*.cpp | sed -e 's#^\(.*\)\.o:#\1.d \1.o:#' > $#
sed adds the name of the .d file to the beginning of each dependency line like so:
foo.d foo.o: foo.cpp foo.h bar.h baz.h
I got the idea from this amazing paper on the dangers of recursive make:
Recursive Make Considered Harmful
I also add the following to the makefile:
clean_list += ${program_SRCS:.c=.d}
# At the end of the makefile
# Include the list of dependancies generated for each object file
# unless make was called with target clean
ifneq "$(MAKECMDGOALS)" "clean"
-include ${program_SRCS:.c=.d}
endif

You are relying on an implicit rule to compile your .cpp files. You have to redefine it to use the -MM and -MF flags that will create the dependency file.
%.o: %.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $# -MM -MF $#.d
Then, you have to include these dependencies files in the Makefile, using -include that will not error when the dependencies files do not exist yet (on the first time, or after a clean).
program_DEPS := $(program_OBJS:.o=.o.d)
-include $(program_DEPS)
And remember to add the rm command for the dependencies files in the clean rule.

An important point that it took me a while to grasp is that the make.deps from the previous build are good enough. Think about it: for a given object file, the only way the list of dependency files can change is if... one of the old dependency files has been altered. And if that's the case, then the old make.deps will cause that object file to be rebuilt, and if rebuilding the object file also rebuilds make.deps, then everything will be up to date. You don't have to rebuild make.deps before checking to see which objects must be rebuilt.

The include directives work like they do in C and C++ - they are processed before anything else happens, to build the "real" makefile that make then processes. Specifically, they are processed before any rules are fired.

Related

When do files in C++ with direct & indirect dependencies have to be recompiled and when is a new linking of the executable sufficient? [duplicate]

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.

How to create a Makefile for a C++ project with multiple directories?

I want to create a Makefile for a project with the following layout:
Source files (.cpp, potentially .c) in /src, with potential subdirectories
Header files (.h, .hpp...) in /inc, with potential subdirectories
Object files (.o) in /obj, with potential subdirectories
External libraries in /lib
Compiled program in /bin
So far, I've managed to write together this Makefile, but with some issues:
SRC_DIR := src
BIN_DIR := bin
LIB_DIR := lib
INC_DIR := inc
OBJ_DIR := obj
SRCEXTS := .c .C .cc .cpp .CPP .c++ .cxx .cp
HDREXTS := .h .H .hh .hpp .HPP .h++ .hxx .hp
TARGETS := $(BIN_DIR)/program
SOURCES := $(wildcard $(addprefix $(SRC_DIR)/*,$(SRCEXTS)))
HEADERS := $(wildcard $(addprefix $(LIB_DIR)/*,$(HDREXTS)))
OBJECTS := $(addsuffix .o, $(basename $(SOURCES)))
CXX = g++
CXXFLAGS = -std=c++17 -c -g -Wall
.PHONY: all clean
all: $(TARGETS)
$(TARGETS): $(OBJECTS)
$(CXX) $^ -o $#
$(OBJ_DIR)%$(OBJECTS): $(SRC_DIR)%$(SOURCES)
$(CXX) $(CXXFLAGS) $< -o $#
clean:
rm -f $(OBJECTS) $(TARGETS)
I've tried to make it as "generic" as possible, so future projects could be started with this layout and makefile as a template. Currently, it creates the .o-files inside the src-directory alongisde the source code. It also fails when trying to compile the program with
g++ src/main.o -o bin/program
/usr/bin/ld: src/main.o: _ZSt4cout: invalid version 3 (max 0)
/usr/bin/ld: src/main.o: error adding symbols: bad value
collect2: error: ld returned 1 exit status
make: *** [Makefile:23: bin/program] Error 1
Very new to C++ development. Been on a wild goose-chase for a while, trying to get a clear image of how it all works. My code is basically a weird Frankenstein monster of several code snippets I've stumbled upon. Hopefully my intentions are clear enough, this is my last ditch effort! Thanks in advance :)
As #JohnBollinger points out, you are attempting too much at once. I will suggest a few changes to get your makefile off the ground.
I can't explain the error you get when you try to build the executable (you haven't given us enough information to reproduce the error), but it doesn't look like a Make problem. I suggest you try to build it without Make, using the command line, and see what happens.
I will assume that the names of your sources end in ".cpp" (such as src/sailboat/foo.cpp), the names of your headers end in ".hpp", and the directory tree under obj/ is already present and correct. These restrictions are temporary training wheels; you can remove them when you have more skill.
First, finding the source files. This:
SOURCES := $(wildcard $(addprefix $(SRC_DIR)/*,$(SRCEXTS)))
will not work if src/ has subdirectories. To recurse into subdirectories, we will use find. (There is a shortcut available to GNUMake, but for now we'll do things the slow and careful way).
SOURCES := $(shell find src -name "*.cpp")
Now to construct the names of the desired object files, such as obj/sailboat/foo.o. This:
OBJECTS := $(addsuffix .o, $(basename $(SOURCES)))
will give you src/sailboat/foo.o. We need a different command to change the leading directory as well as the suffix:
OBJECTS := $(patsubst src/%.cpp,obj/%.o,$(SOURCES))
Some of the source files refer to header files, so before we can start building objects, we must be able to supply them. The compiler can find the needed headers, but we must tell it where to search. So we need the directories, not the full paths:
HEADERS := $(shell find inc -name "*.hpp")
HEADERDIRS := $(sort $(dir $(HEADERS)))
(The sort is just to remove duplicates. Not necessary, but tidy.)
Now the rule to build the objects. This is incorrect:
$(OBJ_DIR)%$(OBJECTS): $(SRC_DIR)%$(SOURCES)
$(CXX) $(CXXFLAGS) $< -o $#
Remember that OBJECTS can contain several space-separated words. So if it contains foo bar, the target will be obj/%foo bar, which is clearly not what you intended. Likewise the prerequisite list is wrong, and the recipe too. Junk it and start over.
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $< -c -o $#
Then remember the header files, and add flags to tell the compiler where to look for them:
INCLUDEFLAGS := $(addprefix -I,$(HEADERDIRS))
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $< -c $(INCLUDEFLAGS) -o $#
That should be enough to get your makefile working; further refinements can wait.
I'm not mastering makefiles but one thing for sure : target "all" is definitively not a PHONY target because it often depends on other targets (in fact, it always depends on other targets, by definition !).
Also, as said John Bollinger, it is obviously possible to have only one makefile at the root.
"all" target is not mandatory : make will look for the first target fisrt.
The folder structure is like this :
----root
----src
----inc
----obj
----lib
Here's a simple one of mine (rules to build static libraries have been commented out) :
CC=g++
SRCDIR=./src/
INCDIR=./inc/
INCFLAG=-I$(INCDIR)
OBJDIR=./obj/
LIB=./lib/
LIBFLAG=-lstdc++
#-lmystaticlibrary -lmyclasses
#$(LIBFLAG) -L$(LIB)
#STATICLIBRARIES= mystaticlibrary myclasses
OBJECTS = $(OBJDIR)apprendre.o $(OBJDIR)myfunctions.o $(OBJDIR)myclasses.o
apprendre: $(OBJECTS)
# echo
# echo --------------------- Edition des liens
$(CC) $(OBJECTS) -o $# $(INCFLAG)
# mystaticlibrary: mystaticlibrary.o
# # echo
# # echo --------------------- Compilation librairie statique $#
# ar cr $(LIB)lib$#.a $(OBJ)$#.o
# ranlib $(LIB)lib$#.a
# myclasses: myclasses.o
# # echo
# # echo --------------------- Compilation librairie statique $#
# ar cr $(LIB)lib$#.a $(OBJ)$#.o
# ranlib $(LIB)lib$#.a
$(OBJDIR)%.o: $(SRCDIR)%.cpp $(INCDIR)myfunctions.h $(INCDIR)myclasses.h
# echo
# echo --------------------- Compilation $<
$(CC) -c $< $(INCFLAG) -o $#
run:
# echo
# echo "-----------------------> GO !!! : apprendre"
# ./apprendre

Makefile Pattern rule: Circular makefile.o <- makefile dependency dropped

I am working on a makefile for a C++ project that needs to support a few configurations, i.e. debug , release and maybe a few more customized ones in the future.
Currently, my naming convention for generated .o files is $(SOURCE_FULLPATH).$(CONFIGURATION).o. For instance, ABC.cpp generates ABC.cpp.debug.o in debug mode.
Now I would like to write the pattern rule for generating those object files in a configuration-independent way. What I did was: from each XX.o filename, I strip the .debug or .release suffix from XX, and use the remaining part of XX as the source filename.
%.o: $$(basename %)
$(CC) $(CC_FLAGS) $(INCLUDE_FOLDERS) -c -o $# $<
With this trick, I can build the executable correctly, except that I get one warning message from make:
make: Circular makefile.o <- makefile dependency dropped.
I am puzzled because I do not list makefile or makefile.o as a target or dependency anywhere in my makefile. I did a search on SO, but most questions about Circular dependency is on a specific user source file, rather than the makefile itself. Can anyone help me understand what causes the circular dependency, and how to get rid of this warning message?
A sample makefile that can reproduce this issue is listed below.
.SECONDEXPANSION:
PROJECT := helloworld
CC := clang++
BUILD_FOLDER := Build
OBJ_FILE_SUFFIX := .o
# Source
CPP_FILES :=\
Source/hello.cpp \
Source/mysqrt.cpp \
INCLUDE_FOLDERS := \
-IInclude
# MMD outputs the dependency files (".d" files). These files will be used by
# this makefile to allow for dependency checking on .h files.
CC_FLAGS += -MMD
EXISTING_OBJ_FILES = $(wildcard $(addsuffix *.o, $(basename $(CPP_FILES))))
##--------------------
## Targets definition
##--------------------
.PHONY:default
default: all
.PHONY:all
all: debug release
.PHONY:debug release
# Add a 'debug'/'release' suffix to the name of the object file
# e.g. hello.cpp -> hello.cpp.debug.o
debug release: OBJ_FILES=$(addsuffix .$#$(OBJ_FILE_SUFFIX), $(CPP_FILES))
debug release: $${OBJ_FILES} # Use Secondary Expansion to get the obj names
$(CC) $^ -o $(BUILD_FOLDER)/$(PROJECT)_$#
# Strip configuration name from the end of the object file name
%.o: $$(basename %)
$(CC) $(CC_FLAGS) $(INCLUDE_FOLDERS) -c -o $# $<
## clean: remove executable, all object files, and all dependency files
.PHONY:clean
clean:
-rm -f $(BUILD_FOLDER)/$(PROJECT) $(EXISTING_OBJ_FILES) $(EXISTING_OBJ_FILES:.o=.d)
# Include the dependent files so that in later builds, modified .h files
# will cause all .cpp dependent on them to rebuild
-include $(OBJ_FILES:.o=.d)
The folder structure is
makefile
Source
- hello.cpp
- mysqrt.cpp
Include
- mysqrt.h
The full output of make debug is
make: Circular makefile.o <- makefile dependency dropped.
clang++ -MMD -IInclude -c -o Source/hello.cpp.debug.o Source/hello.cpp
clang++ -MMD -IInclude -c -o Source/mysqrt.cpp.debug.o Source/mysqrt.cpp
clang++ Source/hello.cpp.debug.o Source/mysqrt.cpp.debug.o -o Build/helloworld_debug
Everything is good except for the first line.
I would also really appreciate it if anyone can point to me if there is any bad practice in my makefile (I am still a newbie in makefile). Thank you in advance!
GNU Make always attempts to update the makefile(s) it has read before
making anything else. If it finds rules and prerequisites that tell it
to update makefile(s), then it does so and then starts again from scratch -
including attempting to update the makefile(s). See 3.5 How Makefiles Are Remade.
In your recipe:
%.o: $$(basename %)
$(CC) $(CC_FLAGS) $(INCLUDE_FOLDERS) -c -o $# $<
you have provided make with a rule for making makefile.o from makefile.
It is also the inverse of the rule in the builtin recipe
%: %.o
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $#
which makes an executable from a single object file. So your recipe has introduced the circularity:
makefile.o <- makefile <- makefile.o
when make is considering makefile itself as a target.
You could suppress the circularity by expressly deleting the builtin inverse rule,
by writing the empty rule:
%: %.o
in the makefile. Then you could observe the following confusion on the part of the
compiler:
$ make makefile.o
clang++ -c -o makefile.o makefile
clang: warning: makefile: 'linker' input unused
And the same would occur if you attempted to make any target that depended
on makefile.o.
It is probably safe to assume that you will have no targets that depend on
makefile.o. Nevertheless a rule that would attempt to
compile foo.o from any existing file foo is clearly more sweeping that you
want or need. For the particular pattern of dependency that you wish to capture:
foo.cpp.{debug|release}.o: foo.cpp
You'd be better off with:
%.o: $$(basename $$(basename %)).cpp
$(CC) $(CC_FLAGS) $(INCLUDE_FOLDERS) -c -o $# $<
Note, BTW, that in GNU Make conventions - the conventions that are
assumed by GNU Make's builtin rules - CC denotes your C compiler while
CXX denotes your C++ compiler. Likewise flags for the C compiler are
denoted CFLAGS and flags for the C++ compiler are denoted CXXFLAGS.
Flags for the preprocessor are denoted CPPFLAGS, and -Ipath options
- which are preprocessor options - are conventionally be passed through CPPFLAGS.

How to link objects in different directories in c++ with make without refering to them in the makefile?

I'm trying to clean up my project a little and I want to put object files and include files in a separate folder and be able to compile another makefile in my a different testing subdirectory. I would like to do this so that the make file in the testing directory doesn't have to know about the objects in the the above directory: I have been struggling all day trying to figure out make and compilation.
Not sure what I'm doing wrong but in addition to this question I would be appreciative of any information to straighten out my thinking about make and g++ so in the future I know where to look.
Anyways I have 2 Questions both with regards to my project layout:
Project
inc/
-- header files
-obj/
--object files
-source
-make file for project that compiles objects in obj directory (makefile0)
-testing/
--test1/
---test.cc
---makefile1
Question 1
So I want to include the header files in the inc directory in test.cc and then just focus on compiling test.cc like I would if I included a standard library header file. Right now I need to make reference to the object in ../../obj/ in makefile1 and would like to ignore that. and just do something simple like
g++ -I ../../inc/ -c test.cc
How is it possible to do this?
Question 2
In makefile0, for each source file I have to append a $(OBJ) or $(INC) to the front of any file I have in those folders and wondering if there is anyway to clean up my make file an do something like
Spinless2DFieldIndex.o: Spinless2DFieldIndex.cc Utils.o Dispersion.h
instead of
$(ODIR)/Spinless2DFieldIndex.o: Spinless2DFieldIndex.cc $(ODIR)/Utils.o $(INC)/Dispersion.h
The following should work:
Project/Makefile
objdir := obj/
vpath %.cc source
vpath %.o $(objdir)
CPPFLAGS := -Iinc -MMD -MP
.PHONY: all
all: testing/test1/test
include source/Makefile
include testing/test1/Makefile
Project/source/Makefile
override objects := $(objdir)obj.o
$(objects): $(objdir)%.o: %.cc
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(OUTPUT_OPTION) $<
clean:: ; $(RM) $(objects) $(objects:.o=.d)
-include $(objects:.o=.d)
Project/testing/test1/Makefile
override dir := $(dir $(lastword $(MAKEFILE_LIST)))
$(dir)test: obj.o
clean:: ; $(RM) $(dir)test $(dir)test.d
-include $(dir)test.d
This should allow for a certain amount of modularity, although the asymmetry in the makefiles betrays the fact that your idea of having a separate obj directory while at the same time wanting to have the test executables in their own directory is perhaps not the best way to organize things. Personally I use a more configure style of makefile that recreates the project tree in the current working directory which helps separate the source from the build.

Makefile - Dependency generation

I am trying to create a makefile that automatically compiles and links my .cpp files into an executable via .o files. What I can't get working is automated (or even manual) dependency generation. When i uncomment the below commented code, nothing is recompiled when i run make build. All i get is make: Nothing to be done for 'build'., even if x.h (or any .h file) has changed. I've been trying to learn from this question: Makefile, header dependencies, dmckee's answer, especially. Why isn't this makefile working?
Clarification: I can compile everything, but when I modify any header file, the .cpp files that depend on it aren't updated. So, if I for instance compile my entire source, then I change a #define in the header file, and then run make build, and I get Nothing to be done for 'build'. (when I have uncommented either commented chunks of the below code).
CC=gcc
CFLAGS=-O2 -Wall
LDFLAGS=-lSDL -lstdc++
SOURCES=$(wildcard *.cpp)
OBJECTS=$(patsubst %.cpp, obj/%.o,$(SOURCES))
TARGET=bin/test.bin
# Nothing happens when i uncomment the following. (automated attempt)
#depend: .depend
#
#.depend: $(SOURCES)
# rm -f ./.depend
# $(CC) $(CFLAGS) -MM $^ >> ./.depend;
#
#include .depend
# And nothing happens when i uncomment the following. x.cpp and x.h are files in my project. (manual attempt)
#x.o: x.cpp x.h
clean:
rm -f $(TARGET)
rm -f $(OBJECTS)
run: build
./$(TARGET)
build: $(TARGET)
$(TARGET): $(OBJECTS)
#mkdir -p $(#D)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
obj/%.o: %.cpp
#mkdir -p $(#D)
$(CC) -c $(CFLAGS) $< -o $#
This may take a few iterations.
1) I can't reproduce your results from your first approach (and you must be clearer than "nothing happens"-- does Make actually produce no output?). This:
depend: .depend
.depend: $(SOURCES)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^ >> ./.depend;
include .depend
seems to work as intended. I suggest you try $(info sources: $(SOURCES)) to verify that that variable contains the filenames you think it does.
2) I can't reproduce your results from your second approach (and you must be clearer than "nothing happens"-- does Make actually produce no output?). You tried x.o: x.cpp x.h when the first approach was commented out, is that right?
EDIT:
Let's concentrate on x.o. Does it contain #include "x.h"? When you uncomment the first section and make x.o, does Make produce (or modify) .depend? Is there a line in .depend that pertains to x.o, and if so what is it? If you then modify x.h and then make x.o, what does Make do?
You resolve only one kind of dependency with $(CC) -MM. There are various others like changed command options (e.g. -DDO_SOMETHING_ELSE), or a different set of symbols exported by a library. Traditional makes offer you lots of fun debugging inconsistent executables!
That's where makepp comes in. Dependencies are detected automatically. It not only rebuilds targets whenever any kind of dependency warrants this. It even chains everything together and builds what is needed from bottom up. I.e. if your linker has a -lmystuff option and you have a rule to build libmystuff.so or .a, that's all it takes, it will get built in time. Likewise you can include files that don't even exist yet — impossible with your solution.