1#
2# Trigger Rally GNUmakefile for Linux users
3#
4
5# standard GNU and custom variables
6DISTNAME        := trigger-rally
7DISTVER         := 0.6.6.1
8DISTDIR         := $(DISTNAME)-$(DISTVER)
9DISTARC         := $(DISTDIR).tar.gz
10TR_EXENAME      := trigger-rally
11TR_CFGNAME      := trigger-rally.config.defs
12TR_BINDIR       := ../bin
13TR_DATADIR      := ../data
14TR_DOCDIR       := ../doc
15TR_EXEFILE      := $(TR_BINDIR)/$(TR_EXENAME)
16TR_CFGFILE      := $(TR_BINDIR)/$(TR_CFGNAME)
17TR_DATAFILES    := $(shell cd $(TR_DATADIR); find * -type f)
18TR_DOCFILES     := $(shell cd $(TR_DOCDIR); find * -type f)
19PROJDIRS        := PEngine PSim Trigger
20SRCFILES        := $(sort $(shell find $(PROJDIRS) -type f -name "*.cpp"))
21OBJFILES        := $(patsubst %.cpp, %.o, $(SRCFILES))
22DEPFILES        := $(patsubst %.cpp, %.d, $(SRCFILES))
23WARNINGS        ?= -Wall -Wextra -pedantic
24OPTIMS          ?= -Ofast
25DMACROS         := -DNDEBUG -DUNIX -DPACKAGE_VERSION=\"$(DISTVER)\"
26INCDIRS         := -I'./include'
27CXXFLAGS        += -std=c++11 $(WARNINGS) $(OPTIMS)
28CPPFLAGS        += $(DMACROS) $(INCDIRS) `sdl2-config --cflags`
29EXTRA_LIBS      := -lSDL2main -lGL -lGLU -lGLEW -lSDL2 -lSDL2_image -lphysfs -lopenal -lalut -lpthread -ltinyxml2
30LDFLAGS         += `sdl2-config --libs` $(EXTRA_LIBS)
31INSTALL_PROGRAM := install --mode=0755
32INSTALL_DATA    := install --mode=0644
33
34# standard GNU directories
35prefix          ?= /usr/local
36exec_prefix     ?= $(prefix)
37bindir          := $(exec_prefix)/games
38datarootdir     := $(prefix)/share
39datadir         := $(datarootdir)/games
40docdir          := $(datarootdir)/doc/$(DISTNAME)
41
42#
43# phony targets, whose names aren't names of resulting files
44#
45# NOTE that several "standard" targets are missing; here
46# `all` is `build` because I always felt "all" was a bad name,
47# while the others I had either no time or no incentive to implement
48#
49.PHONY: build printvars install uninstall installdirs dist clean
50
51# builds the executable
52build: printvars $(TR_EXEFILE)
53
54#
55# prints the variables that the user can change;
56# if VAR is in the list, then the user can change it by running:
57#
58#   VAR="new value" make [target]
59#
60# examples:
61#   OPTIMS="-O0 -g" make
62#   prefix="/usr" exec_prefix="/usr" make install
63#
64printvars:
65	@printf "\ncurrent values of user-set variables:\n"
66	@printf "\tDESTDIR      ?= %s\n" "$(DESTDIR)"
67	@printf "\tprefix       ?= %s\n" "$(prefix)"
68	@printf "\texec_prefix  ?= %s\n" "$(exec_prefix)"
69	@printf "\tOPTIMS       ?= %s\n" "$(OPTIMS)"
70	@printf "\tWARNINGS     ?= %s\n" "$(WARNINGS)"
71	@printf "\n"
72	@printf "resulting values of build variables:\n"
73	@printf "\tCXXFLAGS     += %s\n" "$(CXXFLAGS)"
74	@printf "\tCPPFLAGS     += %s\n" "$(CPPFLAGS)"
75	@printf "\tLDFLAGS      += %s\n" "$(LDFLAGS)"
76	@printf "\n"
77
78# installs the software (executable, data files and documentation)
79install: installdirs build
80	@printf "\ninstall [%s] begin\n" "$(DISTNAME)"
81	@$(INSTALL_PROGRAM) "$(TR_EXEFILE)" "$(DESTDIR)$(bindir)"
82	@$(INSTALL_DATA) "$(TR_CFGFILE)" "$(DESTDIR)$(bindir)"
83	@for file in $(TR_DATAFILES); do \
84		$(INSTALL_DATA) -D "$(TR_DATADIR)/$$file" "$(DESTDIR)$(datadir)/$(DISTNAME)/$$file"; \
85		done
86	@for file in $(TR_DOCFILES); do \
87		$(INSTALL_DATA) -D "$(TR_DOCDIR)/$$file" "$(DESTDIR)$(docdir)/$$file"; \
88		done
89	@printf "install [%s] end\n\n" "$(DISTNAME)"
90
91# deletes the software (executable, data files and documentation)
92uninstall:
93	-@$(RM) --verbose "$(DESTDIR)$(bindir)/$(TR_EXENAME)"
94	-@$(RM) --verbose "$(DESTDIR)$(bindir)/$(TR_CFGNAME)"
95	-@$(RM) --verbose --recursive "$(DESTDIR)$(datadir)/$(DISTNAME)"
96	-@$(RM) --verbose --recursive "$(DESTDIR)$(docdir)"
97
98# creates the installation directories if they do not exist
99installdirs:
100	@printf "\nmkdir\t[installation directories]\n"
101	@mkdir --mode=0755 --parents \
102		"$(DESTDIR)$(bindir)" \
103		"$(DESTDIR)$(datadir)/$(DISTNAME)" \
104		"$(DESTDIR)$(docdir)"
105
106#
107# creates a zipped tarball for redistribution
108#
109# NOTE that this fails if the directory we're in isn't named $(DISTDIR) however
110# this is by design: it's meant to enforce directory naming consistency and
111# awareness of the $(DISTVER) variable, which you must update for each release!
112#
113dist: clean
114	@printf "\ntar -> \"../../%s\"\n" "$(DISTARC)"
115	@cd ../..; \
116		tar --owner=root --group=root --create --file="$(DISTARC)" --auto-compress "$(DISTDIR)"
117	@printf "md5sum -> \"../../%s.md5\"\n\n" "$(DISTARC)"
118	@cd ../..; \
119		md5sum "$(DISTARC)" > "$(DISTARC).md5"
120
121# links the object files into the executable, which it then strips
122$(TR_EXEFILE): $(OBJFILES)
123	@printf "%s" $(CXX)
124	@for file in $(OBJFILES); do \
125		printf "\t%s\n" $$file; \
126		done
127	@printf "\t-> %s\n" $@
128	@$(CXX) -o $@ $(OBJFILES) $(LDFLAGS)
129	@printf "strip\t%s\n" $@
130	@strip $@
131
132#
133# removes object files, dependency files, executable and
134# backup files (such as "func.cpp~")
135#
136clean:
137	-@$(RM) --verbose \
138		$(OBJFILES) \
139		$(DEPFILES) \
140		$(TR_EXEFILE) \
141		$(shell find -type f -name "*~")
142
143#
144# includes dependency files; these files are needed to speed up
145# the build process by excluding the compilation of object files
146# which are already up-to-date
147#
148-include $(DEPFILES)
149
150#
151# compiles source files to object files
152#
153# GNUmakefile was added as a dependency in order to trigger a rebuild
154# if this makefile is edited
155#
156%.o: %.cpp GNUmakefile
157	@printf "%s\t%s -> %s\n" $(CXX) $< $@
158	@$(CXX) $(CXXFLAGS) $(CPPFLAGS) -MMD -MP -c $< -o $@
159