2023-03-14 18:17:58 +00:00
|
|
|
#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
|
|
|
|
|
2023-03-14 20:47:03 +00:00
|
|
|
INSTDIR := /usr/local/bin
|
|
|
|
|
2023-03-14 18:17:58 +00:00
|
|
|
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 $@
|
|
|
|
|
2023-03-14 20:47:03 +00:00
|
|
|
# $| evaluates to the order-only prerequisites, in this case: $(TARGETS)
|
|
|
|
# The $(foreach ...) function will evaluate to a semicolon-separated list of 'cp <target> $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);)
|
|
|
|
|
2023-03-14 18:17:58 +00:00
|
|
|
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)
|