1##============================================================================
2##
3##   SSSS    tt          lll  lll
4##  SS  SS   tt           ll   ll
5##  SS     tttttt  eeee   ll   ll   aaaa
6##   SSSS    tt   ee  ee  ll   ll      aa
7##      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
8##  SS  SS   tt   ee      ll   ll  aa  aa
9##   SSSS     ttt  eeeee llll llll  aaaaa
10##
11## Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
12## and the Stella Team
13##
14## See the file "License.txt" for information on usage and redistribution of
15## this file, and for a DISCLAIMER OF ALL WARRANTIES.
16##============================================================================
17
18#######################################################################
19# Default compilation parameters. Normally don't edit these           #
20#######################################################################
21
22srcdir      ?= .
23
24DEFINES     := -DSDL_SUPPORT -D_GLIBCXX_USE_CXX11_ABI=1
25LDFLAGS     := -pthread
26INCLUDES    :=
27LIBS	    :=
28OBJS	    :=
29PROF        :=
30
31MODULES     :=
32MODULE_DIRS :=
33
34DISTNAME    := stella-snapshot
35
36# Load the make rules generated by configure
37include config.mak
38
39# Uncomment this for stricter compile time code verification
40# CXXFLAGS+= -Werror
41
42ifdef CXXFLAGS
43  CFLAGS:= $(CXXFLAGS)
44  CXXFLAGS:= $(CXXFLAGS) -x c++
45else
46  CXXFLAGS:= -O2 -x c++
47  CFLAGS:= -O2
48endif
49
50CXXFLAGS+= -Wall -Wextra -Wno-unused-parameter
51CFLAGS+= -Wall -Wextra -Wno-unused-parameter
52
53ifdef HAVE_GCC
54  CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++17
55  CFLAGS+= -Wno-multichar -Wunused
56endif
57
58ifdef HAVE_CLANG
59  CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++17
60  CFLAGS+= -Wno-multichar -Wunused
61endif
62
63ifdef CLANG_WARNINGS
64  EXTRA_WARN=-Weverything -Wno-c++98-compat-pedantic -Wno-unknown-warning-option \
65    -Wno-switch-enum -Wno-conversion -Wno-covered-switch-default \
66    -Wno-inconsistent-missing-destructor-override -Wno-float-equal \
67    -Wno-exit-time-destructors -Wno-global-constructors -Wno-weak-vtables \
68    -Wno-four-char-constants -Wno-padded -Wno-reserved-identifier
69
70  CXXFLAGS+= $(EXTRA_WARN)
71  CFLAGS+= $(EXTRA_WARN)
72endif
73
74ifdef PROFILE
75  PROF:= -pg -fprofile-arcs -ftest-coverage
76  CXXFLAGS+= $(PROF)
77  CFLAGS+= $(PROF)
78endif
79
80ifdef DEBUG
81  CXXFLAGS += -g
82  CFLAGS += -g
83else
84  ifdef HAVE_GCC
85    CXXFLAGS+= -fomit-frame-pointer
86    CFLAGS+= -fomit-frame-pointer
87  endif
88
89  ifdef HAVE_CLANG
90    CXXFLAGS+= -fomit-frame-pointer
91    CFLAGS+= -fomit-frame-pointer
92  endif
93endif
94
95ifdef RELEASE
96  CXXFLAGS += -flto -fno-rtti
97  CFLAGS += -flto
98  LDFLAGS += -flto -fno-rtti
99endif
100
101#######################################################################
102# Misc stuff - you should never have to edit this                     #
103#######################################################################
104
105ifdef STELLA_BUILD_ROOT
106  OBJECT_ROOT := $(STELLA_BUILD_ROOT)/stella-out
107else
108  OBJECT_ROOT := out
109endif
110OBJECT_ROOT_PROFILE_GENERERATE := out.pgen
111OBJECT_ROOT_PROFILE_USE := out.pgo
112
113EXECUTABLE := stella$(EXEEXT)
114EXECUTABLE_PROFILE_GENERATE := stella-pgo-generate$(EXEEXT)
115EXECUTABLE_PROFILE_USE := stella-pgo$(EXEEXT)
116
117PROFILE_DIR = $(CURDIR)/test/roms/profile
118PROFILE_OUT = $(PROFILE_DIR)/out
119PROFILE_STAMP = profile.stamp
120
121CXXFLAGS_PROFILE_GENERATE = $(CXXFLAGS)
122CXXFLAGS_PROFILE_USE = $(CXXFLAGS)
123CFLAGS_PROFILE_GENERATE = $(CFLAGS)
124CFLAGS_PROFILE_USE = $(CFLAGS)
125LDFLAGS_PROFILE_GENERATE = $(LDFLAGS)
126STELLA_PROFILE_GENERATE = $(BINARY_LOADER) ./$(EXECUTABLE_PROFILE_GENERATE) -profile \
127	$(PROFILE_DIR)/128.bin:10 \
128	$(PROFILE_DIR)/catharsis_theory.bin:60
129
130ifdef HAVE_CLANG
131	CXXFLAGS_PROFILE_GENERATE += -fprofile-generate=$(PROFILE_OUT)
132	CXXFLAGS_PROFILE_USE += -fprofile-use=$(PROFILE_OUT)
133	CFLAGS_PROFILE_GENERATE += -fprofile-generate=$(PROFILE_OUT)
134	CFLAGS_PROFILE_USE += -fprofile-use=$(PROFILE_OUT)
135	LDFLAGS_PROFILE_GENERATE += -fprofile-generate
136	STELLA_PROFILE_GENERATE := \
137		LLVM_PROFILE_FILE="$(PROFILE_OUT)/default.profraw" $(STELLA_PROFILE_GENERATE) && \
138		$(LLVM_PROFDATA) merge -o $(PROFILE_OUT)/default.profdata $(PROFILE_OUT)/default.profraw
139endif
140
141ifdef HAVE_GCC
142	CXXFLAGS_PROFILE_GENERATE += -fprofile-generate -fprofile-dir=$(PROFILE_OUT)
143	CXXFLAGS_PROFILE_USE += -fprofile-use -fprofile-dir=$(PROFILE_OUT)
144	CFLAGS_PROFILE_GENERATE += -fprofile-generate -fprofile-dir=$(PROFILE_OUT)
145	CFLAGS_PROFILE_USE += -fprofile-use -fprofile-dir=$(PROFILE_OUT)
146	LDFLAGS_PROFILE_GENERATE += -fprofile-generate
147	STELLA_PROFILE_GENERATE := $(STELLA_PROFILE_GENERATE) && \
148	  rm -fr $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_USE) && \
149		mv $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_GENERERATE) $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_USE)
150endif
151
152all: $(EXECUTABLE)
153
154pgo: $(EXECUTABLE_PROFILE_USE)
155
156######################################################################
157# Various minor settings
158######################################################################
159
160# The name for the directory used for dependency tracking
161DEPDIR := .deps
162
163
164######################################################################
165# Module settings
166######################################################################
167
168MODULES := $(MODULES)
169
170# After the game specific modules follow the shared modules
171MODULES += \
172	src/common \
173	src/common/audio \
174	src/common/tv_filters \
175	src/emucore \
176	src/emucore/tia \
177	src/emucore/tia/frame-manager \
178	src/common/repository/sqlite \
179	src/sqlite
180
181######################################################################
182# The build rules follow - normally you should have no need to
183# touch whatever comes after here.
184######################################################################
185
186# Concat DEFINES and INCLUDES to form the CPPFLAGS
187CPPFLAGS:= $(DEFINES) $(INCLUDES)
188
189# Include the build instructions for all modules
190-include $(addprefix $(srcdir)/, $(addsuffix /module.mk,$(MODULES)))
191
192# Depdir information
193DEPDIRS = $(addsuffix /$(DEPDIR),$(MODULE_DIRS))
194DEPFILES =
195
196OBJ=$(addprefix $(OBJECT_ROOT)/,$(OBJS))
197OBJ_PROFILE_GENERATE=$(addprefix $(OBJECT_ROOT_PROFILE_GENERERATE)/,$(OBJS))
198OBJ_PROFILE_USE=$(addprefix $(OBJECT_ROOT_PROFILE_USE)/,$(OBJS))
199
200# The build rule for the Stella executable
201$(EXECUTABLE): $(OBJ)
202	$(LD) $(LDFLAGS) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@
203
204$(EXECUTABLE_PROFILE_GENERATE): $(OBJ_PROFILE_GENERATE)
205	$(LD) $(LDFLAGS_PROFILE_GENERATE) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@
206
207$(EXECUTABLE_PROFILE_USE): $(OBJ_PROFILE_USE)
208	$(LD) $(LDFLAGS) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@
209
210distclean: clean
211	$(RM_REC) $(DEPDIRS)
212	$(RM) build.rules config.h config.mak config.log
213
214clean:
215	-$(RM) -fr \
216		$(OBJECT_ROOT) $(OBJECT_ROOT_PROFILE_GENERERATE) $(OBJECT_ROOT_PROFILE_USE) \
217		$(EXECUTABLE) $(EXECUTABLE_PROFILE_GENERATE) $(EXECUTABLE_PROFILE_USE) \
218		$(PROFILE_OUT) $(PROFILE_STAMP)
219
220.PHONY: all clean dist distclean
221
222.SUFFIXES: .cxx
223
224define create_dir
225$(MKDIR) -p $(*D)/$(DEPDIR)
226$(MKDIR) -p $(@D)
227endef
228
229define merge_dep
230$(ECHO) "$(*D)/" > $(*D)/$(DEPDIR)/$(*F).d
231$(CAT) "$(*D)/$(DEPDIR)/$(*F).d2" >> "$(*D)/$(DEPDIR)/$(*F).d"
232$(RM) "$(*D)/$(DEPDIR)/$(*F).d2"
233endef
234
235ifndef CXX_UPDATE_DEP_FLAG
236# If you use GCC, disable the above and enable this for intelligent
237# dependency tracking.
238CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d2"
239
240$(OBJECT_ROOT)/%.o: %.cxx
241	$(create_dir)
242	$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $@
243	$(merge_dep)
244
245$(OBJECT_ROOT)/%.o: %.c
246	$(create_dir)
247	$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS) $(CPPFLAGS) -c $(<) -o $@
248	$(merge_dep)
249
250$(OBJECT_ROOT_PROFILE_GENERERATE)/%.pgen.o: %.cxx
251	$(create_dir)
252	$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_GENERATE) $(CPPFLAGS) -c $(<) -o $@
253	$(merge_dep)
254
255$(OBJECT_ROOT_PROFILE_GENERERATE)/%.pgen.o: %.c
256	$(create_dir)
257	$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS_PROFILE_GENERATE) $(CPPFLAGS) -c $(<) -o $@
258	$(merge_dep)
259
260$(OBJECT_ROOT_PROFILE_USE)/%.pgo.o: %.cxx $(PROFILE_STAMP)
261	$(create_dir)
262	$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_USE) $(CPPFLAGS) -c $(<) -o $@
263	$(merge_dep)
264
265$(OBJECT_ROOT_PROFILE_USE)/%.pgo.o: %.c $(PROFILE_STAMP)
266	$(create_dir)
267	$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS_PROFILE_USE) $(CPPFLAGS) -c $(<) -o $@
268	$(merge_dep)
269
270else
271# If you even have GCC 3.x, you can use this build rule, which is safer; the above
272# rule can get you into a bad state if you Ctrl-C at the wrong moment.
273# Also, with this GCC inserts additional dummy rules for the involved headers,
274# which ensures a smooth compilation even if said headers become obsolete.
275$(OBJECT_ROOT)/%.o: %.cxx
276	$(create_dir)
277	$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $@
278
279$(OBJECT_ROOT)/%.o: %.c
280	$(create_dir)
281	$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS) $(CPPFLAGS) -c $(<) -o $@
282
283$(OBJECT_ROOT_PROFILE_GENERERATE)/%.o: %.cxx
284	$(create_dir)
285	$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_GENERATE) $(CPPFLAGS) -c $(<) -o $@
286
287$(OBJECT_ROOT_PROFILE_GENERERATE)/%.o: %.c
288	$(create_dir)
289	$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS_PROFILE_GENERATE) $(CPPFLAGS) -c $(<) -o $@
290
291$(OBJECT_ROOT_PROFILE_USE)/%.o: %.cxx $(PROFILE_STAMP)
292	$(create_dir)
293	$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_USE) $(CPPFLAGS) -c $(<) -o $@
294
295$(OBJECT_ROOT_PROFILE_USE)/%.o: %.c $(PROFILE_STAMP)
296	$(create_dir)
297	$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS_PROFILE_USE) $(CPPFLAGS) -c $(<) -o $@
298
299endif
300
301# Include the dependency tracking files. We add /dev/null at the end
302# of the list to avoid a warning/error if no .d file exist
303-include $(wildcard $(addsuffix /*.d,$(DEPDIRS))) /dev/null
304
305$(PROFILE_STAMP): $(EXECUTABLE_PROFILE_GENERATE)
306	-rm -fr $(PROFILE_OUT)
307	$(STELLA_PROFILE_GENERATE)
308	touch $(PROFILE_STAMP)
309
310# check if configure has been run or has been changed since last run
311config.mak: $(srcdir)/configure
312	@echo "You need to run ./configure before you can run make"
313	@echo "Either you haven't run it before or it has changed."
314	@exit 1
315
316install: all
317	$(INSTALL) -d "$(DESTDIR)$(BINDIR)"
318	$(INSTALL) -c -m 755 "$(srcdir)/stella$(EXEEXT)" "$(DESTDIR)$(BINDIR)/stella$(EXEEXT)"
319	$(INSTALL) -d "$(DESTDIR)$(DOCDIR)"
320	$(INSTALL) -c -m 644 "$(srcdir)/Announce.txt" "$(srcdir)/Changes.txt" "$(srcdir)/Copyright.txt" "$(srcdir)/License.txt" "$(srcdir)/README-SDL.txt" "$(srcdir)/Readme.txt" "$(srcdir)/Todo.txt" "$(srcdir)/docs/index.html" "$(srcdir)/docs/debugger.html" "$(DESTDIR)$(DOCDIR)/"
321	$(INSTALL) -d "$(DESTDIR)$(DOCDIR)/graphics"
322	$(INSTALL) -c -m 644 $(wildcard $(srcdir)/docs/graphics/*.png) "$(DESTDIR)$(DOCDIR)/graphics"
323	$(INSTALL) -d "$(DESTDIR)$(DATADIR)/applications"
324	$(INSTALL) -c -m 644 "$(srcdir)/src/unix/stella.desktop" "$(DESTDIR)$(DATADIR)/applications"
325	$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/16x16/apps"
326	$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/22x22/apps"
327	$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/24x24/apps"
328	$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/32x32/apps"
329	$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/48x48/apps"
330	$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/64x64/apps"
331	$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/128x128/apps"
332	$(INSTALL) -c -m 644 "$(srcdir)/src/common/stella-16x16.png" "$(DESTDIR)$(DATADIR)/icons/hicolor/16x16/apps/stella.png"
333	$(INSTALL) -c -m 644 "$(srcdir)/src/common/stella-22x22.png" "$(DESTDIR)$(DATADIR)/icons/hicolor/22x22/apps/stella.png"
334	$(INSTALL) -c -m 644 "$(srcdir)/src/common/stella-24x24.png" "$(DESTDIR)$(DATADIR)/icons/hicolor/24x24/apps/stella.png"
335	$(INSTALL) -c -m 644 "$(srcdir)/src/common/stella-32x32.png" "$(DESTDIR)$(DATADIR)/icons/hicolor/32x32/apps/stella.png"
336	$(INSTALL) -c -m 644 "$(srcdir)/src/common/stella-48x48.png" "$(DESTDIR)$(DATADIR)/icons/hicolor/48x48/apps/stella.png"
337	$(INSTALL) -c -m 644 "$(srcdir)/src/common/stella-64x64.png" "$(DESTDIR)$(DATADIR)/icons/hicolor/64x64/apps/stella.png"
338	$(INSTALL) -c -m 644 "$(srcdir)/src/common/stella-128x128.png" "$(DESTDIR)$(DATADIR)/icons/hicolor/128x128/apps/stella.png"
339
340install-strip: install
341	$(STRIP) stella$(EXEEXT)
342
343uninstall:
344	rm -f  "$(DESTDIR)$(BINDIR)/stella$(EXEEXT)"
345	rm -rf "$(DESTDIR)$(DOCDIR)/"
346	rm -f  "$(DESTDIR)$(DATADIR)/applications/stella.desktop"
347	rm -f  "$(DESTDIR)$(DATADIR)/icons/hicolor/16x16/apps/stella.png"
348	rm -f  "$(DESTDIR)$(DATADIR)/icons/hicolor/22x22/apps/stella.png"
349	rm -f  "$(DESTDIR)$(DATADIR)/icons/hicolor/24x24/apps/stella.png"
350	rm -f  "$(DESTDIR)$(DATADIR)/icons/hicolor/32x32/apps/stella.png"
351	rm -f  "$(DESTDIR)$(DATADIR)/icons/hicolor/48x48/apps/stella.png"
352	rm -f  "$(DESTDIR)$(DATADIR)/icons/hicolor/64x64/apps/stella.png"
353	rm -f  "$(DESTDIR)$(DATADIR)/icons/hicolor/128x128/apps/stella.png"
354
355# Special rule for M6502.ins, generated from m4 (there's probably a better way to do this ...)
356src/emucore/M6502.ins: src/emucore/M6502.m4
357	m4 src/emucore/M6502.m4 > src/emucore/M6502.ins
358
359# Special rule for windows icon stuff (there's probably a better way to do this ...)
360src/windows/stella_icon.o: src/windows/stella.ico src/windows/stella.rc
361	windres --include-dir src/windows src/windows/stella.rc src/windows/stella_icon.o
362
363.PHONY: deb bundle test install uninstall
364