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.
$(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
= tests
/gdbserver.py \
127 #-------------------------------------------------------------------------
128 # Include subproject makefile fragments
129 #-------------------------------------------------------------------------
131 sprojs_mk
= $(addsuffix .mk
, $(sprojs_enabled
))
133 -include $(sprojs_mk
)
135 dist_junk
+= $(sprojs_mk
)
137 #-------------------------------------------------------------------------
138 # Reverse list helper function
139 #-------------------------------------------------------------------------
140 # This function is used by the subproject template to reverse the list
141 # of dependencies. It uses recursion to perform the reversal.
144 # $(1) : space separated input list
145 # retval : input list in reverse order
148 reverse_list
= $(call reverse_list_h
,$(1),)
149 define reverse_list_h
150 $(if
$(strip $(1)), \
151 $(call reverse_list_h
, \
152 $(wordlist
2,$(words $(1)),$(1)), \
153 $(firstword $(1)) $(2)), \
157 #-------------------------------------------------------------------------
158 # Template for per subproject rules
159 #-------------------------------------------------------------------------
160 # The template is instantiated for each of the subprojects. It relies on
161 # subprojects defining a certain set of make variables which are all
162 # prefixed with the subproject name. Since subproject names can have
163 # dashes in them (and the make variables are assumed to only use
164 # underscores) the template takes two arguments - one with the regular
165 # subproject name and one with dashes replaced with underscores.
168 # $(1) : real subproject name (ie with dashes)
169 # $(2) : normalized subproject name (ie dashes replaced with underscores)
172 define subproject_template
174 # In some (rare) cases, a subproject might not have any actual object
175 # files. It might only include header files or program sources. To keep
176 # things consistent we still want a library for this subproject, so in
177 # this spectial case we create a dummy source file and thus the build
178 # system will create a library for this subproject with just the
179 # corresponding dummy object file.
181 ifeq ($$(strip $$($(2)_srcs
) $$($(2)_c_srcs
)),)
182 $(2)_srcs
+= _
$(1).
cc
183 $(2)_junk
+= _
$(1).
cc
187 echo
"int _$(2)( int arg ) { return arg; }" > $$@
189 # Build the object files for this subproject
191 $(2)_pch
:= $$(patsubst %.h
, %.h.gch
, $$($(2)_precompiled_hdrs
))
192 $(2)_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_srcs
))
193 $(2)_c_objs
:= $$(patsubst %.c
, %.o
, $$($(2)_c_srcs
))
194 $(2)_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_objs
))
195 $(2)_deps
+= $$(patsubst %.o
, %.d
, $$($(2)_c_objs
))
196 $(2)_deps
+= $$(patsubst %.h
, %.h.d
, $$($(2)_precompiled_hdrs
))
197 $$($(2)_pch
) : %.h.gch
: %.h
198 $(COMPILE
) $$< -o
$$@
199 # If using clang, don't depend (and thus don't build) precompiled headers
200 $$($(2)_objs
) : %.o
: %.
cc $$($(2)_gen_hdrs
) $(if
$(filter-out clang
,$(CC
)),$$($(2)_pch
))
202 $$($(2)_c_objs
) : %.o
: %.c
$$($(2)_gen_hdrs
)
205 $(2)_junk
+= $$($(2)_pch
) $$($(2)_objs
) $$($(2)_c_objs
) $$($(2)_deps
) \
208 # Reverse the dependency list so that a given subproject only depends on
209 # subprojects listed to its right. This is the correct order for linking
210 # the list of subproject libraries.
212 $(2)_reverse_deps
:= $$(call reverse_list
,$$($(2)_subproject_deps
))
214 # Build a library for this subproject
216 $(2)_lib_libs
:= $$($(2)_reverse_deps
)
217 $(2)_lib_libnames
:= $$(patsubst %, lib
%.so
, $$($(2)_lib_libs
))
218 $(2)_lib_libarg
:= $$(patsubst %, -l
%, $$($(2)_lib_libs
))
220 lib
$(1).so
: $$($(2)_objs
) $$($(2)_c_objs
) $$($(2)_lib_libnames
)
221 $(LINK
) -shared
-o
$$@
$(if
$(filter Darwin
,$(shell uname
-s
)),-install_name
$(install_libs_dir
)/$$@
) $$^
$$($(2)_lib_libarg
) $(LIBS
)
223 $(2)_junk
+= lib
$(1).so
227 $(2)_test_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_test_srcs
))
228 $(2)_test_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_test_objs
))
229 $(2)_test_exes
:= $$(patsubst %.t.
cc, %-utst
, $$($(2)_test_srcs
))
230 $(2)_test_outs
:= $$(patsubst %, %.out
, $$($(2)_test_exes
))
231 $(2)_test_libs
:= $(1) $$($(2)_reverse_deps
) utst
232 $(2)_test_libnames
:= $$(patsubst %, lib
%.so
, $$($(2)_test_libs
))
233 $(2)_test_libarg
:= $$(patsubst %, -l
%, $$($(2)_test_libs
))
235 $$($(2)_test_objs
) : %.o
: %.
cc
238 $$($(2)_test_exes
) : %-utst
: %.t.o
$$($(2)_test_libnames
)
239 $(LINK
) -o
$$@
$$< $$($(2)_test_libarg
) $(LIBS
)
241 $(2)_deps
+= $$($(2)_test_deps
)
243 $$($(2)_test_objs
) $$($(2)_test_deps
) \
244 $$($(2)_test_exes
) *.junk-dat
248 $$($(2)_test_outs
) : %.out
: %
249 $(RUN
) $(RUNFLAGS
) .
/$$< default | tee
$$@
251 $(2)_junk
+= $$($(2)_test_outs
)
255 $(2)_prog_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_prog_srcs
))
256 $(2)_prog_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_prog_objs
))
257 $(2)_prog_exes
:= $$(patsubst %.
cc, %, $$($(2)_prog_srcs
))
258 $(2)_prog_libs
:= $(1) $$($(2)_reverse_deps
)
259 $(2)_prog_libnames
:= $$(patsubst %, lib
%.so
, $$($(2)_prog_libs
))
260 $(2)_prog_libarg
:= $$(patsubst %, -l
%, $$($(2)_prog_libs
))
262 $$($(2)_prog_objs
) : %.o
: %.
cc
265 $$($(2)_prog_exes
) : % : %.o
$$($(2)_prog_libnames
)
266 $(LINK
) -o
$$@
$$< $$($(2)_prog_libarg
) $(LIBS
)
268 $(2)_deps
+= $$($(2)_prog_deps
)
269 $(2)_junk
+= $$($(2)_prog_objs
) $$($(2)_prog_deps
) $$($(2)_prog_exes
)
271 # Build programs which will be installed
273 $(2)_install_prog_objs
:= $$(patsubst %.
cc, %.o
, $$($(2)_install_prog_srcs
))
274 $(2)_install_prog_deps
:= $$(patsubst %.o
, %.d
, $$($(2)_install_prog_objs
))
275 $(2)_install_prog_exes
:= $$(patsubst %.
cc, %, $$($(2)_install_prog_srcs
))
277 $$($(2)_install_prog_objs
) : %.o
: %.
cc $$($(2)_gen_hdrs
)
280 $$($(2)_install_prog_exes
) : % : %.o
$$($(2)_prog_libnames
)
281 $(LINK
) -o
$$@
$$< $$($(2)_prog_libarg
) $(LIBS
)
283 $(2)_deps
+= $$($(2)_install_prog_deps
)
285 $$($(2)_install_prog_objs
) $$($(2)_install_prog_deps
) \
286 $$($(2)_install_prog_exes
)
288 # Subproject specific targets
290 all-
$(1) : lib
$(1).so
$$($(2)_install_prog_exes
)
292 check-
$(1) : $$($(2)_test_outs
)
293 echo
; grep
-h
-e
'Unit Tests' -e
'FAILED' -e
'Segementation' $$^
; echo
298 .PHONY
: all-
$(1) check-
$(1) clean-
$(1)
300 # Update running variables
303 objs
+= $$($(2)_objs
)
304 srcs
+= $$(addprefix $(src_dir
)/$(1)/, $$($(2)_srcs
))
305 hdrs
+= $$(addprefix $(src_dir
)/$(1)/, $$($(2)_hdrs
)) $$($(2)_gen_hdrs
)
306 junk
+= $$($(2)_junk
)
307 deps
+= $$($(2)_deps
)
309 test_outs
+= $$($(2)_test_outs
)
311 install_hdrs
+= $$(addprefix $(src_dir
)/$(1)/, $$($(2)_hdrs
)) $$($(2)_gen_hdrs
)
312 install_libs
+= lib
$(1).so
313 install_exes
+= $$($(2)_install_prog_exes
)
314 install_pcs
+= riscv-
$(1).
pc
318 # Iterate over the subprojects and call the template for each one
320 $(foreach sproj
,$(sprojs_enabled
), \
321 $(eval
$(call subproject_template
,$(sproj
),$(subst -,_
,$(sproj
)))))
323 #-------------------------------------------------------------------------
324 # Autodependency files
325 #-------------------------------------------------------------------------
332 #-------------------------------------------------------------------------
334 #-------------------------------------------------------------------------
336 bintest_outs
= $(bintests
:=.out
)
337 junk
+= $(bintest_outs
)
339 .
/$* < /dev
/null
2>&1 | tee
$@
341 check-cpp
: $(test_outs
)
342 echo
; grep
-h
-e
'Unit Tests' -e
'FAILED' -e
'Segmentation' $^
< /dev
/null
; echo
344 check-bin
: $(bintest_outs
)
345 tail
-n
1 $^
< /dev
/null
347 check : check-cpp check-bin
351 #-------------------------------------------------------------------------
353 #-------------------------------------------------------------------------
355 install-hdrs
: $(install_hdrs
) config.h
356 $(MKINSTALLDIRS
) $(install_hdrs_dir
)
359 $(INSTALL_HDR
) $$file $(install_hdrs_dir
); \
362 install-libs
: $(install_libs
)
363 $(MKINSTALLDIRS
) $(install_libs_dir
)
366 $(INSTALL_LIB
) $$file $(install_libs_dir
); \
369 install-exes
: $(install_exes
)
370 $(MKINSTALLDIRS
) $(install_exes_dir
)
373 $(INSTALL_EXE
) $$file $(install_exes_dir
); \
376 install-pc
: $(install_pcs
)
377 $(MKINSTALLDIRS
) $(install_libs_dir
)/pkgconfig
/
380 $(INSTALL_HDR
) $$file $(install_libs_dir
)/pkgconfig
/; \
383 install : install-hdrs install-libs install-exes install-pc
384 ifeq ($(enable_stow
),yes
)
385 $(MKINSTALLDIRS
) $(stow_pkg_dir
)
386 cd
$(stow_pkg_dir
) && \
387 $(STOW
) --delete
$(project_name
)-* && \
388 $(STOW
) $(project_name
)-$(project_ver
)
391 .PHONY
: install install-hdrs install-libs install-exes
393 #-------------------------------------------------------------------------
394 # Regenerate configure information
395 #-------------------------------------------------------------------------
397 config.status
: $(src_dir
)/configure
398 .
/config.status
--recheck
401 $(join $(addprefix $(src_dir
)/, $(sprojs_enabled
)), \
402 $(patsubst %, /%.mk.in
, $(sprojs_enabled
)))
404 Makefile
: $(src_dir
)/Makefile.in
$(sprojs_mk_in
) config.status
407 dist_junk
+= config.status config.h Makefile config.log
409 #-------------------------------------------------------------------------
411 #-------------------------------------------------------------------------
412 # The distribution tarball is named project-ver.tar.gz and it includes
413 # both enabled and disabled subprojects.
427 dist_dir
:= $(project_name
)-$(project_ver
)
428 dist_tgz
:= $(project_name
)-$(project_ver
).
tar.gz
430 # Notice that when we make the distribution we rewrite the configure.ac
431 # script with the current version and we rerun autoconf in the new
432 # source directory so that the distribution will have the proper version
433 # information. We also rewrite the "Version : " line in the README.
438 tar -C
$(src_dir
) -cf
- $(dist_files
) |
tar -C
$(dist_dir
) -xpf
-
439 sed
-i.bak
's/^\(# Version :\).*/\1 $(project_ver)/' $(dist_dir
)/README
440 sed
-i.bak
's/\( proj_version,\).*/\1 [$(project_ver)])/' $(dist_dir
)/configure.ac
442 autoconf
&& autoheader
&& \
443 rm -rf autom4te.cache configure.ac.bak README.bak
444 tar -czvf
$(dist_tgz
) $(dist_dir
)
447 # You can use the distcheck target to try untarring the distribution and
448 # then running configure, make, make check, and make distclean. A
449 # "directory is not empty" error means distclean is not removing
454 tar -xzvf
$(dist_tgz
)
455 mkdir
-p
$(dist_dir
)/build
456 cd
$(dist_dir
)/build
; ..
/configure
; make
; make
check; make
distclean
459 junk
+= $(project_name
)-*.
tar.gz
461 .PHONY
: dist distcheck
463 #-------------------------------------------------------------------------
465 #-------------------------------------------------------------------------
467 all : $(install_hdrs
) $(install_libs
) $(install_exes
)
470 #-------------------------------------------------------------------------
472 #-------------------------------------------------------------------------
473 # This handy rule will display the contents of any make variable by
474 # using the target debug-<varname>. So for example, make debug-junk will
475 # display the contents of the junk variable.
480 #-------------------------------------------------------------------------
482 #-------------------------------------------------------------------------
485 rm -rf
*~ \
#* $(junk)
488 rm -rf
*~ \
#* $(junk) $(dist_junk)
490 .PHONY
: clean distclean