Make: a software build tool by Stuart Feldman in 1976 at Bell Labs (to unify and abstract common build scripts). It uses a single Makefile for your project instructions (but may load from other Makefiles). Originally it was written by & for the C language.
Refactoring or fixing-up a large code base often involves both renaming and splitting into new files. Inside the Makefile, this can become verbose & wordy as files are explicitly defined each line.
However, Make supports wildcards & modular compiling. This means you can just break your Makefile up into paths with wildcards ('*' or '%') and should apply the rules to both the headers, code, and outputted objects. You should even be able to apply this to multiple subpaths so multitudes of files will be auto-gathered for you.
With all these benefits, one wonders why this is not a common way that Makefiles are set up. In fact it is difficult to find information online. So very thin is the information, I could even find the answer after I detailed a question with on Stackoverflow.com.
Don't worry though, through trial and error (and perhaps using Stackoverflow to rubberduck or bounce ideas off) I did reach the solution.
Let's say we have 2 apps to build. App #1 is a network host (or server) that runs by Command Line Interface in a terminal. App #2 is a user (or client) that can also host or run a server, but has additional features like a Graphic User Interface with windows & buttons.
Naturally, we want to share nearly all of the code from the host and place it inside the user.
HOST_OBJECTS = \
$(HOST_BUILDPATH)/hostFile0000.o \
$(HOST_BUILDPATH)/hostFile0001.o \
$(HOST_BUILDPATH)/hostFile0002.o \
$(HOST_BUILDPATH)/hostFile0003.o \
$(HOST_BUILDPATH)/hostFile0004.o \
$(HOST_BUILDPATH)/hostFile0005.o \
$(HOST_BUILDPATH)/hostFile0006.o \
...
# On & on seemingly forever...
USER_OBJECTS = \
$(USER_BUILDPATH)/hostFile0000.o \
$(USER_BUILDPATH)/hostFile0001.o \
$(USER_BUILDPATH)/hostFile0002.o \
$(USER_BUILDPATH)/hostFile0003.o \
$(USER_BUILDPATH)/hostFile0004.o \
$(USER_BUILDPATH)/hostFile0005.o \
$(USER_BUILDPATH)/hostFile0006.o \
# On & on seemingly forever + still going for the user!
$(USER_BUILDPATH)/userFile0000.o \
$(USER_BUILDPATH)/userFile0001.o \
$(USER_BUILDPATH)/userFile0002.o \
$(USER_BUILDPATH)/userFile0003.o \
$(USER_BUILDPATH)/userFile0004.o \
$(USER_BUILDPATH)/userFile0005.o \
$(USER_BUILDPATH)/userFile0006.o \
########################################################################
# Rules:
########################################################################
$(HOST_BUILDPATH)/%.o: $(PATH0000)/%.s
$(DO_HOST_CC)
$(HOST_BUILDPATH)/%.o: $(PATH0002)/%.s
$(DO_HOST_CC)
$(HOST_BUILDPATH)/%.o: $(PATH0002)/%.s
$(DO_HOST_CC)
$(HOST_BUILDPATH)/%.o: $(PATH0003)/%.s
$(DO_HOST_CC)
# On & on seemingly forever + still going for the user rules!
$(USER_BUILDPATH)/%.o: $(PATH0000)/%.s
$(DO_USER_CC)
$(USER_BUILDPATH)/%.o: $(PATH0001)/%.s
$(DO_USER_CC)
$(USER_BUILDPATH)/%.o: $(PATH0002)/%.s
$(DO_USER_CC)
$(USER_BUILDPATH)/%.o: $(PATH0003)/%.s
$(DO_USER_CC)
# On & on seemingly forever...
CORE_CODE := $(wildcard $(PATH0000)/*/*/*.c) \
$(wildcard $(PATH0001)/*/*/*.c) \
$(wildcard $(PATH0002)/*/*.c) \
$(wildcard $(PATH0003)/*/*/*/*.c) \
$(wildcard $(PATH0004)/*/*/*.c) \
$(wildcard $(HOST_PATH0000)/*/*.c)
HOST_CODE := $(wildcard $(HOST_PATH0001)/*/*.c) \
$(CORE_CODE)
HOST_OBJECTS = $(patsubst $(MAIN_PATH)/%.c, $(HOST_BUILDPATH)/%.o, $(HOST_CODE))
# Or to append:
#HOST_OBJECTS += $(patsubst $(MAIN_PATH)/%.c, $(HOST_BUILDPATH)/%.o, $(HOST_CODE))
USER_CODE := $(wildcard $(USER_PATH0000)/*/*.c) \
$(wildcard $(USER_PATH0001)/*/*.c) \
$(wildcard $(USER_PATH0002)/*.c) \
$(wildcard $(USER_PATH0003)/*/*.c) \
$(wildcard $(USER_PATH0004)/*/*.c) \
$(wildcard $(USER_PATH0005)/*/*/*.c) \
$(CORE_CODE)
USER_OBJECTS = $(patsubst $(MAIN_PATH)/%.c, $(USER_BUILDPATH)/%.o, $(USER_CODE))
# Or to append:
#USER_OBJECTS += $(patsubst $(MAIN_PATH)/%.c, $(USER_BUILDPATH)/%.o, $(USER_CODE))
########################################################################
# Rules:
########################################################################
$(HOST_BUILDPATH)/%.o: $(MAIN_PATH)/%.c
$(DO_HOST_CC)
$(USER_BUILDPATH)/%.o: $(MAIN_PATH)/%.c
$(DO_USER_CC)
# !!! DONE !!!
Feel free to read my Stackoverflow Q&A ↗.
Like this post? Read more from the ^DevOps topic.