diff --git a/Makefile b/Makefile index c3a70ddad..47e1be9bf 100644 --- a/Makefile +++ b/Makefile @@ -49,10 +49,17 @@ ifdef CXXFLAGS else CXXFLAGS:= -O2 -x c++ endif + CXXFLAGS+= -Wall -Wextra -Wno-unused-parameter -Wno-ignored-qualifiers + ifdef HAVE_GCC CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 endif + +ifdef HAVE_CLANG + CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 +endif + ifdef CLANG_WARNINGS CXXFLAGS+= -Weverything -Wno-c++17-extensions -Wno-c++98-compat -Wno-c++98-compat-pedantic \ -Wno-double-promotion -Wno-switch-enum -Wno-conversion -Wno-covered-switch-default \ @@ -62,23 +69,60 @@ ifdef CLANG_WARNINGS endif ifdef PROFILE - PROF:= -g -pg -fprofile-arcs -ftest-coverage + PROF:= -pg -fprofile-arcs -ftest-coverage CXXFLAGS+= $(PROF) +endif + +ifdef DEBUG + CXXFLAGS += -g else ifdef HAVE_GCC CXXFLAGS+= -fomit-frame-pointer endif -endif + ifdef HAVE_CLANG + CXXFLAGS+= -fomit-frame-pointer + endif +endif ####################################################################### # Misc stuff - you should never have to edit this # ####################################################################### -EXECUTABLE := stella$(EXEEXT) +EXECUTABLE := stella$(EXEEXT) +EXECUTABLE_PROFILE_GENERATE := stella-pgo-generate$(EXEEXT) +EXECUTABLE_PROFILE_USE := stella-pgo$(EXEEXT) + +PROFILE_DIR = $(CURDIR)/profile +PROFILE_OUT = $(PROFILE_DIR)/out +PROFILE_STAMP = profile.stamp + +CXXFLAGS_PROFILE_GENERATE = $(CXXFLAGS) +CXXFLAGS_PROFILE_USE = $(CXXFLAGS) +LDFLAGS_PROFILE_GENERATE = $(LDFLAGS) +STELLA_PROFILE_GENERATE = $(BINARY_LOADER) ./$(EXECUTABLE_PROFILE_GENERATE) -profile \ + $(PROFILE_DIR)/128.bin:10 \ + $(PROFILE_DIR)/catharsis_theory.bin:60 + +ifdef HAVE_CLANG + CXXFLAGS_PROFILE_GENERATE += -fprofile-generate=$(PROFILE_OUT) + CXXFLAGS_PROFILE_USE += -fprofile-use=$(PROFILE_OUT) + LDFLAGS_PROFILE_GENERATE += -fprofile-generate + STELLA_PROFILE_GENERATE := \ + LLVM_PROFILE_FILE="$(PROFILE_OUT)/default.profraw" $(STELLA_PROFILE_GENERATE) && \ + $(LLVM_PROFDATA) merge -o $(PROFILE_OUT)/default.profdata $(PROFILE_OUT)/default.profraw +endif + +ifdef HAVE_GCC + CXXFLAGS_PROFILE_GENERATE += -fprofile-generate -fprofile-dir=$(PROFILE_OUT) + CXXFLAGS_PROFILE_USE += -fprofile-use -fprofile-dir=$(PROFILE_OUT) + LDFLAGS_PROFILE_GENERATE += -fprofile-generate + LDFLAGS_PROFILE_USE += -fprofile-generate +endif all: $(EXECUTABLE) +pgo: $(EXECUTABLE_PROFILE_USE) ###################################################################### # Various minor settings @@ -119,57 +163,118 @@ CPPFLAGS:= $(DEFINES) $(INCLUDES) DEPDIRS = $(addsuffix /$(DEPDIR),$(MODULE_DIRS)) DEPFILES = +OBJS_PROFILE_GENERATE=$(OBJS:.o=.pgen.o) +OBJS_PROFILE_USE=$(OBJS:.o=.pgo.o) + # The build rule for the Stella executable -$(EXECUTABLE): $(OBJS) +$(EXECUTABLE): $(OBJS) $(LD) $(LDFLAGS) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@ +$(EXECUTABLE_PROFILE_GENERATE): $(OBJS_PROFILE_GENERATE) + $(LD) $(LDFLAGS_PROFILE_GENERATE) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@ + +$(EXECUTABLE_PROFILE_USE): $(OBJS_PROFILE_USE) + $(LD) $(LDFLAGS_PROFILE_USE) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@ + distclean: clean $(RM_REC) $(DEPDIRS) $(RM) build.rules config.h config.mak config.log clean: - $(RM) $(OBJS) $(EXECUTABLE) + -$(RM) -fr \ + $(OBJS) $(OBJS_PROFILE_GENERATE) $(OBJS_PROFILE_USE) \ + $(EXECUTABLE) $(EXECUTABLE_PROFILE_GENERATE) $(EXECUTABLE_PROFILE_USE) \ + $(PROFILE_OUT) $(PROFILE_STAMP) .PHONY: all clean dist distclean .SUFFIXES: .cxx +define create_depdir +$(MKDIR) $(*D)/$(DEPDIR) +endef + +define merge_dep +$(ECHO) "$(*D)/" > $(*D)/$(DEPDIR)/$(*F).d +$(CAT) "$(*D)/$(DEPDIR)/$(*F).d2" >> "$(*D)/$(DEPDIR)/$(*F).d" +$(RM) "$(*D)/$(DEPDIR)/$(*F).d2" +endef ifndef CXX_UPDATE_DEP_FLAG # If you use GCC, disable the above and enable this for intelligent # dependency tracking. CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d2" -.cxx.o: - $(MKDIR) $(*D)/$(DEPDIR) - $(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o - $(ECHO) "$(*D)/" > $(*D)/$(DEPDIR)/$(*F).d - $(CAT) "$(*D)/$(DEPDIR)/$(*F).d2" >> "$(*D)/$(DEPDIR)/$(*F).d" - $(RM) "$(*D)/$(DEPDIR)/$(*F).d2" -.c.o: - $(MKDIR) $(*D)/$(DEPDIR) - $(CC) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o - $(ECHO) "$(*D)/" > $(*D)/$(DEPDIR)/$(*F).d - $(CAT) "$(*D)/$(DEPDIR)/$(*F).d2" >> "$(*D)/$(DEPDIR)/$(*F).d" - $(RM) "$(*D)/$(DEPDIR)/$(*F).d2" +%.o: %.cxx + $(create_depdir) + $(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $@ + $(merge_dep) + +%.o: %.c + $(create_depdir) + $(CC) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $@ + $(merge_dep) + +%.pgen.o: %.cxx + $(create_depdir) + $(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_GENERATE) $(CPPFLAGS) -c $(<) -o $@ + $(merge_dep) + +%.pgen.o: %.cxx + $(create_depdir) + $(CC) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_GENERATE) $(CPPFLAGS) -c $(<) -o $@ + $(merge_dep) + +%.pgo.o: %.cxx $(PROFILE_STAMP) + $(create_depdir) + $(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_USE) $(CPPFLAGS) -c $(<) -o $@ + $(merge_dep) + +%.pgo.o: %.cxx $(PROFILE_STAMP) + $(create_depdir) + $(CC) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_USE) $(CPPFLAGS) -c $(<) -o $@ + $(merge_dep) + else # If you even have GCC 3.x, you can use this build rule, which is safer; the above # rule can get you into a bad state if you Ctrl-C at the wrong moment. # Also, with this GCC inserts additional dummy rules for the involved headers, # which ensures a smooth compilation even if said headers become obsolete. -.cxx.o: - $(MKDIR) $(*D)/$(DEPDIR) - $(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o +%.o: %.cxx + $(create_depdir) + $(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $@ + +%.o: %.c + $(create_depdir) + $(CC) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $@ + +%.pgen.o: %.cxx + $(create_depdir) + $(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_GENERATE) $(CPPFLAGS) -c $(<) -o $@ + +%.pgen.o: %.c + $(create_depdir) + $(CC) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_GENERATE) $(CPPFLAGS) -c $(<) -o $@ + +%.pgo.o: %.cxx $(PROFILE_STAMP) + $(create_depdir) + $(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_USE) $(CPPFLAGS) -c $(<) -o $@ + +%.pgo.o: %.c $(PROFILE_STAMP) + $(create_depdir) + $(CC) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_USE) $(CPPFLAGS) -c $(<) -o $@ -.c.o: - $(MKDIR) $(*D)/$(DEPDIR) - $(CC) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o endif # Include the dependency tracking files. We add /dev/null at the end # of the list to avoid a warning/error if no .d file exist -include $(wildcard $(addsuffix /*.d,$(DEPDIRS))) /dev/null +$(PROFILE_STAMP): $(EXECUTABLE_PROFILE_GENERATE) + -rm -fr $(PROFILE_OUT) + $(STELLA_PROFILE_GENERATE) + touch $(PROFILE_STAMP) + # check if configure has been run or has been changed since last run config.mak: $(srcdir)/configure @echo "You need to run ./configure before you can run make" diff --git a/configure b/configure index d188ba94a..482bf888b 100755 --- a/configure +++ b/configure @@ -24,6 +24,7 @@ _build_joystick=yes _build_cheats=yes _build_static=no _build_profile=no +_build_debug=no # more defaults _ranlib=ranlib @@ -204,6 +205,8 @@ Optional Features: --disable-static --enable-profile build binary with profiling info [disabled] --disable-profile + --enable-debug build with debugging symbols [disabled] + --disable-debug --force-builtin-libpng force use of built-in libpng library [auto] Optional Libraries: @@ -241,6 +244,8 @@ for ac_option in $@; do --disable-static) _build_static=no ;; --enable-profile) _build_profile=yes ;; --disable-profile) _build_profile=no ;; + --enable-debug) _build_debug=yes ;; + --disable-debug) _build_debug=false ;; --force-builtin-libpng) _libpng=no ;; --with-sdl-prefix=*) arg=`echo $ac_option | cut -d '=' -f 2` @@ -404,6 +409,8 @@ if test "$have_clang" = yes; then cxx_version="$cxx_version, bad" cxx_verc_fail=yes fi + + _make_def_CLANG_WARNINGS='CLANG_WARNINGS = 1' else # Need at least version 3.5 if [ $clang_major -ge 4 ] || [ $clang_major -eq 3 -a $clang_minor -ge 5 ]; then @@ -420,9 +427,8 @@ if test "$have_clang" = yes; then fi fi CXXFLAGS="$CXXFLAGS" - _make_def_HAVE_GCC3='HAVE_GCC3 = 1' + _make_def_HAVE_CLANG='HAVE_CLANG = 1' add_line_to_config_mk 'CXX_UPDATE_DEP_FLAG = -MMD -MF "$(*D)/$(DEPDIR)/$(*F).d" -MQ "$@" -MP' - _make_def_HAVE_GCC='HAVE_GCC = 1' echo "$cxx_version" elif test "$have_gcc" = yes; then @@ -448,7 +454,6 @@ elif test "$have_gcc" = yes; then ;; esac CXXFLAGS="$CXXFLAGS" - _make_def_HAVE_GCC3='HAVE_GCC3 = 1' add_line_to_config_mk 'CXX_UPDATE_DEP_FLAG = -MMD -MF "$(*D)/$(DEPDIR)/$(*F).d" -MQ "$@" -MP' _make_def_HAVE_GCC='HAVE_GCC = 1' echo "$cxx_version" @@ -670,11 +675,20 @@ fi if test "$_build_profile" = yes ; then echo_n " Profiling enabled" echo + + _build_debug=yes else echo_n " Profiling disabled" echo fi +if test "$_build_debug" = yes ; then + echo_n " Debug symbols enabled" + echo +else + echo_n " Debug symbols disabled" + echo +fi # # Now, add the appropriate defines/libraries/headers @@ -774,6 +788,9 @@ if test "$_build_profile" = no ; then _build_profile= fi +if test "$_build_debug" = no ; then + _build_debug= +fi echo "Creating config.mak" cat > config.mak << EOF @@ -795,6 +812,8 @@ ZIP := $_zip CP := $_cp WINDOWSPATH=$_windowspath STRIP := $_strip +LLVM_PROFDATA := llvm-profdata +BINARY_LOADER := MODULES += $MODULES MODULE_DIRS += $MODULE_DIRS @@ -805,9 +824,10 @@ BINDIR := $_bindir DOCDIR := $_docdir DATADIR := $_datadir PROFILE := $_build_profile +DEBUG := $_build_debug $_make_def_HAVE_GCC -$_make_def_HAVE_GCC3 +$_make_def_HAVE_CLANG $_make_def_CLANG_WARNINGS INCLUDES += $INCLUDES @@ -818,12 +838,11 @@ $_config_mk_data EOF # This should be taken care of elsewhere, but I'm not sure where -rm -f stella-conf* +rm -f stella-conf stella-conf.cxx if test "$_host_os" = darwin; then cat <