I'm learning how to use makefiles for complex projects. I got it working but I don't know how to add pre-requisites under certain conditions without specifying them one by one. In this particular case I'm trying to add header files as requisites of objects goals so if any header file is modified, that particular cpp has to be rebuild again and linked with the rest.
After looking for clues on the manual I tried to use some shell scripting but I guess the substitution I'm doing is expanded after checking for dependencies so it does nothing. I have tried to use the $(if ) expression in the requisites too but I ended up moving it just in case it was some kind of conflict with using it inside a static pattern rule.
Some additional notes:
- I'm learning the tool so I would prefer to avoid CMake or any kind of utility that builds the makefile for me (I would gladly use the facilities after being sure I can replicate at some degree what they do by myself)
- I also prefer to avoid solutions tied to the language I'm using in the example as it should work with any compiler and other kind of files and goals/requisites.
I have the following files in my working directory:
.
├── Makefile
└── src
├── main.cpp
└── somemodule
├── module.cpp
└── module.h
My makefile has to generate the following structure:
.
├── app
├── Makefile
├── obj
│ ├── main.o
│ └── somemodule
│ └── module.o
└── src
├── main.cpp
└── somemodule
├── module.cpp
└── module.h
My current makefile:
APP := app
SRCDIR := src
OBJDIR := obj
OBJS := obj/main.o obj/somemodule/module.o
SRCS := $(OBJS:.o=.cpp)
$(APP): $(OBJDIR) $(OBJS)
g++ $(OBJS) -o $(APP)
$(OBJDIR):
mkdir -p $(patsubst $(SRCDIR)%,$(OBJDIR)%,$(shell tree src -fid --noreport))
$(OBJS): HEADERS += $(if $(shell if [ -e $(@:obj%.o=src%.h) ]; then echo "y"; fi), $(@:obj%.o=src%.h))
$(OBJS): $(OBJDIR)%.o: $(SRCDIR)%.cpp $(HEADERS)
g++ -c $(patsubst $(OBJDIR)%.o,$(SRCDIR)%.cpp,$@) -o $@
.PHONY: clean
clean:
rm -rf $(OBJDIR)
rm $(APP)