Subversion Repositories shark

Rev

Rev 1618 | Rev 1683 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1681 fabio 1
# Copyright (c) 2007 Fabio Checconi <fabio@gandalf.sssup.it>
2 pj 2
#
1681 fabio 3
# This is a non-recursive makefile that supports a Kbuild-like syntax
4
# for input/output specification.
5
 
6
# Handle the V=0|1 option.  We use both a long and a short form.  In
7
# the short one we use the $(Q) variable prepended to shell commands
8
# (e.g., $(Q)mkdir) that in quiet mode expands to @, and in verbose
9
# mode expands to nothing.  In the long one we have a couple of strings
10
# per command, one named quiet_cmd, the other cmd, and we always echo
11
# $(QS)cmd, so if $(QS) expands to quiet_ the first string is printed.
12
# The first string is the quiet version of the command, the second one
13
# holds the whole command.
14
ifneq ($(V),1)
15
	Q:=@
16
	QS:=quiet_
17
endif
18
 
19
# Handle the make -s flag: produce no output at all...
20
ifneq ($(findstring s,$(MAKEFLAGS)),)
21
	Q:=@
22
	QS:=nothing_
23
endif
24
 
25
# The variables used to generate the rules to build targets.  Use
26
# CROSS_COMPILE to specify the prefix to be used for the toolchain.
27
ar:= $(CROSS_COMPILE)$(AR)
28
as:= $(CROSS_COMPILE)$(CC)
29
cc:= $(CROSS_COMPILE)$(CC)
30
ld:= $(CROSS_COMPILE)$(LD)
31
rm:= $(if $(RM),$(RM),rm)
32
install:= $(if $(INSTALL),$(INSTALL),install)
33
 
34
# As in the rules we cannot use the variables we use in the makefile,
35
# because we reassign them for every directory we visit, we just try
36
# to recover the information from the targets being built.  Another
37
# way could have been to expand the variables when generating the
38
# rules, but it would have made rule generation unreadable.
39
in-local:= $$(subst $$(srctree)/,,$$<)
40
out-local:= $$(subst install-,,$$(subst $$(objtree)/,,$$@))
41
in-objs:= $$(filter %.o,$$^)
42
in-objs-local:= $$(filter %.o,$$(subst $$(objtree)/,,$$^))
43
 
44
# The rule patterns, in quiet and in verbose form.  The verbose form is
45
# used also for the actual command.
46
quiet_ar_cmd	:= '  AR\\t$(out-local) $(in-objs-local)'
47
ar_cmd		:= $(ar) cr $$@ $(in-objs)
48
 
49
quiet_cc_cmd	:= '  CC\\t$(in-local)'
50
cc_cmd		:= $(cc) $$(cflags-$$(<:.c=.o)) $$(cppflags-$$(<:.c=.o)) \
51
			-c $$< -o $$@
52
 
53
quiet_as_cmd	:= '  AS\\t$(in-local)'
54
as_cmd		:= $(as) $$(aflags-$$(<:.s=.o)) -c $$< -o $$@
55
 
56
quiet_dep_cmd	:= '  DEP\\t$(in-local)'
57
dep_cmd		:= $(cc) $$(cflags-$$(<:.c=.o)) $$(cppflags-$$(<:.c=.o)) \
58
			-M -MT \
59
			"$$(subst $$(srctree),$$(objtree),$$(<:.c=.o))\
60
			$$@" $$< > $$@ 2>/dev/null
61
 
62
quiet_ld-r_cmd	:= '  LD\\t$(out-local) $(in-objs-local)'
63
ld-r_cmd	:= $(ld) $$(ldflags-$$(dir $$@)) -r $(in-objs) -o $$@
64
 
65
quiet_rm_cmd	:= '  RM\\t$$(subst clean-,,$$(subst distclean-,,$(out-local)))'
66
rm_cmd		:= -$(rm) $$(subst clean-,,$$(subst distclean-,,$$@))
67
 
68
quiet_install_cmd := '  INSTALL $(out-local)'
69
install_cmd	:= -$(install) $$(subst install-,,$$@) $$(installdir)
70
 
