1
2# OS package maintainers: Please try invoking make with PACKAGE_REPOSITORY=1 to see if that meets your needs before patching out our optimizations entirely.
3PACKAGE_REPOSITORY ?= 0
4
5# Are we running from synthesis?
6SYNTHESIS := 0
7
8
9##### Makefile Swiss army knife
10
11override empty :=
12override space := $(empty) $(empty)
13override comma := ,
14override paren_open := (
15override paren_close := )
16
17
18##### Detect platform
19
20ifndef HOSTPLATFORM
21    HOSTPLATFORM := UNKNOWN
22    ifeq ($(findstring Windows,$(OS)),Windows)
23        HOSTPLATFORM := WINDOWS
24    else
25        uname := $(strip $(shell uname -s))
26        ifeq ($(findstring Linux,$(uname)),Linux)
27            HOSTPLATFORM := LINUX
28        else ifeq ($(findstring DragonFly,$(uname)),DragonFly)
29            HOSTPLATFORM := BSD
30        else ifeq ($(findstring BSD,$(uname)),BSD)
31            HOSTPLATFORM := BSD
32        else ifeq ($(findstring MINGW,$(uname)),MINGW)
33            HOSTPLATFORM := WINDOWS
34        else ifeq ($(findstring MSYS,$(uname)),MSYS)
35            HOSTPLATFORM := WINDOWS
36        else ifeq ($(findstring Darwin,$(uname)),Darwin)
37            HOSTPLATFORM := DARWIN
38        else ifeq ($(findstring BeOS,$(uname)),BeOS)
39            HOSTPLATFORM := BEOS
40        else ifeq ($(findstring skyos,$(uname)),skyos)
41            HOSTPLATFORM := SKYOS
42        else ifeq ($(findstring QNX,$(uname)),QNX)
43            HOSTPLATFORM := QNX
44        else ifeq ($(findstring SunOS,$(uname)),SunOS)
45            HOSTPLATFORM := SUNOS
46        else ifeq ($(findstring syllable,$(uname)),syllable)
47            HOSTPLATFORM := SYLLABLE
48        endif
49    endif
50endif
51ifndef PLATFORM
52    PLATFORM := $(HOSTPLATFORM)
53endif
54
55ifndef SUBPLATFORM
56    SUBPLATFORM :=
57    ifeq ($(PLATFORM),$(filter $(PLATFORM),LINUX DINGOO GCW CAANOO))
58        SUBPLATFORM := LINUX
59    endif
60endif
61
62ifeq ($(HOSTPLATFORM),DARWIN)
63    DARWINVERSION := $(word 1,$(subst ., ,$(strip $(shell uname -r))))
64
65    DARWIN9 := 0
66    DARWIN10 := 0
67    ifneq (,$(filter 0 1 2 3 4 5 6 7 8 9 10,$(DARWINVERSION)))
68        DARWIN10 := 1
69        ifneq (,$(filter 0 1 2 3 4 5 6 7 8 9,$(DARWINVERSION)))
70            DARWIN9 := 1
71        endif
72    endif
73endif
74
75HOSTEXESUFFIX :=
76ifeq ($(HOSTPLATFORM),WINDOWS)
77    HOSTEXESUFFIX := .exe
78endif
79
80EXESUFFIX :=
81DLLSUFFIX := .so
82DOLSUFFIX := .dol
83ifeq ($(PLATFORM),DARWIN)
84    DLLSUFFIX := .dylib
85endif
86ifeq ($(PLATFORM),WII)
87    EXESUFFIX := .elf
88endif
89ifeq ($(PLATFORM),SKYOS)
90    EXESUFFIX := .app
91endif
92ifeq ($(PLATFORM),WINDOWS)
93    EXESUFFIX := .exe
94    DLLSUFFIX := .dll
95endif
96
97
98##### Makefile meta-settings
99
100PRETTY_OUTPUT := 1
101
102NULLSTREAM := /dev/null
103
104ifeq ($(HOSTPLATFORM),WINDOWS)
105# MSYS2 lets you create files named NUL but has a /dev/null. Go figure.
106    ifeq (,$(wildcard /dev/null))
107        NULLSTREAM := NUL
108    endif
109endif
110
111DONT_PRINT := > $(NULLSTREAM) 2>&1
112DONT_PRINT_STDERR := 2> $(NULLSTREAM)
113DONT_FAIL := ; exit 0
114ESCAPE=\\
115
116HAVE_SH := 1
117# when no sh.exe is found in PATH on Windows, no path is prepended to it
118ifeq (sh.exe,$(SHELL))
119    HAVE_SH := 0
120endif
121
122define LL
123    ls -l $1
124endef
125define MKDIR
126    mkdir -p $1
127endef
128define RM
129    rm -f $(filter-out / *,$1)
130endef
131define RMDIR
132    rm -rf $(filter-out / *,$1)
133endef
134define CAT
135    cat $1
136endef
137define RAW_ECHO
138    echo '$1'
139endef
140
141ifeq (0,$(HAVE_SH))
142    DONT_FAIL := & rem
143    ESCAPE=^
144
145    define LL
146        dir $(subst /,\,$1)
147    endef
148    define MKDIR
149        if not exist $(subst /,\,$1) mkdir $(subst /,\,$1)
150    endef
151    define RM
152        del /f /q $(subst /,\,$(filter-out / *,$1)) $(DONT_PRINT_STDERR) $(DONT_FAIL)
153    endef
154    define RMDIR
155        rmdir /s /q $(subst /,\,$(filter-out / *,$1)) $(DONT_PRINT_STDERR) $(DONT_FAIL)
156    endef
157    define CAT
158        type $(subst /,\,$1)
159    endef
160    define RAW_ECHO
161        echo $(subst ",$(ESCAPE)",$(subst $(paren_open),$(ESCAPE)$(paren_open),$(subst $(paren_close),$(ESCAPE)$(paren_close),$1)))
162    endef
163
164    # if, printf, exit, and ; are unavailable without sh
165    PRETTY_OUTPUT := 0
166endif
167
168
169##### Toolchain setup
170
171CROSS :=
172CROSS_SUFFIX :=
173
174CCFULLPATH = $(CC)
175
176ifeq ($(PLATFORM),WII)
177    ifeq ($(strip $(DEVKITPPC)),)
178        $(error "Please set DEVKITPPC in your environment. export DEVKITPPC := <path to>devkitPPC")
179    endif
180
181    ifeq ($(HOSTPLATFORM),WINDOWS)
182        override DEVKITPRO := $(subst /c/,C:/,$(DEVKITPRO))
183        override DEVKITPPC := $(subst /c/,C:/,$(DEVKITPPC))
184    endif
185
186    export PATH := $(DEVKITPPC)/bin:$(PATH)
187
188    CROSS := powerpc-eabi-
189
190    CCFULLPATH = $(DEVKITPPC)/bin/$(CC)
191endif
192
193CC := $(CROSS)gcc$(CROSS_SUFFIX)
194CXX := $(CROSS)g++$(CROSS_SUFFIX)
195
196ifeq ($(PLATFORM),DARWIN)
197    CC := $(CROSS)clang$(CROSS_SUFFIX)
198    CXX := $(CROSS)clang++$(CROSS_SUFFIX)
199endif
200
201COBJC := $(CC) -x objective-c
202COBJCXX := $(CXX) -x objective-c++
203L_CC := $(CC)
204L_CXX := $(CXX)
205
206AR := $(CROSS)ar$(CROSS_SUFFIX)
207RC := $(CROSS)windres$(CROSS_SUFFIX)
208RANLIB := $(CROSS)ranlib$(CROSS_SUFFIX)
209STRIP := $(CROSS)strip$(CROSS_SUFFIX)
210
211AS := nasm
212
213PKG_CONFIG := pkg-config
214
215ELF2DOL := elf2dol
216
217# Override defaults that absolutely will not work.
218ifeq ($(CC),cc)
219    override CC := gcc
220endif
221ifeq ($(AS),as)
222    override AS := nasm
223endif
224
225ifeq ($(PLATFORM),$(filter $(PLATFORM),DINGOO GCW))
226    CROSS := mipsel-linux-
227endif
228
229CLANG := 0
230ifeq ($(findstring clang,$(CC) $(MAKECMDGOALS)),clang)
231    override CLANG := 1
232    CLANGNAME := $(CC)
233else
234    CLANGNAME := clang
235endif
236# detect clang symlinked as gcc, as in OS X
237CLANG_POTENTIAL_VERSION := $(shell $(CCFULLPATH) --version)
238ifeq ($(findstring clang,$(CLANG_POTENTIAL_VERSION)),clang)
239    override CLANG := 1
240    ifeq ($(findstring Apple,$(CLANG_POTENTIAL_VERSION)),Apple)
241        override APPLE_CLANG := 1
242        APPLE_CLANG_VER := $(word 4,$(CLANG_POTENTIAL_VERSION))
243        override APPLE_CLANG_VER_SPLIT := $(subst ., ,$(APPLE_CLANG_VER))
244        APPLE_CLANG_MAJOR := $(word 1,$(APPLE_CLANG_VER_SPLIT))
245        APPLE_CLANG_MINOR := $(word 2,$(APPLE_CLANG_VER_SPLIT))
246    else
247        CLANG_VER := $(word 3,$(CLANG_POTENTIAL_VERSION))
248        override CLANG_VER_SPLIT := $(subst ., ,$(CLANG_VER))
249        CLANG_MAJOR := $(word 1,$(CLANG_VER_SPLIT))
250        CLANG_MINOR := $(word 2,$(CLANG_VER_SPLIT))
251    endif
252endif
253
254ifneq (0,$(CLANG))
255    CLANGXXNAME := $(subst clang,clang++,$(CLANGNAME))
256    override CC := $(CLANGNAME) -x c
257    override CXX := $(CLANGXXNAME) -x c++
258    override COBJC := $(CLANGNAME) -x objective-c
259    override COBJCXX := $(CLANGXXNAME) -x objective-c++
260    override L_CC := $(CLANGNAME)
261    override L_CXX := $(CLANGXXNAME)
262endif
263
264GCC_VER :=
265ifeq (0,$(CLANG))
266    GCC_VER := $(strip $(shell $(CCFULLPATH) -dumpversion 2>&1))
267endif
268ifeq (,$(GCC_VER))
269    GCC_VER := 4.9.0
270endif
271override GCC_VER_SPLIT := $(subst ., ,$(GCC_VER))
272GCC_MAJOR := $(word 1,$(GCC_VER_SPLIT))
273GCC_MINOR := $(word 2,$(GCC_VER_SPLIT))
274
275GCC_PREREQ_4 := 1
276
277ifneq (,$(filter 1 2 3,$(GCC_MAJOR)))
278    ifeq (0,$(CLANG))
279        GCC_PREREQ_4 := 0
280        $(error How do you still have an old GCC in $$(CURRENT_YEAR)?)
281    endif
282endif
283
284
285##### Detect machine architecture
286
287BITS := 32
288
289ifeq ($(PLATFORM),WINDOWS)
290    ifndef COMPILERTARGET
291        COMPILERTARGET := $(strip $(shell $(CC) -dumpmachine))
292    endif
293
294    IMPLICIT_ARCH := i386
295    ifeq ($(findstring x86_64,$(COMPILERTARGET)),x86_64)
296        IMPLICIT_ARCH := x86_64
297        BITS := 64
298    endif
299else ifeq ($(PLATFORM),WII)
300    IMPLICIT_ARCH := ppc
301else
302    ifneq ($(ARCH),)
303        override ARCH := $(subst i486,i386,$(subst i586,i386,$(subst i686,i386,$(strip $(ARCH)))))
304        IMPLICIT_ARCH := $(ARCH)
305    else
306        IMPLICIT_ARCH := $(subst i486,i386,$(subst i586,i386,$(subst i686,i386,$(strip $(shell uname -m)))))
307    endif
308
309    ifeq ($(findstring x86_64,$(IMPLICIT_ARCH)),x86_64)
310        BITS := 64
311    endif
312endif
313
314
315##### Toggles
316
317#  CPLUSPLUS - 1 := enable C++ building
318#  RELEASE - 1 := no debugging
319#  FORCEDEBUG:
320#    1 := Include debug symbols even when generating release code.
321#    2 := Also enable sanitizers with Clang. On the C side, make 'sprite' etc. be real arrays.
322#  KRANDDEBUG - 1 := include logging of krand() calls for debugging the demo system
323#  MEMMAP - 1 := produce .memmap file when linking
324#  OPTLEVEL - 0..3 := GCC optimization strategy
325#  LTO - 1 := enable link-time optimization
326
327# Optional overrides for text
328APPNAME ?=
329APPBASENAME ?=
330
331# Build toggles
332RELEASE := 1
333NOASM := 0
334# EXPERIMENTAL, unfinished x86_64 assembly routines. DO NOT ENABLE.
335USE_ASM64 := 0
336MEMMAP := 0
337CPLUSPLUS := 1
338
339# Feature toggles
340STANDALONE ?= 0
341NETCODE ?= 1
342STARTUP_WINDOW ?= 1
343RETAIL_MENU ?= 0
344POLYMER ?= 1
345USE_OPENGL := 1
346
347NOONE_EXTENSIONS ?= 1
348
349# Library toggles
350HAVE_GTK2 := 1
351USE_LIBVPX ?= 1
352HAVE_VORBIS := 1
353HAVE_FLAC := 1
354HAVE_XMP := 1
355RENDERTYPE := SDL
356SDL_TARGET := 2
357USE_PHYSFS := 0
358
359ifneq (0,$(USE_PHYSFS))
360    # PhysFS requires this to be off
361    override CPLUSPLUS := 0
362endif
363
364# Debugging/Build options
365FORCEDEBUG := 0
366KRANDDEBUG := 0
367PROFILER := 0
368# Make allocache() a wrapper around malloc()? Useful for debugging
369# allocache()-allocated memory accesses with e.g. Valgrind.
370# For debugging with Valgrind + GDB, see
371# http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver
372ALLOCACHE_AS_MALLOC := 0
373MICROPROFILE := 0
374
375##### Settings overrides and implicit cascades
376
377ifneq (0,$(KRANDDEBUG))
378    RELEASE := 0
379endif
380ifneq (100,$(RELEASE)$(PROFILER)$(ALLOCACHE_AS_MALLOC))
381    # so that we have debug symbols
382    FORCEDEBUG := 1
383endif
384
385ifeq ($(PLATFORM),WINDOWS)
386    override HAVE_GTK2 := 0
387else ifeq ($(PLATFORM),DARWIN)
388    HAVE_GTK2 := 0
389else ifeq ($(PLATFORM),WII)
390    override USE_OPENGL := 0
391    override NETCODE := 0
392    override HAVE_GTK2 := 0
393    override HAVE_FLAC := 0
394    SDL_TARGET := 1
395else ifeq ($(PLATFORM),$(filter $(PLATFORM),DINGOO GCW QNX SUNOS SYLLABLE))
396    override USE_OPENGL := 0
397    override NOASM := 1
398else ifeq ($(PLATFORM),$(filter $(PLATFORM),BEOS SKYOS))
399    override NOASM := 1
400endif
401
402ifneq (i386,$(strip $(IMPLICIT_ARCH)))
403    override NOASM := 1
404endif
405
406ifeq (0,$(USE_OPENGL))
407    override POLYMER := 0
408    override USE_LIBVPX := 0
409endif
410
411ifeq ($(RELEASE),0)
412    override STRIP :=
413endif
414ifneq ($(FORCEDEBUG),0)
415    override STRIP :=
416endif
417
418DBGLEVEL :=
419ifeq ($(RELEASE),0)
420    OPTLEVEL := 0
421
422    # see if we can use -Og
423    ifeq (1,$(APPLE_CLANG))
424      # Apple clang >= 9.0
425      ifeq (,$(filter 0 1 2 3 4 5 6 7 8,$(APPLE_CLANG_MAJOR)))
426        OPTLEVEL := g
427      endif
428    else ifeq (1,$(CLANG))
429      # clang >= 4.0
430      ifeq (,$(filter 0 1 2 3,$(CLANG_MAJOR)))
431        OPTLEVEL := g
432      endif
433    else
434      # GCC >= 4.8
435      ifeq (,$(filter 0 1 2 3 4,$(GCC_MAJOR)))
436        OPTLEVEL := g
437      else ifeq (4,$(GCC_MAJOR))
438        ifeq (,$(filter 0 1 2 3 4 5 6 7,$(GCC_MINOR)))
439          OPTLEVEL := g
440        endif
441      endif
442    endif
443
444    LTO := 0
445else
446    OPTLEVEL := 2
447    LTO := 1
448endif
449
450ifneq (0,$(CLANG))
451    ifeq ($(PLATFORM),WINDOWS)
452        LTO := 0
453    endif
454endif
455ifeq (0,$(CLANG))
456    ifeq (0,$(GCC_PREREQ_4))
457        override LTO := 0
458    endif
459    ifeq (4,$(GCC_MAJOR))
460        ifeq ($(PLATFORM),WII)
461            ifneq (,$(filter 0 1 2 3 4 5 6 7,$(GCC_MINOR)))
462                override LTO := 0
463            endif
464        else
465            ifneq (,$(filter 0 1 2 3 4 5,$(GCC_MINOR)))
466                override LTO := 0
467            endif
468        endif
469    endif
470endif
471
472
473########## End Toggles, Begin Construction ##########
474
475
476##### Instantiate variables
477
478COMMONFLAGS :=
479COMPILERFLAGS := -funsigned-char
480
481CSTD := -std=gnu99
482CXXSTD := -std=gnu++11
483ifneq (0,$(CLANG))
484    CSTD := $(subst gnu,c,$(CSTD))
485    CXXSTD := $(subst gnu,c,$(CXXSTD))
486endif
487CONLYFLAGS := $(CSTD)
488CXXONLYFLAGS := $(CXXSTD) -fno-exceptions -fno-rtti
489
490ASFLAGS := -s #-g
491
492LINKERFLAGS :=
493L_CXXONLYFLAGS :=
494
495LIBS :=
496GUI_LIBS :=
497LIBDIRS :=
498
499
500##### Mandatory platform parameters
501
502ASFORMAT := elf$(BITS)
503ifeq ($(PLATFORM),WINDOWS)
504    LINKERFLAGS += -static-libgcc -static
505    ifeq (0,$(CLANG))
506        L_CXXONLYFLAGS += -static-libstdc++
507    endif
508
509    ifeq (0,$(CLANG))
510        GUI_LIBS += -mwindows
511    endif
512
513    COMPILERFLAGS += -DUNDERSCORES
514    ASFORMAT := win$(BITS)
515    ASFLAGS += -DUNDERSCORES
516
517    ifneq ($(RELEASE),0)
518        ifeq ($(FORCEDEBUG),0)
519            DYNAMICBASE := -Wl,--dynamicbase
520            ifeq ($(findstring x86_64,$(COMPILERTARGET)),x86_64)
521                DYNAMICBASE := $(DYNAMICBASE),--high-entropy-va
522            endif
523        endif
524    endif
525    LINKERFLAGS += -Wl,--enable-auto-import,--nxcompat $(DYNAMICBASE)
526    ifneq ($(findstring x86_64,$(COMPILERTARGET)),x86_64)
527        LINKERFLAGS += -Wl,--large-address-aware
528    endif
529else ifeq ($(PLATFORM),DARWIN)
530    ifneq ($(ARCH),)
531        ifneq ($(findstring -arch,$(ARCH)),-arch)
532            override ARCH := -arch $(ARCH)
533        endif
534    endif
535    COMMONFLAGS += $(ARCH)
536
537    ifneq ($(findstring x86_64,$(IMPLICIT_ARCH)),x86_64)
538        LINKERFLAGS += -read_only_relocs suppress
539    endif
540
541    COMPILERFLAGS += -DUNDERSCORES
542    ASFORMAT := macho
543    ASFLAGS += -DUNDERSCORES
544
545    ifeq ($(findstring x86_64,$(IMPLICIT_ARCH)),x86_64)
546        ASFORMAT += 64
547    endif
548else ifeq ($(PLATFORM),WII)
549    LIBOGC_INC := $(DEVKITPRO)/libogc/include
550    LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii
551
552    COMMONFLAGS += -mrvl -mcpu=750 -meabi -mhard-float
553    LINKERFLAGS += -Wl,--gc-sections
554    # -msdata=eabiexport
555    COMPILERFLAGS += -DGEKKO -D__POWERPC__ -I$(LIBOGC_INC)
556    LIBDIRS += -L$(LIBOGC_LIB)
557else ifeq ($(PLATFORM),$(filter $(PLATFORM),DINGOO GCW))
558    COMPILERFLAGS += -D__OPENDINGUX__
559else ifeq ($(PLATFORM),SKYOS)
560    COMPILERFLAGS += -DUNDERSCORES
561else ifeq ($(SUBPLATFORM),LINUX)
562    # Locate .so files
563    LINKERFLAGS += -Wl,-rpath,'$$ORIGIN' -Wl,-z,origin
564endif
565ASFLAGS += -f $(ASFORMAT)
566
567COMPILERFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0
568
569
570##### Optimizations
571
572ifndef OPTOPT
573    ifeq ($(findstring x86_64, $(IMPLICIT_ARCH)),x86_64)
574        ifeq ($(findstring x86_64h, $(IMPLICIT_ARCH)),x86_64h)
575            OPTOPT := -march=haswell -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mpopcnt -mpclmul -mavx -mrdrnd -mf16c -mfsgsbase -mavx2 -maes -mfma -mbmi -mbmi2
576            # -mcrc32 -mmovbe
577        else
578            ifeq ($(PLATFORM),DARWIN)
579                OPTOPT := -march=core2 -mmmx -msse -msse2 -msse3 -mssse3
580            else
581                OPTOPT := -march=nocona
582            endif
583        endif
584    endif
585    ifeq ($(findstring i386, $(IMPLICIT_ARCH)),i386)
586        ifeq ($(PLATFORM),DARWIN)
587            OPTOPT := -march=nocona -mmmx -msse -msse2 -msse3
588        else
589            USE_SSE2 := 0
590            ifneq (0,$(USE_SSE2))
591                OPTOPT := -march=pentium-m
592            else
593                OPTOPT := -march=pentium3
594            endif
595            ifneq (0,$(GCC_PREREQ_4))
596                OPTOPT += -mtune=generic
597                # -mstackrealign
598            endif
599            OPTOPT += -mmmx -msse -mfpmath=sse
600            ifneq (0,$(USE_SSE2))
601                OPTOPT += -msse2
602            endif
603        endif
604    endif
605    ifeq ($(PLATFORM),WII)
606        OPTOPT := -mtune=750
607    endif
608endif
609
610ifeq ($(PACKAGE_REPOSITORY),0)
611    COMMONFLAGS += -O$(OPTLEVEL) $(OPTOPT)
612endif
613
614ifneq (0,$(LTO))
615    COMPILERFLAGS += -DUSING_LTO
616    COMMONFLAGS += -flto
617endif
618
619
620##### Debugging
621
622ifneq ($(RELEASE)$(FORCEDEBUG),10)
623    ifeq ($(PACKAGE_REPOSITORY),0)
624        COMMONFLAGS += -g$(DBGLEVEL)
625        ifeq (0,$(CLANG))
626            ifneq ($(PLATFORM),WII)
627                COMMONFLAGS += -fno-omit-frame-pointer
628            endif
629        endif
630    endif
631    ifeq ($(SUBPLATFORM),LINUX)
632        # This option is needed to allow obtaining backtraces from within a program.
633        LIBS += -rdynamic
634    endif
635endif
636
637ifneq ($(ALLOCACHE_AS_MALLOC),0)
638    COMPILERFLAGS += -DDEBUG_ALLOCACHE_AS_MALLOC
639endif
640
641# See https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
642# and https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html
643# for a list of possible ASan and UBsan options.
644
645ASAN_FLAGS := -fsanitize=address -fsanitize=bounds,enum,float-cast-overflow
646ASAN_FLAGS := $(ASAN_FLAGS),signed-integer-overflow,unsigned-integer-overflow
647ASAN_FLAGS := $(ASAN_FLAGS),undefined,return,null,pointer-overflow,float-divide-by-zero
648#ASAN_FLAGS := $(ASAN_FLAGS) -fsanitize-undefined-trap-on-error
649
650ifeq (0,$(FORCEDEBUG))
651    COMPILERFLAGS += -DNDEBUG
652else
653    COMPILERFLAGS += -DDEBUGGINGAIDS=$(FORCEDEBUG)
654
655    ifeq (2,$(FORCEDEBUG))
656        ifneq (0,$(CLANG))
657            COMMONFLAGS += $(ASAN_FLAGS)
658        else ifneq (,$(filter 1 2 3 4 5 6,$(GCC_MAJOR)))
659            ifneq (,$(filter 0 1,$(GCC_MINOR)))
660                COMMONFLAGS += $(ASAN_FLAGS)
661            endif
662        endif
663    endif
664endif
665
666ifneq (0,$(KRANDDEBUG))
667    COMPILERFLAGS += -DKRANDDEBUG=1
668endif
669
670ifneq (0,$(PROFILER))
671    ifneq ($(PLATFORM),DARWIN)
672        LIBS += -lprofiler
673    endif
674    COMMONFLAGS += -pg
675endif
676
677
678##### -f stuff
679
680ifneq (0,$(GCC_PREREQ_4))
681    F_NO_STACK_PROTECTOR := -fno-stack-protector
682    ifeq (0,$(CLANG))
683        F_JUMP_TABLES := -fjump-tables
684    endif
685endif
686
687ifeq ($(PLATFORM),DARWIN)
688    ifeq (1,$(DARWIN9))
689        F_JUMP_TABLES :=
690    endif
691    ifeq ($(findstring ppc,$(IMPLICIT_ARCH))$(findstring i386,$(IMPLICIT_ARCH)),)
692        F_NO_STACK_PROTECTOR :=
693    endif
694endif
695
696ifeq (0,$(RELEASE))
697    F_NO_STACK_PROTECTOR :=
698else
699    ifeq (0,$(CLANG))
700        COMMONFLAGS += -funswitch-loops
701    endif
702
703    ifeq (0,$(FORCEDEBUG))
704        COMMONFLAGS += -fomit-frame-pointer
705    endif
706endif
707
708ifneq (0,$(KRANDDEBUG))
709    COMMONFLAGS += -fno-inline -fno-inline-functions -fno-inline-functions-called-once
710endif
711
712COMMONFLAGS += -fno-strict-aliasing -fno-threadsafe-statics $(F_JUMP_TABLES) $(F_NO_STACK_PROTECTOR)
713
714
715##### Warnings
716
717W_STRICT_OVERFLOW := -Wno-strict-overflow
718
719ifeq ($(PLATFORM),DARWIN)
720    ifneq (0,$(DARWIN9))
721        W_STRICT_OVERFLOW :=
722    endif
723endif
724
725W_UNINITIALIZED := -Wuninitialized
726W_GCC_4_1 := -Wno-attributes
727W_GCC_4_2 := $(W_STRICT_OVERFLOW)
728W_GCC_4_4 := -Wno-unused-result
729W_GCC_4_5 := -Wlogical-op -Wcast-qual
730W_GCC_6 := -Wduplicated-cond -Wnull-dereference
731W_GCC_7 := -Wduplicated-branches
732W_GCC_8 := -Warray-bounds=2
733W_GCC_9 := -Wmultistatement-macros
734W_CLANG := -Wno-unused-value -Wno-parentheses -Wno-unknown-warning-option
735
736ifeq (0,$(CLANG))
737    W_CLANG :=
738
739    ifneq (,$(filter 4 5 6 7 8,$(GCC_MAJOR)))
740        W_GCC_9 :=
741        ifneq (,$(filter 4 5 6 7,$(GCC_MAJOR)))
742            W_GCC_8 :=
743            ifneq (,$(filter 4 5 6,$(GCC_MAJOR)))
744                W_GCC_7 :=
745                ifneq (,$(filter 4 5,$(GCC_MAJOR)))
746                    W_GCC_6 :=
747                endif
748            endif
749        endif
750    endif
751
752    ifeq (0,$(GCC_PREREQ_4))
753        W_GCC_9 :=
754        W_GCC_8 :=
755        W_GCC_7 :=
756        W_GCC_6 :=
757        W_GCC_4_5 :=
758        W_GCC_4_4 :=
759        ifeq (0,$(OPTLEVEL))
760            W_UNINITIALIZED :=
761        endif
762        W_GCC_4_2 :=
763        W_GCC_4_1 :=
764    endif
765
766    ifeq (4,$(GCC_MAJOR))
767        ifneq (,$(filter 0 1 2 3 4,$(GCC_MINOR)))
768            W_GCC_4_5 :=
769            ifneq (,$(filter 0 1 2 3,$(GCC_MINOR)))
770                W_GCC_4_4 :=
771                ifeq (0,$(OPTLEVEL))
772                    W_UNINITIALIZED :=
773                endif
774                ifneq (,$(filter 0 1,$(GCC_MINOR)))
775                    W_GCC_4_2 :=
776                    ifeq (0,$(GCC_MINOR))
777                        W_GCC_4_1 :=
778                    endif
779                endif
780            endif
781        endif
782    endif
783endif
784
785CONLYWARNS := -Wimplicit -Werror-implicit-function-declaration
786
787CWARNS := -W -Wall \
788    -Wextra \
789    -Wpointer-arith \
790    -Wno-char-subscripts \
791    -Wno-missing-braces \
792    -Wwrite-strings \
793    $(W_UNINITIALIZED) \
794    $(W_GCC_4_1) \
795    $(W_GCC_4_2) \
796    $(W_GCC_4_4) \
797    $(W_GCC_4_5) \
798    $(W_GCC_6) \
799    $(W_GCC_7) \
800    $(W_GCC_8) \
801    $(W_GCC_9) \
802    $(W_CLANG) \
803    #-Wstrict-prototypes \
804    #-Waggregate-return \
805    #-Wcast-align \
806    #-Waddress
807
808
809##### Features
810
811ifneq (,$(APPNAME))
812    COMPILERFLAGS += "-DAPPNAME=\"$(APPNAME)\""
813endif
814ifneq (,$(APPBASENAME))
815    COMPILERFLAGS += "-DAPPBASENAME=\"$(APPBASENAME)\""
816endif
817
818ifneq (0,$(NOASM))
819    COMPILERFLAGS += -DNOASM
820endif
821ifneq (0,$(USE_ASM64))
822    COMPILERFLAGS += -DUSE_ASM64
823endif
824ifneq (0,$(MEMMAP))
825    ifeq ($(PLATFORM),DARWIN)
826        LINKERFLAGS += -Wl,-map -Wl,$@.memmap
827    else
828        LINKERFLAGS += -Wl,-Map=$@.memmap
829    endif
830endif
831
832COMPILERFLAGS += -DRENDERTYPE$(RENDERTYPE)=1
833
834ifeq (0,$(NETCODE))
835    COMPILERFLAGS += -DNETCODE_DISABLE
836endif
837ifneq (0,$(STARTUP_WINDOW))
838    COMPILERFLAGS += -DSTARTUP_WINDOW
839endif
840ifneq (0,$(RETAIL_MENU))
841    COMPILERFLAGS += -DEDUKE32_RETAIL_MENU
842endif
843ifneq (0,$(STANDALONE))
844    COMPILERFLAGS += -DEDUKE32_STANDALONE
845endif
846ifneq (0,$(USE_OPENGL))
847    COMPILERFLAGS += -DUSE_OPENGL
848endif
849ifneq (0,$(POLYMER))
850    COMPILERFLAGS += -DPOLYMER
851endif
852ifneq (0,$(NOONE_EXTENSIONS))
853    COMPILERFLAGS += -DNOONE_EXTENSIONS
854endif
855
856
857##### External library paths
858
859ifeq ($(PLATFORM),WINDOWS)
860    COMPILERFLAGS += -Iplatform/Windows/include
861    LIBDIRS += -Lplatform/Windows/lib/$(BITS)
862else ifeq ($(PLATFORM),DARWIN)
863    ifneq ($(shell port --version &>/dev/null; echo $$?),127)
864        LIBDIRS += -L/opt/local/lib
865        COMPILERFLAGS += -I/opt/local/include
866    endif
867    ifneq ($(shell brew --version &>/dev/null; echo $$?),127)
868        LIBDIRS += -L/usr/local/lib
869        COMPILERFLAGS += -I/usr/local/include
870    endif
871    ifneq ($(shell fink --version &>/dev/null; echo $$?),127)
872        LIBDIRS += -L/sw/lib
873        COMPILERFLAGS += -I/sw/include
874    endif
875else ifeq ($(PLATFORM),BSD)
876    COMPILERFLAGS += -I/usr/local/include
877else ifeq ($(PLATFORM),WII)
878    COMPILERFLAGS += -I$(PORTLIBS)/include -Iplatform/Wii/include
879    LIBDIRS += -L$(PORTLIBS)/lib -Lplatform/Wii/lib
880endif
881
882
883##### External libraries
884
885ifneq (0,$(USE_LIBVPX))
886    COMPILERFLAGS += -DUSE_LIBVPX
887    LIBS += -lvpx
888endif
889
890ifneq (0,$(HAVE_VORBIS))
891    COMPILERFLAGS += -DHAVE_VORBIS
892endif
893ifneq (0,$(HAVE_FLAC))
894    COMPILERFLAGS += -DHAVE_FLAC
895endif
896ifneq (0,$(HAVE_XMP))
897    COMPILERFLAGS += -DHAVE_XMP
898endif
899
900ifeq ($(RENDERTYPE),SDL)
901    ifeq ($(SDL_TARGET),2)
902        SDLCONFIG := sdl2-config
903        SDLNAME := SDL2
904    else ifeq ($(SDL_TARGET),1)
905        SDLCONFIG := sdl-config
906        SDLNAME := SDL
907        ifeq (0,$(RELEASE))
908            COMPILERFLAGS += -DNOSDLPARACHUTE
909        endif
910    endif
911
912    ifeq ($(PLATFORM), WINDOWS)
913        SDLCONFIG :=
914    endif
915
916    ifeq ($(PLATFORM),WII)
917        SDLCONFIG :=
918    else ifeq ($(PLATFORM),SKYOS)
919        COMPILERFLAGS += -I/boot/programs/sdk/include/sdl
920        SDLCONFIG :=
921    endif
922
923    ifneq ($(strip $(SDLCONFIG)),)
924        ifeq ($(strip $(shell $(SDLCONFIG) --version $(DONT_PRINT_STDERR))),)
925            override SDLCONFIG :=
926        endif
927    endif
928
929    COMPILERFLAGS += -DSDL_TARGET=$(SDL_TARGET)
930
931    SDL_FRAMEWORK := 0
932    ifneq ($(SDL_FRAMEWORK),0)
933        ifeq ($(PLATFORM),DARWIN)
934            APPLE_FRAMEWORKS := /Library/Frameworks
935            LIBDIRS += -F$(APPLE_FRAMEWORKS)
936            COMPILERFLAGS += -I$(APPLE_FRAMEWORKS)/$(SDLNAME).framework/Headers
937            LIBS += -Wl,-framework,$(SDLNAME) -Wl,-rpath -Wl,"@loader_path/../Frameworks"
938        endif
939    else
940        ifneq ($(SDLCONFIG),)
941            SDLCONFIG_CFLAGS := $(strip $(subst -Dmain=SDL_main,,$(shell $(SDLCONFIG) --cflags)))
942            SDLCONFIG_LIBS := $(strip $(subst -mwindows,,$(shell $(SDLCONFIG) --libs)))
943
944            COMPILERFLAGS += $(SDLCONFIG_CFLAGS)
945            LIBS += $(SDLCONFIG_LIBS)
946        else
947            ifeq ($(SDL_TARGET),1)
948                COMPILERFLAGS += -D_GNU_SOURCE=1
949            endif
950            COMPILERFLAGS += -D_REENTRANT -DSDL_USEFOLDER
951            LIBS += -l$(SDLNAME)
952        endif
953    endif
954endif
955
956ifneq (0,$(HAVE_GTK2))
957    ifneq (No,$(shell $(PKG_CONFIG) --exists gtk+-2.0 || echo No))
958        COMPILERFLAGS += -DHAVE_GTK2 $(shell $(PKG_CONFIG) --cflags gtk+-2.0)
959    else
960        override HAVE_GTK2 := 0
961    endif
962endif
963
964
965##### System libraries
966
967ifeq ($(PLATFORM),WINDOWS)
968    ifneq (0,$(GCC_PREREQ_4))
969        L_SSP := -lssp
970    endif
971    LIBS += -lmingwex -lgdi32
972    ifneq (0,$(CLANG))
973        LIBS += -pthread
974    else
975        LIBS += -lpthread
976    endif
977    ifeq ($(RENDERTYPE),WIN)
978        LIBS += -ldxguid
979    else ifeq ($(SDL_TARGET),1)
980        LIBS += -ldxguid -lmingw32 -limm32 -lole32 -loleaut32 -lversion
981    else
982        LIBS += -ldxguid_sdl -lmingw32 -limm32 -lole32 -loleaut32 -lversion -lsetupapi
983    endif
984    LIBS += -lcomctl32 -lwinmm $(L_SSP) -lwsock32 -lws2_32 -lshlwapi -luuid
985    # -lshfolder
986else ifeq ($(PLATFORM),SKYOS)
987    LIBS += -lnet
988else ifeq ($(PLATFORM),QNX)
989    LIBS += -lsocket
990else ifeq ($(PLATFORM),SUNOS)
991    LIBS += -lsocket -lnsl
992else ifeq ($(PLATFORM),WII)
993    LIBS += -laesnd_tueidj -lfat -lwiiuse -lbte -lwiikeyboard -logc
994else ifeq ($(SUBPLATFORM),LINUX)
995    LIBS += -lrt
996    ifneq ($(findstring armv6,$(IMPLICIT_ARCH))$(findstring armv7,$(IMPLICIT_ARCH))$(findstring aarch64,$(IMPLICIT_ARCH)),)
997        LIBS += -latomic
998    endif
999endif
1000
1001ifeq (,$(filter $(PLATFORM),WINDOWS WII))
1002    ifneq ($(PLATFORM),BSD)
1003        LIBS += -ldl
1004    endif
1005    ifneq ($(PLATFORM),DARWIN)
1006        LIBS += -pthread
1007    endif
1008endif
1009
1010LIBS += -lm
1011
1012
1013##### Detect version control revision, if applicable
1014
1015VC_REV :=
1016VC_HASH :=
1017VC_BRANCH :=
1018
1019-include EDUKE32_REVISION.mak
1020ifeq (,$(VC_REV))
1021    VC_REV := $(shell git rev-list --count HEAD 2>&1)
1022endif
1023ifeq (,$(VC_HASH))
1024    VC_HASH := $(shell git rev-parse --short=9 HEAD 2>&1)
1025endif
1026ifeq (,$(VC_BRANCH))
1027    VC_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>&1)
1028    ifneq (master,$(VC_BRANCH))
1029        VC_REV := $(VC_REV)[$(VC_BRANCH)]
1030    endif
1031endif
1032ifneq (,$(VC_REV)$(VC_HASH)$(VC_REV_CUSTOM))
1033    REVFLAG := -DREV="r$(VC_REV)-$(VC_HASH)$(VC_REV_CUSTOM)"
1034endif
1035
1036
1037##### Allow standard environment variables to take precedence, to help package maintainers.
1038
1039ifneq (,$(CFLAGS))
1040    COMMONFLAGS += $(CFLAGS)
1041endif
1042ifneq (,$(CXXFLAGS))
1043    CXXONLYFLAGS += $(CXXFLAGS)
1044endif
1045ifneq (,$(LDFLAGS))
1046    LINKERFLAGS += $(LDFLAGS)
1047endif
1048
1049
1050##### Final assembly of commands
1051
1052COMPILER_C=$(CC) $(CONLYFLAGS) $(COMMONFLAGS) $(CWARNS) $(CONLYWARNS) $(COMPILERFLAGS) $(CUSTOMOPT)
1053COMPILER_CXX=$(CXX) $(CXXONLYFLAGS) $(COMMONFLAGS) $(CWARNS) $(COMPILERFLAGS) $(CUSTOMOPT)
1054COMPILER_OBJC=$(COBJC) $(CONLYFLAGS) $(COMMONFLAGS) $(CWARNS) $(CONLYWARNS) $(COMPILERFLAGS) $(CUSTOMOPT)
1055COMPILER_OBJCXX=$(COBJCXX) $(CXXONLYFLAGS) $(COMMONFLAGS) $(CWARNS) $(COMPILERFLAGS) $(CUSTOMOPT)
1056LINKER=$(L_CXX) $(CXXONLYFLAGS) $(L_CXXONLYFLAGS) $(COMMONFLAGS) $(LINKERFLAGS) $(CUSTOMOPT)
1057ifneq ($(CPLUSPLUS),0)
1058    COMPILER_C=$(COMPILER_CXX)
1059    COMPILER_OBJC=$(COMPILER_OBJCXX)
1060endif
1061
1062
1063##### Pretty-printing
1064
1065ifeq ($(PRETTY_OUTPUT),1)
1066RECIPE_IF = if
1067BUILD_STARTED = printf "\033[K\033[1;36mBuilding: \033[0;36m$(MAKE) $(MAKECMDGOALS) -$(MAKEFLAGS)\033[0m\n"
1068COMPILE_STATUS = printf "\033[K\033[0mBuilding object \033[1m$@\033[0m...\033[0m\r"
1069COMPILE_OK = printf "\033[K\033[0;32mBuilt object \033[1;32m$@\033[0;32m \033[0m\n"
1070COMPILE_FAILED = printf "\033[K\033[0;31mFailed building \033[1;31m$@\033[0;31m from\033[0m \033[1;31m$<\033[0;31m!\033[0m\n"; exit 1
1071RECIPE_RESULT_COMPILE = ; then $(COMPILE_OK); else $(COMPILE_FAILED); fi
1072ONESTEP_STATUS = printf "\033[K\033[0mBuilding \033[1m$@\033[0m...\033[0m\r"
1073ONESTEP_OK = printf "\033[K\033[0;32mBuilt \033[1;32m$@\033[0;32m \033[0m\n"
1074ONESTEP_FAILED = printf "\033[K\033[0;31mFailed building \033[1;31m$@\033[0;31m!\033[0m\n"; exit 1
1075RECIPE_RESULT_ONESTEP = ; then $(ONESTEP_OK); else $(ONESTEP_FAILED); fi
1076ARCHIVE_STATUS = printf "\033[K\033[0mCreating library archive \033[1m$@\033[0m...\033[0m\r"
1077ARCHIVE_OK = printf "\033[K\033[0;32mCreated library archive \033[1;32m$@\033[0;32m \033[0m\n"
1078ARCHIVE_FAILED = printf "\033[K\033[0;31mFailed creating library archive \033[1;31m$@\033[0;31m from\033[0m \033[1;31m$<\033[0;31m!\033[0m\n"; exit 1
1079RECIPE_RESULT_ARCHIVE = ; then $(ARCHIVE_OK); else $(ARCHIVE_FAILED); fi
1080LINK_STATUS = printf "\033[K\033[0;0mLinking \033[1m$@\033[0;0m...\033[0m\r"
1081LINK_OK = printf "\033[K\033[0;32mLinked \033[1;32m$@\033[0;32m \033[0m\n"
1082LINK_FAILED = printf "\033[K\033[0;31mFailed linking \033[1;31m$@\033[0;31m!\nIf the build options, environment, or system packages have changed, run \'\033[1;31mmake clean\033[0;31m\' and try again.\033[0m\n"; exit 1
1083RECIPE_RESULT_LINK = ; then $(LINK_OK); else $(LINK_FAILED); fi
1084else
1085RECIPE_IF =
1086BUILD_STARTED =
1087COMPILE_STATUS =
1088COMPILE_OK = true
1089COMPILE_FAILED = false; exit 1
1090RECIPE_RESULT_COMPILE =
1091ONESTEP_STATUS =
1092ONESTEP_OK = true
1093ONESTEP_FAILED = false; exit 1
1094RECIPE_RESULT_ONESTEP =
1095ARCHIVE_STATUS =
1096ARCHIVE_OK = true
1097ARCHIVE_FAILED = false; exit 1
1098RECIPE_RESULT_ARCHIVE =
1099LINK_STATUS =
1100LINK_OK = true
1101LINK_FAILED = false; exit 1
1102RECIPE_RESULT_LINK =
1103endif
1104