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 INSTALLDIR ?
= $(DESTDIR
)$(stow_pkg_dir
)/$(project_name
)-$(project_ver
)
60 INSTALLDIR ?
= $(DESTDIR
)$(prefix)
63 install_hdrs_dir
:= $(INSTALLDIR
)/include/$(project_name
)
64 install_libs_dir
:= $(INSTALLDIR
)/lib
65 install_exes_dir
:= $(INSTALLDIR
)/bin
67 #-------------------------------------------------------------------------
69 #-------------------------------------------------------------------------
71 sprojs
:= @subprojects@
72 sprojs_enabled
:= @subprojects_enabled@
74 sprojs_include
:= -I.
-I
$(src_dir
) $(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 CFLAGS
+= @CFLAGS@
-DPREFIX
=\"$(prefix)\" -Werror
88 CPPFLAGS
+= @CPPFLAGS@
89 CXXFLAGS
+= @CXXFLAGS@
-DPREFIX
=\"$(prefix)\" -Werror
90 COMPILE
:= $(CXX
) -fPIC
-MMD
-MP
$(CPPFLAGS
) $(CXXFLAGS
) \
92 COMPILE_C
:= $(CC
) -fPIC
-MMD
-MP
$(CPPFLAGS
) $(CFLAGS
) \
95 # - LDFLAGS : Flags for the linker (eg. -L)
96 # - LIBS : Library flags (eg. -l)
102 LINK
:= $(LD
) -L.
$(LDFLAGS
) -Wl
,-rpath
,$(install_libs_dir
) $(patsubst -L
%,-Wl
$(comma
)-rpath
$(comma
)%,$(filter -L
%,$(LDFLAGS
)))
112 RUNFLAGS
:= @RUNFLAGS@
116 MKINSTALLDIRS
:= $(scripts_dir
)/mk-install-dirs.sh
118 INSTALL_HDR
:= $(INSTALL
) -m
444
119 INSTALL_LIB
:= $(INSTALL
) -m
644
120 INSTALL_EXE
:= $(INSTALL
) -m
555
124 bintests
= $(src_dir
)/tests
/ebreak.py
126 #-------------------------------------------------------------------------
127 # Include subproject makefile fragments
128 #-------------------------------------------------------------------------
130 sprojs_mk
= $(addsuffix .mk
, $(sprojs_enabled
))
132 -include $(sprojs_mk
)
134 dist_junk
+= $(sprojs_mk
)
136 #-------------------------------------------------------------------------
137 # Reverse list helper function
138 #-------------------------------------------------------------------------
139 # This function is used by the subproject template to reverse the list
140 # of dependencies. It uses recursion to perform the reversal.
143 # $(1) : space separated input list
144 # retval : input list in reverse order
147 reverse_list
= $(call reverse_list_h
,$(1),)
148 define reverse_list_h
149 $(if
$(strip $(1)), \
150 $(call reverse_list_h
, \
151 $(wordlist
2,$(words $(1)),$(1)), \
152 $(firstword $(1)) $(2)), \
156 #-------------------------------------------------------------------------
157 # Template for per subproject rules
158 #-------------------------------------------------------------------------
159 # The template is instantiated for each of the subprojects. It relies on
160 # subprojects defining a certain set of make variables which are all
161 # prefixed with the subproject name. Since subproject names can have
162 # dashes in them (and the make variables are assumed to only use
163 # underscores) the template takes two arguments - one with the regular
164 # subproject name and one with dashes replaced with underscores.
167 # $(1) : real subproject name (ie with dashes)
168 # $(2) : normalized subproject name (ie dashes replaced with underscores)
171 define subproject_template
173 # In some (rare) cases, a subproject might not have any actual object
174 # files. It might only include header files or program sources. To keep
175 # things consistent we still want a library for this subproject, so in
176 # this spectial case we create a dummy source file and thus the build
177 # system will create a library for this subproject with just the
178 # corresponding dummy object file.
180 ifeq ($$(strip $$($(2)_srcs
) $$($(2)_c_srcs
)),)
181 $(2)_srcs
+= _
$(1).
cc
182 $(2)_junk
+= _
$(1).
cc
186 echo
"int _$(2)( int arg ) { return arg; }" > $$@
188 # Build the object files for this subproject
190 $(2)_pch
:= $$(patsubst %.h
, %.h.gch
, $$($(2)_precompiled_hdrs
))
191 $(2)_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_srcs
))
192 $(2)_c_objs
:= $$(patsubst %.c
, %.o
, $$($(2)_c_srcs
))
193 $(2)_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_objs
))
194 $(2)_deps
+= $$(patsubst %.o
, %.d
, $$($(2)_c_objs
))
195 $(2)_deps
+= $$(patsubst %.h
, %.h.d
, $$($(2)_precompiled_hdrs
))
196 $$($(2)_pch
) : %.h.gch
: %.h
197 $(COMPILE
) -x c
++-header
$$< -o
$$@
198 # If using clang, don't depend (and thus don't build) precompiled headers
199 $$($(2)_objs
) : %.o
: %.
cc $$($(2)_gen_hdrs
) $(if
$(filter-out clang
,$(CC
)),$$($(2)_pch
))
201 $$($(2)_c_objs
) : %.o
: %.c
$$($(2)_gen_hdrs
)
204 $(2)_junk
+= $$($(2)_pch
) $$($(2)_objs
) $$($(2)_c_objs
) $$($(2)_deps
) \
207 # Reverse the dependency list so that a given subproject only depends on
208 # subprojects listed to its right. This is the correct order for linking
209 # the list of subproject libraries.
211 $(2)_reverse_deps
:= $$(call reverse_list
,$$($(2)_subproject_deps
))
213 # Build a library for this subproject
215 $(2)_lib_libs
:= $$($(2)_reverse_deps
)
216 $(2)_lib_libnames
:= $$(patsubst %, lib
%.so
, $$($(2)_lib_libs
))
217 $(2)_lib_libarg
:= $$(patsubst %, -l
%, $$($(2)_lib_libs
))
219 lib
$(1).so
: $$($(2)_objs
) $$($(2)_c_objs
) $$($(2)_lib_libnames
)
220 $(LINK
) -shared
-o
$$@
$(if
$(filter Darwin
,$(shell uname
-s
)),-install_name
$(install_libs_dir
)/$$@
) $$^
$$($(2)_lib_libarg
) $(LIBS
)
222 $(2)_junk
+= lib
$(1).so
226 $(2)_test_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_test_srcs
))
227 $(2)_test_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_test_objs
))
228 $(2)_test_exes
:= $$(patsubst %.t.
cc, %-utst
, $$($(2)_test_srcs
))
229 $(2)_test_outs
:= $$(patsubst %, %.out
, $$($(2)_test_exes
))
230 $(2)_test_libs
:= $(1) $$($(2)_reverse_deps
) utst
231 $(2)_test_libnames
:= $$(patsubst %, lib
%.so
, $$($(2)_test_libs
))
232 $(2)_test_libarg
:= $$(patsubst %, -l
%, $$($(2)_test_libs
))
234 $$($(2)_test_objs
) : %.o
: %.
cc
237 $$($(2)_test_exes
) : %-utst
: %.t.o
$$($(2)_test_libnames
)
238 $(LINK
) -o
$$@
$$< $$($(2)_test_libarg
) $(LIBS
)
240 $(2)_deps
+= $$($(2)_test_deps
)
242 $$($(2)_test_objs
) $$($(2)_test_deps
) \
243 $$($(2)_test_exes
) *.junk-dat
247 $$($(2)_test_outs
) : %.out
: %
248 $(RUN
) $(RUNFLAGS
) .
/$$< default | tee
$$@
250 $(2)_junk
+= $$($(2)_test_outs
)
254 $(2)_prog_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_prog_srcs
))
255 $(2)_prog_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_prog_objs
))
256 $(2)_prog_exes
:= $$(patsubst %.
cc, %, $$($(2)_prog_srcs
))
257 $(2)_prog_libs
:= $(1) $$($(2)_reverse_deps
)
258 $(2)_prog_libnames
:= $$(patsubst %, lib
%.so
, $$($(2)_prog_libs
))
259 $(2)_prog_libarg
:= $$(patsubst %, -l
%, $$($(2)_prog_libs
))
261 $$($(2)_prog_objs
) : %.o
: %.
cc
264 $$($(2)_prog_exes
) : % : %.o
$$($(2)_prog_libnames
)
265 $(LINK
) -o
$$@
$$< $$($(2)_prog_libarg
) $(LIBS
)
267 $(2)_deps
+= $$($(2)_prog_deps
)
268 $(2)_junk
+= $$($(2)_prog_objs
) $$($(2)_prog_deps
) $$($(2)_prog_exes
)
270 # Build programs which will be installed
272 $(2)_install_prog_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_install_prog_srcs
))
273 $(2)_install_prog_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_install_prog_objs
))
274 $(2)_install_prog_exes
:= $$(patsubst %.
cc, %, $$($(2)_install_prog_srcs
))
276 $$($(2)_install_prog_objs
) : %.o
: %.
cc $$($(2)_gen_hdrs
)
279 $$($(2)_install_prog_exes
) : % : %.o
$$($(2)_prog_libnames
)
280 $(LINK
) -o
$$@
$$< $$($(2)_prog_libarg
) $(LIBS
)
282 $(2)_deps
+= $$($(2)_install_prog_deps
)
284 $$($(2)_install_prog_objs
) $$($(2)_install_prog_deps
) \
285 $$($(2)_install_prog_exes
)
287 # Subproject specific targets
289 all-
$(1) : lib
$(1).so
$$($(2)_install_prog_exes
)
291 check-
$(1) : $$($(2)_test_outs
)
292 echo
; grep
-h
-e
'Unit Tests' -e
'FAILED' -e
'Segementation' $$^
; echo
297 .PHONY
: all-
$(1) check-
$(1) clean-
$(1)
299 # Update running variables
302 objs
+= $$($(2)_objs
)
303 srcs
+= $$(addprefix $(src_dir
)/$(1)/, $$($(2)_srcs
))
304 hdrs
+= $$(addprefix $(src_dir
)/$(1)/, $$($(2)_hdrs
)) $$($(2)_gen_hdrs
)
305 junk
+= $$($(2)_junk
)
306 deps
+= $$($(2)_deps
)
308 test_outs
+= $$($(2)_test_outs
)
310 install_hdrs
+= $$(addprefix $(src_dir
)/$(1)/, $$($(2)_hdrs
)) $$($(2)_gen_hdrs
)
311 install_libs
+= lib
$(1).so
312 install_exes
+= $$($(2)_install_prog_exes
)
313 install_pcs
+= riscv-
$(1).
pc
317 # Iterate over the subprojects and call the template for each one
319 $(foreach sproj
,$(sprojs_enabled
), \
320 $(eval
$(call subproject_template
,$(sproj
),$(subst -,_
,$(sproj
)))))
322 #-------------------------------------------------------------------------
323 # Autodependency files
324 #-------------------------------------------------------------------------
331 #-------------------------------------------------------------------------
333 #-------------------------------------------------------------------------
335 bintest_outs
= $(bintests
:=.out
)
336 junk
+= $(bintest_outs
)
338 .
/$* < /dev
/null
2>&1 | tee
$@
340 check-cpp
: $(test_outs
)
342 ! grep
-h
-e
'Unit Tests' -e
'FAILED' -e
'Segmentation' $^
< /dev
/null
345 check-bin
: $(bintest_outs
)
346 ! tail
-n
1 $^
< /dev
/null
2>&1 | grep FAILED
348 check : check-cpp check-bin
352 #-------------------------------------------------------------------------
354 #-------------------------------------------------------------------------
356 install-hdrs
: $(install_hdrs
) config.h
357 $(MKINSTALLDIRS
) $(install_hdrs_dir
)
360 $(INSTALL_HDR
) $$file $(install_hdrs_dir
); \
363 install-libs
: $(install_libs
)
364 $(MKINSTALLDIRS
) $(install_libs_dir
)
367 $(INSTALL_LIB
) $$file $(install_libs_dir
); \
370 install-exes
: $(install_exes
)
371 $(MKINSTALLDIRS
) $(install_exes_dir
)
374 $(INSTALL_EXE
) $$file $(install_exes_dir
); \
377 install-pc
: $(install_pcs
)
378 $(MKINSTALLDIRS
) $(install_libs_dir
)/pkgconfig
/
381 $(INSTALL_HDR
) $$file $(install_libs_dir
)/pkgconfig
/; \
384 install : install-hdrs install-libs install-exes install-pc
385 ifeq ($(enable_stow
),yes
)
386 $(MKINSTALLDIRS
) $(stow_pkg_dir
)
387 cd
$(stow_pkg_dir
) && \
388 $(STOW
) --delete
$(project_name
)-* && \
389 $(STOW
) $(project_name
)-$(project_ver
)
392 .PHONY
: install install-hdrs install-libs install-exes
394 #-------------------------------------------------------------------------
395 # Regenerate configure information
396 #-------------------------------------------------------------------------
398 config.status
: $(src_dir
)/configure
399 .
/config.status
--recheck
402 $(join $(addprefix $(src_dir
)/, $(sprojs_enabled
)), \
403 $(patsubst %, /%.mk.in
, $(sprojs_enabled
)))
405 Makefile
: $(src_dir
)/Makefile.in
$(sprojs_mk_in
) config.status
408 dist_junk
+= config.status config.h Makefile config.log
410 #-------------------------------------------------------------------------
412 #-------------------------------------------------------------------------
413 # The distribution tarball is named project-ver.tar.gz and it includes
414 # both enabled and disabled subprojects.
428 dist_dir
:= $(project_name
)-$(project_ver
)
429 dist_tgz
:= $(project_name
)-$(project_ver
).
tar.gz
431 # Notice that when we make the distribution we rewrite the configure.ac
432 # script with the current version and we rerun autoconf in the new
433 # source directory so that the distribution will have the proper version
434 # information. We also rewrite the "Version : " line in the README.
439 tar -C
$(src_dir
) -cf
- $(dist_files
) |
tar -C
$(dist_dir
) -xpf
-
440 sed
-i.bak
's/^\(# Version :\).*/\1 $(project_ver)/' $(dist_dir
)/README
441 sed
-i.bak
's/\( proj_version,\).*/\1 [$(project_ver)])/' $(dist_dir
)/configure.ac
443 autoconf
&& autoheader
&& \
444 rm -rf autom4te.cache configure.ac.bak README.bak
445 tar -czvf
$(dist_tgz
) $(dist_dir
)
448 # You can use the distcheck target to try untarring the distribution and
449 # then running configure, make, make check, and make distclean. A
450 # "directory is not empty" error means distclean is not removing
455 tar -xzvf
$(dist_tgz
)
456 mkdir
-p
$(dist_dir
)/build
457 cd
$(dist_dir
)/build
; ..
/configure
; make
; make
check; make
distclean
460 junk
+= $(project_name
)-*.
tar.gz
462 .PHONY
: dist distcheck
464 #-------------------------------------------------------------------------
466 #-------------------------------------------------------------------------
468 all : $(install_hdrs
) $(install_libs
) $(install_exes
)
471 #-------------------------------------------------------------------------
473 #-------------------------------------------------------------------------
474 # This handy rule will display the contents of any make variable by
475 # using the target debug-<varname>. So for example, make debug-junk will
476 # display the contents of the junk variable.
481 #-------------------------------------------------------------------------
483 #-------------------------------------------------------------------------
486 rm -rf
*~ \
#* $(junk)
489 rm -rf
*~ \
#* $(junk) $(dist_junk)
491 .PHONY
: clean distclean