#NEWPROJECT requires refactor.sh main.c # Taken from https://stackoverflow.com/questions/30573481/how-to-write-a-makefile-with-separate-source-and-header-directories SRCDIR := sources MAINDIR := $(SRCDIR)/main INCDIR := include OBJDIR := objects MAINOD := $(OBJDIR)/main BINDIR := build INSTDIR := /usr/local/bin REFACTOR := refactor.h HEADERS := $(wildcard $(INCDIR)/*.h) MAINS := $(wildcard $(MAINDIR)/*.c) MAINOBJS := $(patsubst $(MAINDIR)/%.c, $(MAINOD)/%.o, $(MAINS)) TARGETS := $(patsubst $(MAINDIR)/%.c, $(BINDIR)/%, $(MAINS)) SOURCES := $(wildcard $(SRCDIR)/*.c) OBJECTS := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(SOURCES)) CPPFLAGS := -Iinclude -MMD -MP CFLAGS := -Wall -Werror -Wpedantic LDFLAGS := #-Lmath or whatever LDLIBS := #-lm or whatever .PHONY: all clean all: $(TARGETS) @echo $(TARGETS) refactor: ./refactor.sh $(TARGETS): $(OBJECTS) $(MAINOBJS) | $(BINDIR) $(OBJDIR) $(MAINOD) $(CC) $(LDFLAGS) $(OBJECTS) $(patsubst $(BINDIR)/%, $(MAINOD)/%.o, $@) $(LDLIBS) -o $@ $(BINDIR) $(OBJDIR) $(MAINOD): mkdir --parents $@ $(OBJDIR)/%.o: $(SRCDIR)/%.c $(HEADERS) | $(OBJDIR) $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ $(MAINOD)/%.o: $(MAINDIR)/%.c $(HEADERS) | $(MAINOD) $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ # $| evaluates to the order-only prerequisites, in this case: $(TARGETS) # The $(foreach ...) function will evaluate to a semicolon-separated list of 'cp $instdir' # Putting this $(foreach ...) into the recipe means that its result # cp a /usr/local/bin; cp b /usr/local/bin; # will be run as a shell command. # # Shamelessly derived from: # https://stackoverflow.com/questions/7918511/make-execute-an-action-for-each-prerequisite install: | $(TARGETS) @echo "Installing executables to $(INSTDIR)" @$(foreach target, $|, cp -v $(target) $(INSTDIR);) uninstall: | $(TARGETS) @echo "Removing executables from $(INSTDIR)" $(foreach target, $(notdir $|), rm -v $(INSTDIR)/$(target);) clean: $(RM) -rv $(BINDIR) $(OBJDIR) # Honestly still not sure what this directive does. # It's an include directive, which processes all .d files that correspond to members of $(OBJ), # with the hyphen in front meaning that it suppresses/ignores errors (from nonexistent .d files) # Seems to be included under the stipulation that GNU make will auto-generate .d files based on # a given file's #include directives? # https://stackoverflow.com/questions/19114410/what-is-d-file-after-building-with-make -include $(OBJ:.o=.d)