Mon, 03 Aug 2009 17:23:54 +0100
1st version with printing support. Now uses Libgd for image generation functionality.
1 # Phil's multiplatform makefile template
2 # With auto-incrementing build number and automatic version.h generation
3 # Version 1.4, 2009-01-27
4 #
5 # The latest version of this Makefile can be found at http://www.philpem.me.uk/
6 #
7 #
8 # Copyright (c) 2009 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 #
86 ####
87 # Build configuration
88 ####
90 # version information -- major.minor.extra
91 # note that VER_EXTRA can be overridden on the command line, e.g.:
92 # make VER_EXTRA=12345 all
93 VER_MAJOR = 0
94 VER_MINOR = 0
95 VER_EXTRA ?=
97 # build platform: win32 or linux
98 PLATFORM ?= linux
99 # build type: release or debug
100 BUILD_TYPE ?= debug
102 # target executable
103 TARGET = ptouch
105 # source files that produce object files
106 SRC = main.c hexdump.c ptouch.c
108 # source type - either "c" or "cpp" (C or C++)
109 SRC_TYPE = c
111 # additional object files that don't necessarily include source
112 EXT_OBJ =
113 # libraries to link in -- these will be specified as "-l" parameters, the -l
114 # is prepended automatically
115 #LIB = jpeg tiff png z
116 LIB = gd
117 # library paths -- where to search for the above libraries
118 LIBPATH =
119 # include paths -- where to search for #include files (in addition to the
120 # standard paths
121 INCPATH =
122 # garbage files that should be deleted on a 'make clean' or 'make tidy'
123 GARBAGE =
125 # extra dependencies - files that we don't necessarily know how to build, but
126 # that are required for building the application; e.g. object files or
127 # libraries in sub or parent directories
128 EXTDEP =
130 ####
131 # Win32 target-specific settings
132 ####
133 ifeq ($(strip $(PLATFORM)),win32)
134 # windows executables have a .exe suffix
135 TARGET := $(addsuffix .exe,$(TARGET))
136 # console mode application
137 EXT_CFLAGS = -mconsole
138 # additional libraries required by CImg on win32
139 LIB += gdi32
140 endif
142 ####
143 # Linux target-specific settings
144 ####
145 ifeq ($(strip $(PLATFORM)),linux)
146 # additional libraries required by CImg on linux
147 LIB += m pthread X11
148 endif
151 ####
152 # Tool setup
153 ####
154 MAKE = make
155 CC = gcc
156 CXX = g++
157 CFLAGS = -Wall -pedantic -std=gnu99 $(EXT_CFLAGS)
158 CXXFLAGS= -Wall -pedantic $(EXT_CXXFLAGS)
159 LDFLAGS = $(EXT_LDFLAGS)
160 RM = rm
161 STRIP = strip
163 ###############################################################################
164 # You should not need to touch anything below here, unless you're adding a new
165 # platform or build type (or changing the version string format)
166 ###############################################################################
168 ####
169 # A quick sanity check on the platform type
170 ####
171 ifneq ($(PLATFORM),linux)
172 ifneq ($(PLATFORM),win32)
173 $(error Platform '$(PLATFORM)' not supported. Supported platforms are: linux, win32)
174 endif
175 endif
177 ####
178 # Version info generation
179 ####
180 # get the current build number
181 VER_BUILDNUM = $(shell cat .buildnum)
183 # there are two ways to get the SVN rev - use svnversion, or use svn info
184 # then pipe through awk. which one you use is up to you.
185 VER_SVNREV = $(shell LANG=C svn info 2>/dev/null || echo 'Revision: 0' | awk '/^Revision:/ { print$$2 }' )
186 #VER_SVNREV = $(shell svnversion .)
188 # if the version string is "exported", then the CSD was not checked out of SVN
189 # note that if the CSD is not an SVN checkout, then @@svnrev@@ will be set to
190 # zero.
191 ifeq ($(VER_SVNREV),exported)
192 VER_SVNREV = 0
193 endif
195 # start creating the revision string
196 VER_FULLSTR = $(VER_MAJOR).$(VER_MINOR).$(VER_BUILDNUM)$(VER_EXTRA)
198 # if this is an SVN release, include the SVN revision in the version string
199 ifneq ($(VER_SVNREV),0)
200 VER_FULLSTR += (svn $(VER_SVNREV))
201 endif
204 ####
205 # Build-type specific configuration
206 ####
207 ifeq ($(BUILD_TYPE),debug)
208 CFLAGS += -g -ggdb
209 CXXFLAGS += -g -ggdb
210 else
211 ifeq ($(BUILD_TYPE),release)
212 CFLAGS += -O2
213 CXXFLAGS += -O2
214 else
215 $(error Unsupported build type: '$(BUILD_TYPE)')
216 endif
217 endif
219 ####
220 # rules
221 ####
223 # object files
224 OBJ = $(addprefix obj/, $(addsuffix .o, $(basename $(SRC))) $(EXT_OBJ)) $(addsuffix .o, $(basename $(EXTSRC)))
226 # dependency files
227 DEPFILES = $(addprefix dep/, $(addsuffix .d, $(basename $(SRC))) $(EXT_OBJ)) $(addsuffix .d, $(basename $(EXTSRC)))
229 # path commands
230 LIBLNK = $(addprefix -l, $(LIB))
231 LIBPTH = $(addprefix -L, $(LIBPATH))
232 INCPTH = $(addprefix -I, $(INCPATH))
234 CPPFLAGS += $(INCPTH)
236 ####
237 # Make sure there is at least one object file to be linked in
238 ####
239 ifeq ($(strip $(OBJ)),)
240 $(error Unable to build: no object or source files specified in Makefile)
241 endif
243 ####
244 # targets
245 ####
246 .PHONY: default all update-revision versionheader clean-versioninfo init cleandep clean tidy
248 all: update-revision
249 @$(MAKE) versionheader
250 $(MAKE) $(TARGET)
252 # increment the current build number
253 NEWBUILD=$(shell expr $(VER_BUILDNUM) + 1)
254 update-revision:
255 @echo $(NEWBUILD) > .buildnum
257 versionheader:
258 @sed -e 's/@@date@@/$(shell LC_ALL=C date)/g' \
259 -e 's/@@time@@/$(shell LC_ALL=C date +%T)/g' \
260 -e 's/@@whoami@@/$(shell whoami)/g' \
261 -e 's/@@hostname@@/$(shell hostname)/g' \
262 -e 's|@@compiler@@|$(shell $(CC) $(CFLAGS) -v 2>&1 | tail -n 1 | sed -e "s;|;/;")|g' \
263 -e 's/@@majorver@@/$(VER_MAJOR)/g' \
264 -e 's/@@minorver@@/$(VER_MINOR)/g' \
265 -e 's/@@extraver@@/$(subst \",,$(VER_EXTRA))/g' \
266 -e 's/@@buildnum@@/$(VER_BUILDNUM)/g' \
267 -e 's/@@buildtype@@/$(BUILD_TYPE)/g' \
268 -e 's/@@svnrev@@/$(VER_SVNREV)/g' \
269 -e 's/@@fullverstr@@/$(VER_FULLSTR)/g' \
270 -e 's/@@cflags@@/$(CFLAGS)/g' \
271 < src/version.h.in > src/version.h
273 # version.h creation stuff based on code from the Xen makefile
274 clean-versioninfo:
275 @if [ ! -r src/version.h -o -O src/version.h ]; then \
276 rm -f src/version.h; \
277 fi
278 @echo 0 > .buildnum
280 # initialise the build system for a new project
281 init:
282 @mkdir -p src dep obj
283 @echo 0 > .buildnum
284 @echo '#define VER_COMPILE_DATE "@@date@@"' > src/version.h.in
285 @echo '#define VER_COMPILE_TIME "@@time@@"' >> src/version.h.in
286 @echo '#define VER_COMPILE_BY "@@whoami@@"' >> src/version.h.in
287 @echo '#define VER_COMPILE_HOST "@@hostname@@"' >> src/version.h.in
288 @echo '#define VER_COMPILER "@@compiler@@"' >> src/version.h.in
289 @echo '#define VER_BUILD_TYPE "@@buildtype@@"' >> src/version.h.in
290 @echo '#define VER_CFLAGS "@@cflags@@"' >> src/version.h.in
291 @echo '' >> src/version.h.in
292 @echo '#define VER_MAJOR @@majorver@@' >> src/version.h.in
293 @echo '#define VER_MINOR @@minorver@@' >> src/version.h.in
294 @echo '#define VER_BUILDNUM @@buildnum@@' >> src/version.h.in
295 @echo '#define VER_EXTRA "@@extraver@@"' >> src/version.h.in
296 @echo '#define VER_SVNREV @@svnrev@@' >> src/version.h.in
297 @echo '' >> src/version.h.in
298 @echo '#define VER_FULLSTR "@@fullverstr@@"' >> src/version.h.in
299 @echo '' >> src/version.h.in
300 @echo Build system initialised
302 # remove the dependency files
303 cleandep:
304 -rm $(DEPFILES)
306 # remove the dependency files and any target or intermediate build files
307 clean: cleandep clean-versioninfo
308 -rm $(OBJ) $(TARGET) $(GARBAGE)
310 # remove any dependency or intermediate build files
311 tidy: cleandep clean-versioninfo
312 -rm $(OBJ) $(GARBAGE)
314 #################################
316 $(TARGET): $(OBJ) $(EXTDEP)
317 ifeq ($(SRC_TYPE),c)
318 $(CC) $(CXXFLAGS) $(LDFLAGS) $(OBJ) $(LIBPTH) $(LIBLNK) -o $@
319 else
320 $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJ) $(LIBPTH) $(LIBLNK) -o $@
321 endif
322 ifeq ($(BUILD_TYPE),release)
323 $(STRIP) $(TARGET)
324 endif
326 ###
327 # extra rules
328 # example:
329 #src/parser.c: src/parser.h
331 ####
332 # make object files from C source files
333 obj/%.o: src/%.c
334 $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
336 ##
337 # make object files from C++ source files
338 obj/%.o: src/%.cc
339 $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $< -o $@
341 obj/%.o: src/%.cpp
342 $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $< -o $@
344 ###
345 # make C files from yacc/bison source
346 src/%.h src/%.c: src/%.y
347 $(YACC) $(YFLAGS) -d $<
348 mv -f y.tab.c $*.c
349 mv -f y.tab.h $*.h
351 ###
352 # make C files from lex/flex source
353 src/%.c: src/%.l
354 $(LEX) $(LFLAGS) -o$@ $<
356 ###
357 # make dependencies for our source files
358 dep/%.d: src/%.c
359 $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
360 sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
361 rm -f $@.$$$$
363 dep/%.d: src/%.cpp
364 $(CXX) -MM $(CPPFLAGS) $< > $@.$$$$; \
365 sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
366 rm -f $@.$$$$
368 dep/%.d: src/%.cc
369 $(CXX) -MM $(CPPFLAGS) $< > $@.$$$$; \
370 sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
371 rm -f $@.$$$$
373 ####
374 # pull in the dependency files, but only for 'make $(TARGET)'
375 ####
377 ifeq ($(MAKECMDGOALS),$(TARGET))
378 -include $(DEPFILES)
379 endif