A selection of relatively minor problems in the build system.
[wvstreams.git] / wvrules.mk
blob82204217c452f63861d8a0118599c236dcff2c24
1 # wvrules.mk: 2007 08 15
3 # Copyright (C) 1998-2007 by Avery Pennarun <apenwarr@alumnit.ca>.
4 # Use, distribute, modify, and redistribute freely. (But if you're nice,
5 # you'll send all your changes back to me.)
7 # This is a complicated-looking set of Makefile rules that should make your
8 # own Makefiles simpler, by providing for several useful features (like
9 # autodependencies and a 'clean' target) without any extra effort.
11 # It will only work with GNU make.
14 # if WVSTREAMS_SRC is set assume everything else is set.
15 # For packages that use WvStreams use WVSTREAMS_SRC=. for distribution.
16 ifneq ($(WVSTREAMS),)
17 WVSTREAMS_SRC=$(WVSTREAMS)
18 WVSTREAMS_LIB=$(WVSTREAMS)
19 WVSTREAMS_INC=$(WVSTREAMS)/include
20 WVSTREAMS_BIN=$(WVSTREAMS)
21 endif
22 export WVSTREAMS WVSTREAMS_SRC WVSTREAMS_LIB WVSTREAMS_INC WVSTREAMS_BIN
24 SHELL=/bin/bash
26 ifneq ($(wildcard $(WVSTREAMS_SRC)/config.mk),)
27 include $(WVSTREAMS_SRC)/config.mk
28 __junk:=$(shell echo "Using compiler type '$(COMPILER_STANDARD)'" >&2)
29 include $(WVSTREAMS_SRC)/wvrules-$(COMPILER_STANDARD).mk
30 else
31 __junk:=$(shell echo "Warning: $(WVSTREAMS_SRC)/config.mk doesn't exist" >&2)
32 COMPILER_STANDARD=posix
33 endif
35 ifeq (${EXEEXT},.exe)
36 include $(WVSTREAMS_SRC)/wvrules-win32.mk
37 endif
39 ifeq (${WVTESTRUN},)
40 WVTESTRUN=$(WVSTREAMS_BIN)/wvtesthelper
41 endif
43 STRIP=strip --remove-section=.note --remove-section=.comment
44 #STRIP=echo
46 # macros that expand to the object files in the given directories
47 objects=$(sort $(foreach type,c cc,$(call objects_$(type),$1)))
48 objects_c=$(patsubst %.c,%.o,$(wildcard $(addsuffix /*.c,$1)))
49 objects_cc=$(patsubst %.cc,%.o,$(wildcard $(addsuffix /*.cc,$1)))
51 # macro that expands to the subdir.mk files to include
52 xsubdirs=$(sort $(wildcard $1/*/subdir.mk)) /dev/null
54 # we need a default rule, since the 'includes' below causes trouble
55 .PHONY: default all
56 default: all
58 # default "test" rule does nothing...
59 .PHONY: test runtests clean-valgrind
60 test:
61 runtests: clean-valgrind
63 clean-valgrind:
64 @rm -f valgrind.log.pid*
66 %/test:
67 $(MAKE) -C $(dir $@) test
69 $(WVSTREAMS_SRC)/rules.local.mk:
70 @true
72 -include $(WVSTREAMS_SRC)/rules.local.mk
74 INCFLAGS=$(addprefix -I,$(WVSTREAMS_INC) $(XPATH))
75 CPPFLAGS+=$(INCFLAGS) \
76 -D_BSD_SOURCE -D_GNU_SOURCE $(OSDEFINE) \
77 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
79 ifeq ($(VERBOSE),1)
80 COMPILE_MSG :=
81 LINK_MSG :=
82 DEPEND_MSG :=
83 SYMLINK_MSG :=
84 else
85 COMPILE_MSG = @echo compiling $@...;
86 LINK_MSG = @echo linking $@...;
87 #DEPEND_MSG = @echo " depending $@...";
88 DEPEND_MSG := @
89 SYMLINK_MSG := @
90 endif
92 # any rule that depends on FORCE will always run
93 .PHONY: FORCE
94 FORCE:
96 ifeq ($(LN_S),)
97 LN_S := ln -s
98 endif
99 ifeq ($(LN),)
100 LN := ln
101 endif
103 # Create symbolic links
104 # usage: $(wvlns,source,dest)
105 wvlns=$(SYMLINK_MSG)$(LN_S) -f $1 $2
107 # Create hard links
108 # usage: $(wvln,source,dest)
109 wvln=$(SYMLINK_MSG)$(LN) -f $1 $2
111 # usage: $(wvcc_base,outfile,infile,stem,compiler cflags,mode)
112 # eg: $(wvcc,foo.o,foo.cc,foo,$(CC) $(CFLAGS) -fPIC,-c)
113 DEPFILE = $(if $(filter %.o,$1),$(dir $1).$(notdir $(1:.o=.d)),/dev/null)
114 wvcc=$(call wvcc_base,$1,$2,$3,$(CC) $(CFLAGS) $($1-CFLAGS) $(CPPFLAGS) $($1-CPPFLAGS) $4,$(if $5,$5,-c))
115 wvcxx=$(call wvcc_base,$1,$2,$3,$(CXX) $(CXXFLAGS) $($1-CFLAGS) $(CPPFLAGS) $($1-CPPFLAGS) $($1-CXXFLAGS) $4,$(if $5,$5,-c))
117 %.so: SONAME=$@$(if $(SO_VERSION),.$(SO_VERSION))
119 wvsoname=$(if $($1-SONAME),$($1-SONAME),$(if $(SONAME),$(SONAME),$1))
120 define wvlink_so
121 $(LINK_MSG)$(WVLINK_CC) $(LDFLAGS) $($1-LDFLAGS) -Wl,-z,defs -Wl,-soname,$(call wvsoname,$1) -shared -o $1 $(filter %.o %.a %.so,$2) $($1-LIBS) $(LIBS) $(XX_LIBS)
122 $(if $(filter-out $(call wvsoname,$1),$1),$(call wvlns,$1,$(call wvsoname,$1)))
123 endef
125 ../%.so:; @echo "Shared library $@ does not exist!"; exit 1
126 ../%.a:; @echo "Library $@ does not exist!"; exit 1
127 ../%.o:; @echo "Object $@ does not exist!"; exit 1
128 /%.a:; @echo "Library $@ does not exist!"; exit 1
130 %.o: %.c; $(call wvcc ,$@,$<,$*)
131 %.fpic.o: %.c; $(call wvcc ,$@,$<,$*,-fPIC)
132 %.o: %.cc; $(call wvcxx,$@,$<,$*)
133 %.fpic.o: %.cc; $(call wvcxx,$@,$<,$*,-fPIC)
134 %.o: %.cpp; $(call wvcxx,$@,$<,$*)
135 %.fpic.o:%.cpp; $(call wvcxx,$@,$<,$*,-fPIC)
136 %.s: %.c; $(call wvcc ,$@,$<,$*,,-S)
137 %.s: %.cc; $(call wvcxx,$@,$<,$*,,-S)
138 %.s: %.cpp; $(call wvcxx,$@,$<,$*,,-S)
139 %.E: %.c; $(call wvcc,$@,$<,$*,,-E)
140 %.E: %.cc; $(call wvcxx,$@,$<,$*,,-E)
141 %.E: %.cpp; $(call wvcxx,$@,$<,$*,,-E)
143 %.moc: %.h; moc -o $@ $<
145 %: %.o; $(call wvlink,$@,$^)
146 %.t: %.t.o; $(call wvlink,$@,$(call reverse,$(filter %.o,$^)) $(filter-out %.o,$^) $(LIBWVTEST))
147 %.a %.libs:; $(call wvlink_ar,$@,$^)
148 %.so:; $(call wvlink_so,$@,$^)
150 # Force objects to be built before final binaries
151 $(addsuffix .o,$(basename $(wildcard *.c) $(wildcard *.cc) $(wildcard *.cpp))):
153 %.gz: FORCE %
154 @rm -f $@
155 gzip -f $*
156 @ls -l $@
159 # Header files for tcl/tk packages
161 pkgIndex.tcl: $(filter-out pkgIndex.tcl,$(wildcard *.tcl))
162 @echo Generating pkgIndex.tcl...
163 @rm -f $@
164 @echo pkg_mkIndex . \
165 $$(echo $^ | sed 's,\.tcl_paths,,') | tclsh
167 pkgIndex.tcl $(wildcard *.tcl): .tcl_paths
168 .tcl_paths:
169 @echo Generating .tcl_paths...
170 @rm -f $@
171 @find . $(TOPDIR) -name '*.tcl' -printf '%h\n' | sort | uniq | \
172 (echo lappend auto_path \\; sed 's/^.*$$/ & \\/'; echo) >$@.tmp
173 @mv $@.tmp $@
176 # We automatically generate header dependencies for .c and .cc files. The
177 # dependencies are stored in the file ".filename.d"
179 depfiles_sf = $(wildcard .*.d t/.*.d)
181 ifneq ($(depfiles_sf),)
182 -include $(depfiles_sf)
183 endif
187 # A macro for compiling subdirectories listed in the SUBDIRS variable.
188 # Tries to make the target ($@) in each subdir, unless the target is called
189 # "subdirs" in which case it makes "all" in each subdir.
191 define subdirs_func
192 +@OLDDIR="$$(pwd)"; set -e; \
193 for d in __fx__ $2; do \
194 if [ "$$d" = "__fx__" ]; then continue; fi; \
195 cd "$$d"; \
196 echo ; \
197 echo "--> Making $1 in $$(pwd)..."; \
198 $(MAKE) --no-print-directory $1 || exit 1; \
199 cd "$$OLDDIR"; \
200 done
201 @echo
202 @echo "--> Back in $$(pwd)..."
203 endef
205 subdirs = $(call subdirs_func,$(subst subdirs,all,$(if $1,$1,$@)),$(if $2,$2,$(SUBDIRS)))
207 # # $(call reverse,$(SUBDIRS)) works since GNU make 3.80 only
208 # reverse = \
209 # $(if $(1),$(call reverse,$(wordlist 2, 999, $(1))) $(firstword $(1)))
211 define shell_reverse
212 revlist="" ; \
213 for word in $(1) ; do \
214 revlist="$${word} $${revlist}"; \
215 done ; \
216 echo "$${revlist}"
217 endef
219 reverse = $(shell $(call shell_reverse,$(1)))
221 clean_subdirs = $(call subdirs,clean,$(call reverse,$(SUBDIRS)),keep)
223 %: %/Makefile FORCE
224 @cd "$@"; echo; echo "--> Making all in $$(pwd)..."; \
225 $(MAKE) --no-print-directory all
227 subdirs: ${SUBDIRS}
230 # Auto-clean rule. Feel free to append to this in your own directory, by
231 # defining your own "clean" rule.
233 .PHONY: clean _wvclean
235 clean: _wvclean
237 _wvclean:
238 @echo '--> Cleaning $(shell pwd)...'
239 @rm -f *~ *.tmp *.o *.a *.so *.so.* *.libs *.dll *.lib *.moc *.d .*.d .depend \
240 .\#* .tcl_paths pkgIndex.tcl gmon.out core build-stamp \
241 wvtestmain
242 @rm -f $(patsubst %.t.cc,%.t,$(wildcard *.t.cc) $(wildcard t/*.t.cc)) \
243 t/*.o t/*~ t/.*.d t/.\#*
244 @rm -f valgrind.log.pid*
245 @rm -f semantic.cache tags
246 @rm -rf debian/tmp
249 # default dist rules.
250 distclean: clean
252 PKGNAME := $(notdir $(shell pwd))
253 PPKGNAME := $(shell echo $(PKGNAME) | tr a-z A-Z | tr - _)
254 PKGVER := $(shell test -f wvver.h \
255 && cat wvver.h | sed -ne "s/\#define $(PPKGNAME)_VER_STRING.*\"\([^ ]*\).*\".*/\1/p")
256 ifneq ($(PKGVER),)
257 PKGDIR := $(PKGNAME)-$(PKGVER)
258 else
259 PKGDIR := $(PKGNAME)
260 endif
261 ifneq ($(PKGSNAPSHOT),)
262 PKGDIR := $(PKGDIR)+$(shell date +%Y%m%d)
263 endif
264 dist-dir:
265 @echo $(PKGDIR)
267 dist-hook:
269 dist: dist-hook ChangeLog
270 @echo '--> Making dist in ../build/$(PKGDIR)...'
271 @test -d ../build || mkdir ../build
272 @rsync -a --delete --force '$(shell pwd)/' '../build/$(PKGDIR)'
273 @find '../build/$(PKGDIR)' -name .svn -type d -print0 | xargs -0 rm -rf --
274 @find '../build/$(PKGDIR)' -name .cvsignore -type f -print0 | xargs -0 rm -f --
275 @$(MAKE) -C '../build/$(PKGDIR)' distclean
276 @rm -f '../build/$(PKGDIR).tar.gz'
277 @cd ../build; tar -zcf '$(PKGDIR).tar.gz' '$(PKGDIR)'
278 @echo '--> Created tarball in ../build/$(PKGDIR).tar.gz.'
280 ChangeLog: FORCE
281 @echo '--> Generating ChangeLog from Subversion...'
282 @rm -f ChangeLog ChangeLog.bak
283 @svn log --xml --verbose | xsltproc svn2cl.xsl - > ChangeLog
286 # Make 'tags' file using the ctags program - useful for editing
288 #tags: $(shell find -name '*.cc' -o -name '*.[ch]')
289 # @echo '(creating "tags")'
290 # @if [ -x /usr/bin/ctags ]; then /usr/bin/ctags $^; fi
292 print_vars:
293 @echo "CPPOPTS: $(CPPOPTS)"
294 @echo "COPTS: $(COPTS)"
295 @echo "CACXX: $(C_AND_CXX_FLAGS)"
296 @echo "CPPFLAGS: $(CPPFLAGS)"
297 @echo "CFLAGS: $(CFLAGS)"
298 @echo "CXXFLAGS: $(CXXFLAGS)"