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)
87 CPPFLAGS
:= @CPPFLAGS@
88 CXXFLAGS
:= @CXXFLAGS@
89 COMPILE
:= $(CXX
) -MMD
-MP
$(CPPFLAGS
) $(CXXFLAGS
) \
91 COMPILE_C
:= $(CC
) -MMD
-MP
$(CPPFLAGS
) $(CXXFLAGS
) \
94 # - LDFLAGS : Flags for the linker (eg. -L)
95 # - LIBS : Library flags (eg. -l)
100 LINK
:= $(LD
) $(LDFLAGS
)
110 RUNFLAGS
:= @RUNFLAGS@
114 MKINSTALLDIRS
:= $(scripts_dir
)/mk-install-dirs.sh
116 INSTALL_HDR
:= $(INSTALL
) -m
444
117 INSTALL_LIB
:= $(INSTALL
) -m
644
118 INSTALL_EXE
:= $(INSTALL
) -m
555
121 #-------------------------------------------------------------------------
122 # Include subproject makefile fragments
123 #-------------------------------------------------------------------------
125 sprojs_mk
= $(addsuffix .mk
, $(sprojs_enabled
))
127 -include $(sprojs_mk
)
129 dist_junk
+= $(sprojs_mk
)
131 #-------------------------------------------------------------------------
132 # Reverse list helper function
133 #-------------------------------------------------------------------------
134 # This function is used by the subproject template to reverse the list
135 # of dependencies. It uses recursion to perform the reversal.
138 # $(1) : space separated input list
139 # retval : input list in reverse order
142 reverse_list
= $(call reverse_list_h
,$(1),)
143 define reverse_list_h
144 $(if
$(strip $(1)), \
145 $(call reverse_list_h
, \
146 $(wordlist
2,$(words $(1)),$(1)), \
147 $(firstword $(1)) $(2)), \
151 #-------------------------------------------------------------------------
152 # Template for per subproject rules
153 #-------------------------------------------------------------------------
154 # The template is instantiated for each of the subprojects. It relies on
155 # subprojects defining a certain set of make variables which are all
156 # prefixed with the subproject name. Since subproject names can have
157 # dashes in them (and the make variables are assumed to only use
158 # underscores) the template takes two arguments - one with the regular
159 # subproject name and one with dashes replaced with underscores.
162 # $(1) : real subproject name (ie with dashes)
163 # $(2) : normalized subproject name (ie dashes replaced with underscores)
166 define subproject_template
168 # In some (rare) cases, a subproject might not have any actual object
169 # files. It might only include header files or program sources. To keep
170 # things consistent we still want a library for this subproject, so in
171 # this spectial case we create a dummy source file and thus the build
172 # system will create a library for this subproject with just the
173 # corresponding dummy object file.
175 ifeq ($$(strip $$($(2)_srcs
) $$($(2)_c_srcs
)),)
176 $(2)_srcs
+= _
$(1).
cc
177 $(2)_junk
+= _
$(1).
cc
181 echo
"int _$(2)( int arg ) { return arg; }" > $$@
183 # Build the object files for this subproject
185 $(2)_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_srcs
))
186 $(2)_c_objs
:= $$(patsubst %.c
, %.o
, $$($(2)_c_srcs
))
187 $(2)_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_objs
))
188 $(2)_c_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_c_objs
))
189 $$($(2)_objs
) : %.o
: %.
cc
191 $$($(2)_c_objs
) : %.o
: %.c
194 $(2)_junk
+= $$($(2)_objs
) $$($(2)_c_objs
) $$($(2)_deps
) $$($(2)_c_deps
)
196 # Build a library for this subproject
198 lib
$(1).a
: $$($(2)_objs
) $$($(2)_c_objs
)
202 $(2)_junk
+= lib
$(1).a
204 # Reverse the dependency list so that a given subproject only depends on
205 # subprojects listed to its right. This is the correct order for linking
206 # the list of subproject libraries.
208 $(2)_reverse_deps
:= $$(call reverse_list
,$$($(2)_subproject_deps
))
212 $(2)_test_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_test_srcs
))
213 $(2)_test_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_test_objs
))
214 $(2)_test_exes
:= $$(patsubst %.t.
cc, %-utst
, $$($(2)_test_srcs
))
215 $(2)_test_outs
:= $$(patsubst %, %.out
, $$($(2)_test_exes
))
216 $(2)_test_libs
:= $(1) $$($(2)_reverse_deps
) utst
217 $(2)_test_libnames
:= $$(patsubst %, lib
%.a
, $$($(2)_test_libs
))
218 $(2)_test_libarg
:= -L.
$$(patsubst %, -l
%, $$($(2)_test_libs
))
220 $$($(2)_test_objs
) : %.o
: %.
cc
223 $$($(2)_test_exes
) : %-utst
: %.t.o
$$($(2)_test_libnames
)
224 $(LINK
) -o
$$@
$$< $$($(2)_test_libarg
) $(LIBS
)
226 $(2)_deps
+= $$($(2)_test_deps
)
228 $$($(2)_test_objs
) $$($(2)_test_deps
) \
229 $$($(2)_test_exes
) *.junk-dat
233 $$($(2)_test_outs
) : %.out
: %
234 $(RUN
) $(RUNFLAGS
) .
/$$< default | tee
$$@
236 $(2)_junk
+= $$($(2)_test_outs
)
240 $(2)_prog_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_prog_srcs
))
241 $(2)_prog_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_prog_objs
))
242 $(2)_prog_exes
:= $$(patsubst %.
cc, %, $$($(2)_prog_srcs
))
243 $(2)_prog_libs
:= $(1) $$($(2)_reverse_deps
)
244 $(2)_prog_libnames
:= $$(patsubst %, lib
%.a
, $$($(2)_prog_libs
))
245 $(2)_prog_libarg
:= -L.
$$(patsubst %, -l
%, $$($(2)_prog_libs
))
247 $$($(2)_prog_objs
) : %.o
: %.
cc
250 $$($(2)_prog_exes
) : % : %.o
$$($(2)_prog_libnames
)
251 $(LINK
) -o
$$@
$$< $$($(2)_prog_libarg
) $(LIBS
)
253 $(2)_deps
+= $$($(2)_prog_deps
)
254 $(2)_junk
+= $$($(2)_prog_objs
) $$($(2)_prog_deps
) $$($(2)_prog_exes
)
256 # Build programs which will be installed
258 $(2)_install_prog_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_install_prog_srcs
))
259 $(2)_install_prog_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_install_prog_objs
))
260 $(2)_install_prog_exes
:= $$(patsubst %.
cc, %, $$($(2)_install_prog_srcs
))
262 $$($(2)_install_prog_objs
) : %.o
: %.
cc
265 $$($(2)_install_prog_exes
) : % : %.o
$$($(2)_prog_libnames
)
266 $(LINK
) -o
$$@
$$< $$($(2)_prog_libarg
) $(LIBS
)
268 $(2)_deps
+= $$($(2)_install_prog_deps
)
270 $$($(2)_install_prog_objs
) $$($(2)_install_prog_deps
) \
271 $$($(2)_install_prog_exes
)
273 # Subproject specific targets
275 all-
$(1) : lib
$(1).a
$$($(2)_install_prog_exes
)
277 check-
$(1) : $$($(2)_test_outs
)
278 echo
; grep
-h
-e
'Unit Tests' -e
'FAILED' -e
'Segementation' $$^
; echo
283 .PHONY
: all-
$(1) check-
$(1) clean-
$(1)
285 # Update running variables
288 objs
+= $$($(2)_objs
)
289 srcs
+= $$(addprefix $(src_dir
)/$(1)/, $$($(2)_srcs
))
290 hdrs
+= $$(addprefix $(src_dir
)/$(1)/, $$($(2)_hdrs
))
291 junk
+= $$($(2)_junk
)
292 deps
+= $$($(2)_deps
)
294 test_outs
+= $$($(2)_test_outs
)
296 install_hdrs
+= $$(addprefix $(src_dir
)/$(1)/, $$($(2)_hdrs
))
297 install_libs
+= lib
$(1).a
298 install_exes
+= $$($(2)_install_prog_exes
)
302 # Iterate over the subprojects and call the template for each one
304 $(foreach sproj
,$(sprojs_enabled
), \
305 $(eval
$(call subproject_template
,$(sproj
),$(subst -,_
,$(sproj
)))))
307 #-------------------------------------------------------------------------
308 # Autodependency files
309 #-------------------------------------------------------------------------
316 #-------------------------------------------------------------------------
318 #-------------------------------------------------------------------------
321 echo
; grep
-h
-e
'Unit Tests' -e
'FAILED' -e
'Segementation' $^
; echo
325 #-------------------------------------------------------------------------
327 #-------------------------------------------------------------------------
329 install-hdrs
: $(install_hdrs
)
330 $(MKINSTALLDIRS
) $(install_hdrs_dir
)
331 for file in
$(install_hdrs
); \
333 $(INSTALL_HDR
) $$file $(install_hdrs_dir
); \
336 install-libs
: $(install_libs
)
337 $(MKINSTALLDIRS
) $(install_libs_dir
)
338 for file in
$(install_libs
); \
340 $(INSTALL_LIB
) $$file $(install_libs_dir
); \
343 install-exes
: $(install_exes
)
344 $(MKINSTALLDIRS
) $(install_exes_dir
)
345 for file in
$(install_exes
); \
347 $(INSTALL_EXE
) $$file $(install_exes_dir
); \
350 install : install-hdrs install-libs install-exes
351 ifeq ($(enable_stow
),yes
)
352 $(MKINSTALLDIRS
) $(stow_pkg_dir
)
353 cd
$(stow_pkg_dir
) && \
354 $(STOW
) --delete
$(project_name
)-* && \
355 $(STOW
) $(project_name
)-$(project_ver
)
358 .PHONY
: install install-hdrs install-libs install-exes
360 #-------------------------------------------------------------------------
361 # Regenerate configure information
362 #-------------------------------------------------------------------------
365 $(src_dir
)/configure.ac \
366 $(src_dir
)/aclocal.m4 \
367 $(join $(addprefix $(src_dir
)/, $(sprojs_enabled
)), \
368 $(patsubst %, /%.ac
, $(sprojs_enabled
)))
370 $(src_dir
)/configure
: $(configure_prereq
)
371 cd
$(src_dir
) && autoconf
&& autoheader
373 config.status
: $(src_dir
)/configure
374 .
/config.status
--recheck
377 $(join $(addprefix $(src_dir
)/, $(sprojs_enabled
)), \
378 $(patsubst %, /%.mk.in
, $(sprojs_enabled
)))
380 Makefile
: $(src_dir
)/Makefile.in
$(sprojs_mk_in
) config.status
383 dist_junk
+= config.status config.h Makefile config.log
385 #-------------------------------------------------------------------------
387 #-------------------------------------------------------------------------
388 # The distribution tarball is named project-ver.tar.gz and it includes
389 # both enabled and disabled subprojects.
403 dist_dir
:= $(project_name
)-$(project_ver
)
404 dist_tgz
:= $(project_name
)-$(project_ver
).
tar.gz
406 # Notice that when we make the distribution we rewrite the configure.ac
407 # script with the current version and we rerun autoconf in the new
408 # source directory so that the distribution will have the proper version
409 # information. We also rewrite the "Version : " line in the README.
414 tar -C
$(src_dir
) -cf
- $(dist_files
) |
tar -C
$(dist_dir
) -xpf
-
415 sed
-i.bak
's/^\(# Version :\).*/\1 $(project_ver)/' $(dist_dir
)/README
416 sed
-i.bak
's/\( proj_version,\).*/\1 [$(project_ver)])/' $(dist_dir
)/configure.ac
418 autoconf
&& autoheader
&& \
419 rm -rf autom4te.cache configure.ac.bak README.bak
420 tar -czvf
$(dist_tgz
) $(dist_dir
)
423 # You can use the distcheck target to try untarring the distribution and
424 # then running configure, make, make check, and make distclean. A
425 # "directory is not empty" error means distclean is not removing
430 tar -xzvf
$(dist_tgz
)
431 mkdir
-p
$(dist_dir
)/build
432 cd
$(dist_dir
)/build
; ..
/configure
; make
; make
check; make
distclean
435 junk
+= $(project_name
)-*.
tar.gz
437 .PHONY
: dist distcheck
439 #-------------------------------------------------------------------------
441 #-------------------------------------------------------------------------
443 all : $(install_hdrs
) $(install_libs
) $(install_exes
)
446 #-------------------------------------------------------------------------
448 #-------------------------------------------------------------------------
449 # This handy rule will display the contents of any make variable by
450 # using the target debug-<varname>. So for example, make debug-junk will
451 # display the contents of the junk variable.
456 #-------------------------------------------------------------------------
458 #-------------------------------------------------------------------------
461 rm -rf
*~ \
#* $(junk)
464 rm -rf
*~ \
#* $(junk) $(dist_junk)
466 .PHONY
: clean distclean