Makefile

Wed, 16 Jan 2013 00:34:11 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Wed, 16 Jan 2013 00:34:11 +0000
changeset 122
b214cf455ff2
parent 112
a392eb8f9806
child 128
3246b74d96bc
child 137
994d03cdcba2
permissions
-rw-r--r--

[wd2010] use size_t for init filesize, make disc init more verbose

     1 # Phil's multiplatform makefile template
     2 # With auto-incrementing build number and automatic version.h generation
     3 # Version 1.9, 2010-02-15
     4 #
     5 # The latest version of this Makefile can be found at http://www.philpem.me.uk/
     6 #
     7 #
     8 # Copyright (c) 2010 Philip Pemberton <code@philpem.me.uk>
     9 #
    10 # Permission is hereby granted, free of charge, to any person obtaining a copy
    11 # of this software and associated documentation files (the "Software"), to deal
    12 # in the Software without restriction, including without limitation the rights
    13 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    14 # copies of the Software, and to permit persons to whom the Software is
    15 # furnished to do so, subject to the following conditions:
    16 #
    17 # The above copyright notice and this permission notice shall be included in
    18 # all copies or substantial portions of the Software.
    19 #
    20 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    21 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    22 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    23 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    24 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    25 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    26 # THE SOFTWARE.
    27 #
    28 #
    29 # Instructions for use:
    30 #   Run 'make init' to create the required directories
    31 #   Add your source files to the 'SOURCES' list, and change the TARGET filename
    32 #   Set the desired build type and platform in the BUILD_TYPE and PLATFORM
    33 #     variables respectively
    34 #   Set your project type (C only, or C++) in the SRC_TYPE variable
    35 #   Add any libraries you need to link against to the 'LIB' list
    36 #   Run 'make'
    37 #
    38 # Object files are created in the 'obj' subdirectory, from source code in the
    39 # 'src' directory. Dependency files are created in the 'dep' directory from
    40 # the same source code the object files are created from.
    41 #
    42 # Supported targets are:
    43 #   all                 Build everything.
    44 #   update-revision     Increment the build number without building anything.
    45 #   clean-versioninfo   Delete src/version.h (will be rebuilt on the next
    46 #                       'make all').
    47 #   init                Initialise the build system for a new project.
    48 #                       WARNING: overwrites .buildnum and src/version.h.in!
    49 #   cleandep            Delete all dependency files.
    50 #   clean               Delete all dependency, intermediate and target files.
    51 #   tidy                Delete all dependency and intermediate files, leaving
    52 #                       the target file intact.
    53 #
    54 # If you want to reset the build number to zero, delete '.buildnum'. This
    55 # should be done whenever the major or minor version changes. Excluding
    56 # .buildnum from version control may also be a good idea, depending on how
    57 # you want your build numbers to work.
    58 #
    59 # The BUILD_TYPE variable contains the current build type. There are two
    60 # supported build types:
    61 #   debug       Debug mode - object files are compiled with debug information
    62 #               and the target is left unstripped.
    63 #   release     Release mode - object files are not compiled with debug info,
    64 #               and the target is fed through strip to remove redundant
    65 #               data.
    66 #
    67 # The PLATFORM variable contains the current target platform. There are two
    68 # supported platforms:
    69 #   linux       GNU/Linux with GNU Compiler Collection
    70 #   win32       Windows 32-bit with MinGW
    71 #
    72 # The EXTSRC variable is used to specify other files to build. It is typically
    73 # used to specify platform or build-type specific source files, e.g.
    74 #
    75 # ifeq ($(BUILD_TYPE),debug-memwatch)
    76 #   CFLAGS += -g -ggdb
    77 #   CPPFLAGS += -DMEMWATCH
    78 #   INCPATH += ./memwatch
    79 #   EXTSRC += memwatch/memwatch.c
    80 # endif
    81 #
    82 # (example taken from one of my projects that allowed the use of Memwatch to
    83 #  track down memory allocation/deallocation bugs)
    84 #
    85 #
    86 # Change history:
    87 #   1.9 - Bugfix -- if CFLAGS contained a forward-slash, sed would fall over.
    88 #         Also added SDL support and fixed the date/time formats. To use SDL,
    89 #         set ENABLE_SDL to "yes".
    90 #   1.8 - Now supports the use of the wxWidgets GUI framework. To turn
    91 #         this on, set ENABLE_WX to "yes".
    92 #   1.7 - Now creates a basic Hgignore file and directory keepers for the
    93 #         dep and obj directories.
    94 #   1.6 - Added CFLAGS and CXXFLAGS to the command-lines for the dependency
    95 #         building commands. This was causing issues with C99 / C++0x mode.
    96 #   1.5 - Added support for Mercurial revision (changeset ID) display
    97 #         Fixed a few issues with Subversion support (svn: and version 0 would
    98 #         be displayed for exported code)
    99 #
   101 ####
   102 # Build configuration
   103 ####
   105 # version information -- major.minor.extra
   106 # note that VER_EXTRA can be overridden on the command line, e.g.:
   107 # make VER_EXTRA=12345 all
   108 VER_MAJOR	= 0
   109 VER_MINOR	= 0
   110 VER_EXTRA	?= 
   112 # build platform: win32 or linux
   113 PLATFORM	?=	linux
   114 # build type: release or debug
   115 BUILD_TYPE	?=	debug
   117 # target executable
   118 TARGET		=	freebee
   120 # source files that produce object files
   121 SRC			=	main.c state.c memory.c wd279x.c wd2010.c keyboard.c
   122 SRC			+=	musashi/m68kcpu.c musashi/m68kdasm.c musashi/m68kops.c musashi/m68kopac.c musashi/m68kopdm.c musashi/m68kopnz.c
   124 # source type - either "c" or "cpp" (C or C++)
   125 SRC_TYPE	=	c
   127 # additional object files that don't necessarily include source
   128 EXT_OBJ		=
   129 # libraries to link in -- these will be specified as "-l" parameters, the -l
   130 # is prepended automatically
   131 LIB			=
   132 # library paths -- where to search for the above libraries
   133 LIBPATH		=
   134 # include paths -- where to search for #include files (in addition to the
   135 # standard paths
   136 INCPATH		=
   137 # garbage files that should be deleted on a 'make clean' or 'make tidy'
   138 GARBAGE		=	obj/musashi/m68kmake obj/musashi/m68kmake.exe obj/musashi/m68kmake.o
   140 # extra dependencies - files that we don't necessarily know how to build, but
   141 # that are required for building the application; e.g. object files or
   142 # libraries in sub or parent directories
   143 EXTDEP		=
   145 # Extra libraries
   146 # wxWidgets: set to "yes" to enable, anything else to disable
   147 ENABLE_WX	=	no
   148 # wxWidgets: list of wxWidgets libraries to enable
   149 WX_LIBS		=	std
   150 # SDL: set to "yes" to enable, anything else to disable
   151 ENABLE_SDL	=	yes
   153 ####
   154 # Win32 target-specific settings
   155 ####
   156 ifeq ($(strip $(PLATFORM)),win32)
   157 	# windows executables have a .exe suffix
   158 	TARGET := $(addsuffix .exe,$(TARGET))
   159 	# console mode application
   160 	EXT_CFLAGS = -mconsole
   161 endif
   164 ####
   165 # Tool setup
   166 ####
   167 MAKE	=	make
   168 CC		=	gcc
   169 CXX		=	g++
   170 CFLAGS	=	-Wall -pedantic -std=gnu99 $(EXT_CFLAGS)
   171 CXXFLAGS=	-Wall -pedantic -std=gnu++0x $(EXT_CXXFLAGS)
   172 LDFLAGS	=	$(EXT_LDFLAGS)
   173 RM		=	rm
   174 STRIP	=	strip
   176 ###############################################################################
   177 # You should not need to touch anything below here, unless you're adding a new
   178 # platform or build type (or changing the version string format)
   179 ###############################################################################
   181 ####
   182 # A quick sanity check on the platform type
   183 ####
   184 ifneq ($(PLATFORM),linux)
   185 ifneq ($(PLATFORM),win32)
   186     $(error Platform '$(PLATFORM)' not supported. Supported platforms are: linux, win32)
   187 endif
   188 endif
   190 ####
   191 # Version info generation
   192 ####
   193 # get the current build number
   194 VER_BUILDNUM	= $(shell cat .buildnum)
   196 #### --- begin Subversion revision grabber ---
   197 # there are two ways to get the SVN revision - use svnversion, or use svn info
   198 # then pipe through awk. which one you use is up to you.
   199 VER_SVNREV		= $(shell LANG=C svn info 2>/dev/null || echo 'Revision: exported' | awk '/^Revision:/ { print$$2 }' )
   200 #VER_SVNREV		= $(shell svnversion .)
   202 # if the version string is "exported", then the CSD was not checked out of SVN
   203 # note that if the CSD is not an SVN checkout, then @@svnrev@@ will be set to
   204 # zero.
   205 ifeq ($(VER_SVNREV),exported)
   206     VER_VCS		= none
   207     VER_VCSREV	= 0
   208 else
   209     VER_VCS		= svn
   210     VER_VCSREV	= $(VER_SVNREV)
   211 endif
   213 #### --- begin Mercurial revision grabber ---
   214 # If SVN didn't give us a revision, try Mercurial instead
   215 ifeq ($(VER_VCS),none)
   216     # get the current Mercurial changeset number
   217 	VER_HGREV=$(shell ((hg tip --template "{node|short}") || echo "000000000000") 2>/dev/null)
   218     ifneq ($(VER_HGREV),000000000000)
   219         # a non-empty repo
   220         VER_VCS		= hg
   221         VER_VCSREV	= $(VER_HGREV)
   222     else
   223         # either an empty Hg repo, or no repo at all
   224         VER_VCS		= none
   225         VER_VCSREV	= 0
   226     endif
   227 endif
   229 #### --- end version grabbers ---
   231 # start creating the revision string
   232 VER_FULLSTR		= $(VER_MAJOR).$(VER_MINOR).$(VER_BUILDNUM)$(VER_EXTRA)
   234 # if this is a VCS release, include the SVN revision in the version string
   235 # also create a revision string that is either "svn:12345", "hg:12345" or
   236 # blank
   237 ifneq ($(VER_VCS),none)
   238     VER_FULLSTR	+= ($(VER_VCS) $(VER_VCSREV))
   239     VER_VCSSTR	= $(VER_VCS):$(VER_VCSREV)
   240 else
   241     VER_VCSSTR	=
   242 endif
   245 ####
   246 # Build-type specific configuration
   247 ####
   248 ifeq ($(BUILD_TYPE),debug)
   249 	CFLAGS		+= -g -ggdb -DDEBUG
   250 	CXXFLAGS	+= -g -ggdb -DDEBUG
   251 else
   252  ifeq ($(BUILD_TYPE),release)
   253 	CFLAGS		+= -O2
   254 	CXXFLAGS	+= -O2
   255  else
   256  	$(error Unsupported build type: '$(BUILD_TYPE)')
   257  endif
   258 endif
   260 ####
   261 # wxWidgets support
   262 ####
   263 ifeq ($(ENABLE_WX),yes)
   264 	ifeq ($(BUILD_TYPE),debug)
   265 		LIBLNK		+=	`wx-config --debug --libs $(WX_LIBS)`
   266 		CFLAGS		+=	`wx-config --debug --cflags $(WX_LIBS)`
   267 		CXXFLAGS	+=	`wx-config --debug --cxxflags $(WX_LIBS)`
   268 		CPPFLAGS	+=	`wx-config --debug --cppflags $(WX_LIBS)`
   269 	else
   270 		ifeq ($(BUILD_TYPE),release)
   271 			LIBLNK		+=	`wx-config --libs $(WX_LIBS)`
   272 			CFLAGS		+=	`wx-config --cflags $(WX_LIBS)`
   273 			CPPFLAGS	+=	`wx-config --cppflags $(WX_LIBS)`
   274 			CXXFLAGS	+=	`wx-config --cxxflags $(WX_LIBS)`
   275 		else
   276 			$(error Unsupported build type: '$(BUILD_TYPE)')
   277 		endif
   278 	endif
   279 endif
   281 ####
   282 # SDL support
   283 ####
   284 ifeq ($(ENABLE_SDL),yes)
   285 	LIBLNK		+=	$(shell sdl-config --libs)
   286 	CFLAGS		+=	$(shell sdl-config --cflags)
   287 endif
   290 ####
   291 # rules
   292 ####
   294 # object files
   295 OBJ		=	$(addprefix obj/, $(addsuffix .o, $(basename $(SRC))) $(EXT_OBJ)) $(addsuffix .o, $(basename $(EXTSRC)))
   297 # dependency files
   298 DEPFILES =	$(addprefix dep/, $(addsuffix .d, $(basename $(SRC))) $(EXT_OBJ)) $(addsuffix .d, $(basename $(EXTSRC)))
   300 # path commands
   301 LIBLNK	+=	$(addprefix -l, $(LIB))
   302 LIBPTH	+=	$(addprefix -L, $(LIBPATH))
   303 INCPTH	+=	$(addprefix -I, $(INCPATH))
   305 CPPFLAGS +=	$(INCPTH)
   307 ####
   308 # Make sure there is at least one object file to be linked in
   309 ####
   310 ifeq ($(strip $(OBJ)),)
   311     $(error Unable to build: no object or source files specified in Makefile)
   312 endif
   314 ####
   315 # targets
   316 ####
   317 .PHONY:	default all update-revision versionheader clean-versioninfo init cleandep clean tidy
   319 all:	update-revision
   320 	@$(MAKE) versionheader
   321 	$(MAKE) $(TARGET)
   323 # increment the current build number
   324 NEWBUILD=$(shell expr $(VER_BUILDNUM) + 1)
   325 update-revision:
   326 	@echo $(NEWBUILD) > .buildnum
   328 versionheader:
   329 	@sed -e 's/@@datetime@@/$(shell LC_ALL=C date +"%a %d-%b-%Y %T %Z")/g'		\
   330 		 -e 's/@@date@@/$(shell LC_ALL=C date +"%a %d-%b-%Y")/g'			\
   331 		 -e 's/@@time@@/$(shell LC_ALL=C date +"%T %Z")/g'		\
   332 		 -e 's/@@whoami@@/$(shell whoami)/g'				\
   333 		 -e 's/@@hostname@@/$(shell hostname)/g'			\
   334 		 -e 's|@@compiler@@|$(shell $(CC) $(CFLAGS) -v 2>&1 | tail -n 1 | sed -e "s;|;/;")|g'	\
   335 		 -e 's/@@majorver@@/$(VER_MAJOR)/g'					\
   336 		 -e 's/@@minorver@@/$(VER_MINOR)/g'					\
   337 		 -e 's/@@extraver@@/$(subst \",,$(VER_EXTRA))/g'	\
   338 		 -e 's/@@buildnum@@/$(VER_BUILDNUM)/g'				\
   339 		 -e 's/@@buildtype@@/$(BUILD_TYPE)/g'				\
   340 		 -e 's/@@vcs@@/$(VER_VCS)/g'						\
   341 		 -e 's/@@vcsrev@@/$(VER_VCSREV)/g'					\
   342 		 -e 's/@@vcsstr@@/$(VER_VCSSTR)/g'					\
   343 		 -e 's/@@fullverstr@@/$(VER_FULLSTR)/g'				\
   344 		 -e 's#@@cflags@@#$(CFLAGS)#g'						\
   345 		 < src/version.h.in > src/version.h
   347 # version.h creation stuff based on code from the Xen makefile
   348 clean-versioninfo:
   349 	@if [ ! -r src/version.h -o -O src/version.h ]; then \
   350 		rm -f src/version.h; \
   351 	fi
   352 	@echo 0 > .buildnum
   354 # initialise the build system for a new project
   355 init:
   356 	@mkdir -p src dep obj
   357 	@echo "This file is a directory-keeper. Do not delete it." > dep/.keepme
   358 	@echo "This file is a directory-keeper. Do not delete it." > obj/.keepme
   359 	@echo 0 > .buildnum
   360 	@echo 'syntax: glob' > .hgignore
   361 	@echo 'obj/*.o' >> .hgignore
   362 	@echo 'dep/*.d' >> .hgignore
   363 	@echo '*~' >> .hgignore
   364 	@echo '.*.sw?' >> .hgignore
   365 	@echo '#define VER_COMPILE_DATETIME	"@@datetime@@"'			> src/version.h.in
   366 	@echo '#define VER_COMPILE_DATE		"@@date@@"'				>> src/version.h.in
   367 	@echo '#define VER_COMPILE_TIME		"@@time@@"'				>> src/version.h.in
   368 	@echo '#define VER_COMPILE_BY			"@@whoami@@"'		>> src/version.h.in
   369 	@echo '#define VER_COMPILE_HOST		"@@hostname@@"'			>> src/version.h.in
   370 	@echo '#define VER_COMPILER			"@@compiler@@"'			>> src/version.h.in
   371 	@echo '#define VER_BUILD_TYPE			"@@buildtype@@"'	>> src/version.h.in
   372 	@echo '#define VER_CFLAGS				"@@cflags@@"'		>> src/version.h.in
   373 	@echo ''													>> src/version.h.in
   374 	@echo '#define VER_MAJOR				@@majorver@@'		>> src/version.h.in
   375 	@echo '#define VER_MINOR				@@minorver@@'		>> src/version.h.in
   376 	@echo '#define VER_BUILDNUM			@@buildnum@@'			>> src/version.h.in
   377 	@echo '#define VER_EXTRA				"@@extraver@@"'		>> src/version.h.in
   378 	@echo '#define VER_VCSREV				"@@vcsstr@@"'		>> src/version.h.in
   379 	@echo ''													>> src/version.h.in
   380 	@echo '#define VER_FULLSTR				"@@fullverstr@@"'	>> src/version.h.in
   381 	@echo ''													>> src/version.h.in
   382 	@echo Build system initialised
   384 # remove the dependency files
   385 cleandep:
   386 	-rm $(DEPFILES)
   388 # remove the dependency files and any target or intermediate build files
   389 clean:	cleandep clean-versioninfo
   390 	-rm $(OBJ) $(TARGET) $(GARBAGE)
   392 # remove any dependency or intermediate build files
   393 tidy:	cleandep clean-versioninfo
   394 	-rm $(OBJ) $(GARBAGE)
   396 #################################
   398 $(TARGET):	$(OBJ) $(EXTDEP)
   399 ifeq ($(SRC_TYPE),c)
   400 	$(CC) $(CXXFLAGS) $(LDFLAGS) $(OBJ) $(LIBPTH) $(LIBLNK) -o $@
   401 else
   402 	$(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJ) $(LIBPTH) $(LIBLNK) -o $@
   403 endif
   404 ifeq ($(BUILD_TYPE),release)
   405 	$(STRIP) $(TARGET)
   406 endif
   408 ###
   409 # extra rules
   410 # example:
   411 #src/parser.c:	src/parser.h
   414 ####
   415 ## musashi build rules
   416 # 68k CPU builder
   417 obj/musashi/m68kmake:	obj/musashi/m68kmake.o
   418 	$(CC) $(CFLAGS) $(CPPFLAGS) obj/musashi/m68kmake.o -o $@
   419 # 68k CPU sources
   420 src/musashi/m68kops.h src/musashi/m68kops.c src/musashi/m68kopac.c src/musashi/m68kopdm.c src/musashi/m68kopnz.c:	obj/musashi/m68kmake src/musashi/m68k_in.c
   421 	./obj/musashi/m68kmake src/musashi src/musashi/m68k_in.c
   423 ####
   424 # make object files from C source files
   425 obj/%.o:	src/%.c
   426 	$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
   428 ##
   429 # make object files from C++ source files
   430 obj/%.o:	src/%.cc
   431 	$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $< -o $@
   433 obj/%.o:	src/%.cpp
   434 	$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $< -o $@
   436 ###
   437 # make C files from yacc/bison source
   438 src/%.h src/%.c:	src/%.y
   439 	$(YACC) $(YFLAGS) -d $<
   440 	mv -f y.tab.c $*.c
   441 	mv -f y.tab.h $*.h
   443 ###
   444 # make C files from lex/flex source
   445 src/%.c:	src/%.l
   446 	$(LEX) $(LFLAGS) -o$@ $<
   448 ###
   449 # make dependencies for our source files
   450 dep/%.d:	src/%.c
   451 	$(CC) -MM $(CFLAGS) $(CPPFLAGS) $< > $@.$$$$; \
   452 		sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
   453 		rm -f $@.$$$$
   455 dep/%.d:	src/%.cpp
   456 	$(CXX) -MM $(CXXFLAGS) $(CPPFLAGS) $< > $@.$$$$; \
   457 		sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
   458 		rm -f $@.$$$$
   460 dep/%.d:	src/%.cc
   461 	$(CXX) -MM $(CXXFLAGS) $(CPPFLAGS) $< > $@.$$$$; \
   462 		sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
   463 		rm -f $@.$$$$
   465 ####
   466 # pull in the dependency files, but only for 'make $(TARGET)'
   467 ####
   469 ifeq ($(MAKECMDGOALS),$(TARGET))
   470   -include $(DEPFILES)
   471 endif