71
# Generate the requested rule for the requested directory.  First echo
72
# the command according to the requested verbosity (suppress all the
73
# output if $(QS)$(1)_cmd is not defined, i.e., in the silent make case,)
74
# and then emit the actual command.
75
define cmd
76
	$(if $($(QS)$(1)_cmd),@echo -e '$($(QS)$(1)_cmd)')
77
	@$($(1)_cmd)
78
endef
79
 
80
# Remove duplicate slashes, ../'s, trailing slashes and so on from paths.
81
define clean-path
82
$(dir $(abspath $(1)))$(notdir $(abspath $(1)))
83
endef
84
 
85
# Adjust the paths for all the prerequisites of a target.  Given a list
86
# of objects, with relative or absolute path, figure out the right paths
87
# in the build directory.  Leave the output in $(target-objs).
88
define all-prerequisites-templ
89
target-obj-list:=$(1)
90
 
91
# Filter absolute paths.
92
target-objs:=$$(filter $(srctree)/%,$$(target-obj-list))
93
target-obj-list:=$$(filter-out $$(target-objs),$$(target-obj-list))
94
 
95
# Add all the other objects, and convert the path to the $(objtree)
96
# root and with a reasonable path.
97
target-objs+=$$(addprefix $$(curdir)/,$$(target-obj-list))
98
target-objs:=$$(foreach dir,$$(subst $(srctree),$(objtree),$$(target-objs)),\
99
	$$(call clean-path,$$(dir)))
100
endef
101
 
102
# Produce targets for a given library.
103
define lib-templ
104
lib:=$(1)
105
lib-target:=$$(objdir)/$$(lib)
106
 
107
# Get a list of all the prerequisites needed to build the library.
108
$$(eval $$(call all-prerequisites-templ,\
109
	$$(patsubst %/,%/obj.o,$$($$(lib)-objs))))
110
 
111
$$(foreach flag,$(flags),$$(eval $$(call flags-per-target,$$(flag),$$(lib))))
112
$$(foreach obj,$$(target-objs),\
113
	$$(eval $$(call flags-per-objects,$$(obj),$$(lib))))
114
 
115
# Produce the real target, in $(objtree), and the user-friendly target,
116
# with a relative path to $(srctree).  Note that even when the two trees
117
# are equal we define two targets; a possible optimization could be to
118
# use relative paths for the object tree in this case, but the code can
119
# become even less readable than it is now...
120
$$(lib-target): $$(target-objs)
121
	$(call cmd,ar)
122
short-lib-taget:=$$(subst $$(srctree)/,,$$(curdir)/$$(lib))
123
.PHONY: $$(short-lib-target)
124
$$(short-lib-target): $$(lib-target)
125
 
126
# Update the $(subdirs) for $(curdir) and its target list.
127
subdirs+=$$(filter %/,$$($$(lib)-objs))
128
curdir-targets+=$$(lib-target)
129
 
130
.PHONY: clean-$$(lib-target)
131
clean-$$(lib-target):
132
	$(call cmd,rm)
133
curdir-clean-targets+= clean-$$(lib-target)
134
 
135
.PHONY: install-$$(lib-target)
136
install-$$(lib-target): $$(lib-target)
137
	$(call cmd,install)
138
curdir-install-targets+= install-$$(lib-target)
139
endef
140
 
141
# Produce the needed code for a given object.
142
define obj-templ
143
obj:=$(1)
144
obj-target:=$$(objdir)/$$(obj)
145
obj-dep:=$$(objdir)/.$$(obj:.o=.c).deps
146
 
147
# Handle dependencies.
148
ifeq ($(goals-have-clean),)
149
$$(obj-dep): $$(objdir-prereq)
150
-include $$(obj-dep)
151
endif
152
 
153
# Produce the user shortcut for the real target (that does not need to
154
# be produced, as it is handled by implicit rules.)
155
short-obj-target:= $$(subst $$(srctree)/,,$$(curdir)/$$(obj))
156
.PHONY: $$(short-obj-target)
157
$$(short-obj-target): $$(obj-target)
158
 
159
curdir-targets+=$$(obj-target)
160
 
161
.PHONY: clean-$$(obj-target) distclean-$$(obj-dep)
162
clean-$$(obj-target):
163
	$(call cmd,rm)
