Makefile

Mon, 03 Aug 2009 23:39:53 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 03 Aug 2009 23:39:53 +0100
changeset 10
604c205d9163
parent 9
ebce4a7615e9
permissions
-rw-r--r--

add basic test routine for Ptouch library

     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