Makefile

Sun, 28 Nov 2010 03:17:08 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sun, 28 Nov 2010 03:17:08 +0000
changeset 5
6a0c1ee6f6ca
parent 3
916a2c764bde
child 6
5dc2f3565377
permissions
-rw-r--r--

update hgignore

     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 musashi/m68kopac.c musashi/m68kopdm.c musashi/m68kopnz.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			=
   128 # library paths -- where to search for the above libraries
   129 LIBPATH		=
   130 # include paths -- where to search for #include files (in addition to the
   131 # standard paths
   132 INCPATH		=
   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
   146 # SDL: set to "yes" to enable, anything else to disable
   147 ENABLE_SDL	=	yes
   149 ####
   150 # Win32 target-specific settings
   151 ####
   152 ifeq ($(strip $(PLATFORM)),win32)
   153 	# windows executables have a .exe suffix
   154 	TARGET := $(addsuffix .exe,$(TARGET))
   155 	# console mode application
   156 	EXT_CFLAGS = -mconsole
   157 endif
   160 ####
   161 # Tool setup
   162 ####
   163 MAKE	=	make
   164 CC		=	gcc
   165 CXX		=	g++
   166 CFLAGS	=	-Wall -pedantic -std=gnu99 $(EXT_CFLAGS)
   167 CXXFLAGS=	-Wall -pedantic -std=gnu++0x $(EXT_CXXFLAGS)
   168 LDFLAGS	=	$(EXT_LDFLAGS)
   169 RM		=	rm
   170 STRIP	=	strip
   172 ###############################################################################
   173 # You should not need to touch anything below here, unless you're adding a new
   174 # platform or build type (or changing the version string format)
   175 ###############################################################################
   177 ####
   178 # A quick sanity check on the platform type
   179 ####
   180 ifneq ($(PLATFORM),linux)
   181 ifneq ($(PLATFORM),win32)
   182     $(error Platform '$(PLATFORM)' not supported. Supported platforms are: linux, win32)
   183 endif
   184 endif
   186 ####
   187 # Version info generation
   188 ####
   189 # get the current build number
   190 VER_BUILDNUM	= $(shell cat .buildnum)
   192 #### --- begin Subversion revision grabber ---
   193 # there are two ways to get the SVN revision - use svnversion, or use svn info
   194 # then pipe through awk. which one you use is up to you.
   195 VER_SVNREV		= $(shell LANG=C svn info 2>/dev/null || echo 'Revision: exported' | awk '/^Revision:/ { print$$2 }' )
   196 #VER_SVNREV		= $(shell svnversion .)
   198 # if the version string is "exported", then the CSD was not checked out of SVN
   199 # note that if the CSD is not an SVN checkout, then @@svnrev@@ will be set to
   200 # zero.
   201 ifeq ($(VER_SVNREV),exported)
   202     VER_VCS		= none
   203     VER_VCSREV	= 0
   204 else
   205     VER_VCS		= svn
   206     VER_VCSREV	= $(VER_SVNREV)
   207 endif
   209 #### --- begin Mercurial revision grabber ---
   210 # If SVN didn't give us a revision, try Mercurial instead
   211 ifeq ($(VER_VCS),none)
   212     # get the current Mercurial changeset number
   213 	VER_HGREV=$(shell ((hg tip --template "{node|short}") || echo "000000000000") 2>/dev/null)
   214     ifneq ($(VER_HGREV),000000000000)
   215         # a non-empty repo
   216         VER_VCS		= hg
   217         VER_VCSREV	= $(VER_HGREV)
   218     else
   219         # either an empty Hg repo, or no repo at all
   220         VER_VCS		= none
   221         VER_VCSREV	= 0
   222     endif
   223 endif
   225 #### --- end version grabbers ---
   227 # start creating the revision string
   228 VER_FULLSTR		= $(VER_MAJOR).$(VER_MINOR).$(VER_BUILDNUM)$(VER_EXTRA)
   230 # if this is a VCS release, include the SVN revision in the version string
   231 # also create a revision string that is either "svn:12345", "hg:12345" or
   232 # blank
   233 ifneq ($(VER_VCS),none)
   234     VER_FULLSTR	+= ($(VER_VCS) $(VER_VCSREV))
   235     VER_VCSSTR	= $(VER_VCS):$(VER_VCSREV)
   236 else
   237     VER_VCSSTR	=
   238 endif
   241 ####
   242 # Build-type specific configuration
   243 ####
   244 ifeq ($(BUILD_TYPE),debug)
   245 	CFLAGS		+= -g -ggdb -DDEBUG
   246 	CXXFLAGS	+= -g -ggdb -DDEBUG
   247 else
   248  ifeq ($(BUILD_TYPE),release)
   249 	CFLAGS		+= -O2
   250 	CXXFLAGS	+= -O2
   251  else
   252  	$(error Unsupported build type: '$(BUILD_TYPE)')
   253  endif
   254 endif
   256 ####
   257 # wxWidgets support
   258 ####
   259 ifeq ($(ENABLE_WX),yes)
   260 	ifeq ($(BUILD_TYPE),debug)
   261 		LIBLNK		+=	`wx-config --debug --libs $(WX_LIBS)`
   262 		CFLAGS		+=	`wx-config --debug --cflags $(WX_LIBS)`
   263 		CXXFLAGS	+=	`wx-config --debug --cxxflags $(WX_LIBS)`
   264 		CPPFLAGS	+=	`wx-config --debug --cppflags $(WX_LIBS)`
   265 	else
   266 		ifeq ($(BUILD_TYPE),release)
   267 			LIBLNK		+=	`wx-config --libs $(WX_LIBS)`
   268 			CFLAGS		+=	`wx-config --cflags $(WX_LIBS)`
   269 			CPPFLAGS	+=	`wx-config --cppflags $(WX_LIBS)`
   270 			CXXFLAGS	+=	`wx-config --cxxflags $(WX_LIBS)`
   271 		else
   272 			$(error Unsupported build type: '$(BUILD_TYPE)')
   273 		endif
   274 	endif
   275 endif
   277 ####
   278 # SDL support
   279 ####
   280 ifeq ($(ENABLE_SDL),yes)
   281 	LIBLNK		+=	`sdl-config --libs`
   282 	CFLAGS		+=	`sdl-config --cflags`
   283 endif
   286 ####
   287 # rules
   288 ####
   290 # object files
   291 OBJ		=	$(addprefix obj/, $(addsuffix .o, $(basename $(SRC))) $(EXT_OBJ)) $(addsuffix .o, $(basename $(EXTSRC)))
   293 # dependency files
   294 DEPFILES =	$(addprefix dep/, $(addsuffix .d, $(basename $(SRC))) $(EXT_OBJ)) $(addsuffix .d, $(basename $(EXTSRC)))
   296 # path commands
   297 LIBLNK	+=	$(addprefix -l, $(LIB))
   298 LIBPTH	+=	$(addprefix -L, $(LIBPATH))
   299 INCPTH	+=	$(addprefix -I, $(INCPATH))
   301 CPPFLAGS +=	$(INCPTH)
   303 ####
   304 # Make sure there is at least one object file to be linked in
   305 ####
   306 ifeq ($(strip $(OBJ)),)
   307     $(error Unable to build: no object or source files specified in Makefile)
   308 endif
   310 ####
   311 # targets
   312 ####
   313 .PHONY:	default all update-revision versionheader clean-versioninfo init cleandep clean tidy
   315 all:	update-revision
   316 	@$(MAKE) versionheader
   317 	$(MAKE) $(TARGET)
   319 # increment the current build number
   320 NEWBUILD=$(shell expr $(VER_BUILDNUM) + 1)
   321 update-revision:
   322 	@echo $(NEWBUILD) > .buildnum
   324 versionheader:
   325 	@sed -e 's/@@date@@/$(shell LC_ALL=C date)/g'			\
   326 		 -e 's/@@time@@/$(shell LC_ALL=C date +%T)/g'		\
   327 		 -e 's/@@whoami@@/$(shell whoami)/g'				\
   328 		 -e 's/@@hostname@@/$(shell hostname)/g'			\
   329 		 -e 's|@@compiler@@|$(shell $(CC) $(CFLAGS) -v 2>&1 | tail -n 1 | sed -e "s;|;/;")|g'	\
   330 		 -e 's/@@majorver@@/$(VER_MAJOR)/g'					\
   331 		 -e 's/@@minorver@@/$(VER_MINOR)/g'					\
   332 		 -e 's/@@extraver@@/$(subst \",,$(VER_EXTRA))/g'	\
   333 		 -e 's/@@buildnum@@/$(VER_BUILDNUM)/g'				\
   334 		 -e 's/@@buildtype@@/$(BUILD_TYPE)/g'				\
   335 		 -e 's/@@vcs@@/$(VER_VCS)/g'						\
   336 		 -e 's/@@vcsrev@@/$(VER_VCSREV)/g'					\
   337 		 -e 's/@@vcsstr@@/$(VER_VCSSTR)/g'					\
   338 		 -e 's/@@fullverstr@@/$(VER_FULLSTR)/g'				\
   339 		 -e 's/@@cflags@@/$(CFLAGS)/g'						\
   340 		 < src/version.h.in > src/version.h
   342 # version.h creation stuff based on code from the Xen makefile
   343 clean-versioninfo:
   344 	@if [ ! -r src/version.h -o -O src/version.h ]; then \
   345 		rm -f src/version.h; \
   346 	fi
   347 	@echo 0 > .buildnum
   349 # initialise the build system for a new project
   350 init:
   351 	@mkdir -p src dep obj
   352 	@echo "This file is a directory-keeper. Do not delete it." > dep/.keepme
   353 	@echo "This file is a directory-keeper. Do not delete it." > obj/.keepme
   354 	@echo 0 > .buildnum
   355 	@echo 'syntax: glob' > .hgignore
   356 	@echo 'obj/*.o' >> .hgignore
   357 	@echo 'dep/*.d' >> .hgignore
   358 	@echo '*~' >> .hgignore
   359 	@echo '.*.sw?' >> .hgignore
   360 	@echo '#define VER_COMPILE_DATE	"@@date@@"'				> src/version.h.in
   361 	@echo '#define VER_COMPILE_TIME	"@@time@@"'				>> src/version.h.in
   362 	@echo '#define VER_COMPILE_BY		"@@whoami@@"'		>> src/version.h.in
   363 	@echo '#define VER_COMPILE_HOST	"@@hostname@@"'			>> src/version.h.in
   364 	@echo '#define VER_COMPILER		"@@compiler@@"'			>> src/version.h.in
   365 	@echo '#define VER_BUILD_TYPE		"@@buildtype@@"'	>> src/version.h.in
   366 	@echo '#define VER_CFLAGS			"@@cflags@@"'		>> src/version.h.in
   367 	@echo ''												>> src/version.h.in
   368 	@echo '#define VER_MAJOR			@@majorver@@'		>> src/version.h.in
   369 	@echo '#define VER_MINOR			@@minorver@@'		>> src/version.h.in
   370 	@echo '#define VER_BUILDNUM		@@buildnum@@'			>> src/version.h.in
   371 	@echo '#define VER_EXTRA			"@@extraver@@"'		>> src/version.h.in
   372 	@echo '#define VER_VCSREV			"@@vcsstr@@"'		>> src/version.h.in
   373 	@echo ''												>> src/version.h.in
   374 	@echo '#define VER_FULLSTR			"@@fullverstr@@"'	>> src/version.h.in
   375 	@echo ''												>> src/version.h.in
   376 	@echo Build system initialised
   378 # remove the dependency files
   379 cleandep:
   380 	-rm $(DEPFILES)
   382 # remove the dependency files and any target or intermediate build files
   383 clean:	cleandep clean-versioninfo
   384 	-rm $(OBJ) $(TARGET) $(GARBAGE)
   386 # remove any dependency or intermediate build files
   387 tidy:	cleandep clean-versioninfo
   388 	-rm $(OBJ) $(GARBAGE)
   390 #################################
   392 $(TARGET):	$(OBJ) $(EXTDEP)
   393 ifeq ($(SRC_TYPE),c)
   394 	$(CC) $(CXXFLAGS) $(LDFLAGS) $(OBJ) $(LIBPTH) $(LIBLNK) -o $@
   395 else
   396 	$(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJ) $(LIBPTH) $(LIBLNK) -o $@
   397 endif
   398 ifeq ($(BUILD_TYPE),release)
   399 	$(STRIP) $(TARGET)
   400 endif
   402 ###
   403 # extra rules
   404 # example:
   405 #src/parser.c:	src/parser.h
   408 ####
   409 ## musashi build rules
   410 # 68k CPU builder
   411 obj/musashi/m68kmake:	obj/musashi/m68kmake.o
   412 	$(CC) $(CFLAGS) $(CPPFLAGS) obj/musashi/m68kmake.o -o $@
   413 # 68k CPU sources
   414 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
   415 	./obj/musashi/m68kmake src/musashi src/musashi/m68k_in.c
   417 ####
   418 # make object files from C source files
   419 obj/%.o:	src/%.c
   420 	$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
   422 ##
   423 # make object files from C++ source files
   424 obj/%.o:	src/%.cc
   425 	$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $< -o $@
   427 obj/%.o:	src/%.cpp
   428 	$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $< -o $@
   430 ###
   431 # make C files from yacc/bison source
   432 src/%.h src/%.c:	src/%.y
   433 	$(YACC) $(YFLAGS) -d $<
   434 	mv -f y.tab.c $*.c
   435 	mv -f y.tab.h $*.h
   437 ###
   438 # make C files from lex/flex source
   439 src/%.c:	src/%.l
   440 	$(LEX) $(LFLAGS) -o$@ $<
   442 ###
   443 # make dependencies for our source files
   444 dep/%.d:	src/%.c
   445 	$(CC) -MM $(CFLAGS) $(CPPFLAGS) $< > $@.$$$$; \
   446 		sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
   447 		rm -f $@.$$$$
   449 dep/%.d:	src/%.cpp
   450 	$(CXX) -MM $(CXXFLAGS) $(CPPFLAGS) $< > $@.$$$$; \
   451 		sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
   452 		rm -f $@.$$$$
   454 dep/%.d:	src/%.cc
   455 	$(CXX) -MM $(CXXFLAGS) $(CPPFLAGS) $< > $@.$$$$; \
   456 		sed 's,\($*\)\.o[ :]*,obj/\1.o $@ : ,g' < $@.$$$$ > $@; \
   457 		rm -f $@.$$$$
   459 ####
   460 # pull in the dependency files, but only for 'make $(TARGET)'
   461 ####
   463 ifeq ($(MAKECMDGOALS),$(TARGET))
   464   -include $(DEPFILES)
   465 endif