164
distclean-$$(obj-dep):
165
	$(call cmd,rm)
166
curdir-clean-targets+= clean-$$(obj-target)
167
curdir-distclean-targets+= distclean-$$(obj-dep)
168
 
169
endef
170
 
171
# Handle the flags for the current directory.  for each *FLAGS variable
172
# used by the implicit rules there are two variants:
173
#    o the local one, e.g., cflags:=-I. or cflags+=-I. changing the
174
#      flags used only by the current directory.
175
#    o The global one, e.g., exported-cflags:=-I$(srctree) changing the
176
#      flags for the current directory and all its subdirs.
177
# The flag handling is split in three parts, one to be inserted before
178
# including the current directory makefile, one before recurring into
179
# subdirs, the other one after the recursion.
180
define flags-save-templ
181
flag:=$(1)
182
# Flags on input to this dir; they must be preserved for our sibling
183
# directories.
184
saved-$$(flag)-$$(curdir):= $$($$(flag))
185
endef
186
 
187
define flags-pre-templ
188
flag:=$(1)
189
 
190
# For the current directory, use the user-specified flags (that may
191
# come from our parent directory.)  Extra flags are used to specify
192
# library-specific flags.
193
$$(flag)-$$(curdir):=$$($$(flag)) $$(exported-$$(flag))
194
 
195
#to-print+= [ $$(flag)-$$(curdir) = $$($$(flag)-$$(curdir)) ] RET
196
 
197
# Export to our children also the user exported flags.
198
$$(flag):= $$(saved-$$(flag)-$$(curdir)) $$(exported-$$(flag))
199
exported-$$(flag):=
200
endef
201
 
202
define flags-post-templ
203
flag:=$(1)
204
 
205
# Restore the flags that our parent specified.
206
$$(flag):= $$(saved-$$(flag)-$$(curdir))
207
endef
208
 
209
# Allow redefinition of flags on the basis of a single target.  Each
210
# target gets its own version of the flags, based on the ones of the
211
# current directory and its own ones.
212
define flags-per-target
213
flag:=$(1)
214
target:=$(2)
215
 
216
$$(flag)-$$(curdir)/$$(target):=$$($$(flag)-$$(curdir)) \
217
	 $$($$(target)-$$(flag)) $$(extra-$$(flag)-$$(curdir)/$$(target))
218
 
219
# Those are the flags coming from the upper directories, they are set for
220
# obj.o targets, we must export them to our children, so we leave them here.
221
exported-$$(flag)-$$(curdir)/$$(target):= $$($$(target)-$$(flag)) \
222
	$$(extra-$$(flag)-$$(curdir)/$$(target))
223
$$(target)-$$(flag):=
224
endef
225
 
226
define flags-per-object
227
# Generate flags only for objects in the current directory, as prerequisites
228
# that come from ousdide are not compiled here.
229
flag:=$(1)
230
target:=$(3)
231
ifeq ($(dir $(subst $(objtree),$(srctree),$(2))),$$(curdir)/)
232
this-obj:=$(notdir $(2))
233
 
234
# The flags for a given object are the ones specified for its target
235
# plus any specific one.
236
$$(flag)-$$(curdir)/$$(this-obj):=$$($$(flag)-$$(curdir)/$$(target)) \
237
	$$($$(this-obj)-$$(flag))
238
$$(this-obj)-$$(flag):=
239
 
240
#to-print+= [ $$(flag)-$$(curdir)/$$(this-obj) = $$($$(flag)-$$(curdir)/$$(this-obj)) ] RET
241
endif
242
# Pass the right flags to the subdirs we use to build $(target).
243
ifeq ($$(notdir $(2)),obj.o)
244
extra-$$(flag)-$(2):= $$(exported-$$(flag)-$$(curdir)/$$(target))
245
endif
246
endef
247
 
248
# Allow the user to specify per-object flags
249
define flags-per-objects
250
$$(foreach flag,$$(flags),\
251
	$$(eval $$(call flags-per-object,$$(flags),$(1),$(2))))
252
endef
253
 
254
# Helper to define per-library flags.
255
define flags-per-libs
256
$$(foreach flag,$$(flags),\
257
	$$(eval $$(call flags-per-lib,$$(flags),$(1),$(2))))
