1# vim:set ts=8 sw=4 noexpandtab:
2#
3# Dungeon Crawl Stone Soup
4# GNU Makefile
5#
6# largely written by Steven Noonan <steven@uplinklabs.net>
7#    (if something breaks, blame him.)
8#
9
10# Typical targets:
11#    make
12#    make debug
13#    make debug-lite    # Like "make debug", but without all the spew.
14#    make install
15#    make debug install
16#    -- note, unlike most programs, you need to specify build type when
17#       installing even if you just built it.
18# Typical parameters:
19#    TILES         -- set to anything to enable tiles build
20#
21#    SOUND         -- set to anything to enable sound; note that you will need to
22#                     uncomment some lines in sound.h if not building tiles
23#
24#    CROSSHOST     -- target system, eg, i386-pc-msdosdjgpp or i586-mingw32msvc
25#
26#    prefix        -- installation base.  Specify eg. /usr/local on Unix systems.
27#    DESTDIR       -- installation staging area (the dir you intend to pack)
28#    DATADIR       -- place to hold immutable files.  Can be either relative to
29#                     "prefix" or absolute.
30#    SAVEDIR       -- place to hold writeable data (saves, database, morgue
31#                     dumps).  Can be relative to "prefix", absolute or placed
32#                     in the user's home dir (~).  Remember to protect the ~
33#                     from your shell!
34#                     Warning, as of 0.8, directories shared between
35#                     multiple system users are no longer supported.
36#    SHAREDDIR     -- place to hold writeable data common to multiple
37#                     versions of Crawl (scores, the logfile, ghosts).  Will
38#                     be placed inside the SAVEDIR if not specified.
39#       Layout examples:
40#         prefix=~/crawl DATADIR=data/ SAVEDIR=saves/
41#                  -- everything under ~/crawl
42#         prefix=/usr/local
43#                  -- system-wide installation
44#
45#    V             -- set to anything to enable verbose build
46#
47#    USE_ICC       -- set to use Intel's compiler
48#    LTO           -- set for better optimization but slower compilation,
49#                     requires gcc4.6+
50#    NO_TRY_LLD    -- if set don't try to detect a working lld linker
51#    NO_TRY_GOLD   -- if set don't try to detect a working gold linker
52#    NOASSERTS     -- set to disable assertion checks (ignored in debug mode)
53#    NOWIZARD      -- set to disable wizard mode.  Use if you have untrusted
54#                     remote players without DGL.
55#
56#    PROPORTIONAL_FONT -- set to a .ttf file you want to use for a proportional
57#                         font; if not set, a copy of Bitstream Vera Sans
58#                         shipped with Crawl will be used
59#    MONOSPACED_FONT   -- monospaced font; Bitstream Vera Mono Sans
60#    COPY_FONTS    -- force installing fonts
61#
62#    WEBTILES      -- set to anything to compile for Webtiles
63#    WEBDIR        -- place to hold the Webtiles client data. Can be either
64#                     relative to prefix or absolute.
65#
66#    ANDROID       -- perform an Android build (see docs/develop/android.txt)
67#    TOUCH_UI      -- enable UI behaviour more compatible with touch-screens
68#
69# For various mac build tricks oriented at release builds see the various
70# mac-app-* targets as well as the crawl-universal target. (For normal dev
71# circumstances, none of this is needed.)
72#
73# There are a number of #defines that may be useful for downstream packaging
74# or custom server setups. See AppHdr.h for more details. Of note:
75#
76#    VERSIONED_CACHE_DIR -- use a cache dir per version, rather than a shared
77#                           cache dir across versions. This may be useful for
78#                           reproducible builds, since the shared cache
79#                           directory makes use of mtimes.
80#
81# To set defines from the command line while building, use EXTERNAL_DEFINES.
82# E.g.: make EXTERNAL_DEFINES="-DVERSIONED_CACHE_DIR"
83#
84# Requirements:
85#    For tile builds, you need pkg-config.
86#    You also need libpng, sdl2, sdl2-image, sdl2-mixer and libfreetype -- if
87#    you got your source from git, you can 'git submodule update' to fetch
88#    them; you can also ask for a package with convenience libraries instead --
89#    we'll try to provide them somewhere in the near future.
90
91# allow overriding GAME at the command line, intended for downstream packaging
92# processes. Not supported for MSYS2/cygwin builds, and will be overridden for
93# mac universal builds. This does not count as a change in build flags.
94ifndef GAME
95	GAME = crawl
96endif
97
98# Disable GNU Make implicit rules and variables. Leaving them enabled will slow
99# down MinGW and Cygwin builds by a very VERY noticeable degree. Besides, we have
100# _explicit_ rules defined for everything. So we don't need them.
101MAKEFLAGS += -rR # This only works for recursive makes, i.e. contribs ...
102.SUFFIXES:       # ... so zap the suffix list to neutralize most predifined rules, too
103
104.PHONY: all test install clean clean-contrib clean-rltiles clean-android \
105        clean-catch2 clean-plug-and-play-tests \
106		clean-coverage clean-coverage-full \
107        distclean debug debug-lite profile package-source source \
108        build-windows package-windows-installer docs greet api api-dev android FORCE \
109        monster catch2-tests plug-and-play-tests \
110        crawl-universal crawl-arm64-apple-macos11 crawl-x86_64-apple-macos10.7 clean-mac
111
112include Makefile.obj
113
114#
115# Compiler Flags
116#
117# The compiler flag variables are separated into their individual
118# purposes, making it easier to deal with the various tools involved
119# in a compile.
120#
121# These are also divided into global vs. local flags. So for instance,
122# CFOPTIMIZE affects Crawl, Lua, and SQLite, while CFOPTIMIZE_L only
123# affects Crawl.
124#
125# The variables are as follows:
126# CFOPTIMIZE(_L) - Optimization flags
127# CFWARN(_L) - Warning flags
128# CFOTHERS(_L) - Anything else
129#
130
131# Which C++ standard to support
132STDFLAG = -std=c++11
133
134CFOTHERS := $(EXTERNAL_FLAGS)
135# Build with FORCE_SSE=y to get better seed stability on 32 bit x86 builds. It
136# is not recommended to do this unless you are building with contrib lua.
137# On any 64bit  builds where the arch supports it, (at least) sse2 is implied.
138ifdef FORCE_SSE
139CFOTHERS += -mfpmath=sse -msse2
140endif
141
142CFWARN :=
143CFWARN_L := -Wall -Wformat-security -Wundef
144
145# Exceptions:
146#  -Wmissing-field-initializers: need c++14 to set default struct fields
147#  -Wimplicit-fallthrough: need c++17 for [[fallthrough]]
148#  -Wtype-limits: mostly complains about ASSERT_RANGE, and _Pragma is buggy on
149#      old g++ anyway: re-enable when we bump the minimum g++ version
150#  -Wuninitialized: added later in this makefile, conditional on NO_OPTIMIZE
151CFWARN_L += -Wextra \
152	    -Wno-missing-field-initializers \
153	    -Wno-implicit-fallthrough \
154	    -Wno-type-limits \
155	    -Wno-uninitialized \
156
157DEFINES := $(EXTERNAL_DEFINES)
158
159#
160# The GCC and GXX variables are set later.
161#
162AR = ar
163RANLIB = ranlib
164CC = $(GCC)
165CXX = $(GXX)
166RM = rm -f
167COPY = cp
168COPY_R = cp -r
169STRIP = strip -s
170SED = sed
171WINDRES = windres
172CHMOD = chmod 2>/dev/null
173CHOWN = chown 2>/dev/null
174PNGCRUSH = $(COPY)
175PNGCRUSH_LABEL = COPY
176ADVPNG = advpng -z -2
177PKGCONFIG = pkg-config
178DOXYGEN = doxygen
179DOXYGEN_SIMPLE_CONF = crawl_simple.doxy
180DOXYGEN_ALL_CONF = crawl_all.doxy
181DOXYGEN_HTML_GEN = html/
182# Prefer python3, if available
183PYTHON = python
184ifneq (, $(shell which python3 2>&1))
185	PYTHON = python3
186endif
187
188export AR
189export RANLIB
190export RM
191export CC
192export CXX
193export CFLAGS
194export STDFLAG
195export MAKEFLAGS
196export CONFIGURE_FLAGS
197export uname_S
198
199#
200# Platform Detection
201#
202uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
203uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not')
204
205HOST := $(shell sh -c 'cc -dumpmachine || echo unknown')
206ARCH := $(HOST)
207
208ifdef CROSSHOST
209	ARCH := $(CROSSHOST)
210	ifneq (,$(shell which $(ARCH)-pkg-config 2>/dev/null))
211	  PKGCONFIG = $(ARCH)-pkg-config
212	else
213	  ifneq (,$(wildcard /usr/$(ARCH)/lib/pkgconfig))
214	    PKGCONFIG = PKG_CONFIG_LIBDIR=/usr/$(ARCH)/lib/pkgconfig pkg-config
215	  else
216	    NO_PKGCONFIG = YesPlease
217	    BUILD_LUA = yes
218	    BUILD_SQLITE = yes
219	    BUILD_ZLIB = YesPlease
220	  endif
221	endif
222	NO_AUTO_OPT = YesPlease
223	CONFIGURE_FLAGS += --host=$(CROSSHOST)
224
225	# If needed, override uname_S so we get the appropriate
226	# things compiled.
227	ifneq (,$(findstring mingw,$(CROSSHOST)))
228		uname_S=MINGW32
229	endif
230
231endif
232
233msys =
234ifneq (,$(findstring MINGW,$(uname_S)))
235	msys = Yes
236endif
237ifneq (,$(findstring MSYS,$(uname_S)))
238	msys = Yes
239endif
240ifdef msys
241	GAME = crawl.exe
242	bin_prefix = .
243	WIN32 = Yes
244	NO_NCURSES = YesPlease
245	NEED_LIBW32C = YesPlease
246	BUILD_PCRE = YesPlease
247	BUILD_ZLIB = YesPlease
248	SOUND = YesPlease
249	DEFINES_L += -DWINMM_PLAY_SOUNDS -D__USE_MINGW_ANSI_STDIO
250	EXTRA_LIBS += -lwinmm
251	ifdef TILES
252		EXTRA_LIBS += -lmingw32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lversion contrib/install/$(ARCH)/lib/libSDL2main.a -mwindows
253		BUILD_FREETYPE = YesPlease
254		BUILD_SDL2 = YesPlease
255		BUILD_SDL2IMAGE = YesPlease
256		BUILD_LIBPNG = YesPlease
257		COPY_FONTS = yes
258	endif
259	ifeq ($(shell gcc -v -static -static-libstdc++ 2>&1 | grep 'unrecognized option'),)
260		EXTRA_LIBS += -static -static-libgcc -static-libstdc++
261	endif
262endif
263ifeq ($(uname_S),Darwin)
264ifdef MAC_TARGET
265	# for reasons I really cannot figure out, setting GAME later (when the
266	# other MAC_TARGET checks are done) really does not work.
267	GAME = crawl-$(MAC_TARGET)
268endif
269
270	STRIP := strip -x
271	NEED_APPKIT = YesPlease
272	LIBNCURSES_IS_UNICODE = Yes
273	ifdef TILES
274		EXTRA_LIBS += -framework AppKit -framework AudioUnit -framework CoreAudio -framework ForceFeedback -framework Carbon -framework IOKit -framework OpenGL -framework AudioToolbox -framework CoreVideo
275		COPY_FONTS = yes
276	endif
277	ifndef FORCE_PKGCONFIG
278		NO_PKGCONFIG = Yes
279		# is any of this stuff actually needed if NO_PKGCONFIG is set?
280		BUILD_SQLITE = YesPlease
281		BUILD_ZLIB = YesPlease
282		ifdef TILES
283			EXTRA_LIBS += contrib/install/$(ARCH)/lib/libSDL2main.a
284			BUILD_FREETYPE = YesPlease
285			BUILD_SDL2 = YesPlease
286			BUILD_SDL2IMAGE = YesPlease
287			ifdef SOUND
288				ifndef WIN32
289					BUILD_SDL2MIXER = YesPlease
290				endif
291			endif
292			BUILD_LIBPNG = YesPlease
293		endif
294	endif
295endif
296ifneq (,$(findstring CYGWIN,$(uname_S)))
297	GAME = crawl.exe
298	BUILD_PCRE = YesPlease
299	# newlib doesn't provide Posix functions with c++11
300	STDFLAG = -std=gnu++11
301endif
302
303ifdef BUILD_ALL
304	ifdef TILES
305		BUILD_FREETYPE = YesPlease
306		BUILD_SDL2 = YesPlease
307		BUILD_SDL2IMAGE = YesPlease
308		BUILD_LIBPNG = YesPlease
309	endif
310	ifdef WEBTILES
311		BUILD_LIBPNG = YesPlease
312	endif
313
314	BUILD_PCRE = YesPlease
315	ifdef SOUND
316		ifndef WIN32
317			BUILD_SDL2MIXER = YesPlease
318		endif
319	endif
320	BUILD_SQLITE = YesPlease
321	BUILD_LUA = YesPlease
322	BUILD_ZLIB = YesPlease
323endif
324
325# Should be the first rule, but must come after $(GAME) is set.
326all: greet check-fonts $(GAME) docs webserver
327
328LIBPCRE := contrib/install/$(ARCH)/lib/libpcre.a
329LIBSDL2 := contrib/install/$(ARCH)/lib/libSDL2.a
330LIBPNG := contrib/install/$(ARCH)/lib/libpng.a
331LIBSDL2IMAGE := contrib/install/$(ARCH)/lib/libSDL2_image.a
332LIBSDL2MIXER := contrib/install/$(ARCH)/lib/libSDL2_mixer.a
333LIBFREETYPE := contrib/install/$(ARCH)/lib/libfreetype.a
334LIBSQLITE := contrib/install/$(ARCH)/lib/libsqlite3.a
335ifdef USE_LUAJIT
336LIBLUA := contrib/install/$(ARCH)/lib/libluajit.a
337else
338LIBLUA := contrib/install/$(ARCH)/lib/liblua.a
339endif
340LIBZ := contrib/install/$(ARCH)/lib/libz.a
341
342#
343# Set up the TILES variant
344#
345ifdef TILES
346TILES_ANY = YesPlease
347OBJECTS += $(TILES_OBJECTS) $(GLTILES_OBJECTS)
348  ifdef WEBTILES
349    OBJECTS += $(error Web and local tiles are exclusive)
350  endif
351endif
352
353ifdef WEBTILES
354TILES_ANY = YesPlease
355OBJECTS += $(TILES_OBJECTS) $(WEBTILES_OBJECTS)
356ifdef NO_PKGCONFIG
357BUILD_LIBPNG = YesPlease # used by build-rltiles sub-make
358endif
359endif
360
361ifdef ANDROID
362TILES_ANY = YesPlease
363endif
364
365#
366# Check for an Apple-released compiler.
367#
368ifndef NO_APPLE_PLATFORM
369ifeq ($(uname_S),Darwin)
370ifneq ($(shell gcc -v 2>&1 | grep Apple),)
371APPLE_PLATFORM = YesPlease
372endif
373endif
374endif
375
376
377ifdef WIN32
378EXTRA_OBJECTS += icon.o
379else
380ifndef ANDROID
381EXTRA_LIBS += -pthread
382endif
383endif
384
385ifndef TILES
386ifdef NEED_LIBW32C
387OBJECTS += libw32c.o
388else
389OBJECTS += libunix.o
390endif
391endif
392
393ifdef USE_MERGE_BASE
394MERGE_BASE := $(shell git merge-base HEAD $(USE_MERGE_BASE))
395endif
396
397ifdef USE_DGAMELAUNCH
398# Permissions to set on the game executable.
399MCHMOD := 755
400
401# Permissions to set on the save directory.
402MCHMOD_SAVEDIR := 775
403MCHMOD_LOGS := 664
404
405# The user:group to install the game as.
406INSTALL_UGRP := games:games
407endif
408
409ifeq ($(patsubst %/local,%,$(patsubst %/,%,$(prefix))),/usr)
410FHS := yes
411endif
412
413ifeq (,$(bin_prefix))
414ifneq ($(patsubst %/,%,$(prefix)),/usr)
415bin_prefix    := bin
416else
417bin_prefix    := games
418endif
419endif
420
421# If you're installing Crawl for multiple users, you *must* set this to a
422# valid path before building Crawl. This is not necessary if you are building
423# Crawl for a single user.
424# If you're installing to /usr, /usr/local or /opt, we have sane defaults.
425
426# SAVEDIR := saves/
427# DATADIR := data/
428ifneq (,$(FHS))
429DATADIR       := share/crawl
430SAVEDIR       := ~/.crawl
431endif
432
433ifneq ($(patsubst /opt%,%,$(prefix)),$(prefix))
434DATADIR := data
435SAVEDIR := ~/.crawl
436endif
437
438
439INCLUDES_L += -Iutil -I.
440
441
442ifdef APPLE_PLATFORM
443
444ifdef MAC_TARGET
445	# support mac cross-compiling. As of Apr 2021 on OS X 11, some example
446	# values for this that seem to work include:
447	#   x86_64-apple-macos10.7
448	#   x86_64-apple-macos10.12
449	#   arm64-apple-macos11
450	# leave MACOSX_MIN_VERSION unset, or there will be many warnings
451	CFLAGS_ARCH := -target $(MAC_TARGET)
452	# couldn't get setting GAME here to work?
453else
454ifdef BUILD_OLD_UNIVERSAL
455	# XX can be removed?
456	# [ds] 10.4 SDK g++-4.0 + x86_64 runs into SDL compile issues.
457	CFLAGS_ARCH := -arch i386 -arch ppc -faltivec
458	CFLAGS_DEPCC_ARCH := -arch i386
459	NO_INLINE_DEPGEN := YesPlease
460else
461	CFLAGS_ARCH := -arch $(uname_M)
462	MACOSX_MIN_VERSION=10.7
463endif
464endif
465
466# only set this when no -target is passed
467ifdef MACOSX_MIN_VERSION
468	CFLAGS_ARCH += -mmacosx-version-min=$(MACOSX_MIN_VERSION)
469	CFLAGS_DEPCC_ARCH += -mmacosx-version-min=$(MACOSX_MIN_VERSION)
470endif
471CC = $(GCC) $(CFLAGS_ARCH)
472CXX = $(GXX) $(CFLAGS_ARCH) -stdlib=libc++
473DEPCC = $(GCC) $(or $(CFLAGS_DEPCC_ARCH),$(CFLAGS_ARCH))
474DEPCXX = $(GXX) $(or $(CFLAGS_DEPCC_ARCH),$(CFLAGS_ARCH)) -stdlib=libc++
475
476ifdef USE_ICC
477CC += -gcc-name=gcc-$(GCC_VER) -gxx-name=g++-$(GCC_VER)
478CXX += -gcc-name=gcc-$(GCC_VER) -gxx-name=g++-$(GCC_VER)
479endif
480
481ifndef CROSSHOST
482# Don't need a universal build of host tools, so use DEPCC.
483HOSTCC = $(DEPCC)
484HOSTCXX = $(DEPCXX)
485export HOSTCC
486export HOSTCXX
487endif
488
489endif # MacOS
490
491ifndef CROSSHOST
492
493ifneq ($(GCC_VER),)
494# We do this in a separate variable because if we
495# specify GCC_VER on the make command-line, the
496# variable is immutable, and we can't add the dash.
497GCC_VER_SUFFIX:=-$(GCC_VER)
498endif
499
500# Attempt to use a full compiler name, to make
501# distcc builds work nicely.
502LMACH := $(shell $(FORCE_CC) -dumpmachine)-
503ifeq ($(LMACH),-)
504LMACH :=
505endif
506ifeq ($(shell which $(LMACH)gcc$(GCC_VER_SUFFIX) > /dev/null 2> /dev/null && echo "Yes"),)
507LMACH :=
508endif
509
510ifneq ($(FORCE_CC),)
511GCC := $(FORCE_CC)
512HOSTCC := $(FORCE_CC)
513export HOSTCC
514else
515GCC := $(LMACH)$(GCC_VER_PREFIX)gcc$(GCC_VER_SUFFIX)
516endif
517
518ifneq ($(FORCE_CXX),)
519GXX := $(FORCE_CXX)
520HOSTCXX := $(FORCE_CXX)
521export HOSTCXX
522else
523GXX := $(LMACH)$(GCC_VER_PREFIX)g++$(GCC_VER_SUFFIX)
524endif
525
526else
527
528# Cross-compiling is a weird case.
529GCC := $(CROSSHOST)-gcc
530GXX := $(CROSSHOST)-g++
531AR := $(CROSSHOST)-ar
532RANLIB := $(CROSSHOST)-ranlib
533STRIP := $(CROSSHOST)-strip
534WINDRES := $(CROSSHOST)-windres
535
536endif
537
538ifdef USE_ICC
539# If you have a Core 2 processor, this _really_ makes things fly:
540#CFOPTIMIZE := -O2 -parallel -xT
541
542# Optionally enable the 'ipo' feature, to facilitate inlining
543# across object file bounds.
544#CFOPTIMIZE_L := -ipo
545
546# Some very good optimization flags.
547  CFOPTIMIZE := -O2 -parallel
548endif
549
550# Define this to automatically generate code optimized for your machine
551# (GCC only as of now).
552#
553# NOTE: Don't use this with a release build, since the generated code
554# won't work for all machines.
555ifdef HURRY
556NO_AUTO_OPT = YesPlease
557endif
558
559ifdef AUTO_OPT
560ifndef NO_AUTO_OPT
561CFOPTIMIZE += -march=native
562endif
563endif
564
565ifdef LTO
566  ifeq ($(shell $(GXX) -v 2>&1|grep clang),)
567    CFOPTIMIZE += -flto=jobserver -fwhole-program
568    # FIXME: this check is fragile, and should be done via a full compile test.
569    ifeq ($(shell $(GXX) -x c++ /dev/null -fno-fat-lto-objects 2>&1 | grep 'unrecognized command line option'),)
570      CFOPTIMIZE += -fno-fat-lto-objects
571    endif
572  else
573    CFOPTIMIZE += -flto
574  endif
575endif
576
577# To get stack trace symbols.
578# Note that Msys, MinGW, ICC, and Cygwin don't support -rdynamic.
579ifeq (,$(shell echo 'int main(){return 1;}'|$(GXX) -x c++ - -o /dev/null -rdynamic 2>&1))
580  LDFLAGS += -rdynamic
581endif
582
583# Okay, we have to assume we're on something else that
584# uses standard UNIX-like methods for finding libs.
585#
586# For instance, on Linux and most other UNIX-likes,
587# the app pkg-config can provide the appropriate
588# CFLAGS and LDFLAGS.
589#
590
591ifndef NO_PKGCONFIG
592ifeq ($(shell which $(PKGCONFIG) 2> /dev/null),)
593NO_PKGCONFIG = YesPlease
594endif
595endif
596
597ifdef ANDROID
598  BUILD_LUA=
599  BUILD_SQLITE=
600  BUILD_ZLIB=
601  BUILD_SDL2=
602  BUILD_FREETYPE=
603  COPY_FONTS = yes
604  NO_PKGCONFIG=Y
605  GLES=Y
606  TOUCH_UI=Y
607  TILES=Y
608  SOUND=Y
609  SAVEDIR="/sdcard/Android/data/org.develz.crawl/saves/"
610else
611
612ifndef BUILD_LUA
613  ifdef NO_PKGCONFIG
614    BUILD_LUA = yes
615  endif
616endif
617# You can override the Lua package search with "make LUA_PACKAGE=lua-5-1".
618# pkg-config is still required.
619ifndef LUA_PACKAGE
620  ifndef BUILD_LUA
621    ifneq ($(USE_LUAJIT),)
622      ifeq ($(shell $(PKGCONFIG) luajit --exists || echo no),)
623        LUA_PACKAGE = luajit
624      endif
625    else
626      ifneq ($(shell $(PKGCONFIG) lua5.1 --exists || echo no),)
627        ifneq ($(shell $(PKGCONFIG) lua-5.1 --exists || echo no),)
628          ifneq ($(shell $(PKGCONFIG) lua51 --exists || echo no),)
629            ifeq ($(shell $(PKGCONFIG) lua --exists || echo no),)
630              ifeq ($(shell $(PKGCONFIG) lua --modversion | head -c 3),5.1)
631                LUA_PACKAGE = lua
632              endif
633            endif
634          else
635            LUA_PACKAGE = lua51
636          endif
637        else
638          LUA_PACKAGE = lua-5.1
639        endif
640      else
641        LUA_PACKAGE = lua5.1
642      endif
643    endif
644  endif
645endif
646ifndef LUA_PACKAGE
647  BUILD_LUA = yes
648endif
649
650ifndef BUILD_LUA
651  ifndef LUA_PACKAGE
652    LUA_PACKAGE = lua5.1
653  endif
654  INCLUDES_L += $(shell $(PKGCONFIG) $(LUA_PACKAGE) --cflags-only-I | sed -e 's/-I/-isystem /')
655  CFLAGS_L  += $(shell $(PKGCONFIG) $(LUA_PACKAGE) --cflags-only-other)
656  LIBS += $(shell $(PKGCONFIG) $(LUA_PACKAGE) --libs)
657endif
658
659ifdef USE_LUAJIT
660DEFINES_L += -DUSE_LUAJIT
661endif
662
663ifndef BUILD_SQLITE
664  ifdef NO_PKGCONFIG
665    BUILD_SQLITE = yes
666  endif
667endif
668ifndef BUILD_SQLITE
669 ifneq ($(shell $(PKGCONFIG) sqlite3 --exists || echo no),)
670   BUILD_SQLITE = yes
671 else
672   INCLUDES_L += $(shell $(PKGCONFIG) sqlite3 --cflags-only-I | sed -e 's/-I/-isystem /')
673   CFLAGS_L += $(shell $(PKGCONFIG) sqlite3 --cflags-only-other)
674   LIBS += $(shell $(PKGCONFIG) sqlite3 --libs)
675  endif
676endif
677
678ifndef BUILD_ZLIB
679  LIBS += -lz
680else
681  LIBS += $(LIBZ)
682endif
683endif #ANDROID
684
685RLTILES = rltiles
686
687ifdef WEBTILES
688DEFINES_L += -DUSE_TILE
689DEFINES_L += -DUSE_TILE_WEB
690endif
691
692#
693# Tiles build stuff
694#
695ifdef TILES
696
697DEFINES_L += -DUSE_TILE
698DEFINES_L += -DUSE_TILE_LOCAL
699
700ifdef TOUCH_UI
701DEFINES_L += -DTOUCH_UI
702endif
703
704ifdef BUILD_SDL2
705INCLUDES_L += -isystem contrib/install/$(ARCH)/include/SDL2
706endif
707ifdef BUILD_FREETYPE
708INCLUDES_L += -isystem contrib/install/$(ARCH)/include/freetype2
709endif
710
711DEFINES_L += -DUSE_SDL -DUSE_GL -DUSE_FT
712
713ifdef GLES
714DEFINES_L += -DUSE_GLES
715endif
716
717ifndef NO_PKGCONFIG
718
719# If pkg-config is available, it's the surest way to find where
720# the contributing libraries are located.
721#
722
723ifndef BUILD_FREETYPE
724FREETYPE_INCLUDE := $(shell $(PKGCONFIG) freetype2 --cflags-only-I | sed -e 's/-I/-isystem /' )
725FREETYPE_CFLAGS  := $(shell $(PKGCONFIG) freetype2 --cflags-only-other)
726FREETYPE_LDFLAGS := $(shell $(PKGCONFIG) freetype2 --libs-only-L) $(shell $(PKGCONFIG) freetype2 --libs-only-l)
727endif
728
729ifndef BUILD_SDL2
730SDL2_INCLUDE := $(shell $(PKGCONFIG) sdl2 --cflags-only-I | sed -e 's/-I/-isystem /')
731SDL2_CFLAGS  := $(shell $(PKGCONFIG) sdl2 --cflags-only-other)
732SDL2_LDFLAGS := $(shell $(PKGCONFIG) sdl2 --libs-only-L) $(shell $(PKGCONFIG) sdl2 --libs-only-l)
733endif
734
735ifdef SOUND
736ifndef WIN32
737LIBS += -lSDL2_mixer
738endif
739endif
740LIBS += -lSDL2_image $(SDL2_LDFLAGS) $(FREETYPE_LDFLAGS)
741
742endif # pkg-config
743
744ifndef GLES
745ifneq ($(uname_S),Darwin)
746ifeq ($(msys),Yes)
747LIBS += -lopengl32 -lglu32
748else
749LIBS += -lGL -lGLU
750endif
751endif
752endif
753
754DEFINES_L += $(PNG_CFLAGS) $(FREETYPE_CFLAGS) $(SDL2_CFLAGS)
755INCLUDES_L += $(PNG_INCLUDE) $(FREETYPE_INCLUDE) $(SDL2_INCLUDE)
756
757endif # TILES
758
759ifdef SOUND
760DEFINES_L += -DUSE_SOUND
761endif
762
763# On clang, unknown -Wfoo is merely a warning, thus -Werror.
764# For `no-` options, gcc will only emit an error if there are other errors, so
765# we need to check positive forms (applies to array-bounds, format-zero-length,
766# and tautological-unsigned-enum-zero-compare.)
767CFWARN_L += $(shell w=array-bounds;echo|$(GXX) -E -x c++ - -Werror -W$$w >/dev/null 2>&1 && echo -Wno-$$w)
768CFWARN_L += $(shell w=format-zero-length;echo|$(GXX) -E -x c++ - -Werror -W$$w >/dev/null 2>&1 && echo -Wno-$$w)
769CFWARN_L += $(shell w=-Wmissing-declarations;echo|$(GXX) -E -x c++ - -Werror $$w >/dev/null 2>&1 && echo $$w)
770CFWARN_L  += $(shell w=-Wredundant-decls;echo|$(GXX) -E -x c++ - -Werror $$w >/dev/null 2>&1 && echo $$w)
771# Avoid warnings about safety checks that might be necessary on other compilers
772# where the same enum is assigned a signed underlying type.
773CFWARN_L  += $(shell w=tautological-unsigned-enum-zero-compare;echo|$(GXX) -E -x c++ - -Werror -W$$w >/dev/null 2>&1 && echo -Wno-$$w)
774
775CFWARN_L += -Wno-parentheses -Wwrite-strings -Wshadow -pedantic
776CFOTHERS_L = $(EXTERNAL_FLAGS_L) $(EXTRA_FLAGS) $(DEFINES) $(SDL2_CFLAGS)
777
778ifndef NO_LUA_BINDINGS
779CFOTHERS_L += -DCLUA_BINDINGS
780endif
781
782ifdef USE_DGAMELAUNCH
783SRC_BRANCH    := $(shell git rev-parse --abbrev-ref HEAD || echo release)
784ifneq ($(SRC_BRANCH),$(filter master release stone_soup-%, $(SRC_BRANCH)))
785  DEFINES_L += -DEXPERIMENTAL_BRANCH="\"$(SRC_BRANCH)\""
786endif
787endif
788
789#
790# Figure out the build settings for this type of build
791#
792
793# Debug
794# No optimization, full debugging.
795ifneq (,$(filter debug,$(MAKECMDGOALS)))
796	FULLDEBUG=YesPlease
797	DEBUG=YesPlease
798	NO_OPTIMIZE=YesPlease
799	COVERAGE=YesPlease
800endif
801
802# Debug-Lite
803# No optimization, but little/no debugging spew.
804ifneq (,$(filter debug-lite,$(MAKECMDGOALS)))
805	DEBUG=YesPlease
806	NO_OPTIMIZE=YesPlease
807	COVERAGE=YesPlease
808endif
809
810# Profile
811# Optimized, with full debugging.
812ifneq (,$(filter profile,$(MAKECMDGOALS)))
813	FULLDEBUG=YesPlease
814	DEBUG=YesPlease
815	COVERAGE=YesPlease
816endif
817
818# Unit tests
819ifneq (,$(filter catch2-tests,$(MAKECMDGOALS)))
820	COVERAGE=YesPlease
821endif
822
823ifdef HURRY
824	NO_OPTIMIZE=YesPlease
825endif
826
827ifdef COVERAGE
828    # GCC
829    ifeq ($(shell $(GXX) -v 2>&1|grep clang),)
830		CFOPTIMIZE_L = -fprofile-arcs -ftest-coverage
831    else
832    # Clang
833		CFOPTIMIZE_L = -fprofile-instr-generate -fcoverage-mapping
834    endif
835endif
836
837ifdef FULLDEBUG
838DEFINES += -DFULLDEBUG
839endif
840ifdef DEBUG
841CFOTHERS := -ggdb $(CFOTHERS)
842DEFINES += -DDEBUG
843endif
844ifndef NOWIZARD
845DEFINES += -DWIZARD
846endif
847ifdef NO_OPTIMIZE
848CFOPTIMIZE  :=
849endif
850
851ifdef PCH
852CFWARN_L += -Winvalid-pch
853
854ifdef PCH_BYTHEBOOK
855# Follow the suggestions in ccache(1)
856CFOTHERS_L += -fpch-preprocess
857export CCACHE_SLOPPINESS = time_macros
858# ... for everything but version.cc, which uses __DATE__ and __TIME__
859version.o: CCACHE_SLOPPINESS =
860else
861# Just keep ccache blisfully ignorant of the precompiled header
862export CCACHE_CPP2 = yes
863endif
864endif
865
866ifndef NOASSERTS
867DEFINES += -DASSERTS
868endif
869
870# Cygwin has a panic attack if we do this...
871ifndef NO_OPTIMIZE
872CFWARN_L += -Wuninitialized
873endif
874
875ifneq ($(strip $(chroot_prefix)),)
876	USE_CHROOT=YesPlease
877endif
878
879ifdef USE_DGAMELAUNCH
880	CFOTHERS_L += -DDGAMELAUNCH
881endif
882
883ifdef USE_CHROOT
884	prefix_fp := $(abspath $(strip $(DESTDIR)$(chroot_prefix))/$(strip $(prefix)))
885else
886	prefix_fp := $(abspath $(strip $(DESTDIR)$(prefix)))
887endif
888
889ifneq ($(strip $(SAVEDIR)),)
890  ifneq ($(filter ~%,$(SAVEDIR))$(ANDROID),)
891    CFOTHERS_L += -DSAVE_DIR_PATH=\"$(SAVEDIR)\"
892    savedir_fp :=
893    shareddir_fp :=
894  else
895    ifeq ($(filter /%,$(SAVEDIR)),)
896      ifneq ($(prefix),)
897	override SAVEDIR := $(strip $(prefix))/$(strip $(SAVEDIR))
898      endif
899    endif
900    CFOTHERS_L += -DSAVE_DIR_PATH=\"$(abspath $(SAVEDIR))\"
901    savedir_fp := $(abspath $(strip $(DESTDIR))$(strip $(SAVEDIR)))
902    shareddir_fp := $(savedir_fp)/saves
903  endif
904endif
905
906ifneq ($(strip $(SHAREDDIR)),)
907  ifneq ($(filter ~%,$(SHAREDDIR)),)
908    CFOTHERS_L += -DSHARED_DIR_PATH=\"$(SHAREDDIR)\"
909    shareddir_fp :=
910  else
911    ifeq ($(filter /%,$(SHAREDDIR)),)
912      ifneq ($(prefix),)
913	override SHAREDDIR := $(strip $(prefix))/$(strip $(SHAREDDIR))
914      endif
915    endif
916    CFOTHERS_L += -DSHARED_DIR_PATH=\"$(abspath $(SHAREDDIR))\"
917    shareddir_fp := $(abspath $(strip $(DESTDIR))$(strip $(SHAREDDIR)))
918  endif
919endif
920
921ifneq ($(strip $(DATADIR)),)
922  ifeq ($(filter /%,$(DATADIR)),)
923    #relative DATADIR
924    ifneq ($(prefix),)
925	override DATADIR := $(strip $(prefix))/$(strip $(DATADIR))
926    endif
927  endif
928  CFOTHERS_L += -DDATA_DIR_PATH=\"$(abspath $(DATADIR))/\"
929  FONTDIR = $(abspath $(DATADIR))/dat/tiles/
930else
931  ifneq ($(prefix),)
932	DATADIR := $(strip $(prefix))/$(strip $(DATADIR))
933	FONTDIR = $(strip $(DATADIR))/dat/tiles/
934  else
935    ifneq ($(DESTDIR)$(ANDROID),)
936        FONTDIR = dat/tiles/
937    else
938        FONTDIR = contrib/fonts/
939    endif
940  endif
941endif
942datadir_fp := $(abspath $(strip $(DESTDIR))$(strip $(DATADIR)))
943
944ifneq ($(strip $(WEBDIR)),)
945  ifeq ($(filter /%,$(WEBDIR)),)
946    #relative WEBDIR
947    ifneq ($(prefix),)
948	override WEBDIR := $(strip $(prefix))/$(strip $(WEBDIR))
949    endif
950  endif
951  CFOTHERS_L += -DWEB_DIR_PATH=\"$(abspath $(WEBDIR))/\"
952else
953  ifneq ($(prefix),)
954	WEBDIR := $(strip $(prefix))/$(strip $(WEBDIR))
955  endif
956endif
957webdir_fp := $(abspath $(strip $(DESTDIR))$(strip $(WEBDIR)))
958
959
960# Fonts.
961ifdef TILES
962
963OUR_PROPORTIONAL_FONT=DejaVuSans.ttf
964OUR_MONOSPACED_FONT=DejaVuSansMono.ttf
965
966ifdef PROPORTIONAL_FONT
967  DEFINES += -DPROPORTIONAL_FONT=\"$(PROPORTIONAL_FONT)\"
968  ifneq (,$(COPY_FONTS))
969    INSTALL_FONTS += "$(PROPORTIONAL_FONT)"
970  endif
971else
972  SYS_PROPORTIONAL_FONT = $(shell util/find_font "$(OUR_PROPORTIONAL_FONT)")
973  ifneq (,$(SYS_PROPORTIONAL_FONT))
974    ifeq (,$(COPY_FONTS))
975      DEFINES += -DPROPORTIONAL_FONT=\"$(SYS_PROPORTIONAL_FONT)\"
976    else
977      DEFINES += -DPROPORTIONAL_FONT=\"$(FONTDIR)$(OUR_PROPORTIONAL_FONT)\"
978      INSTALL_FONTS += "$(SYS_PROPORTIONAL_FONT)"
979    endif
980  else
981    DEFINES += -DPROPORTIONAL_FONT=\"$(FONTDIR)$(OUR_PROPORTIONAL_FONT)\"
982    INSTALL_FONTS += "contrib/fonts/$(OUR_PROPORTIONAL_FONT)"
983  endif
984endif
985
986ifdef MONOSPACED_FONT
987  DEFINES += -DMONOSPACED_FONT=\"$(MONOSPACED_FONT)\"
988  ifneq (,$(COPY_FONTS))
989    INSTALL_FONTS += "$(MONOSPACED_FONT)"
990  endif
991else
992  SYS_MONOSPACED_FONT = $(shell util/find_font "$(OUR_MONOSPACED_FONT)")
993  ifneq (,$(SYS_MONOSPACED_FONT))
994    ifeq (,$(COPY_FONTS))
995      DEFINES += -DMONOSPACED_FONT=\"$(SYS_MONOSPACED_FONT)\"
996    else
997      DEFINES += -DMONOSPACED_FONT=\"$(FONTDIR)$(OUR_MONOSPACED_FONT)\"
998      INSTALL_FONTS += "$(SYS_MONOSPACED_FONT)"
999    endif
1000  else
1001    DEFINES += -DMONOSPACED_FONT=\"$(FONTDIR)$(OUR_MONOSPACED_FONT)\"
1002    INSTALL_FONTS += "contrib/fonts/$(OUR_MONOSPACED_FONT)"
1003  endif
1004endif
1005
1006endif
1007
1008
1009ifndef NO_NCURSES
1010
1011ifndef CROSSHOST
1012	NC_PREFIX = /usr
1013else
1014	NC_PREFIX = /usr/$(ARCH)
1015endif
1016
1017# Include path for (n)curses with Unicode support.
1018
1019# Your ncurses library may include Unicode support, and you may not have a
1020# separate libncursesw; this is the case on Mac OS/Darwin.
1021ifdef LIBNCURSES_IS_UNICODE
1022  NCURSESLIB = ncurses
1023else
1024  NCURSESLIB = ncursesw
1025endif
1026
1027NC_LIBS := -L$(NC_PREFIX)/lib -l$(NCURSESLIB)
1028NC_CFLAGS := -isystem $(NC_PREFIX)/include/$(NCURSESLIB)
1029
1030ifndef NO_PKGCONFIG
1031  NC_LIBS := $(shell $(PKGCONFIG) --libs $(NCURSESLIB) 2>/dev/null || echo "$(NC_LIBS)")
1032  NC_CFLAGS := $(subst -I,-isystem ,$(shell $(PKGCONFIG) --cflags $(NCURSESLIB) 2>/dev/null || echo "$(NC_CFLAGS)"))
1033endif
1034
1035ifndef TILES
1036CFOTHERS_L += $(NC_CFLAGS)
1037LIBS += $(NC_LIBS)
1038endif
1039
1040endif
1041
1042ifdef BUILD_PCRE
1043DEFINES += -DREGEX_PCRE
1044else
1045  ifdef USE_PCRE
1046  DEFINES += -DREGEX_PCRE
1047  LIBS += -lpcre
1048  endif
1049endif
1050
1051ifdef USE_ICC
1052NO_INLINE_DEPGEN := YesPlease
1053GCC := icc
1054GXX := icpc
1055AR  := xiar
1056RANLIB := true
1057LIBS += -lguide -lpthread
1058CFWARN := -wd383,810,869,981,1418 -we14,193,304
1059CFWARN_L :=
1060endif
1061
1062LINKER_LDFLAG=
1063ifndef NO_TRY_LLD
1064ifeq (,$(shell echo 'int main(){return 1;}'|$(GXX) -x c++ - -o /dev/null -fuse-ld=lld 2>&1))
1065 LINKER_LDFLAG = -fuse-ld=lld
1066endif
1067endif
1068ifeq ($(LINKER_LDFLAG),)
1069ifndef NO_TRY_GOLD
1070ifeq (,$(shell echo 'int main(){return 1;}'|$(GXX) -x c++ - -o /dev/null -fuse-ld=gold 2>&1))
1071  LINKER_LDFLAG = -fuse-ld=gold
1072endif
1073endif
1074endif
1075ifneq ($(LINKER_LDFLAG),)
1076LDFLAGS += $(LINKER_LDFLAG)
1077endif
1078
1079LDFLAGS += $(CFOPTIMIZE) $(CFOPTIMIZE_L) $(EXTERNAL_LDFLAGS)
1080
1081ifdef REPORT
1082CFOTHERS += -ftime-report
1083endif
1084
1085UTIL = util/
1086
1087EXTRA_OBJECTS += $(YACC_OBJECTS)
1088
1089LEX := $(shell which flex 2> /dev/null)
1090YACC := $(shell which bison 2> /dev/null)
1091
1092ifeq ($(strip $(LEX)),)
1093NO_YACC = YesPlease
1094endif
1095ifeq ($(strip $(YACC)),)
1096NO_YACC = YesPlease
1097endif
1098
1099ifneq ($(findstring s,$(MAKEFLAGS)),s)
1100ifndef V
1101        QUIET_CC          = @echo '   ' CC $@;
1102        QUIET_CXX         = @echo '   ' CXX $@;
1103        QUIET_PCH         = @echo '   ' PCH $@;
1104        QUIET_LINK        = @echo '   ' LINK $@;
1105        QUIET_GEN         = @echo '   ' GEN $@;
1106        QUIET_COPY        = @echo '   ' COPY $@;
1107        QUIET_DEPEND      = @echo '   ' DEPEND $@;
1108        QUIET_WINDRES     = @echo '   ' WINDRES $@;
1109        QUIET_HOSTCC      = @echo '   ' HOSTCC $@;
1110        QUIET_PNGCRUSH    = @echo '   ' $(PNGCRUSH_LABEL) $@;
1111        QUIET_ADVPNG      = @echo '   ' ADVPNG $@;
1112        QUIET_PYTHON      = @echo '   ' PYTHON $@;
1113        export V
1114endif
1115endif
1116
1117TILEIMAGEFILES := floor wall feat main player gui icons
1118TILEDEFS = $(TILEIMAGEFILES) dngn unrand
1119TILEDEFPRES = $(TILEDEFS:%=$(RLTILES)/tiledef-%)
1120TILEDEFOBJS = $(TILEDEFPRES:%=%.o)
1121TILEDEFSRCS = $(TILEDEFPRES:%=%.cc)
1122TILEDEFHDRS = $(TILEDEFPRES:%=%.h)
1123
1124TILEFILES = $(TILEIMAGEFILES:%=%.png)
1125ORIGTILEFILES = $(TILEFILES:%=$(RLTILES)/%)
1126DESTTILEFILES = $(TILEFILES:%=dat/tiles/%)
1127
1128OBJECTS += $(TILEDEFOBJS)
1129
1130ifdef TILES_ANY
1131ifndef NO_OPTIMIZE
1132  ifneq (,$(shell which advpng))
1133    USE_ADVPNG = y
1134  else
1135    ifneq (,$(shell which pngcrush))
1136      PNGCRUSH = pngcrush -q -m 113
1137      PNGCRUSH_LABEL = PNGCRUSH
1138    endif
1139  endif
1140endif
1141endif
1142
1143ifdef BUILD_PCRE
1144CONTRIBS += pcre
1145CONTRIB_LIBS += $(LIBPCRE)
1146endif
1147ifdef BUILD_FREETYPE
1148CONTRIBS += freetype
1149CONTRIB_LIBS += $(LIBFREETYPE)
1150endif
1151ifdef BUILD_LIBPNG
1152CONTRIBS += libpng
1153CONTRIB_LIBS := $(LIBPNG) $(CONTRIB_LIBS)
1154endif
1155ifdef BUILD_SDL2
1156CONTRIBS += sdl2
1157CONTRIB_LIBS := $(LIBSDL2) $(CONTRIB_LIBS)
1158ifeq ($(uname_S),Linux)
1159LIBS += -ldl -lrt
1160endif
1161endif
1162ifdef BUILD_SDL2IMAGE
1163CONTRIBS += sdl2-image
1164CONTRIB_LIBS := $(LIBSDL2IMAGE) $(CONTRIB_LIBS)
1165endif
1166ifdef BUILD_SDL2MIXER
1167CONTRIBS += sdl2-mixer
1168CONTRIB_LIBS := $(LIBSDL2MIXER) $(CONTRIB_LIBS)
1169endif
1170ifdef BUILD_ZLIB
1171CONTRIBS += zlib
1172CONTRIB_LIBS += $(LIBZ)
1173endif
1174ifdef BUILD_LUA
1175ifdef USE_LUAJIT
1176CONTRIBS += luajit/src
1177CFOTHER_L += -DUSE_LUAJIT
1178else
1179CONTRIBS += lua/src
1180endif
1181CONTRIB_LIBS += $(LIBLUA)
1182endif
1183ifdef BUILD_SQLITE
1184CONTRIBS += sqlite
1185CONTRIB_LIBS += $(LIBSQLITE)
1186endif
1187
1188EXTRA_OBJECTS += version.o
1189
1190ifdef CONTRIBS
1191INCLUDES_L += -isystem contrib/install/$(ARCH)/include
1192LIBS += -Lcontrib/install/$(ARCH)/lib
1193endif
1194
1195LIBS += $(CONTRIB_LIBS) $(EXTRA_LIBS)
1196
1197
1198ifdef ANDROID
1199CFLAGS   := $(CFOPTIMIZE) $(CFOTHERS) $(CFWARN) $(CFLAGS)
1200else
1201CFLAGS   := $(CFOPTIMIZE) $(CFOTHERS) $(CFWARN)
1202endif
1203CFLAGS_L := $(CFOPTIMIZE_L) $(DEFINES_L) $(CFWARN_L) $(INCLUDES_L) $(CFOTHERS_L)
1204ALL_CFLAGS := $(CFLAGS) $(CFLAGS_L)
1205YACC_CFLAGS  := $(ALL_CFLAGS) -Wno-unused-function -Wno-sign-compare -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -Wno-null-conversion
1206RLTILES_CFLAGS := $(ALL_CFLAGS) -Wno-tautological-compare
1207
1208
1209DOC_BASE        := ../docs
1210DOC_TEMPLATES   := $(DOC_BASE)/template
1211GENERATED_DOCS  := $(DOC_BASE)/aptitudes.txt $(DOC_BASE)/aptitudes-wide.txt $(DOC_BASE)/FAQ.html $(DOC_BASE)/crawl_manual.txt $(DOC_BASE)/quickstart.txt
1212# Headers that need to exist before attempting to compile cc files
1213GENERATED_HEADERS := art-enum.h config.h mon-mst.h species-type.h
1214# All other generated files will be created later
1215GENERATED_FILES := $(GENERATED_HEADERS) art-data.h mi-enum.h \
1216                   $(RLTILES)/dc-unrand.txt build.h compflag.h dat/dlua/tags.lua \
1217                   cmd-name.h species-data.h aptitudes.h species-groups.h
1218
1219LANGUAGES = $(filter-out en, $(notdir $(wildcard dat/descript/??)))
1220SRC_PKG_BASE  := stone_soup
1221SRC_VERSION   := $(shell git describe --tags $(MERGE_BASE) 2>/dev/null || cat util/release_ver)
1222MAJOR_VERSION = $(shell echo "$(SRC_VERSION)"|$(SED) -r 's/-.*//;s/^([^.]+\.[^.]+).*/\1/')
1223RECENT_TAG    := $(shell git describe --abbrev=0 --tags $(MERGE_BASE))
1224WINARCH := $(shell $(GXX) -dumpmachine | grep -q x64_64 && echo win64 || echo win32)
1225
1226export SRC_VERSION
1227export WINARCH
1228
1229# Update .ver file if SRC_VERSION has changed
1230.ver: FORCE
1231	@echo '$(SRC_VERSION)' | cmp -s - $@ || echo '$(SRC_VERSION)' > $@
1232
1233PKG_SRC_DIR   := $(SRC_PKG_BASE)-$(SRC_VERSION)
1234SRC_PKG_TAR   := $(PKG_SRC_DIR).tar.xz
1235SRC_PKG_TAR_NODEPS := $(PKG_SRC_DIR)-nodeps.tar.xz
1236SRC_PKG_ZIP   := $(PKG_SRC_DIR).zip
1237
1238greet:
1239	@if [ ! -e $(GAME) ]; then\
1240		printf '  * %s\n' "If you experience any problems building Crawl, please take a second look"\
1241		                  "at INSTALL.md: the solution to your problem just might be in there!";\
1242	fi
1243
1244docs: $(GENERATED_DOCS)
1245
1246
1247# Webtiles data
1248.PHONY: webserver clean-webserver
1249
1250webserver/static/%.png: dat/tiles/%.png
1251	$(QUIET_COPY)$(COPY) $< webserver/static/
1252
1253webserver/game_data/static/%.png: dat/tiles/%.png
1254	$(QUIET_COPY)$(COPY) $< webserver/game_data/static/
1255
1256TILEINFOJS = $(TILEIMAGEFILES) dngn
1257TITLEIMGS = denzi_dragon denzi_kitchen_duty denzi_summoner \
1258            denzi_undead_warrior omndra_zot_demon firemage \
1259            shadyamish_octm denzi_evil_mage denzi_invasion \
1260            psiweapon_kiku white_noise_entering_the_dungeon \
1261            white_noise_grabbing_the_orb pooryurik_knight \
1262            psiweapon_roxanne baconkid_gastronok baconkid_mnoleg \
1263            peileppe_bloax_eye baconkid_duvessa_dowan ploomutoo_ijyb \
1264	    froggy_thunder_fist_nikola froggy_rune_and_run_failed_on_dis \
1265	    froggy_natasha_and_boris froggy_jiyva_felid \
1266	    froggy_goodgod_tengu_gold Cws_Minotauros nibiki_octopode \
1267	    e_m_fields sastrei_chei anon_octopus_wizard arbituhhh_tesu
1268
1269STATICFILES = $(TILEIMAGEFILES:%=webserver/game_data/static/%.png) \
1270              webserver/static/stone_soup_icon-32x32.png \
1271              $(TITLEIMGS:%=webserver/static/title_%.png) \
1272              $(TILEINFOJS:%=webserver/game_data/static/tileinfo-%.js)
1273
1274$(TILEINFOJS:%=$(RLTILES)/tileinfo-%.js): build-rltiles
1275
1276webserver/game_data/static/%.js: $(RLTILES)/%.js
1277	$(QUIET_COPY)$(COPY) $< webserver/game_data/static/
1278
1279clean-webserver:
1280	$(RM) $(STATICFILES) webserver/*.pyc
1281
1282ifdef WEBTILES
1283webserver: $(STATICFILES)
1284else
1285webserver:
1286endif
1287
1288GAME_OBJS=$(OBJECTS) main.o $(EXTRA_OBJECTS)
1289MONSTER_OBJS=$(OBJECTS) util/monster/monster-main.o $(EXTRA_OBJECTS)
1290CATCH2_TEST_OBJECTS = $(OBJECTS) $(TEST_OBJECTS) catch2-tests/test_main.o $(EXTRA_OBJECTS)
1291
1292
1293ifneq (,$(filter plug-and-play-tests,$(MAKECMDGOALS)))
1294    ifeq ("$(wildcard catch2-tests/test_plug_and_play.cc)","")
1295$(info  ----------------------------------------------------------------)
1296$(info  ERROR: 'catch2-tests_files/test_plug_and_play.cc' is not present)
1297$(info  you must create a catch2-tests_files/test_plug_and_play.cc file)
1298$(info  in order to use the 'make plug-and-play-tests' option. See )
1299$(info  'docs/develop/test_plug_and_play_cc.txt' for more details.)
1300$(info  ----------------------------------------------------------------)
1301$(error See above ^ ^ ^ ^ ^ ^ ^)
1302
1303    endif
1304endif
1305
1306# There might not have been any goals passed on the commandline, so...
1307GOALS = $(or $(MAKECMDGOALS),$(.DEFAULT_GOAL))
1308# Unless these are the only goals...
1309ifneq ($(GOALS),$(filter clean test %-windows,$(GOALS)))
1310
1311#
1312# CFLAGS difference check
1313#
1314# Check for flag changes between the previous build and the current one,
1315# because any CFLAGS change could result in an inconsistent build if the
1316# person building it isn't careful.
1317#
1318# This should eliminate an annoying need to use 'make clean' every time.
1319#
1320
1321TRACK_CFLAGS = $(strip $(subst ','\'',$(CC) $(CXX) $(ALL_CFLAGS)))
1322        # (stray ' for highlights)
1323OLD_CFLAGS = $(strip $(subst ','\'',$(shell cat .cflags 2>/dev/null)))
1324        # (stray ' for highlights)
1325
1326ifneq ($(TRACK_CFLAGS),$(OLD_CFLAGS))
1327  NEED_REBUILD = y
1328endif
1329
1330.cflags: .force-cflags
1331ifdef NEED_REBUILD
1332	@echo "    * rebuilding crawl: new build flags or prefix"
1333	@echo 'TRACK_CFLAGS = $(TRACK_CFLAGS) #EOL'
1334	@echo 'OLD_CFLAGS   = $(OLD_CFLAGS) #EOL'
1335	@echo '$(TRACK_CFLAGS)' > .cflags
1336endif
1337
1338.android-cflags: .cflags
1339	@echo $(STDFLAG) $(CFLAGS_L) | sed 's@"@\\"@g' >.android-cxxflags
1340	@echo $(CFLAGS_L) | sed 's@"@\\"@g' >.android-cflags
1341
1342.PHONY: .force-cflags
1343
1344endif
1345
1346##########################################################################
1347# Dependencies
1348
1349DEPS := $(ALL_OBJECTS:.o=.d)
1350
1351# Any stale .d files are worse than useless, as they can break builds by
1352# telling make a header or file no longer present is needed.  This is very
1353# likely to happen if the compilation mode changes (normal vs debug, tiles
1354# vs console vs webtiles) or if the compiler itself changes (gcc vs
1355# gcc-snapshot vs clang, or x86_64-linux-gnu-gcc vs x86_64-w64-mingw32-g++).
1356#
1357# In such cases, the dependency forces a rebuild of that file. If the
1358# dependency file referred to a non-existent header, as determined by
1359# util/good-depfile, then replace it with a rule that forces a rebuild.
1360# That rebuild will overwrite the stopgap .d file with a good one for
1361# the next build.
1362ifndef NEED_REBUILD
1363  VALID_DEPS := $(shell checkdep () { \
1364                          x_d="$$1"; \
1365                          x="$${x_d%%.d}"; x_cc="$${x}.cc"; x_o="$${x}.o"; \
1366                          if [ "$$x_cc" -ot "$$x_d" \
1367                               -a "$$x_d" -nt .cflags ]; \
1368                          then \
1369                            util/good-depfile "$$x_d" \
1370                              || echo "$$x_o: FORCE" > "$$x_d"; \
1371                            echo "$$x_d"; \
1372                          fi; \
1373                        }; \
1374                        for x_d in $(DEPS); do \
1375                          checkdep "$$x_d" & \
1376                        done)
1377endif
1378-include $(VALID_DEPS)
1379
1380
1381# This information is included in crash reports, and is printed with
1382# "crawl -version"
1383compflag.h: $(OBJECTS:.o=.cc) main.cc util/gen-cflg.pl .cflags
1384	$(QUIET_GEN)util/gen-cflg.pl compflag.h "$(ALL_CFLAGS)" "$(LDFLAGS)" "$(HOST)" "$(ARCH)"
1385
1386build.h: $(OBJECTS:.o=.cc) main.cc util/gen_ver.pl .ver
1387	$(QUIET_GEN)util/gen_ver.pl $@ $(MERGE_BASE)
1388
1389version.o: build.h compflag.h
1390
1391##########################################################################
1392# Documentation
1393#
1394$(DOC_BASE)/aptitudes.txt: $(DOC_TEMPLATES)/apt-tmpl.txt species-data.h aptitudes.h \
1395						   util/gen-apt.pl
1396	$(QUIET_GEN)./util/gen-apt.pl $@ $^
1397
1398$(DOC_BASE)/aptitudes-wide.txt: $(DOC_TEMPLATES)/apt-tmpl-wide.txt species-data.h \
1399						   aptitudes.h util/gen-apt.pl
1400	$(QUIET_GEN)./util/gen-apt.pl $@ $^
1401
1402$(DOC_BASE)/FAQ.html: dat/database/FAQ.txt util/FAQ2html.pl
1403	$(QUIET_GEN)./util/FAQ2html.pl $< $@
1404
1405# Generate a .txt version because some servers need it
1406# TODO: actually render this
1407$(DOC_BASE)/quickstart.txt: $(DOC_BASE)/quickstart.md
1408	$(QUIET_COPY)$(COPY) $< $@
1409
1410$(DOC_BASE)/crawl_manual.txt: $(DOC_BASE)/crawl_manual.rst util/unrest.pl
1411	$(QUIET_GEN)util/unrest.pl <$< >$@
1412
1413api:
1414	mkdir -p $(DOC_BASE)/develop/lua/
1415	# need abspath here because ldoc is fragile
1416	ldoc --config util/config.ld --dir $(abspath $(DOC_BASE)/lua/) .
1417
1418api-dev:
1419	mkdir -p $(DOC_BASE)/develop/lua/
1420	# need abspath here because ldoc is fragile
1421	ldoc --config util/config.ld --dir $(abspath $(DOC_BASE)/develop/lua/) \
1422	     --all .
1423
1424##########################################################################
1425# The level compiler
1426#
1427
1428$(YACC_OBJECTS): $(CONTRIB_LIBS)
1429
1430ifndef NO_YACC
1431
1432prebuildyacc:	$(UTIL)levcomp.tab.cc $(UTIL)levcomp.tab.h $(UTIL)levcomp.lex.cc
1433		$(QUIET_COPY)$(COPY) $^ prebuilt/
1434
1435$(UTIL)levcomp.tab.cc: $(UTIL)levcomp.ypp
1436		+@$(MAKE) -C $(UTIL) levcomp.tab.cc
1437
1438$(UTIL)levcomp.lex.cc: $(UTIL)levcomp.lpp $(UTIL)levcomp.tab.cc
1439		+@$(MAKE) -C $(UTIL) levcomp.lex.cc
1440
1441$(UTIL)levcomp.tab.h: $(UTIL)levcomp.tab.cc
1442
1443else
1444
1445prebuildyacc:
1446		@echo "**** yacc is not installed, aborting."; false
1447
1448# Pull the level-compiler stuff up from prebuilt/
1449
1450$(UTIL)levcomp.tab.cc: prebuilt/levcomp.tab.cc
1451		$(QUIET_COPY)$(COPY) prebuilt/*.h $(UTIL)
1452		$(QUIET_COPY)$(COPY) $< $@
1453
1454$(UTIL)levcomp.lex.cc: prebuilt/levcomp.lex.cc
1455		$(QUIET_COPY)$(COPY) $< $@
1456
1457endif
1458
1459##########################################################################
1460
1461
1462##########################################################################
1463# The actual build targets
1464#
1465ifdef ANDROID
1466  # during build, data goes in a different directory to when crawl runs!
1467  prefix_fp = ..
1468  datadir_fp = android-project/assets
1469  savedir_fp =
1470  shareddir_fp =
1471endif
1472
1473install-data: $(GENERATED_FILES)
1474ifeq ($(DESTDIR)$(prefix)$(ANDROID),)
1475	@echo Neither "DESTDIR" nor "prefix" defined -- nowhere to install to, aborting.
1476	@exit 1
1477endif
1478	[ -d $(datadir_fp) ] || mkdir -p $(datadir_fp)
1479	mkdir -p $(datadir_fp)/dat/des
1480	mkdir -p $(datadir_fp)/dat/dlua
1481	mkdir -p $(datadir_fp)/dat/clua
1482	mkdir -p $(datadir_fp)/dat/database
1483	mkdir -p $(datadir_fp)/dat/defaults
1484	mkdir -p $(datadir_fp)/dat/descript
1485	for LANG in $(LANGUAGES); \
1486		do mkdir -p $(datadir_fp)/dat/descript/$$LANG; \
1487	done
1488	mkdir -p $(datadir_fp)/docs/develop
1489	mkdir -p $(datadir_fp)/docs/develop/levels
1490	mkdir -p $(datadir_fp)/docs/license
1491	mkdir -p $(datadir_fp)/settings
1492	$(COPY_R) dat/des/* $(datadir_fp)/dat/des/
1493	$(COPY_R) dat/dlua/* $(datadir_fp)/dat/dlua/
1494	echo "-- Autogenerated list of maps to load and compile:" \
1495	    >$(datadir_fp)/dat/dlua/loadmaps.lua
1496	find dat -name '*.des'|LC_ALL=C sort|sed s:dat/::| \
1497	while read x; \
1498	    do echo "dgn.load_des_file('$$x')"; \
1499	    done >>$(datadir_fp)/dat/dlua/loadmaps.lua
1500	$(COPY)   dat/clua/*.lua $(datadir_fp)/dat/clua/
1501	$(COPY_R) dat/database/* $(datadir_fp)/dat/database/
1502	$(COPY_R) dat/defaults/* $(datadir_fp)/dat/defaults/
1503	$(COPY) dat/descript/*.txt $(datadir_fp)/dat/descript/
1504	for LANG in $(LANGUAGES); \
1505		do $(COPY) dat/descript/$$LANG/*.txt $(datadir_fp)/dat/descript/$$LANG; \
1506	done
1507	mkdir -p $(datadir_fp)/dat/dist_bones
1508	$(COPY) dat/dist_bones/* $(datadir_fp)/dat/dist_bones/
1509	$(COPY) ../docs/*.txt $(datadir_fp)/docs/
1510	$(COPY) ../docs/*.md $(datadir_fp)/docs/
1511	$(COPY) ../docs/develop/*.txt $(datadir_fp)/docs/develop/
1512	$(COPY) ../docs/develop/levels/*.txt $(datadir_fp)/docs/develop/levels/
1513	$(COPY) ../docs/license/*.txt $(datadir_fp)/docs/license/
1514	$(COPY) ../CREDITS.txt $(datadir_fp)/docs/
1515	$(COPY_R) ../settings/* $(datadir_fp)/settings/
1516ifeq ($(GAME),crawl.exe)
1517	$(SED) -i 's/$$/\r/' `find $(datadir_fp) -iname '*.txt' -or -iname '*.des'`
1518endif
1519ifdef TILES
1520	mkdir -p $(datadir_fp)/dat/tiles
1521	$(COPY) dat/tiles/*.png $(datadir_fp)/dat/tiles/
1522ifneq (,$(INSTALL_FONTS))
1523	$(COPY) $(INSTALL_FONTS) $(datadir_fp)/dat/tiles/
1524endif
1525endif
1526ifdef WEBTILES
1527	mkdir -p $(webdir_fp)
1528	$(COPY_R) webserver/game_data/* $(webdir_fp)/
1529endif
1530ifneq ($(savedir_fp),)
1531	mkdir -p $(savedir_fp)/saves
1532	mkdir -p $(savedir_fp)/morgue
1533ifeq ($(USE_DGAMELAUNCH),)
1534	$(CHOWN) -R $(INSTALL_UGRP) $(datadir_fp) || true
1535	$(CHOWN) -R $(INSTALL_UGRP) $(savedir_fp) || true
1536	$(CHMOD) $(MCHMOD_SAVEDIR) $(savedir_fp) || true
1537	$(CHMOD) $(MCHMOD_SAVEDIR) $(savedir_fp)/saves || true
1538	$(CHMOD) $(MCHMOD_SAVEDIR) $(savedir_fp)/morgue || true
1539endif
1540endif
1541ifneq ($(shareddir_fp),)
1542	mkdir -p $(shareddir_fp)
1543ifneq ($(patsubst /var/%,%,$(shareddir_fp)),$(shareddir_fp))
1544# Only if we're being installed for real.  Installations to a staging dir
1545# which are then packaged would trample existing files; these need to be
1546# handled by packagers themselves.
1547	touch $(shareddir_fp)/logfile
1548	touch $(shareddir_fp)/scores
1549endif
1550ifeq ($(USE_DGAMELAUNCH),)
1551	$(CHOWN) -R $(INSTALL_UGRP) $(shareddir_fp) || true
1552	$(CHMOD) $(MCHMOD_SAVEDIR) $(shareddir_fp) || true
1553	$(CHMOD) $(MCHMOD_LOGS) $(shareddir_fp)/logfile || true
1554	$(CHMOD) $(MCHMOD_LOGS) $(shareddir_fp)/scores || true
1555endif
1556endif
1557
1558install: all install-data
1559	[ -d $(prefix_fp)/$(bin_prefix) ] || mkdir -p $(prefix_fp)/$(bin_prefix)
1560	$(COPY) $(GAME) $(prefix_fp)/$(bin_prefix)/
1561	$(STRIP) $(prefix_fp)/$(bin_prefix)/$(GAME)
1562ifeq ($(USE_DGAMELAUNCH),)
1563	$(CHOWN) $(INSTALL_UGRP) $(prefix_fp)/$(bin_prefix)/$(GAME) || true
1564	$(CHMOD) $(MCHMOD) $(prefix_fp)/$(bin_prefix)/$(GAME) || true
1565endif
1566
1567clean: clean-rltiles clean-webserver clean-android clean-monster clean-catch2 \
1568       clean-plug-and-play-tests clean-coverage-full clean-mac
1569	+$(MAKE) -C $(UTIL) clean
1570	$(RM) $(GAME) $(GAME).exe $(GENERATED_FILES) $(EXTRA_OBJECTS) libw32c.o\
1571	    libunix.o $(ALL_OBJECTS) $(ALL_OBJECTS:.o=.d) *.ixx  \
1572	    .contrib-libs .cflags AppHdr.h.gch AppHdr.h.d util/fake_pty \
1573            rltiles/tiledef-unrand.cc
1574	$(RM) -r build-win
1575	$(RM) -r build
1576
1577clean-contrib:
1578	+$(MAKE) -C contrib clean
1579
1580clean-android:
1581ifneq ($(ANDROID),)
1582	$(RM) -r $(datadir_fp)
1583	+cd android-project && ant clean && ndk-build -$(MAKEFLAGS) clean \
1584	 && remove AndroidManifest.xml
1585endif
1586
1587distclean: clean clean-contrib clean-rltiles
1588	$(RM) -r morgue saves
1589	$(RM) scores $(GAME) core $(DEPENDENCY_MKF)
1590	$(RM) -r mac-app-zips
1591	$(RM) -r $(DOXYGEN_HTML_GEN)
1592
1593$(GAME): $(GAME_OBJS) $(CONTRIB_LIBS) dat/dlua/tags.lua
1594	+$(QUIET_LINK)$(CXX) $(LDFLAGS) $(GAME_OBJS) -o $(GAME) $(LIBS)
1595
1596util/monster/vault_monster_data.h: dat/des util/gather_mons
1597	util/gather_mons -v > $@
1598
1599util/monster/monster-main.o: util/monster/vault_monster_data.h
1600
1601util/monster/monster: $(MONSTER_OBJS) $(CONTRIB_LIBS) dat/dlua/tags.lua
1602	+$(QUIET_LINK)$(CXX) $(LDFLAGS) $(MONSTER_OBJS) -o $@ $(LIBS)
1603
1604monster: util/monster/monster
1605
1606test-monster: monster
1607	util/monster/monster quasit
1608
1609clean-monster:
1610	$(RM) util/monster/monster util/monster/vault_monster_data.h tile_info.txt
1611
1612install-monster: monster
1613	util/gather_mons -t > tile_info.txt
1614	strip -s util/monster/monster
1615	cp util/monster/monster $(HOME)/bin/
1616	if [ -f ~/source/announcements.log ]; then \
1617	  echo 'Monster database of master branch on crawl.develz.org updated to: $(VERSION)' >>~/source/announcements.log;\
1618	fi
1619
1620catch2-tests-executable: $(CATCH2_TEST_OBJECTS) $(CONTRIB_LIBS) dat/dlua/tags.lua
1621	+$(QUIET_LINK)$(CXX) $(LDFLAGS) $(CATCH2_TEST_OBJECTS) -o catch2-tests-executable $(LIBS)
1622
1623CATCH2_PNP_OBJECTS = $(OBJECTS) catch2-tests/test_plug_and_play.o \
1624                     catch2-tests/test_main.o $(EXTRA_OBJECTS)
1625
1626plug-and-play-tests: $(CATCH2_PNP_OBJECTS) $(CONTRIB_LIBS) dat/dlua/tags.lua
1627	+$(QUIET_LINK)$(CXX) $(LDFLAGS) $(CATCH2_PNP_OBJECTS) -o $@ $(LIBS)
1628
1629catch2-tests: catch2-tests-executable
1630	./catch2-tests-executable
1631
1632clean-coverage-full: clean-coverage
1633	find . -type f -name '*.gcno' -delete
1634
1635clean-coverage:
1636	$(RM) default.profraw default.profdata coverage.info coverage.profdata
1637	find . -type f \( -name '*.gcda' -or -name '*.gcov' \) -delete
1638	$(RM) -r coverage-html-report
1639
1640clean-catch2:
1641	$(RM) catch2-tests-executable catch2-tests-executable.exe
1642
1643clean-plug-and-play-tests:
1644	$(RM) plug-and-play-tests plug-and-play-tests.exe
1645
1646debug: all
1647debug-lite: all
1648profile: all
1649
1650doxy-simple: doxygen-simple
1651doxygen-simple:
1652	$(DOXYGEN) $(DOXYGEN_SIMPLE_CONF)
1653
1654doxy-all: doxygen-all
1655doxygen-all:
1656	$(DOXYGEN) $(DOXYGEN_ALL_CONF)
1657
1658# Dependency generation
1659#
1660ifndef NO_INLINE_DEPGEN
1661# See info node: (gcc) Preprocessor Options
1662INLINE_DEPGEN_CFLAGS = -MMD
1663endif
1664
1665$(DEPS): %.d: %.cc
1666
1667# Precompiled headers
1668#
1669ifdef PCH
1670-include AppHdr.h.d
1671%.gch: % .cflags $(CONTRIB_LIBS)
1672# This needs -MD, not -MMD, lest we be haunted by the ghosts of stale
1673# system headers.
1674	$(QUIET_PCH)$(CXX) $(STDFLAG) $(ALL_CFLAGS) -MD -c $< -o $@
1675
1676CC_DEP := AppHdr.h.gch
1677endif
1678
1679#
1680# Header build rule: order before regular .o rule for backwards compatibility
1681# with gnu make <3.82.
1682#
1683
1684%.h.o: %.h | $(GENERATED_HEADERS)
1685ifdef NO_INLINE_DEPGEN
1686	$(QUIET_DEPEND)$(or $(DEPCXX),$(CXX)) -MM $(STDFLAG) $(ALL_CFLAGS) -MT $*.o $< > $*.d
1687endif
1688	$(QUIET_CXX)$(CXX) $(STDFLAG) $(ALL_CFLAGS) $(INLINE_DEPGEN_CFLAGS) -x c++-header -c $< -o $@
1689ifndef NO_INLINE_DEPGEN
1690	@if [ -f $(@:%.o=%.d) ]; then touch -r $@ $(@:%.o=%.d); fi
1691endif
1692
1693
1694# Plain old compilation
1695#
1696
1697$(OBJECTS:%.o=%.cc) main.cc: $(CONTRIB_LIBS)
1698
1699$(UTIL)%.o: ALL_CFLAGS=$(YACC_CFLAGS)
1700$(TILEDEFOBJS): ALL_CFLAGS=$(RLTILES_CFLAGS)
1701
1702# The "|" designates "order-only" dependancies. See: (make) Prerequisite Types.
1703#
1704# This ensures that we update these headers before building anything
1705# that might depend on them without our knowing it yet, but lets the
1706# .d files take care of *whether* or not to rebuild.
1707#
1708# This is kind of important when building without ccache.
1709
1710%.o: %.m .cflags | $(GENERATED_HEADERS)
1711	$(QUIET_CC)$(CC) $(ALL_CFLAGS) $(INLINE_DEPGEN_CFLAGS) -c $< -o $@
1712
1713%.o: %.cc %.d .cflags $(CC_DEP) | $(GENERATED_HEADERS) $(TILEDEFHDRS)
1714ifdef NO_INLINE_DEPGEN
1715	$(QUIET_DEPEND)$(or $(DEPCXX),$(CXX)) -MM $(STDFLAG) $(ALL_CFLAGS) -MT $*.o $< > $*.d
1716endif
1717	$(QUIET_CXX)$(CXX) $(STDFLAG) $(ALL_CFLAGS) $(INLINE_DEPGEN_CFLAGS) -c $< -o $@
1718ifndef NO_INLINE_DEPGEN
1719	@if [ -f $(@:%.o=%.d) ]; then touch -r $@ $(@:%.o=%.d); fi
1720endif
1721
1722icon.o: util/crawl.rc dat/tiles/stone_soup_icon.ico .cflags
1723	$(QUIET_WINDRES)$(WINDRES) util/crawl.rc icon.o
1724
1725config.h: util/configure .cflags
1726	${QUIET_GEN}util/configure "$(CXX)" $(STDFLAG) $(ALL_CFLAGS)
1727
1728#
1729# Header build tests.
1730#
1731
1732.PHONY: header-build-tests
1733header-build-tests: $(HEADER_OBJECTS)
1734
1735#
1736# Contribs
1737#
1738
1739$(CONTRIB_LIBS): .contrib-libs
1740	@:
1741
1742.contrib-libs: .cflags
1743ifneq (,$(CONTRIBS))
1744	@echo "    * Need to build contribs: $(CONTRIBS)"
1745	+@$(MAKE) -C contrib $(CONTRIBS) ARCH=$(ARCH)
1746endif
1747	@touch $@
1748
1749$(foreach t,$(CONTRIB_LIBS),$(if $(wildcard $t),,$(shell rm -f .contrib-libs)))
1750
1751#############################################################################
1752# Build unrandart data
1753art-data.h: art-data.txt util/art-data.pl art-func.h
1754	util/art-data.pl
1755art-enum.h rltiles/dc-unrand.txt rltiles/tiledef-unrand.cc: art-data.h
1756
1757mon-mst.h: mon-spell.h util/gen-mst.pl
1758	$(QUIET_GEN)util/gen-mst.pl
1759
1760cmd-name.h: command-type.h util/cmd-name.pl
1761	$(QUIET_GEN)util/cmd-name.pl
1762
1763dat/dlua/tags.lua: tag-version.h util/gen-luatags.pl
1764	$(QUIET_GEN)util/gen-luatags.pl
1765
1766mi-enum.h: mon-info.h util/gen-mi-enum
1767	$(QUIET_GEN)util/gen-mi-enum
1768
1769# species-gen.py creates multiple files at once. Ensure Make doesn't run it once
1770# per target file by adding all the files into a single dependency chain.
1771# Ref: https://stackoverflow.com/q/2973445
1772species-data.h: dat/species/*.yaml util/species-gen.py util/species-gen/*.txt
1773	$(QUIET_PYTHON)$(PYTHON) util/species-gen.py dat/species/ util/species-gen/ species-data.h aptitudes.h species-groups.h species-type.h
1774# no-op
1775aptitudes.h: species-data.h
1776	$(QUIET_GEN)
1777# no-op
1778species-groups.h: aptitudes.h
1779	$(QUIET_GEN)
1780# no-op
1781species-type.h: species-groups.h
1782	$(QUIET_GEN)
1783
1784$(RLTILES)/dc-unrand.txt: art-data.h
1785
1786artefact.o: art-data.h art-enum.h
1787mon-util.o: mon-mst.h
1788mon-util.d: mon-mst.h
1789l-moninf.o: mi-enum.h
1790macro.o: cmd-name.h
1791
1792#############################################################################
1793# RLTiles
1794#
1795
1796#.PHONY: build-rltiles
1797build-rltiles: .contrib-libs $(RLTILES)/dc-unrand.txt
1798ifdef ANDROID
1799        # force submake to run properly
1800	+$(MAKE) -C $(RLTILES) all ANDROID=1 TILES=1 V=1
1801        # prove that tiles were generated properly
1802	grep tile_info rltiles/*.cc| head
1803else
1804# ensure we don't use contrib libpng when cross-compiling - it won't work.
1805ifdef CROSSHOST
1806	+$(MAKE) -C $(RLTILES) all ARCH=$(ARCH) TILES=$(TILES)$(WEBTILES)
1807else
1808	+$(MAKE) -C $(RLTILES) all ARCH=$(ARCH) NO_PKGCONFIG=$(NO_PKGCONFIG) TILES=$(TILES)$(WEBTILES)
1809endif
1810endif
1811
1812$(TILEDEFSRCS) $(TILEDEFHDRS) $(ORIGTILEFILES): build-rltiles
1813
1814dat/tiles/%.png: $(RLTILES)/%.png
1815	$(QUIET_PNGCRUSH)$(PNGCRUSH) $< $@
1816ifdef USE_ADVPNG
1817	$(QUIET_ADVPNG)$(ADVPNG) $@
1818endif
1819
1820clean-rltiles:
1821	$(RM) $(DESTTILEFILES)
1822	+$(MAKE) -C $(RLTILES) distclean
1823
1824ifdef TILES_ANY
1825install-data: $(DESTTILEFILES)
1826$(GAME): $(DESTTILEFILES)
1827endif
1828
1829.PHONY: check-fonts
1830check-fonts:
1831ifneq (,$(INSTALL_FONTS))
1832	@for x in $(INSTALL_FONTS); do if [ ! -e "$$x" ]; then echo \
1833	"Font file $${x##contrib/fonts/} not found. Please install it (possibly via contribs)."; \
1834	exit 1; fi; done
1835endif
1836
1837#############################################################################
1838# Packaging a source tarball for release
1839#
1840
1841# To package, you *must* have lex and yacc to generate the intermediates.
1842BSRC = build/crawl-ref/source/
1843source: removeold prebuildyacc
1844	@git branch >/dev/null 2>/dev/null || (echo You can package source only from git. && false)
1845	rm -rf build
1846	mkdir build
1847	(cd ../..;git ls-files| \
1848		grep -v -f crawl-ref/source/misc/src-pkg-excludes.lst| \
1849		tar cf - -T -)|tar xf - -C build
1850	for x in lua pcre sqlite libpng freetype sdl2 sdl2-image sdl2-mixer zlib fonts; \
1851	  do \
1852	   mkdir -p $(BSRC)contrib/$$x; \
1853	   (cd contrib/$$x;git ls-files|tar cf - -T -)| \
1854		tar xf - -C $(BSRC)contrib/$$x; \
1855	  done
1856	find build -name .gitignore -execdir rm -f '{}' +
1857	git describe --tags $(MERGE_BASE) > $(BSRC)util/release_ver
1858	cp build/LICENSE build/crawl-ref/LICENSE
1859	mv build/crawl-ref build/$(PKG_SRC_DIR)
1860
1861package-tarball-deps: source
1862	cd build && tar cfJ ../../../$(SRC_PKG_TAR) $(PKG_SRC_DIR)
1863
1864package-zipball-deps: source
1865	@if which zip >/dev/null; then \
1866	  echo "cd build && zip -rq ../../../$(SRC_PKG_ZIP) $(PKG_SRC_DIR)"; \
1867	  cd build && zip -rq ../../../$(SRC_PKG_ZIP) $(PKG_SRC_DIR); \
1868	else \
1869	  echo "**** No ZIP installed -- not creating the zipball."; \
1870	fi
1871
1872package-tarball-nodeps: source
1873	cd build && tar cfJ ../../../$(SRC_PKG_TAR_NODEPS) --exclude contrib --exclude simplebar.js $(PKG_SRC_DIR)
1874
1875package-source: package-tarball-deps package-zipball-deps package-tarball-nodeps
1876	$(RM) -r build-win
1877
1878removeold:
1879	if [ -f ../../$(SRC_PKG_TAR) ]; then $(RM) ../../$(SRC_PKG_TAR); fi
1880	if [ -f ../../$(SRC_PKG_ZIP) ]; then $(RM) ../../$(SRC_PKG_ZIP); fi
1881
1882#############################################################################
1883# Building the unified Windows package.
1884#
1885
1886# You need to have NSIS installed.
1887package-windows-installer:
1888ifneq (x$(SRC_VERSION),x$(shell cat build-win/version.txt 2>/dev/null))
1889	+$(MAKE) build-windows
1890endif
1891	makensis -NOCD -DVERSION=$(SRC_VERSION) -DWINARCH="$(WINARCH)" util/crawl.nsi
1892	ln -sf "stone_soup-$(SRC_VERSION)-$(WINARCH)-installer.exe" "stone_soup-latest-$(WINARCH)-installer.exe"
1893	$(RM) -r build-win
1894
1895build-windows:
1896ifneq ($(GAME),crawl.exe)
1897	@echo "This is only for Windows; please specify CROSSHOST.";false
1898endif
1899	+$(MAKE) clean
1900	+$(MAKE) TILES=y DESTDIR=build-win FORCE_SSE=y SAVEDIR='~/crawl' install
1901	mv build-win/crawl.exe build-win/crawl-tiles.exe
1902	+$(MAKE) TILES=  DESTDIR=build-win FORCE_SSE=y SAVEDIR='~/crawl' install
1903	mv build-win/crawl.exe build-win/crawl-console.exe
1904	mv build-win/docs/CREDITS.txt build-win/
1905	echo $(SRC_VERSION) >build-win/version.txt
1906
1907ZIP_DOCS=../../LICENSE
1908package-windows-tiles:
1909ifneq ($(GAME),crawl.exe)
1910	@echo "This is only for Windows; please specify CROSSHOST.";false
1911endif
1912	+$(MAKE) clean
1913	+$(MAKE) TILES=y DESTDIR=build-win/stone_soup-tiles-$(MAJOR_VERSION) FORCE_SSE=y install
1914	cp -p $(ZIP_DOCS) build-win/stone_soup-tiles-$(MAJOR_VERSION)/
1915	cd build-win && zip -9r ../stone_soup-$(SRC_VERSION)-tiles-win32.zip *
1916	if which advzip >/dev/null;then advzip -z3 stone_soup-$(SRC_VERSION)-tiles-win32.zip;fi
1917	ln -sf stone_soup-$(SRC_VERSION)-tiles-win32.zip stone_soup-latest-tiles-win32.zip
1918	$(RM) -r build-win
1919
1920package-windows-console:
1921ifneq ($(GAME),crawl.exe)
1922	@echo "This is only for Windows; please specify CROSSHOST.";false
1923endif
1924	+$(MAKE) clean
1925	+$(MAKE) DESTDIR=build-win/stone_soup-console-$(MAJOR_VERSION) FORCE_SSE=y install
1926	cp -p $(ZIP_DOCS) build-win/stone_soup-console-$(MAJOR_VERSION)/
1927	cd build-win && zip -9r ../stone_soup-$(SRC_VERSION)-console-win32.zip *
1928	if which advzip >/dev/null;then advzip -z3 stone_soup-$(SRC_VERSION)-console-win32.zip;fi
1929	ln -sf stone_soup-$(SRC_VERSION)-console-win32.zip stone_soup-latest-console-win32.zip
1930	$(RM) -r build-win
1931
1932package-windows-zips: package-windows-tiles package-windows-console
1933
1934#############################################################################
1935# Building Mac app bundles
1936#
1937# apple silicon universal builds: just brute-force this with submake commands.
1938# I couldn't see a cleaner way to do this within the Makefile structure,
1939# relative to my current knowledge of how this can be done: it requires
1940# building binaries for each target and then merging them with the `lipo`
1941# utility.
1942
1943# XX parameterise these in some less dumb way
1944# these two targets rely heavily on passing flags to submakes
1945crawl-x86_64-apple-macos10.7:
1946ifeq ($(MAC_TARGET),)
1947	+$(MAKE) MAC_TARGET=x86_64-apple-macos10.7
1948endif
1949
1950crawl-arm64-apple-macos11:
1951ifeq ($(MAC_TARGET),)
1952	+$(MAKE) MAC_TARGET=arm64-apple-macos11
1953endif
1954
1955crawl-universal:
1956	# do these via submake so that -jn doesn't create havoc
1957	+$(MAKE) crawl-arm64-apple-macos11
1958	+$(MAKE) crawl-x86_64-apple-macos10.7
1959	lipo -create -output crawl-universal crawl-arm64-apple-macos11 crawl-x86_64-apple-macos10.7
1960
1961clean-mac:
1962	$(RM) crawl-universal crawl-arm64-apple-macos11 crawl-x86_64-apple-macos10.7
1963
1964# XX is there a way to make these just respect TILES=y and have only 2 targets?
1965mac-app-tiles-universal: crawl-universal
1966	+$(MAKE) -j1 -C mac -f Makefile.app-bundle tiles BUILD_UNIVERSAL=y
1967
1968mac-app-console-universal: crawl-universal
1969	+$(MAKE) -j1 -C mac -f Makefile.app-bundle BUILD_UNIVERSAL=y
1970
1971mac-app-tiles: all
1972	+$(MAKE) -j1 -C mac -f Makefile.app-bundle tiles
1973
1974mac-app-console: all
1975	+$(MAKE) -j1 -C mac -f Makefile.app-bundle
1976
1977#############################################################################
1978# Building the Android package
1979#
1980
1981android-project/AndroidManifest.xml: android-project/AndroidManifest.xml.in
1982	sed "s/@CRAWL_VERSION@/${SRC_VERSION}/" <android-project/AndroidManifest.xml.in >android-project/AndroidManifest.xml
1983
1984android: install-data .android-cflags android-project/AndroidManifest.xml
1985ifeq ($(ANDROID),)
1986	@echo Please define ANDROID to use this build.
1987	@exit 1
1988endif
1989	+cd android-project && ndk-build -$(MAKEFLAGS) && ant debug && \
1990	cp bin/DungeonCrawlStoneSoup-debug.apk \
1991	../../../crawl_tiles_android-$(SRC_VERSION).apk
1992
1993#############################################################################
1994# Canned tests
1995#
1996
1997test: test-test test-all
1998nonwiztest: test-test test-nonwiz
1999nondebugtest: test-all
2000
2001test-%: $(GAME) util/fake_pty builddb
2002	util/fake_pty test/stress/run $*
2003	@echo "Finished: $*"
2004
2005util/fake_pty: util/fake_pty.c
2006	$(QUIET_HOSTCC)$(if $(HOSTCC),$(HOSTCC),$(CC)) $(if $(TRAVIS),-DTIMEOUT=9,-DTIMEOUT=60) -Wall $< -o $@ -lutil
2007
2008# Should be not needed, but the race condition in bug #6509 is hard to fix.
2009builddb: $(GAME)
2010	./$(GAME) --builddb
2011.PHONY: builddb
2012