1#
2# This file is part of RGBDS.
3#
4# Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
5#
6# SPDX-License-Identifier: MIT
7#
8
9.SUFFIXES:
10.SUFFIXES: .h .y .c .o
11
12# User-defined variables
13
14Q		:= @
15PREFIX		:= /usr/local
16bindir		:= ${PREFIX}/bin
17mandir		:= ${PREFIX}/share/man
18STRIP		:= -s
19BINMODE		:= 755
20MANMODE		:= 644
21CHECKPATCH	:= ../linux/scripts/checkpatch.pl
22
23# Other variables
24
25PKG_CONFIG	:= pkg-config
26PNGCFLAGS	:= `${PKG_CONFIG} --cflags libpng`
27PNGLDFLAGS	:= `${PKG_CONFIG} --libs-only-L libpng`
28PNGLDLIBS	:= `${PKG_CONFIG} --libs-only-l libpng`
29
30# Note: if this comes up empty, `version.c` will automatically fall back to last release number
31VERSION_STRING	:= `git describe --tags --dirty --always 2>/dev/null`
32
33WARNFLAGS	:= -Wall
34
35# Overridable CFLAGS
36CFLAGS		?= -O3 -flto -DNDEBUG
37# Non-overridable CFLAGS
38# _ISOC11_SOURCE is required on certain platforms to get C11 on top of the C99-based POSIX 2008
39REALCFLAGS	:= ${CFLAGS} ${WARNFLAGS} -std=gnu11 -I include \
40		   -D_POSIX_C_SOURCE=200809L -D_ISOC11_SOURCE
41# Overridable LDFLAGS
42LDFLAGS		?=
43# Non-overridable LDFLAGS
44REALLDFLAGS	:= ${LDFLAGS} ${WARNFLAGS} \
45		   -DBUILD_VERSION_STRING=\"${VERSION_STRING}\"
46
47YFLAGS		?= -Wall
48
49BISON		:= bison
50RM		:= rm -rf
51
52# Used for checking pull requests
53BASE_REF	:= origin/master
54
55# Rules to build the RGBDS binaries
56
57all: rgbasm rgblink rgbfix rgbgfx
58
59rgbasm_obj := \
60	src/asm/charmap.o \
61	src/asm/fixpoint.o \
62	src/asm/format.o \
63	src/asm/fstack.o \
64	src/asm/lexer.o \
65	src/asm/macro.o \
66	src/asm/main.o \
67	src/asm/opt.o \
68	src/asm/output.o \
69	src/asm/parser.o \
70	src/asm/rpn.o \
71	src/asm/section.o \
72	src/asm/symbol.o \
73	src/asm/util.o \
74	src/asm/warning.o \
75	src/extern/getopt.o \
76	src/extern/utf8decoder.o \
77	src/error.o \
78	src/hashmap.o \
79	src/linkdefs.o \
80	src/opmath.o
81
82src/asm/lexer.o src/asm/main.o: src/asm/parser.h
83
84rgblink_obj := \
85	src/link/assign.o \
86	src/link/main.o \
87	src/link/object.o \
88	src/link/output.o \
89	src/link/patch.o \
90	src/link/script.o \
91	src/link/section.o \
92	src/link/symbol.o \
93	src/extern/getopt.o \
94	src/error.o \
95	src/hashmap.o \
96	src/linkdefs.o \
97	src/opmath.o
98
99rgbfix_obj := \
100	src/fix/main.o \
101	src/extern/getopt.o \
102	src/error.o
103
104rgbgfx_obj := \
105	src/gfx/gb.o \
106	src/gfx/main.o \
107	src/gfx/makepng.o \
108	src/extern/getopt.o \
109	src/error.o
110
111rgbasm: ${rgbasm_obj}
112	$Q${CC} ${REALLDFLAGS} -o $@ ${rgbasm_obj} ${REALCFLAGS} src/version.c -lm
113
114rgblink: ${rgblink_obj}
115	$Q${CC} ${REALLDFLAGS} -o $@ ${rgblink_obj} ${REALCFLAGS} src/version.c
116
117rgbfix: ${rgbfix_obj}
118	$Q${CC} ${REALLDFLAGS} -o $@ ${rgbfix_obj} ${REALCFLAGS} src/version.c
119
120rgbgfx: ${rgbgfx_obj}
121	$Q${CC} ${REALLDFLAGS} ${PNGLDFLAGS} -o $@ ${rgbgfx_obj} ${REALCFLAGS} src/version.c ${PNGLDLIBS}
122
123# Rules to process files
124
125# We want the Bison invocation to pass through our rules, not default ones
126.y.o:
127
128# Bison-generated C files have an accompanying header
129src/asm/parser.h: src/asm/parser.c
130	$Qtouch $@
131
132src/asm/parser.c: src/asm/parser.y
133	$QDEFS=; \
134	add_flag(){ \
135		if src/check_bison_ver.sh $$1 $$2; then \
136			DEFS="-D$$3 $$DEFS"; \
137		fi \
138	}; \
139	add_flag 3 5 api.token.raw=true; \
140	add_flag 3 6 parse.error=detailed; \
141	add_flag 3 0 parse.error=verbose; \
142	add_flag 3 0 parse.lac=full; \
143	add_flag 3 0 lr.type=ielr; \
144	echo "DEFS=$$DEFS"; \
145	${BISON} $$DEFS -d ${YFLAGS} -o $@ $<
146
147.c.o:
148	$Q${CC} ${REALCFLAGS} ${PNGCFLAGS} -c -o $@ $<
149
150# Target used to remove all files generated by other Makefile targets
151
152clean:
153	$Q${RM} rgbasm rgbasm.exe
154	$Q${RM} rgblink rgblink.exe
155	$Q${RM} rgbfix rgbfix.exe
156	$Q${RM} rgbgfx rgbgfx.exe
157	$Qfind src/ -name "*.o" -exec rm {} \;
158	$Q${RM} rgbshim.sh
159	$Q${RM} src/asm/parser.c src/asm/parser.h
160
161# Target used to install the binaries and man pages.
162
163install: all
164	$Qmkdir -p ${DESTDIR}${bindir}
165	$Qinstall ${STRIP} -m ${BINMODE} rgbasm ${DESTDIR}${bindir}/rgbasm
166	$Qinstall ${STRIP} -m ${BINMODE} rgbfix ${DESTDIR}${bindir}/rgbfix
167	$Qinstall ${STRIP} -m ${BINMODE} rgblink ${DESTDIR}${bindir}/rgblink
168	$Qinstall ${STRIP} -m ${BINMODE} rgbgfx ${DESTDIR}${bindir}/rgbgfx
169	$Qmkdir -p ${DESTDIR}${mandir}/man1 ${DESTDIR}${mandir}/man5 ${DESTDIR}${mandir}/man7
170	$Qinstall -m ${MANMODE} src/rgbds.7 ${DESTDIR}${mandir}/man7/rgbds.7
171	$Qinstall -m ${MANMODE} src/gbz80.7 ${DESTDIR}${mandir}/man7/gbz80.7
172	$Qinstall -m ${MANMODE} src/rgbds.5 ${DESTDIR}${mandir}/man5/rgbds.5
173	$Qinstall -m ${MANMODE} src/asm/rgbasm.1 ${DESTDIR}${mandir}/man1/rgbasm.1
174	$Qinstall -m ${MANMODE} src/asm/rgbasm.5 ${DESTDIR}${mandir}/man5/rgbasm.5
175	$Qinstall -m ${MANMODE} src/fix/rgbfix.1 ${DESTDIR}${mandir}/man1/rgbfix.1
176	$Qinstall -m ${MANMODE} src/link/rgblink.1 ${DESTDIR}${mandir}/man1/rgblink.1
177	$Qinstall -m ${MANMODE} src/link/rgblink.5 ${DESTDIR}${mandir}/man5/rgblink.5
178	$Qinstall -m ${MANMODE} src/gfx/rgbgfx.1 ${DESTDIR}${mandir}/man1/rgbgfx.1
179
180# Target used to check the coding style of the whole codebase.
181# `extern/` is excluded, as it contains external code that should not be patched
182# to meet our coding style, so applying upstream patches is easier.
183# `.y` files aren't checked, unfortunately...
184
185checkcodebase:
186	$Qfor file in `git ls-files | grep -E '(\.c|\.h)$$' | grep -Ev '(src|include)/extern/'`; do	\
187		${CHECKPATCH} -f "$$file";					\
188	done
189
190# Target used to check the coding style of the patches from the upstream branch
191# to the HEAD. Runs checkpatch once for each commit between the current HEAD and
192# the first common commit between the HEAD and origin/master.
193# `.y` files aren't checked, unfortunately...
194
195checkpatch:
196	$QCOMMON_COMMIT=`git merge-base HEAD ${BASE_REF}`;		\
197	for commit in `git rev-list $$COMMON_COMMIT..HEAD`; do		\
198		echo "[*] Analyzing commit '$$commit'";			\
199		git format-patch --stdout "$$commit~..$$commit"		\
200			-- src include '!src/extern' '!include/extern'	\
201			| ${CHECKPATCH} - || true;			\
202	done
203
204# Target used to check for suspiciously missing changed files.
205
206checkdiff:
207	$Qcontrib/checkdiff.bash `git merge-base HEAD ${BASE_REF}`
208
209# This target is used during development in order to prevent adding new issues
210# to the source code. All warnings are treated as errors in order to block the
211# compilation and make the continous integration infrastructure return failure.
212
213develop:
214	$Qenv $(MAKE) WARNFLAGS="-Werror -Wall -Wextra -Wpedantic -Wno-type-limits \
215		-Wno-sign-compare -Wvla -Wformat -Wformat-security -Wformat-overflow=2 \
216		-Wformat-truncation=1 -Wformat-y2k -Wswitch-enum -Wunused \
217		-Wuninitialized -Wunknown-pragmas -Wstrict-overflow=4 \
218		-Wstringop-overflow=4 -Walloc-zero -Wduplicated-cond \
219		-Wfloat-equal -Wshadow -Wcast-qual -Wcast-align -Wlogical-op \
220		-Wnested-externs -Wno-aggressive-loop-optimizations -Winline \
221		-Wundef -Wstrict-prototypes -Wold-style-definition \
222		-Wno-unknown-warning-option -Wno-tautological-constant-out-of-range-compare \
223		-fsanitize=shift -fsanitize=integer-divide-by-zero \
224		-fsanitize=unreachable -fsanitize=vla-bound \
225		-fsanitize=signed-integer-overflow -fsanitize=bounds \
226		-fsanitize=object-size -fsanitize=bool -fsanitize=enum \
227		-fsanitize=alignment -fsanitize=null -fsanitize=address" \
228		CFLAGS="-ggdb3 -O0"
229
230# Targets for the project maintainer to easily create Windows exes.
231# This is not for Windows users!
232# If you're building on Windows with Cygwin or Mingw, just follow the Unix
233# install instructions instead.
234
235mingw32:
236	$Qmake CC=i686-w64-mingw32-gcc BISON=bison \
237		PKG_CONFIG=i686-w64-mingw32-pkg-config -j
238
239mingw64:
240	$Qmake CC=x86_64-w64-mingw32-gcc BISON=bison \
241		PKG_CONFIG=x86_64-w64-mingw32-pkg-config -j
242
243wine-shim:
244	$Qecho '#!/bin/bash' > rgbshim.sh
245	$Qecho 'WINEDEBUG=-all wine $$0.exe "$${@:1}"' >> rgbshim.sh
246	$Qchmod +x rgbshim.sh
247	$Qln -s rgbshim.sh rgbasm
248	$Qln -s rgbshim.sh rgblink
249	$Qln -s rgbshim.sh rgbfix
250	$Qln -s rgbshim.sh rgbgfx
251
252# Target for the project maintainer to produce distributable release tarballs
253# of the source code.
254
255dist:
256	$Qgit ls-files | sed s~^~$${PWD##*/}/~ \
257	  | tar -czf rgbds-`git describe --tags | cut -c 2-`.tar.gz -C .. -T -
258