258
endef
259
 
260
# Disable default implicit rules.
261
.SUFFIXES:
262
 
263
# The roots of our source and object trees.  If an O=dir option is
264
# passed to the toplevel makefile all the output of the building
265
# process is in dir.
266
srctree:=$(call clean-path,$(CURDIR))
267
objtree:=$(if $(O),$(call clean-path,$(O)),$(srctree))
268
 
269
ifeq ($(wildcard $(objtree)),)
270
$(error Output directory $(objtree) does not exist)
271
endif
272
 
273
clean-targets:=
274
distclean-targets:=
275
install-targets:=
276
 
277
goals-have-clean:=$(strip $(filter clean distclean,$(MAKECMDGOALS)))
278
 
279
aflags:= $(AFLAGS)
280
cflags:= $(CFLAGS)
281
cppflags:= $(CPPFLAGS)
282
ldflags:= $(LDFLAGS)
283
flags:= aflags cflags cppflags ldflags
284
 
285
# XXX debug only
286
to-print:=
287
 
288
# The following macro is used to do a standard set of operations
289
# for every subdirectory we have to work on.  It is instantiated
290
# every time we change subdirectory, and generates a set of targets
291
# specific to that directory.
292
define recurse-templ
293
 
294
# Remember where we are in the source and object tree.  The clean-path
295
# macro is used for user output and for generating targets independently
296
# from directories being specified as dir or dir/ or with multiple slashes
297
# and so on.
298
curdir:=$$(call clean-path,$(1))
299
objdir:=$(objtree)$$(subst $(srctree),,$$(curdir))
300
 
301
# Save the flags our parent passed us.
302
$$(foreach flag,$(flags),$$(eval $$(call flags-save-templ,$$(flag))))
303
 
304
# A list of all the targets defined for the current directory.  It is
305
# used to produce an user-reachable target for submakes into source tree
306
# subdirectories, e.g., if src/utils is a source directory, make src/utils
307
# will build all the targets defined inside it.  Start with the short path
308
# to all subdirs.
309
curdir-targets:=
310
 
311
curdir-clean-targets:=
312
curdir-distclean-targets:=
313
curdir-install-targets:=
314
 
315
# If the output directory does not exist every target that actually
316
# needs it will have to create it.
317
ifneq ($(objtree),$(srctree))
318
ifeq ($$(wildcard $$(objdir)),)
319
objdir-prereq:=$$(objdir)/.build
320
$$(objdir)/.build:
321
	$(Q)if [ ! -d $$(dir $$@) ] ; then \
322
		mkdir -p $$(dir $$@) ; touch $$@ ; fi
323
endif
324
endif
325
 
326
# Include the next subdirectory.  Don't include the root makefile,
327
# if we are at the first step of the recursion.
328
include $$(subst $(srctree)/Makefile,,$$(curdir)/Makefile)
329
 
330
# Figure out all the targets.  We support three kind of targets:
331
#   - subdirectories
332
#   - libraries
333
#   - objects
2 pj 334
#
1681 fabio 335
# Subdirectories are recursively processed, libraries are built using
336
# the objects specified in their *.a-objs target (if it contains a
337
# subdirectory the latter is processed and the resulting obj.o object
338
# is included,) and objects are compiled and incrementally linked
339
# together in a obj.o file.
340
subdirs:=$$(filter %/, $$(targets))
341
objs:=$$(filter %.o, $$(targets))
342
libs:=$$(filter %.a, $$(targets))
2 pj 343
 
1681 fabio 344
$$(eval $$(call all-prerequisites-templ, $$(subdirs)))
345
subdir-targets:= $$(target-objs)
346
 
347
# Recurse into all the subdirectories.
348
curdir-targets+=$$(subst $(objtree)/,,$$(subdir-targets))
349
 
350
# Look for prerequisites to build obj.o for the current directory.
351
$$(eval $$(call all-prerequisites-templ,\
352
	$$(filter-out $$(exclude),$$(objs))))
353
target-objs+=$$(addsuffix /obj.o,$$(subdir-targets))
354
 
355
$$(foreach flag,$(flags),$$(eval $$(call flags-pre-templ,$$(flag))))
356
 
