[dependencies] Makefile, header dependencies

Most answers are surprisingly complicated or erroneous. However simple and robust examples have been posted elsewhere [codereview]. Admittedly the options provided by the gnu preprocessor are a bit confusing. However, the removal of all directories from the build target with -MM is documented and not a bug [gpp]:

By default CPP takes the name of the main input file, deletes any directory components and any file suffix such as ā€˜.cā€™, and appends the platform's usual object suffix.

The (somewhat newer) -MMD option is probably what you want. For completeness an example of a makefile that supports multiple src dirs and build dirs with some comments. For a simple version without build dirs see [codereview].

CXX = clang++
CXX_FLAGS = -Wfatal-errors -Wall -Wextra -Wpedantic -Wconversion -Wshadow

# Final binary
BIN = mybin
# Put all auto generated stuff to this build dir.
BUILD_DIR = ./build

# List of all .cpp source files.
CPP = main.cpp $(wildcard dir1/*.cpp) $(wildcard dir2/*.cpp)

# All .o files go to build dir.
OBJ = $(CPP:%.cpp=$(BUILD_DIR)/%.o)
# Gcc/Clang will create these .d files containing dependencies.
DEP = $(OBJ:%.o=%.d)

# Default target named after the binary.
$(BIN) : $(BUILD_DIR)/$(BIN)

# Actual target of the binary - depends on all .o files.
$(BUILD_DIR)/$(BIN) : $(OBJ)
    # Create build directories - same structure as sources.
    mkdir -p $(@D)
    # Just link all the object files.
    $(CXX) $(CXX_FLAGS) $^ -o $@

# Include all .d files
-include $(DEP)

# Build target for every single object file.
# The potential dependency on header files is covered
# by calling `-include $(DEP)`.
$(BUILD_DIR)/%.o : %.cpp
    mkdir -p $(@D)
    # The -MMD flags additionaly creates a .d file with
    # the same name as the .o file.
    $(CXX) $(CXX_FLAGS) -MMD -c $< -o $@

.PHONY : clean
clean :
    # This should remove all generated files.
    -rm $(BUILD_DIR)/$(BIN) $(OBJ) $(DEP)

This method works because if there are multiple dependency lines for a single target, the dependencies are simply joined, e.g.:

a.o: a.h
a.o: a.c
    ./cmd

is equivalent to:

a.o: a.c a.h
    ./cmd

as mentioned at: Makefile multiple dependency lines for a single target?

Examples related to dependencies

Upgrading React version and it's dependencies by reading package.json How do I deal with installing peer dependencies in Angular CLI? RHEL 6 - how to install 'GLIBC_2.14' or 'GLIBC_2.15'? Automatically create requirements.txt node.js TypeError: path must be absolute or specify root to res.sendFile [failed to parse JSON] MavenError: Failed to execute goal on project: Could not resolve dependencies In Maven Multimodule project npm install private github repositories by dependency in package.json Find unused npm packages in package.json Failed to load c++ bson extension Maven dependency update on commandline

Examples related to makefile

MINGW64 "make build" error: "bash: make: command not found" "No rule to make target 'install'"... But Makefile exists How to overcome "'aclocal-1.15' is missing on your system" warning? How to install and use "make" in Windows? How to get a shell environment variable in a makefile? Using local makefile for CLion instead of CMake Difference between using Makefile and CMake to compile the code How to set child process' environment variable in Makefile Windows 7 - 'make' is not recognized as an internal or external command, operable program or batch file Debugging the error "gcc: error: x86_64-linux-gnu-gcc: No such file or directory"

Examples related to header-files

How to make g++ search for header files in a specific directory? Where to find the complete definition of off_t type? Where is the <conio.h> header file on Linux? Why can't I find <conio.h>? .c vs .cc vs. .cpp vs .hpp vs .h vs .cxx How do I include the string header? error C2039: 'string' : is not a member of 'std', header file problem How can I create C header files C++, how to declare a struct in a header file Makefile, header dependencies How to fix "unable to open stdio.h in Turbo C" error?