Makefile

Sat, 27 Nov 2010 01:13:12 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 27 Nov 2010 01:13:12 +0000
changeset 0
8bf1bf91a36d
child 3
916a2c764bde
permissions
-rw-r--r--

initial commit

     1 # Phil's multiplatform makefile template
     2 # With auto-incrementing build number and automatic version.h generation
     3 # Version 1.8, 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.8 - Now supports the use of the wxWidgets GUI framework. To turn
    88 #         this on, set ENABLE_WX to "yes".
    89 #   1.7 - Now creates a basic Hgignore file and directory keepers for the
    90 #         dep and obj directories.
    91 #   1.6 - Added CFLAGS and CXXFLAGS to the command-lines for the dependency
    92 #         building commands. This was causing issues with C99 / C++0x mode.
    93 #   1.5 - Added support for Mercurial revision (changeset ID) display
    94 #         Fixed a few issues with Subversion support (svn: and version 0 would
    95 #         be displayed for exported code)
    96 #
    98 ####
    99 # Build configuration
   100 ####
   102 # version information -- major.minor.extra
   103 # note that VER_EXTRA can be overridden on the command line, e.g.:
   104 # make VER_EXTRA=12345 all
   105 VER_MAJOR	= 0
   106 VER_MINOR	= 0
   107 VER_EXTRA	?= 
   109 # build platform: win32 or linux
   110 PLATFORM	?=	linux
   111 # build type: release or debug
   112 BUILD_TYPE	?=	debug
   114 # target executable
   115 TARGET		=	3b1emu
   117 # source files that produce object files
   118 SRC			=	main.c musashi/m68kcpu.c musashi/m68kops.c
   120 # source type - either "c" or "cpp" (C or C++)
   121 SRC_TYPE	=	c
   123 # additional object files that don't necessarily include source
   124 EXT_OBJ		=
   125 # libraries to link in -- these will be specified as "-l" parameters, the -l
   126 # is prepended automatically
   127 LIB			=	sdl
   128 # library paths -- where to search for the above libraries
   129 LIBPATH		=	musashi
   130 # include paths -- where to search for #include files (in addition to the
   131 # standard paths
   132 INCPATH		=	musashi
   133 # garbage files that should be deleted on a 'make clean' or 'make tidy'
   134 GARBAGE		=	obj/musashi/m68kmake obj/musashi/m68kmake.exe obj/musashi/m68kmake.o
   136 # extra dependencies - files that we don't necessarily know how to build, but
   137 # that are required for building the application; e.g. object files or
   138 # libraries in sub or parent directories
   139 EXTDEP		=
   141 # Extra libraries
   142 # wxWidgets: set to "yes" to enable, anything else to disable
   143 ENABLE_WX	=	no
   144 # wxWidgets: list of wxWidgets libraries to enable
   145 WX_LIBS		=	std
   147 ####
   148 # Win32 target-specific settings
   149 ####
   150 ifeq ($(strip $(PLATFORM)),win32)
   151 	# windows executables have a .exe suffix
   152 	TARGET := $(addsuffix .exe,$(TARGET))
   153 	# console mode application
   154 	EXT_CFLAGS = -mconsole
   155 endif
   158 ####
   159 # Tool setup
   160 ####
   161 MAKE	=	make
   162 CC		=	gcc
   163 CXX		=	g++
   164 CFLAGS	=	-Wall -pedantic -std=gnu99 $(EXT_CFLAGS)
   165 CXXFLAGS=	-Wall -pedantic -std=gnu++0x $(EXT_CXXFLAGS)
   166 LDFLAGS	=	$(EXT_LDFLAGS)
   167 RM		=	rm
   168 STRIP	=	strip
   170 ###############################################################################
   171 # You should not need to touch anything below here, unless you're adding a new
   172 # platform or build type (or changing the version string format)
   173 ###############################################################################
   175 ####
   176 # A quick sanity check on the platform type
   177 ####
   178 ifneq ($(PLATFORM),linux)
   179 ifneq ($(PLATFORM),win32)
   180     $(error Platform '$(PLATFORM)' not supported. Supported platforms are: linux, win32)
   181 endif
   182 endif
   184 ####
   185 # Version info generation
   186 ####
   187 # get the current build number
   188 VER_BUILDNUM	= $(shell cat .buildnum)
   190 #### --- begin Subversion revision grabber ---
   191 # there are two ways to get the SVN revision - use svnversion, or use svn info
   192 # then pipe through awk. which one you use is up to you.
   193 VER_SVNREV		= $(shell LANG=C svn info 2>/dev/null || echo 'Revision: exported' | awk '/^Revision:/ { print$$2 }' )
   194 #VER_SVNREV		= $(shell svnversion .)
   196 # if the version string is "exported", then the CSD was not checked out of SVN
   197 # note that if the CSD is not an SVN checkout, then @@svnrev@@ will be set to
   198 # zero.
   199 ifeq ($(VER_SVNREV),exported)
   200     VER_VCS		= none
   201     VER_VCSREV	= 0
   202 else
   203     VER_VCS		= svn
   204     VER_VCSREV	= $(VER_SVNREV)
   205 endif
   207 #### --- begin Mercurial revision grabber ---
   208 # If SVN didn't give us a revision, try Mercurial instead
   209 ifeq ($(VER_VCS),none)
   210     # get the current Mercurial changeset number
   211 	VER_HGREV=$(shell ((hg tip --template "{node|short}") || echo "000000000000") 2>/dev/null)
   212     ifneq ($(VER_HGREV),000000000000)
   213         # a non-empty repo
   214         VER_VCS		= hg
   215         VER_VCSREV	= $(VER_HGREV)
   216     else
   217         # either an empty Hg repo, or no repo at all
   218         VER_VCS		= none
   219         VER_VCSREV	= 0
   220     endif
   221 endif
   223 #### --- end version grabbers ---
   225 # start creating the revision string
   226 VER_FULLSTR		= $(VER_MAJOR).$(VER_MINOR).$(VER_BUILDNUM)$(VER_EXTRA)
   228 # if this is a VCS release, include the SVN revision in the version string
   229 # also create a revision string that is either "svn:12345", "hg:12345" or
   230 # blank
   231 ifneq ($(VER_VCS),none)
   232     VER_FULLSTR	+= ($(VER_VCS) $(VER_VCSREV))
   233     VER_VCSSTR	= $(VER_VCS):$(VER_VCSREV)
   234 else
   235     VER_VCSSTR	=
   236 endif
   239 ####
   240 # Build-type specific configuration
   241 ####
   242 ifeq ($(BUILD_TYPE),debug)
   243 	CFLAGS		+= -g -ggdb -DDEBUG
   244 	CXXFLAGS	+= -g -ggdb -DDEBUG
   245 else
   246  ifeq ($(BUILD_TYPE),release)
   247 	CFLAGS		+= -O2
   248 	CXXFLAGS	+= -O2
   249  else
   250  	$(error Unsupported build type: '$(BUILD_TYPE)')
   251  endif
   252 endif
   254 ####
   255 # wxWidgets support
   256 ####
   257 ifeq ($(ENABLE_WX),yes)
   258 	ifeq ($(BUILD_TYPE),debug)
   259 		LIBLNK		+=	`wx-config --debug --libs $(WX_LIBS)`
   260 		CFLAGS		+=	`wx-config --debug --cflags $(WX_LIBS)`
   261 		CXXFLAGS	+=	`wx-config --debug --cxxflags $(WX_LIBS)`
   262 		CPPFLAGS	+=	`wx-config --debug --cppflags $(WX_LIBS)`
   263 	else
   264 		ifeq ($(BUILD_TYPE),release)
   265 			LIBLNK		+=	`wx-config --libs $(WX_LIBS)`
   266 			CFLAGS		+=	`wx-config --cflags $(WX_LIBS)`
   267 			CPPFLAGS	+=	`wx-config --cppflags $(WX_LIBS)`
   268 			CXXFLAGS	+=	`wx-config --cxxflags $(WX_LIBS)`
   269 		else
   270 			$(error Unsupported build type: '$(BUILD_TYPE)')
   271 		endif
   272 	endif
   273 endif
   275 ####
   276 # rules
   277 ####
   279 # object files
   280 OBJ		=	$(addprefix obj/, $(addsuffix .o, $(basename $(SRC))) $(EXT_OBJ)) $(addsuffix .o, $(basename $(EXTSRC)))
   282 # dependency files
   283 DEPFILES =	$(addprefix dep/, $(addsuffix .d, $(basename $(SRC))) $(EXT_OBJ)) $(addsuffix .d, $(basename $(EXTSRC)))
   285 # path commands
   286 LIBLNK	+=	$(addprefix -l, $(LIB))
   287 LIBPTH	+=	$(addprefix -L, $(LIBPATH))
   288 INCPTH	+=	$(addprefix -I, $(INCPATH))
   290 CPPFLAGS +=	$(INCPTH)
   292 ####
   293 # Make sure there is at least one object file to be linked in
   294 ####
   295 ifeq ($(strip $(OBJ)),)
   296     $(error Unable to build: no object or source files specified in Makefile)
   297 endif
   299 ####
   300 # targets
   301 ####
   302 .PHONY:	default all update-revision versionheader clean-versioninfo init cleandep clean tidy
   304 all:	update-revision
   305 	@$(MAKE) versionheader
   306 	$(MAKE) $(TARGET)
   308 # increment the current build number
   309 NEWBUILD=$(shell expr $(VER_BUILDNUM) + 1)
   310 update-revision:
   311 	@echo $(NEWBUILD) > .buildnum
   313 versionheader:
   314 	@sed -e 's/@@date@@/$(shell LC_ALL=C date)/g'			\
   315 		 -e 's/@@time@@/$(shell LC_ALL=C date +%T)/g'		\
   316 		 -e 's/@@whoami@@/$(shell whoami)/g'				\
   317 		 -e 's/@@hostname@@/$(shell hostname)/g'			\
   318 		 -e 's|@@compiler@@|$(shell $(CC) $(CFLAGS) -v 2>&1 | tail -n 1 | sed -e "s;|;/;")|g'	\
   319 		 -e 's/@@majorver@@/$(VER_MAJOR)/g'					\
   320 		 -e 's/@@minorver@@/$(VER_MINOR)/g'					\
   321 		 -e 's/@@extraver@@/$(subst \",,$(VER_EXTRA))/g'	\
   322 		 -e 's/@@buildnum@@/$(VER_BUILDNUM)/g'				\
   323 		 -e 's/@@buildtype@@/$(BUILD_TYPE)/g'				\
   324 		 -e 's/@@vcs@@/$(VER_VCS)/g'						\
   325 		 -e 's/@@vcsrev@@/$(VER_VCSREV)/g'					\
   326 		 -e 's/@@vcsstr@@/$(VER_VCSSTR)/g'					\
   327 		 -e 's/@@fullverstr@@/$(VER_FULLSTR)/g'				\
   328 		 -e 's/@@cflags@@/$(CFLAGS)/g'						\
   329 		 < src/version.h.in > src/version.h
   331 # version.h creation stuff based on code from the Xen makefile
   332 clean-versioninfo:
   333 	@if [ ! -r src/version.h -o -O src/version.h ]; then \
   334 		rm -f src/version.h; \
   335 	fi
   336 	@echo 0 > .buildnum
   338 # initialise the build system for a new project
   339 init:
   340 	@mkdir -p src dep obj
   341 	@echo "This file is a directory-keeper. Do not delete it." > dep/.keepme
   342 	@echo "This file is a directory-keeper. Do not delete it." > obj/.keepme
   343 	@echo 0 > .buildnum
   344 	@echo 'syntax: glob' > .hgignore
   345 	@echo 'obj/*.o' >> .hgignore
   346 	@echo 'dep/*.d' >> .hgignore
   347 	@echo '*~' >> .hgignore
   348 	@echo '.*.sw?' >> .hgignore
   349 	@echo '#define VER_COMPILE_DATE	"@@date@@"'				> src/version.h.in
   350 	@echo '#define VER_COMPILE_TIME	"@@time@@"'				>> src/version.h.in
   351 	@echo '#define VER_COMPILE_BY		"@@whoami@@"'		>> src/version.h.in
   352 	@echo '#define VER_COMPILE_HOST	"@@hostname@@"'			>> src/version.h.in
   353 	@echo '#define VER_COMPILER		"@@compiler@@"'			>> src/version.h.in
   354 	@echo '#define VER_BUILD_TYPE		"@@buildtype@@"'	>> src/version.h.in
   355 	@echo '#define VER_CFLAGS			"@@cflags@@"'		>> src/version.h.in
   356 	@echo ''												>> src/version.h.in
   357 	@echo '#define VER_MAJOR			@@majorver@@'		>> src/version.h.in
   358 	@echo '#define VER_MINOR			@@minorver@@'		>> src/version.h.in
   359 	@echo '#define VER_BUILDNUM		@@buildnum@@'			>> src/version.h.in
   360 	@echo '#define VER_EXTRA			"@@extraver@@"'		>> src/version.h.in
   361 	@echo '#define VER_VCSREV			"@@vcsstr@@"'		>> src/version.h.in
   362 	@echo ''												>> src/version.h.in
   363 	@echo '#define VER_FULLSTR			"@@fullverstr@@"'	>> src/version.h.in
   364 	@echo ''												>> src/version.h.in
   365 	@echo Build system initialised
   367 # remove the dependency files
   368 cleandep:
   369 	-rm $(DEPFILES)
   371 # remove the dependency files and any target or intermediate build files
   372 clean:	cleandep clean-versioninfo
   373 	-rm $(OBJ) $(TARGET) $(GARBAGE)
   375 # remove any dependency or intermediate build files
   376 tidy:	cleandep clean-versioninfo
   377 	-rm $(OBJ) $(GARBAGE)
   379 #################################
   381 $(TARGET):	$(OBJ) $(EXTDEP)
   382 ifeq ($(SRC_TYPE),c)
   383 	$(CC) $(CXXFLAGS) $(LDFLAGS) $(OBJ) $(LIBPTH) $(LIBLNK) -o $@
   384 else
   385 	$(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJ) $(LIBPTH) $(LIBLNK) -o $@
   386 endif
   387 ifeq ($(BUILD_TYPE),release)
   388 	$(STRIP) $(TARGET)
   389 endif
   391 ###
   392 # extra rules
   393 # example:
   394 #src/parser.c:	src/parser.h
   397 ####
   398 ## musashi build rules
   399 # 68k CPU builder
   400 obj/musashi/m68kmake:	obj/musashi/m68kmake.o
   401 	$(CC) $(CFLAGS) $(CPPFLAGS) obj/musashi/m68kmake.o -o $@
   402 # 68k CPU sources
   403 src/musashi/m68kops.h src/musashi/m68kops.c:	obj/musashi/m68kmake src/musashi/m68k_in.c
   404 	./obj/musashi/m68kmake src/musashi src/musashi/m68k_in.c
   406 ####
   407 # make object files from C source files
   408 obj/%.o:	src/%.c
   409 	$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
   411 ##
   412 # make object files from C++ source files
   413 obj/%.o:	src/%.cc
   414 	$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $< -o $@
   416 obj/%.o:	src/%.cpp
   417 	$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $< -o $@
   419 ###
   420 # make C files from yacc/bison source
   421 src/%.h src/%.c:	src/%.y
   422 	$(YACC) $(YFLAGS) -d $<
   423 	mv -f y.tab.c $*.c
   424 	mv -f y.tab.h $*.h
   426 ###
   427 # make C files from lex/flex source
   428 src/%.c:	src/%.l
   429 	$(LEX) $(LFLAGS) -o$@ $<
   431 ###
   432 # make dependencies for our source files
   433 dep/%.d:	src/%.c
   434 	$(CC) -MM $(CFLAGS) $(CPPFLAGS) $< > $@.$$$$; \
   435 		sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
   436 		rm -f $@.$$$$
   438 dep/%.d:	src/%.cpp
   439 	$(CXX) -MM $(CXXFLAGS) $(CPPFLAGS) $< > $@.$$$$; \
   440 		sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
   441 		rm -f $@.$$$$
   443 dep/%.d:	src/%.cc
   444 	$(CXX) -MM $(CXXFLAGS) $(CPPFLAGS) $< > $@.$$$$; \
   445 		sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
   446 		rm -f $@.$$$$
   448 ####
   449 # pull in the dependency files, but only for 'make $(TARGET)'
   450 ####
   452 ifeq ($(MAKECMDGOALS),$(TARGET))
   453   -include $(DEPFILES)
   454 endif