Makefile

changeset 0
0eef8cf74b80
child 4
5edfbd3e7a46
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Makefile	Wed Apr 01 22:11:05 2009 +0100
     1.3 @@ -0,0 +1,379 @@
     1.4 +# Phil's multiplatform makefile template
     1.5 +# With auto-incrementing build number and automatic version.h generation
     1.6 +# Version 1.4, 2009-01-27
     1.7 +#
     1.8 +# The latest version of this Makefile can be found at http://www.philpem.me.uk/
     1.9 +#
    1.10 +#
    1.11 +# Copyright (c) 2009 Philip Pemberton <code@philpem.me.uk>
    1.12 +#
    1.13 +# Permission is hereby granted, free of charge, to any person obtaining a copy
    1.14 +# of this software and associated documentation files (the "Software"), to deal
    1.15 +# in the Software without restriction, including without limitation the rights
    1.16 +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    1.17 +# copies of the Software, and to permit persons to whom the Software is
    1.18 +# furnished to do so, subject to the following conditions:
    1.19 +#
    1.20 +# The above copyright notice and this permission notice shall be included in
    1.21 +# all copies or substantial portions of the Software.
    1.22 +#
    1.23 +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    1.24 +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    1.25 +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    1.26 +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    1.27 +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    1.28 +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    1.29 +# THE SOFTWARE.
    1.30 +#
    1.31 +#
    1.32 +# Instructions for use:
    1.33 +#   Run 'make init' to create the required directories
    1.34 +#   Add your source files to the 'SOURCES' list, and change the TARGET filename
    1.35 +#   Set the desired build type and platform in the BUILD_TYPE and PLATFORM
    1.36 +#     variables respectively
    1.37 +#   Set your project type (C only, or C++) in the SRC_TYPE variable
    1.38 +#   Add any libraries you need to link against to the 'LIB' list
    1.39 +#   Run 'make'
    1.40 +#
    1.41 +# Object files are created in the 'obj' subdirectory, from source code in the
    1.42 +# 'src' directory. Dependency files are created in the 'dep' directory from
    1.43 +# the same source code the object files are created from.
    1.44 +#
    1.45 +# Supported targets are:
    1.46 +#   all                 Build everything.
    1.47 +#   update-revision     Increment the build number without building anything.
    1.48 +#   clean-versioninfo   Delete src/version.h (will be rebuilt on the next
    1.49 +#                       'make all').
    1.50 +#   init                Initialise the build system for a new project.
    1.51 +#                       WARNING: overwrites .buildnum and src/version.h.in!
    1.52 +#   cleandep            Delete all dependency files.
    1.53 +#   clean               Delete all dependency, intermediate and target files.
    1.54 +#   tidy                Delete all dependency and intermediate files, leaving
    1.55 +#                       the target file intact.
    1.56 +#
    1.57 +# If you want to reset the build number to zero, delete '.buildnum'. This
    1.58 +# should be done whenever the major or minor version changes. Excluding
    1.59 +# .buildnum from version control may also be a good idea, depending on how
    1.60 +# you want your build numbers to work.
    1.61 +#
    1.62 +# The BUILD_TYPE variable contains the current build type. There are two
    1.63 +# supported build types:
    1.64 +#   debug       Debug mode - object files are compiled with debug information
    1.65 +#               and the target is left unstripped.
    1.66 +#   release     Release mode - object files are not compiled with debug info,
    1.67 +#               and the target is fed through strip to remove redundant
    1.68 +#               data.
    1.69 +#
    1.70 +# The PLATFORM variable contains the current target platform. There are two
    1.71 +# supported platforms:
    1.72 +#   linux       GNU/Linux with GNU Compiler Collection
    1.73 +#   win32       Windows 32-bit with MinGW
    1.74 +#
    1.75 +# The EXTSRC variable is used to specify other files to build. It is typically
    1.76 +# used to specify platform or build-type specific source files, e.g.
    1.77 +#
    1.78 +# ifeq ($(BUILD_TYPE),debug-memwatch)
    1.79 +#   CFLAGS += -g -ggdb
    1.80 +#   CPPFLAGS += -DMEMWATCH
    1.81 +#   INCPATH += ./memwatch
    1.82 +#   EXTSRC += memwatch/memwatch.c
    1.83 +# endif
    1.84 +#
    1.85 +# (example taken from one of my projects that allowed the use of Memwatch to
    1.86 +#  track down memory allocation/deallocation bugs)
    1.87 +#
    1.88 +
    1.89 +####
    1.90 +# Build configuration
    1.91 +####
    1.92 +
    1.93 +# version information -- major.minor.extra
    1.94 +# note that VER_EXTRA can be overridden on the command line, e.g.:
    1.95 +# make VER_EXTRA=12345 all
    1.96 +VER_MAJOR	= 0
    1.97 +VER_MINOR	= 0
    1.98 +VER_EXTRA	?= 
    1.99 +
   1.100 +# build platform: win32 or linux
   1.101 +PLATFORM	?=	linux
   1.102 +# build type: release or debug
   1.103 +BUILD_TYPE	?=	debug
   1.104 +
   1.105 +# target executable
   1.106 +TARGET		=	ptouch
   1.107 +
   1.108 +# source files that produce object files
   1.109 +SRC			=	main.c hexdump.c
   1.110 +
   1.111 +# source type - either "c" or "cpp" (C or C++)
   1.112 +SRC_TYPE	=	c
   1.113 +
   1.114 +# additional object files that don't necessarily include source
   1.115 +EXT_OBJ		=
   1.116 +# libraries to link in -- these will be specified as "-l" parameters, the -l
   1.117 +# is prepended automatically
   1.118 +#LIB			=	jpeg tiff png z
   1.119 +LIB			=
   1.120 +# library paths -- where to search for the above libraries
   1.121 +LIBPATH		=
   1.122 +# include paths -- where to search for #include files (in addition to the
   1.123 +# standard paths
   1.124 +INCPATH		=
   1.125 +# garbage files that should be deleted on a 'make clean' or 'make tidy'
   1.126 +GARBAGE		=
   1.127 +
   1.128 +# extra dependencies - files that we don't necessarily know how to build, but
   1.129 +# that are required for building the application; e.g. object files or
   1.130 +# libraries in sub or parent directories
   1.131 +EXTDEP		=
   1.132 +
   1.133 +####
   1.134 +# Win32 target-specific settings
   1.135 +####
   1.136 +ifeq ($(strip $(PLATFORM)),win32)
   1.137 +	# windows executables have a .exe suffix
   1.138 +	TARGET := $(addsuffix .exe,$(TARGET))
   1.139 +	# console mode application
   1.140 +	EXT_CFLAGS = -mconsole
   1.141 +	# additional libraries required by CImg on win32
   1.142 +	LIB += gdi32
   1.143 +endif
   1.144 +
   1.145 +####
   1.146 +# Linux target-specific settings
   1.147 +####
   1.148 +ifeq ($(strip $(PLATFORM)),linux)
   1.149 +	# additional libraries required by CImg on linux
   1.150 +	LIB += m pthread X11
   1.151 +endif
   1.152 +
   1.153 +
   1.154 +####
   1.155 +# Tool setup
   1.156 +####
   1.157 +MAKE	=	make
   1.158 +CC		=	gcc
   1.159 +CXX		=	g++
   1.160 +CFLAGS	=	-Wall -pedantic -std=gnu99 $(EXT_CFLAGS)
   1.161 +CXXFLAGS=	-Wall -pedantic $(EXT_CXXFLAGS)
   1.162 +LDFLAGS	=	$(EXT_LDFLAGS)
   1.163 +RM		=	rm
   1.164 +STRIP	=	strip
   1.165 +
   1.166 +###############################################################################
   1.167 +# You should not need to touch anything below here, unless you're adding a new
   1.168 +# platform or build type (or changing the version string format)
   1.169 +###############################################################################
   1.170 +
   1.171 +####
   1.172 +# A quick sanity check on the platform type
   1.173 +####
   1.174 +ifneq ($(PLATFORM),linux)
   1.175 +ifneq ($(PLATFORM),win32)
   1.176 +    $(error Platform '$(PLATFORM)' not supported. Supported platforms are: linux, win32)
   1.177 +endif
   1.178 +endif
   1.179 +
   1.180 +####
   1.181 +# Version info generation
   1.182 +####
   1.183 +# get the current build number
   1.184 +VER_BUILDNUM	= $(shell cat .buildnum)
   1.185 +
   1.186 +# there are two ways to get the SVN rev - use svnversion, or use svn info
   1.187 +# then pipe through awk. which one you use is up to you.
   1.188 +VER_SVNREV		= $(shell LANG=C svn info 2>/dev/null || echo 'Revision: 0' | awk '/^Revision:/ { print$$2 }' )
   1.189 +#VER_SVNREV		= $(shell svnversion .)
   1.190 +
   1.191 +# if the version string is "exported", then the CSD was not checked out of SVN
   1.192 +# note that if the CSD is not an SVN checkout, then @@svnrev@@ will be set to
   1.193 +# zero.
   1.194 +ifeq ($(VER_SVNREV),exported)
   1.195 +    VER_SVNREV	= 0
   1.196 +endif
   1.197 +
   1.198 +# start creating the revision string
   1.199 +VER_FULLSTR		= $(VER_MAJOR).$(VER_MINOR).$(VER_BUILDNUM)$(VER_EXTRA)
   1.200 +
   1.201 +# if this is an SVN release, include the SVN revision in the version string
   1.202 +ifneq ($(VER_SVNREV),0)
   1.203 +    VER_FULLSTR	+= (svn $(VER_SVNREV))
   1.204 +endif
   1.205 +
   1.206 +
   1.207 +####
   1.208 +# Build-type specific configuration
   1.209 +####
   1.210 +ifeq ($(BUILD_TYPE),debug)
   1.211 +	CFLAGS		+= -g -ggdb
   1.212 +	CXXFLAGS	+= -g -ggdb
   1.213 +else
   1.214 + ifeq ($(BUILD_TYPE),release)
   1.215 +	CFLAGS		+= -O2
   1.216 +	CXXFLAGS	+= -O2
   1.217 + else
   1.218 + 	$(error Unsupported build type: '$(BUILD_TYPE)')
   1.219 + endif
   1.220 +endif
   1.221 +
   1.222 +####
   1.223 +# rules
   1.224 +####
   1.225 +
   1.226 +# object files
   1.227 +OBJ		=	$(addprefix obj/, $(addsuffix .o, $(basename $(SRC))) $(EXT_OBJ)) $(addsuffix .o, $(basename $(EXTSRC)))
   1.228 +
   1.229 +# dependency files
   1.230 +DEPFILES =	$(addprefix dep/, $(addsuffix .d, $(basename $(SRC))) $(EXT_OBJ)) $(addsuffix .d, $(basename $(EXTSRC)))
   1.231 +
   1.232 +# path commands
   1.233 +LIBLNK	=	$(addprefix -l, $(LIB))
   1.234 +LIBPTH	=	$(addprefix -L, $(LIBPATH))
   1.235 +INCPTH	=	$(addprefix -I, $(INCPATH))
   1.236 +
   1.237 +CPPFLAGS +=	$(INCPTH)
   1.238 +
   1.239 +####
   1.240 +# Make sure there is at least one object file to be linked in
   1.241 +####
   1.242 +ifeq ($(strip $(OBJ)),)
   1.243 +    $(error Unable to build: no object or source files specified in Makefile)
   1.244 +endif
   1.245 +
   1.246 +####
   1.247 +# targets
   1.248 +####
   1.249 +.PHONY:	default all update-revision versionheader clean-versioninfo init cleandep clean tidy
   1.250 +
   1.251 +all:	update-revision
   1.252 +	@$(MAKE) versionheader
   1.253 +	$(MAKE) $(TARGET)
   1.254 +
   1.255 +# increment the current build number
   1.256 +NEWBUILD=$(shell expr $(VER_BUILDNUM) + 1)
   1.257 +update-revision:
   1.258 +	@echo $(NEWBUILD) > .buildnum
   1.259 +
   1.260 +versionheader:
   1.261 +	@sed -e 's/@@date@@/$(shell LC_ALL=C date)/g'			\
   1.262 +		 -e 's/@@time@@/$(shell LC_ALL=C date +%T)/g'		\
   1.263 +		 -e 's/@@whoami@@/$(shell whoami)/g'				\
   1.264 +		 -e 's/@@hostname@@/$(shell hostname)/g'			\
   1.265 +		 -e 's|@@compiler@@|$(shell $(CC) $(CFLAGS) -v 2>&1 | tail -n 1 | sed -e "s;|;/;")|g'	\
   1.266 +		 -e 's/@@majorver@@/$(VER_MAJOR)/g'					\
   1.267 +		 -e 's/@@minorver@@/$(VER_MINOR)/g'					\
   1.268 +		 -e 's/@@extraver@@/$(subst \",,$(VER_EXTRA))/g'	\
   1.269 +		 -e 's/@@buildnum@@/$(VER_BUILDNUM)/g'				\
   1.270 +		 -e 's/@@buildtype@@/$(BUILD_TYPE)/g'				\
   1.271 +		 -e 's/@@svnrev@@/$(VER_SVNREV)/g'					\
   1.272 +		 -e 's/@@fullverstr@@/$(VER_FULLSTR)/g'				\
   1.273 +		 -e 's/@@cflags@@/$(CFLAGS)/g'						\
   1.274 +		 < src/version.h.in > src/version.h
   1.275 +
   1.276 +# version.h creation stuff based on code from the Xen makefile
   1.277 +clean-versioninfo:
   1.278 +	@if [ ! -r src/version.h -o -O src/version.h ]; then \
   1.279 +		rm -f src/version.h; \
   1.280 +	fi
   1.281 +	@echo 0 > .buildnum
   1.282 +
   1.283 +# initialise the build system for a new project
   1.284 +init:
   1.285 +	@mkdir -p src dep obj
   1.286 +	@echo 0 > .buildnum
   1.287 +	@echo '#define VER_COMPILE_DATE	"@@date@@"'				> src/version.h.in
   1.288 +	@echo '#define VER_COMPILE_TIME	"@@time@@"'				>> src/version.h.in
   1.289 +	@echo '#define VER_COMPILE_BY		"@@whoami@@"'		>> src/version.h.in
   1.290 +	@echo '#define VER_COMPILE_HOST	"@@hostname@@"'			>> src/version.h.in
   1.291 +	@echo '#define VER_COMPILER		"@@compiler@@"'			>> src/version.h.in
   1.292 +	@echo '#define VER_BUILD_TYPE		"@@buildtype@@"'	>> src/version.h.in
   1.293 +	@echo '#define VER_CFLAGS			"@@cflags@@"'		>> src/version.h.in
   1.294 +	@echo ''												>> src/version.h.in
   1.295 +	@echo '#define VER_MAJOR			@@majorver@@'		>> src/version.h.in
   1.296 +	@echo '#define VER_MINOR			@@minorver@@'		>> src/version.h.in
   1.297 +	@echo '#define VER_BUILDNUM		@@buildnum@@'			>> src/version.h.in
   1.298 +	@echo '#define VER_EXTRA			"@@extraver@@"'		>> src/version.h.in
   1.299 +	@echo '#define VER_SVNREV			@@svnrev@@'			>> src/version.h.in
   1.300 +	@echo ''												>> src/version.h.in
   1.301 +	@echo '#define VER_FULLSTR			"@@fullverstr@@"'	>> src/version.h.in
   1.302 +	@echo ''												>> src/version.h.in
   1.303 +	@echo Build system initialised
   1.304 +
   1.305 +# remove the dependency files
   1.306 +cleandep:
   1.307 +	-rm $(DEPFILES)
   1.308 +
   1.309 +# remove the dependency files and any target or intermediate build files
   1.310 +clean:	cleandep clean-versioninfo
   1.311 +	-rm $(OBJ) $(TARGET) $(GARBAGE)
   1.312 +
   1.313 +# remove any dependency or intermediate build files
   1.314 +tidy:	cleandep clean-versioninfo
   1.315 +	-rm $(OBJ) $(GARBAGE)
   1.316 +
   1.317 +#################################
   1.318 +
   1.319 +$(TARGET):	$(OBJ) $(EXTDEP)
   1.320 +ifeq ($(SRC_TYPE),c)
   1.321 +	$(CC) $(CXXFLAGS) $(LDFLAGS) $(OBJ) $(LIBPTH) $(LIBLNK) -o $@
   1.322 +else
   1.323 +	$(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJ) $(LIBPTH) $(LIBLNK) -o $@
   1.324 +endif
   1.325 +ifeq ($(BUILD_TYPE),release)
   1.326 +	$(STRIP) $(TARGET)
   1.327 +endif
   1.328 +
   1.329 +###
   1.330 +# extra rules
   1.331 +# example:
   1.332 +#src/parser.c:	src/parser.h
   1.333 +
   1.334 +####
   1.335 +# make object files from C source files
   1.336 +obj/%.o:	src/%.c
   1.337 +	$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
   1.338 +
   1.339 +##
   1.340 +# make object files from C++ source files
   1.341 +obj/%.o:	src/%.cc
   1.342 +	$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $< -o $@
   1.343 +
   1.344 +obj/%.o:	src/%.cpp
   1.345 +	$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $< -o $@
   1.346 +
   1.347 +###
   1.348 +# make C files from yacc/bison source
   1.349 +src/%.h src/%.c:	src/%.y
   1.350 +	$(YACC) $(YFLAGS) -d $<
   1.351 +	mv -f y.tab.c $*.c
   1.352 +	mv -f y.tab.h $*.h
   1.353 +
   1.354 +###
   1.355 +# make C files from lex/flex source
   1.356 +src/%.c:	src/%.l
   1.357 +	$(LEX) $(LFLAGS) -o$@ $<
   1.358 +
   1.359 +###
   1.360 +# make dependencies for our source files
   1.361 +dep/%.d:	src/%.c
   1.362 +	$(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
   1.363 +		sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
   1.364 +		rm -f $@.$$$$
   1.365 +
   1.366 +dep/%.d:	src/%.cpp
   1.367 +	$(CXX) -MM $(CPPFLAGS) $< > $@.$$$$; \
   1.368 +		sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
   1.369 +		rm -f $@.$$$$
   1.370 +
   1.371 +dep/%.d:	src/%.cc
   1.372 +	$(CXX) -MM $(CPPFLAGS) $< > $@.$$$$; \
   1.373 +		sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
   1.374 +		rm -f $@.$$$$
   1.375 +
   1.376 +####
   1.377 +# pull in the dependency files, but only for 'make $(TARGET)'
   1.378 +####
   1.379 +
   1.380 +ifeq ($(MAKECMDGOALS),$(TARGET))
   1.381 +  -include $(DEPFILES)
   1.382 +endif