357
# Produce a target for obj.o, even if not needed (it will be empty in
358
# this case.)
359
ifneq ($$(strip $$(target-objs)),)
360
$$(foreach flag,$(flags),$$(eval $$(call flags-per-target,$$(flag),obj.o)))
361
$$(foreach obj,$$(target-objs),\
362
	$$(eval $$(call flags-per-objects,$$(obj),obj.o)))
363
$$(objdir)/obj.o: $$(target-objs)
364
	$(call cmd,ld-r)
365
else
366
$$(objdir)/obj.o:
367
	$(Q)touch $$@
2 pj 368
endif
1681 fabio 369
curdir-targets+= $$(objdir)/obj.o
64 pj 370
 
1681 fabio 371
# to-print+= [ [ $$(objdir)/obj.o ] $$(target-objs) ]
2 pj 372
 
1681 fabio 373
# Produce the needed targets for each library.
374
ifneq ($$(strip $$(libs)),)
375
$$(foreach lib,$$(libs),$$(eval $$(call lib-templ,$$(lib))))
376
endif
377
 
378
# Produce a target for each local object.  Build the list of all the
379
# targets specified by the current subdir.  It is given by all the local
380
# objects in $(targets) or in a library contained in it.  Non-local
381
# objects can be specified as dependencies but must be built from the
382
# directory containing them (if needed their directory can specify that
383
# they are not to be included in the local obj.o putting them into
384
# $(exclude); this may not seem straightforward but is to support a
385
# few corner cases.)
2 pj 386
#
1681 fabio 387
# First build a relative path for all the .o files in the targets (the
388
# default one and the library ones,) taking care of not being confused
389
# by relative directory specifications.
390
all-local-objs-paths:=$$(subst $$(curdir)/,,\
391
	$$(abspath $$(addprefix $$(curdir)/,\
392
	$$(objs) $$(foreach lib,$$(libs),$$(filter %.o,$$($$(lib)-objs))))))
2 pj 393
 
1681 fabio 394
# Then keep only those with a dir equal to ./  A local object is not
395
# allowed to be specified with a path specifying a directory different
396
# from the current one.
397
all-local-objs:=$$(foreach obj, $$(all-local-objs-paths), \
398
	$$(if $$(subst ./,,$$(dir $$(obj))),,$$(obj)))
2 pj 399
 
1681 fabio 400
# Produce one target per object, and the rules to build them along with
401
# their dependencies.
402
ifneq ($$(strip $$(all-local-objs)),)
403
$$(foreach obj,$$(all-local-objs),$$(eval $$(call obj-templ,$$(obj))))
404
 
405
$$(objdir)/%.o: $$(curdir)/%.c
406
	$(call cmd,cc)
407
 
408
$$(objdir)/%.o: $$(curdir)/%.s
409
	$(call cmd,as)
410
 
411
$$(objdir)/.%.c.deps: $$(curdir)/%.c
412
	$(call cmd,dep)
413
 
1037 tullio 414
endif
138 trimarchi 415
 
1681 fabio 416
# Produce the user-friendly target for the source dir, depending
417
# on its obj.o, libs and local objects (only if they can be built.)
418
curdir-target:= $$(subst $$(srctree)/,,$$(curdir))
419
.PHONY: $$(curdir-target)
420
$$(curdir-target): $$(curdir-targets)
421
 
422
# Produce the clean and distclean targets for the current directory.
423
.PHONY: clean-$$(curdir-target) distclean-$$(curdir-target)
424
clean-$$(curdir-target): $$(curdir-clean-targets)
425
 
426
distclean-$$(curdir-target): clean-$$(curdir-target) \
427
	$$(curdir-distclean-targets)
428
 
429
# to-print+=[ distclean-$$(curdir-target) ]
430
 
431
clean-targets+= clean-$$(curdir-target)
432
distclean-targets+= distclean-$$(curdir-target)
433
 
434
# Produce the install target.  This is very Shark specific...
435
.PHONY: install-$$(curdir-target)
436
$$(curdir-install-targets): $(installdir)/.build
437
install-$$(curdir-target): $$(curdir-install-targets)
438
install-targets+= install-$$(curdir-target)
439
 
440
#to-print+=[ install-$$(curdir-target) = $$(curdir-install-targets) ]
441
 
