Wed, 16 Jan 2013 00:34:11 +0000
[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