1 #=========================================================================
2 # Toplevel Makefile for the Modular C++ Build System
3 #=========================================================================
4 # Please read the documenation in 'mcppbs-doc.txt' for more details on
5 # how the Modular C++ Build System works. For most projects, a developer
6 # will not need to make any changes to this makefile. The key targets
9 # - default : build all libraries and programs
10 # - check : build and run all unit tests
11 # - install : install headers, project library, and some programs
12 # - clean : remove all generated content (except autoconf files)
13 # - dist : make a source tarball
14 # - distcheck : make a source tarball, untar it, check it, clean it
15 # - distclean : remove everything
18 #-------------------------------------------------------------------------
20 #-------------------------------------------------------------------------
22 # Remove all default implicit rules since they can cause subtle bugs
23 # and they just make things run slower
31 # Default is to build the prereqs of the all target (defined at bottom)
35 project_name
:= @PACKAGE_TARNAME@
37 scripts_dir
:= $(src_dir
)/scripts
39 # If the version information is not in the configure script, then we
40 # assume that we are in a working directory. We use the vcs-version.sh
41 # script in the scripts directory to generate an appropriate version
42 # string. Currently the way things are setup we have to run this script
43 # everytime we run make so the script needs to be as fast as possible.
45 ifeq (@PACKAGE_VERSION@
,?
)
46 project_ver
:=$(shell $(scripts_dir
)/vcs-version.sh
$(src_dir
))
48 project_ver
:=@PACKAGE_VERSION@
51 # Installation directories
54 enable_stow
:= @enable_stow@
56 ifeq ($(enable_stow
),yes
)
57 stow_pkg_dir
:= $(prefix)/pkgs
58 DESTDIR ?
= $(stow_pkg_dir
)/$(project_name
)-$(project_ver
)
63 install_hdrs_dir
:= $(DESTDIR
)/include/$(project_name
)
64 install_libs_dir
:= $(DESTDIR
)/lib
/$(project_name
)
65 install_exes_dir
:= $(DESTDIR
)/bin
67 #-------------------------------------------------------------------------
69 #-------------------------------------------------------------------------
71 sprojs
:= @subprojects@
72 sprojs_enabled
:= @subprojects_enabled@
74 sprojs_include
:= -I.
$(addprefix -I
$(src_dir
)/, $(sprojs_enabled
))
75 VPATH
:= $(addprefix $(src_dir
)/, $(sprojs_enabled
))
77 #-------------------------------------------------------------------------
79 #-------------------------------------------------------------------------
82 # - CPPFLAGS : flags for the preprocessor (eg. -I,-D)
83 # - CXXFLAGS : flags for C++ compiler (eg. -Wall,-g,-O3)
88 CPPFLAGS
+= @CPPFLAGS@
89 CXXFLAGS
+= @CXXFLAGS@
90 COMPILE
:= $(CXX
) -MMD
-MP
$(CPPFLAGS
) $(CFLAGS
) $(CXXFLAGS
) \
92 COMPILE_C
:= $(CC
) -MMD
-MP
$(CPPFLAGS
) $(CFLAGS
) \
95 # - LDFLAGS : Flags for the linker (eg. -L)
96 # - LIBS : Library flags (eg. -l)
101 LINK
:= $(LD
) $(LDFLAGS
)
111 RUNFLAGS
:= @RUNFLAGS@
115 MKINSTALLDIRS
:= $(scripts_dir
)/mk-install-dirs.sh
117 INSTALL_HDR
:= $(INSTALL
) -m
444
118 INSTALL_LIB
:= $(INSTALL
) -m
644
119 INSTALL_EXE
:= $(INSTALL
) -m
555
122 #-------------------------------------------------------------------------
123 # Range helper function. $(call range,3,6) generates the string 3 4 5
124 #-------------------------------------------------------------------------
126 range
= $(shell _i
=$(1); \
127 while
[ $$_i -le
$(2) ]; do \
129 _i
=`expr $$_i + 1`; \
132 #-------------------------------------------------------------------------
133 # Include subproject makefile fragments
134 #-------------------------------------------------------------------------
136 sprojs_mk
= $(addsuffix .mk
, $(sprojs_enabled
))
138 -include $(sprojs_mk
)
140 dist_junk
+= $(sprojs_mk
)
142 #-------------------------------------------------------------------------
143 # Reverse list helper function
144 #-------------------------------------------------------------------------
145 # This function is used by the subproject template to reverse the list
146 # of dependencies. It uses recursion to perform the reversal.
149 # $(1) : space separated input list
150 # retval : input list in reverse order
153 reverse_list
= $(call reverse_list_h
,$(1),)
154 define reverse_list_h
155 $(if
$(strip $(1)), \
156 $(call reverse_list_h
, \
157 $(wordlist
2,$(words $(1)),$(1)), \
158 $(firstword $(1)) $(2)), \
162 #-------------------------------------------------------------------------
163 # Template for per subproject rules
164 #-------------------------------------------------------------------------
165 # The template is instantiated for each of the subprojects. It relies on
166 # subprojects defining a certain set of make variables which are all
167 # prefixed with the subproject name. Since subproject names can have
168 # dashes in them (and the make variables are assumed to only use
169 # underscores) the template takes two arguments - one with the regular
170 # subproject name and one with dashes replaced with underscores.
173 # $(1) : real subproject name (ie with dashes)
174 # $(2) : normalized subproject name (ie dashes replaced with underscores)
177 define subproject_template
179 # In some (rare) cases, a subproject might not have any actual object
180 # files. It might only include header files or program sources. To keep
181 # things consistent we still want a library for this subproject, so in
182 # this spectial case we create a dummy source file and thus the build
183 # system will create a library for this subproject with just the
184 # corresponding dummy object file.
186 ifeq ($$(strip $$($(2)_srcs
) $$($(2)_c_srcs
)),)
187 $(2)_srcs
+= _
$(1).
cc
188 $(2)_junk
+= _
$(1).
cc
192 echo
"int _$(2)( int arg ) { return arg; }" > $$@
194 # Build the object files for this subproject
196 $(2)_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_srcs
))
197 $(2)_c_objs
:= $$(patsubst %.c
, %.o
, $$($(2)_c_srcs
))
198 $(2)_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_objs
))
199 $(2)_c_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_c_objs
))
200 $$($(2)_objs
) : %.o
: %.
cc $$($(2)_gen_hdrs
)
202 $$($(2)_c_objs
) : %.o
: %.c
205 $(2)_junk
+= $$($(2)_objs
) $$($(2)_c_objs
) $$($(2)_deps
) $$($(2)_c_deps
)
207 # Build a library for this subproject
209 lib
$(1).a
: $$($(2)_objs
) $$($(2)_c_objs
)
213 $(2)_junk
+= lib
$(1).a
215 # Reverse the dependency list so that a given subproject only depends on
216 # subprojects listed to its right. This is the correct order for linking
217 # the list of subproject libraries.
219 $(2)_reverse_deps
:= $$(call reverse_list
,$$($(2)_subproject_deps
))
223 $(2)_test_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_test_srcs
))
224 $(2)_test_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_test_objs
))
225 $(2)_test_exes
:= $$(patsubst %.t.
cc, %-utst
, $$($(2)_test_srcs
))
226 $(2)_test_outs
:= $$(patsubst %, %.out
, $$($(2)_test_exes
))
227 $(2)_test_libs
:= $(1) $$($(2)_reverse_deps
) utst
228 $(2)_test_libnames
:= $$(patsubst %, lib
%.a
, $$($(2)_test_libs
))
229 $(2)_test_libarg
:= -L.
$$(patsubst %, -l
%, $$($(2)_test_libs
))
231 $$($(2)_test_objs
) : %.o
: %.
cc
234 $$($(2)_test_exes
) : %-utst
: %.t.o
$$($(2)_test_libnames
)
235 $(LINK
) -o
$$@
$$< $$($(2)_test_libarg
) $(LIBS
)
237 $(2)_deps
+= $$($(2)_test_deps
)
239 $$($(2)_test_objs
) $$($(2)_test_deps
) \
240 $$($(2)_test_exes
) *.junk-dat
244 $$($(2)_test_outs
) : %.out
: %
245 $(RUN
) $(RUNFLAGS
) .
/$$< default | tee
$$@
247 $(2)_junk
+= $$($(2)_test_outs
)
251 $(2)_prog_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_prog_srcs
))
252 $(2)_prog_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_prog_objs
))
253 $(2)_prog_exes
:= $$(patsubst %.
cc, %, $$($(2)_prog_srcs
))
254 $(2)_prog_libs
:= $(1) $$($(2)_reverse_deps
)
255 $(2)_prog_libnames
:= $$(patsubst %, lib
%.a
, $$($(2)_prog_libs
))
256 $(2)_prog_libarg
:= -L.
$$(patsubst %, -l
%, $$($(2)_prog_libs
))
258 $$($(2)_prog_objs
) : %.o
: %.
cc
261 $$($(2)_prog_exes
) : % : %.o
$$($(2)_prog_libnames
)
262 $(LINK
) -o
$$@
$$< $$($(2)_prog_libarg
) $(LIBS
)
264 $(2)_deps
+= $$($(2)_prog_deps
)
265 $(2)_junk
+= $$($(2)_prog_objs
) $$($(2)_prog_deps
) $$($(2)_prog_exes
)
267 # Build programs which will be installed
269 $(2)_install_prog_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_install_prog_srcs
))
270 $(2)_install_prog_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_install_prog_objs
))
271 $(2)_install_prog_exes
:= $$(patsubst %.
cc, %, $$($(2)_install_prog_srcs
))
273 $$($(2)_install_prog_objs
) : %.o
: %.
cc
276 $$($(2)_install_prog_exes
) : % : %.o
$$($(2)_prog_libnames
)
277 $(LINK
) -o
$$@
$$< $$($(2)_prog_libarg
) $(LIBS
)
279 $(2)_deps
+= $$($(2)_install_prog_deps
)
281 $$($(2)_install_prog_objs
) $$($(2)_install_prog_deps
) \
282 $$($(2)_install_prog_exes
)
284 # Subproject specific targets
286 all-
$(1) : lib
$(1).a
$$($(2)_install_prog_exes
)
288 check-
$(1) : $$($(2)_test_outs
)
289 echo
; grep
-h
-e
'Unit Tests' -e
'FAILED' -e
'Segementation' $$^
; echo
294 .PHONY
: all-
$(1) check-
$(1) clean-
$(1)
296 # Update running variables
299 objs
+= $$($(2)_objs
)
300 srcs
+= $$(addprefix $(src_dir
)/$(1)/, $$($(2)_srcs
))
301 hdrs
+= $$(addprefix $(src_dir
)/$(1)/, $$($(2)_hdrs
)) $$($(2)_gen_hdrs
)
302 junk
+= $$($(2)_junk
)
303 deps
+= $$($(2)_deps
)
305 test_outs
+= $$($(2)_test_outs
)
307 install_hdrs
+= $$(addprefix $(src_dir
)/$(1)/, $$($(2)_hdrs
)) $$($(2)_gen_hdrs
)
308 install_libs
+= lib
$(1).a
309 install_exes
+= $$($(2)_install_prog_exes
)
313 # Iterate over the subprojects and call the template for each one
315 $(foreach sproj
,$(sprojs_enabled
), \
316 $(eval
$(call subproject_template
,$(sproj
),$(subst -,_
,$(sproj
)))))
318 #-------------------------------------------------------------------------
319 # Autodependency files
320 #-------------------------------------------------------------------------
327 #-------------------------------------------------------------------------
329 #-------------------------------------------------------------------------
332 echo
; grep
-h
-e
'Unit Tests' -e
'FAILED' -e
'Segementation' $^
; echo
336 #-------------------------------------------------------------------------
338 #-------------------------------------------------------------------------
340 install-hdrs
: $(install_hdrs
)
341 $(MKINSTALLDIRS
) $(install_hdrs_dir
)
344 $(INSTALL_HDR
) $$file $(install_hdrs_dir
); \
347 install-libs
: $(install_libs
)
348 $(MKINSTALLDIRS
) $(install_libs_dir
)
351 $(INSTALL_LIB
) $$file $(install_libs_dir
); \
354 install-exes
: $(install_exes
)
355 $(MKINSTALLDIRS
) $(install_exes_dir
)
358 $(INSTALL_EXE
) $$file $(install_exes_dir
); \
361 install : install-hdrs install-libs install-exes
362 ifeq ($(enable_stow
),yes
)
363 $(MKINSTALLDIRS
) $(stow_pkg_dir
)
364 cd
$(stow_pkg_dir
) && \
365 $(STOW
) --delete
$(project_name
)-* && \
366 $(STOW
) $(project_name
)-$(project_ver
)
369 .PHONY
: install install-hdrs install-libs install-exes
371 #-------------------------------------------------------------------------
372 # Regenerate configure information
373 #-------------------------------------------------------------------------
376 $(src_dir
)/configure.ac \
377 $(src_dir
)/aclocal.m4 \
378 $(join $(addprefix $(src_dir
)/, $(sprojs_enabled
)), \
379 $(patsubst %, /%.ac
, $(sprojs_enabled
)))
381 $(src_dir
)/configure
: $(configure_prereq
)
382 cd
$(src_dir
) && autoconf
&& autoheader
384 config.status
: $(src_dir
)/configure
385 .
/config.status
--recheck
388 $(join $(addprefix $(src_dir
)/, $(sprojs_enabled
)), \
389 $(patsubst %, /%.mk.in
, $(sprojs_enabled
)))
391 Makefile
: $(src_dir
)/Makefile.in
$(sprojs_mk_in
) config.status
394 dist_junk
+= config.status config.h Makefile config.log
396 #-------------------------------------------------------------------------
398 #-------------------------------------------------------------------------
399 # The distribution tarball is named project-ver.tar.gz and it includes
400 # both enabled and disabled subprojects.
414 dist_dir
:= $(project_name
)-$(project_ver
)
415 dist_tgz
:= $(project_name
)-$(project_ver
).
tar.gz
417 # Notice that when we make the distribution we rewrite the configure.ac
418 # script with the current version and we rerun autoconf in the new
419 # source directory so that the distribution will have the proper version
420 # information. We also rewrite the "Version : " line in the README.
425 tar -C
$(src_dir
) -cf
- $(dist_files
) |
tar -C
$(dist_dir
) -xpf
-
426 sed
-i.bak
's/^\(# Version :\).*/\1 $(project_ver)/' $(dist_dir
)/README
427 sed
-i.bak
's/\( proj_version,\).*/\1 [$(project_ver)])/' $(dist_dir
)/configure.ac
429 autoconf
&& autoheader
&& \
430 rm -rf autom4te.cache configure.ac.bak README.bak
431 tar -czvf
$(dist_tgz
) $(dist_dir
)
434 # You can use the distcheck target to try untarring the distribution and
435 # then running configure, make, make check, and make distclean. A
436 # "directory is not empty" error means distclean is not removing
441 tar -xzvf
$(dist_tgz
)
442 mkdir
-p
$(dist_dir
)/build
443 cd
$(dist_dir
)/build
; ..
/configure
; make
; make
check; make
distclean
446 junk
+= $(project_name
)-*.
tar.gz
448 .PHONY
: dist distcheck
450 #-------------------------------------------------------------------------
452 #-------------------------------------------------------------------------
454 all : $(install_hdrs
) $(install_libs
) $(install_exes
)
457 #-------------------------------------------------------------------------
459 #-------------------------------------------------------------------------
460 # This handy rule will display the contents of any make variable by
461 # using the target debug-<varname>. So for example, make debug-junk will
462 # display the contents of the junk variable.
467 #-------------------------------------------------------------------------
469 #-------------------------------------------------------------------------
472 rm -rf
*~ \
#* $(junk)
475 rm -rf
*~ \
#* $(junk) $(dist_junk)
477 .PHONY
: clean distclean