442
# Actually do the recursion, generating the code specified by
443
# recurse-tmpl for every subdirectory needed from the one we are
444
# leaving.
445
ifneq ($$(strip $$(subdirs)),)
446
$$(foreach dir,$$(subdirs),$$(eval $$(call recurse-templ,$(1)/$$(dir))))
447
curdir:=$$(call clean-path,$(1))
448
endif
449
 
450
$$(foreach flag,$(flags),$$(eval $$(call flags-post-templ,$$(flag))))
451
endef
452
 
453
.DEFAULT_GOAL:= all
454
 
455
include shark.cfg
456
 
457
installdir:=$(objtree)/.lib
458
 
459
# Handle Shark configuration.  Really insane, indeed.
460
options:=TSC APIC BIOS TRACER FG FB COMPILER
461
define strip-in-place
462
$(1):=$(strip $($(1)))
463
endef
464
$(foreach cfgopt,$(options),$(eval $(call strip-in-place,$(cfgopt))))
465
 
466
cpp-tsc-TRUE:= -D__TSC__
467
cpp-apic-TRUE:= -D__APIC__
468
cpp-bios-VM86:= -DVM86
469
cpp-tracer-NEW:= -D__NEW_TRACER__
470
cpp-tracer-OLD:= -D__OLD_TRACER__
471
cpp-fg-FORCE_PXC:= -D__FORCE_PXC__
472
cpp-fb-VESA:= -DCONFIG_FB_VESA -DCONFIG_LOGO
473
cpp-fb-FINDPCI:= -DCONFIG_FB_RIVA -DCONFIG_FB_RADEON -DCONFIG_FB_MATROX	\
474
	-DCONFIG_LOGO -DCONFIG_FB_MATROX_G100				\
475
	-DCONFIG_FB_MATROX_MILLENIUM -DCONFIG_FB_MATROX_MYSTIQUE
476
cpp-fb-VGA16:= -DCONFIG_FB_VGA16
477
 
478
include-dirs:=								\
479
	-I$(srctree)/include -I$(srctree)/modules			\
480
	-I$(srctree)/libc/arch/$(ARCH)/include				\
481
	-I$(srctree)/tracer/include					\
482
	-I$(srctree)/oslib
483
 
484
config:= -D__LINUX__							\
485
	$(cpp-tsc-$(TSC)) $(cpp-apic-$(APIC)) $(cpp-bios-$(BIOS))	\
486
	$(cpp-tracer-$(TRACER)) $(cpp-fg-$(FG)) $(cpp-fb-$(FB))
487
 
488
exported-cppflags:= $(include-dirs) $(config)
489
exported-aflags:= -x assembler-with-cpp $(include-dirs) $(config)
490
 
491
cc-compiler-GCC4:= -Wimplicit-function-declaration -Wno-attributes	\
492
	-Wno-pointer-sign -Wall -O -fno-builtin -nostdinc		\
493
	-minline-all-stringops -fno-stack-protector
494
cc-compiler-GCC3:= -Wimplicit-function-declaration -Wall -O		\
495
	-fno-builtin -nostdinc -minline-all-stringops
496
cc-compiler-DJGPP:= -Wimplicit-function-declaration -Wall -O		\
497
	-fno-builtin -nostdinc -minline-all-stringops
498
 
499
exported-cflags:= $(cc-compiler-$(COMPILER))
500
 
501
fs-YES:= fs/
502
 
503
targets:= libgkern.a drivers/ libc/ ports/ tracer/ $(fs-$(SHARK_FS))
504
libgkern.a-objs:= oslib/ kernel/ modules/
505
 
506
# Let the good times roll...
507
$(eval $(call recurse-templ,$(srctree)))
508
 
509
all: $(srctree)
510
 
511
.PHONY: clean distclean
512
clean: $(clean-targets)
513
distclean: $(distclean-targets)
514
 
515
debug:
516
	@echo $(to-print)
517
 
518
.PHONY: install $(install-targets)
519
$(installdir)/.build:
520
	$(Q)if [ ! -d $(dir $@) ] ; then \
521
		mkdir -p $(dir $@) ; touch $@ ; fi
522
 
523
install: $(install-targets)
524