add comment
[riscv-isa-sim.git] / Makefile.in
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
7 # are as follows:
8 #
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
16 #
17
18 #-------------------------------------------------------------------------
19 # Basic setup
20 #-------------------------------------------------------------------------
21
22 # Remove all default implicit rules since they can cause subtle bugs
23 # and they just make things run slower
24 .SUFFIXES:
25 % : %,v
26 % : RCS/%,v
27 % : RCS/%
28 % : s.%
29 % : SCCS/s.%
30
31 # Default is to build the prereqs of the all target (defined at bottom)
32 default : all
33 .PHONY : default
34
35 project_name := @PACKAGE_TARNAME@
36 src_dir := @srcdir@
37 scripts_dir := $(src_dir)/scripts
38
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.
44
45 ifeq (@PACKAGE_VERSION@,?)
46 project_ver:=$(shell $(scripts_dir)/vcs-version.sh $(src_dir))
47 else
48 project_ver:=@PACKAGE_VERSION@
49 endif
50
51 # Installation directories
52
53 prefix := @prefix@
54 enable_stow := @enable_stow@
55
56 ifeq ($(enable_stow),yes)
57 stow_pkg_dir := $(prefix)/pkgs
58 INSTALLDIR ?= $(DESTDIR)$(stow_pkg_dir)/$(project_name)-$(project_ver)
59 else
60 INSTALLDIR ?= $(DESTDIR)$(prefix)
61 endif
62
63 install_hdrs_dir := $(INSTALLDIR)/include/$(project_name)
64 install_libs_dir := $(INSTALLDIR)/lib
65 install_exes_dir := $(INSTALLDIR)/bin
66
67 #-------------------------------------------------------------------------
68 # List of subprojects
69 #-------------------------------------------------------------------------
70
71 sprojs := @subprojects@
72 sprojs_enabled := @subprojects_enabled@
73
74 sprojs_include := -I. -I$(src_dir) $(addprefix -I$(src_dir)/, $(sprojs_enabled))
75 VPATH := $(addprefix $(src_dir)/, $(sprojs_enabled))
76
77 #-------------------------------------------------------------------------
78 # Programs and flags
79 #-------------------------------------------------------------------------
80
81 # C++ compiler
82 # - CPPFLAGS : flags for the preprocessor (eg. -I,-D)
83 # - CXXFLAGS : flags for C++ compiler (eg. -Wall,-g,-O3)
84
85 CC := @CC@
86 CXX := @CXX@
87 CFLAGS += @CFLAGS@ -DPREFIX=\"$(prefix)\"
88 CPPFLAGS += @CPPFLAGS@
89 CXXFLAGS += @CXXFLAGS@ -DPREFIX=\"$(prefix)\"
90 COMPILE := $(CXX) -fPIC -MMD -MP $(CPPFLAGS) $(CXXFLAGS) \
91 $(sprojs_include)
92 COMPILE_C := $(CC) -fPIC -MMD -MP $(CPPFLAGS) $(CFLAGS) \
93 $(sprojs_include)
94 # Linker
95 # - LDFLAGS : Flags for the linker (eg. -L)
96 # - LIBS : Library flags (eg. -l)
97
98 comma := ,
99 LD := $(CXX)
100 LDFLAGS := @LDFLAGS@
101 LIBS := @LIBS@
102 LINK := $(LD) -L. $(LDFLAGS) -Wl,-rpath,$(install_libs_dir) $(patsubst -L%,-Wl$(comma)-rpath$(comma)%,$(filter -L%,$(LDFLAGS)))
103
104 # Library creation
105
106 AR := @AR@
107 RANLIB := @RANLIB@
108
109 # Host simulator
110
111 RUN := @RUN@
112 RUNFLAGS := @RUNFLAGS@
113
114 # Installation
115
116 MKINSTALLDIRS := $(scripts_dir)/mk-install-dirs.sh
117 INSTALL := @INSTALL@
118 INSTALL_HDR := $(INSTALL) -m 444
119 INSTALL_LIB := $(INSTALL) -m 644
120 INSTALL_EXE := $(INSTALL) -m 555
121 STOW := @stow@
122
123 # Tests
124 bintests = $(src_dir)/tests/ebreak.py
125
126 #-------------------------------------------------------------------------
127 # Include subproject makefile fragments
128 #-------------------------------------------------------------------------
129
130 sprojs_mk = $(addsuffix .mk, $(sprojs_enabled))
131
132 -include $(sprojs_mk)
133
134 dist_junk += $(sprojs_mk)
135
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.
141 #
142 # Arguments:
143 # $(1) : space separated input list
144 # retval : input list in reverse order
145 #
146
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)), \
153 $(2))
154 endef
155
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.
165 #
166 # Arguments:
167 # $(1) : real subproject name (ie with dashes)
168 # $(2) : normalized subproject name (ie dashes replaced with underscores)
169 #
170
171 define subproject_template
172
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.
179
180 ifeq ($$(strip $$($(2)_srcs) $$($(2)_c_srcs)),)
181 $(2)_srcs += _$(1).cc
182 $(2)_junk += _$(1).cc
183 endif
184
185 _$(1).cc :
186 echo "int _$(2)( int arg ) { return arg; }" > $$@
187
188 # Build the object files for this subproject
189
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))
200 $(COMPILE) -c $$<
201 $$($(2)_c_objs) : %.o : %.c $$($(2)_gen_hdrs)
202 $(COMPILE_C) -c $$<
203
204 $(2)_junk += $$($(2)_pch) $$($(2)_objs) $$($(2)_c_objs) $$($(2)_deps) \
205 $$($(2)_gen_hdrs)
206
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.
210
211 $(2)_reverse_deps := $$(call reverse_list,$$($(2)_subproject_deps))
212
213 # Build a library for this subproject
214
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))
218
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)
221
222 $(2)_junk += lib$(1).so
223
224 # Build unit tests
225
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)
231 $(2)_test_libnames := $$(patsubst %, lib%.so, $$($(2)_test_libs))
232 $(2)_test_libarg := $$(patsubst %, -l%, $$($(2)_test_libs))
233
234 $$($(2)_test_objs) : %.o : %.cc
235 $(COMPILE) -c $$<
236
237 $$($(2)_test_exes) : %-utst : %.t.o $$($(2)_test_libnames)
238 $(LINK) -o $$@ $$< $$($(2)_test_libarg) $(LIBS)
239
240 $(2)_deps += $$($(2)_test_deps)
241 $(2)_junk += \
242 $$($(2)_test_objs) $$($(2)_test_deps) \
243 $$($(2)_test_exes) *.junk-dat
244
245 # Run unit tests
246
247 $$($(2)_test_outs) : %.out : %
248 $(RUN) $(RUNFLAGS) ./$$< default | tee $$@
249
250 $(2)_junk += $$($(2)_test_outs)
251
252 # Build programs
253
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))
260
261 $$($(2)_prog_objs) : %.o : %.cc
262 $(COMPILE) -c $$<
263
264 $$($(2)_prog_exes) : % : %.o $$($(2)_prog_libnames)
265 $(LINK) -o $$@ $$< $$($(2)_prog_libarg) $(LIBS)
266
267 $(2)_deps += $$($(2)_prog_deps)
268 $(2)_junk += $$($(2)_prog_objs) $$($(2)_prog_deps) $$($(2)_prog_exes)
269
270 # Build programs which will be installed
271
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))
275
276 $$($(2)_install_prog_objs) : %.o : %.cc $$($(2)_gen_hdrs)
277 $(COMPILE) -c $$<
278
279 $$($(2)_install_prog_exes) : % : %.o $$($(2)_prog_libnames)
280 $(LINK) -o $$@ $$< $$($(2)_prog_libarg) $(LIBS)
281
282 $(2)_deps += $$($(2)_install_prog_deps)
283 $(2)_junk += \
284 $$($(2)_install_prog_objs) $$($(2)_install_prog_deps) \
285 $$($(2)_install_prog_exes)
286
287 # Subproject specific targets
288
289 all-$(1) : lib$(1).so $$($(2)_install_prog_exes)
290
291 check-$(1) : $$($(2)_test_outs)
292 echo; grep -h -e'Unit Tests' -e'FAILED' -e'Segementation' $$^; echo
293
294 clean-$(1) :
295 rm -rf $$($(2)_junk)
296
297 .PHONY : all-$(1) check-$(1) clean-$(1)
298
299 # Update running variables
300
301 libs += lib$(1).so
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)
307
308 test_outs += $$($(2)_test_outs)
309
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
314
315 endef
316
317 # Iterate over the subprojects and call the template for each one
318
319 $(foreach sproj,$(sprojs_enabled), \
320 $(eval $(call subproject_template,$(sproj),$(subst -,_,$(sproj)))))
321
322 #-------------------------------------------------------------------------
323 # Autodependency files
324 #-------------------------------------------------------------------------
325
326 -include $(deps)
327
328 deps : $(deps)
329 .PHONY : deps
330
331 #-------------------------------------------------------------------------
332 # Check
333 #-------------------------------------------------------------------------
334
335 bintest_outs = $(bintests:=.out)
336 junk += $(bintest_outs)
337 %.out: % all
338 ./$* < /dev/null 2>&1 | tee $@
339
340 check-cpp : $(test_outs)
341 @echo
342 ! grep -h -e'Unit Tests' -e'FAILED' -e'Segmentation' $^ < /dev/null
343 @echo
344
345 check-bin : $(bintest_outs)
346 ! tail -n 1 $^ < /dev/null 2>&1 | grep FAILED
347
348 check : check-cpp check-bin
349
350 .PHONY : check
351
352 #-------------------------------------------------------------------------
353 # Installation
354 #-------------------------------------------------------------------------
355
356 install-hdrs : $(install_hdrs) config.h
357 $(MKINSTALLDIRS) $(install_hdrs_dir)
358 for file in $^; \
359 do \
360 $(INSTALL_HDR) $$file $(install_hdrs_dir); \
361 done
362
363 install-libs : $(install_libs)
364 $(MKINSTALLDIRS) $(install_libs_dir)
365 for file in $^; \
366 do \
367 $(INSTALL_LIB) $$file $(install_libs_dir); \
368 done
369
370 install-exes : $(install_exes)
371 $(MKINSTALLDIRS) $(install_exes_dir)
372 for file in $^; \
373 do \
374 $(INSTALL_EXE) $$file $(install_exes_dir); \
375 done
376
377 install-pc : $(install_pcs)
378 $(MKINSTALLDIRS) $(install_libs_dir)/pkgconfig/
379 for file in $^; \
380 do \
381 $(INSTALL_HDR) $$file $(install_libs_dir)/pkgconfig/; \
382 done
383
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)
390 endif
391
392 .PHONY : install install-hdrs install-libs install-exes
393
394 #-------------------------------------------------------------------------
395 # Regenerate configure information
396 #-------------------------------------------------------------------------
397
398 config.status : $(src_dir)/configure
399 ./config.status --recheck
400
401 sprojs_mk_in = \
402 $(join $(addprefix $(src_dir)/, $(sprojs_enabled)), \
403 $(patsubst %, /%.mk.in, $(sprojs_enabled)))
404
405 Makefile : $(src_dir)/Makefile.in $(sprojs_mk_in) config.status
406 ./config.status
407
408 dist_junk += config.status config.h Makefile config.log
409
410 #-------------------------------------------------------------------------
411 # Distribution
412 #-------------------------------------------------------------------------
413 # The distribution tarball is named project-ver.tar.gz and it includes
414 # both enabled and disabled subprojects.
415
416 dist_files = \
417 $(sprojs) \
418 README \
419 style-guide.txt \
420 mcppbs-uguide.txt \
421 scripts \
422 configure.ac \
423 aclocal.m4 \
424 configure \
425 config.h.in \
426 Makefile.in \
427
428 dist_dir := $(project_name)-$(project_ver)
429 dist_tgz := $(project_name)-$(project_ver).tar.gz
430
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.
435
436 dist :
437 rm -rf $(dist_dir)
438 mkdir $(dist_dir)
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
442 cd $(dist_dir) && \
443 autoconf && autoheader && \
444 rm -rf autom4te.cache configure.ac.bak README.bak
445 tar -czvf $(dist_tgz) $(dist_dir)
446 rm -rf $(dist_dir)
447
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
451 # everything.
452
453 distcheck : dist
454 rm -rf $(dist_dir)
455 tar -xzvf $(dist_tgz)
456 mkdir -p $(dist_dir)/build
457 cd $(dist_dir)/build; ../configure; make; make check; make distclean
458 rm -rf $(dist_dir)
459
460 junk += $(project_name)-*.tar.gz
461
462 .PHONY : dist distcheck
463
464 #-------------------------------------------------------------------------
465 # Default
466 #-------------------------------------------------------------------------
467
468 all : $(install_hdrs) $(install_libs) $(install_exes)
469 .PHONY : all
470
471 #-------------------------------------------------------------------------
472 # Makefile debugging
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.
477
478 debug-% :
479 @echo $* = $($*)
480
481 #-------------------------------------------------------------------------
482 # Clean up junk
483 #-------------------------------------------------------------------------
484
485 clean :
486 rm -rf *~ \#* $(junk)
487
488 distclean :
489 rm -rf *~ \#* $(junk) $(dist_junk)
490
491 .PHONY : clean distclean