9897db00a48e74851be711d16c574d6b78170274
[akaros.git] / Makefile
1 # Top-level Makefile for Akaros
2 # Barret Rhoden
3 #
4 #
5 # Notes:
6 #       - I downloaded the kbuild guts from git://github.com/lacombar/kconfig.git,
7 #       and added things from a recent linux makefile.  It is from aug 2011, so
8 #       some things might not match up.
9 #       - Kernel output in obj/: So Linux has the ability to output into another
10 #       directory, via the KBUILD_OUTPUT variable.  This induces a recursive make
11 #       in the output directory.  I mucked with it for a little, but didn't get it
12 #       to work quite right.  Also, there will be other Akaros issues since this
13 #       makefile is also used for userspace and tests.  For now, I'm leaving things
14 #       the default Linux way.
15 #       - Kconfig wants to use include/ in the root directory.  We can change some
16 #       of the default settings that silentoldconfig uses, but I'll leave it as-is
17 #       for now, and just symlink that into kern/include.  It'll be easier for us,
18 #       and also potentially easier if we ever move kern/ up a level.  Similarly,
19 #       there are default Kconfigs in arch/, not in kern/arch.  I might change
20 #       that, if we want to support defconfig, or just symlink it.
21 #
22 # TODO:
23 #       - Connect to kconfig, have it generate our CONFIGS, instead of makelocal.
24 #               - what about userspace / tests?
25 #                       the only one is SYSCALL_TRAP.  the others control building
26 #                       - keep them using the old style
27 #               - might need to symlink arch -> kern/arch/ too
28 #                       - though def config is hardcoded to arch/$ARCH, instead of k/a/
29 #
30 #       - Consider merging the two target-detection bits (Linux's config, mixed, or
31 #       dot target, and the symlink handling).
32 #
33 #       - Do we want some sort of default config?  Or the ability to change arches
34 #       and keep common vars?
35 #
36 #       - Review, with an eye for being better about $(srctree).  It might only be
37 #       necessary in this file, if we every do the KBUILD_OUTPUT option
38 #
39 #       - It's a bit crazy that we build symlinks for parlib, instead of it
40 #       managing its own links based on $(ARCH)
41 #
42 #       - Consider using Kbuild to build userspace and tests
43 #
44 #       - There are a few other TODOs sprinkled throughout the makefile.
45
46 # Do not:
47 # o  use make's built-in rules and variables
48 #    (this increases performance and avoids hard-to-debug behaviour);
49 # o  print "Entering directory ...";
50 MAKEFLAGS += -rR --no-print-directory
51
52 # That's our default target when none is given on the command line
53 # This can be overriden with a Makelocal
54 PHONY := all
55 all: akaros-kernel
56
57 # Symlinks
58 # =========================================================================
59 # We have a few symlinks so that code can include <arch/whatever.h>.  This
60 # section builds and maintains those, as best we can.
61 #
62 # When invoking make, we can pass in ARCH=some-arch.  This value gets 'saved'
63 # in the symlink, so that later invocations do not need ARCH=.  If this value
64 # differs from the symlink, it appears like we are changing arches, which
65 # triggers a clean and symlink reconstruction.
66 #
67 # When the user changes from one arch to another, they ought to reconfig, since
68 # many of the CONFIG_ vars will depend on the arch.  If they try anything other
69 # than one of the "non-build-goals" (cleans or configs), we'll abort.
70 #
71 # Make targets that need these symlinks (like building userspace, the kernel,
72 # configs, etc, should depend on symlinks.
73
74 clean-goals := clean mrproper realclean userclean testclean doxyclean objclean
75 non-build-goals := %config $(clean-goals)
76 ifeq ($(filter $(non-build-goals), $(MAKECMDGOALS)),)
77 goals-has-build-targets := 1
78 endif
79
80 PHONY += symlinks clean_symlinks
81 clean_symlinks:
82         @-rm -f kern/include/arch kern/boot user/parlib/include/arch
83
84 arch-link := $(notdir $(shell readlink kern/include/arch))
85 valid-arches := $(notdir $(wildcard kern/arch/*))
86
87 ifneq ($(ARCH),)
88     ifeq ($(filter $(valid-arches), $(ARCH)),)
89         $(error ARCH $(ARCH) invalid, must be one of: $(valid-arches))
90     endif
91     ifneq ($(ARCH),$(arch-link))
92         ifeq ($(goals-has-build-targets),1)
93             $(error Attempted to make [$(MAKECMDGOALS)] while changing ARCH. \
94                     You need to make *config.)
95         endif
96 symlinks: clean_symlinks
97         @echo Making symlinks...
98         $(Q)ln -fs ../arch/$(ARCH) kern/include/arch
99         $(Q)ln -fs arch/$(ARCH)/boot kern/boot
100         $(Q)ln -fs $(ARCH) user/parlib/include/arch
101         $(Q)$(MAKE) -f $(srctree)/Makefile clean
102
103     else
104 symlinks:
105
106     endif # ifneq ($(ARCH),$(arch-link))
107 else # $(ARCH) is empty
108     ifneq ($(arch-link),)
109         ARCH := $(arch-link)
110 symlinks:
111
112     else
113         # Only allow a clean
114         ifeq ($(filter $(clean-goals), $(MAKECMDGOALS)),)
115             $(error No arch saved or specified.  Make *config with ARCH=arch. \
116                     'arch' must be one of: $(valid-arches))
117         endif
118         ARCH := none # catch bugs
119     endif # ifneq ($(arch-link),)
120 endif # ifeq ($(ARCH),)
121
122 export ARCH
123
124 # Generic Kbuild Environment
125 # =========================================================================
126
127 # To put more focus on warnings, be less verbose as default
128 # Use 'make V=1' to see the full commands
129
130 ifeq ("$(origin V)", "command line")
131   KBUILD_VERBOSE = $(V)
132 endif
133 ifndef KBUILD_VERBOSE
134   KBUILD_VERBOSE = 0
135 endif
136
137 srctree         := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))
138 objtree         := $(CURDIR)
139
140 export srctree objtree
141
142 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
143           else if [ -x /bin/bash ]; then echo /bin/bash; \
144           else echo sh; fi ; fi)
145
146 HOSTCC       = gcc
147 HOSTCXX      = g++
148 HOSTCFLAGS   = -Wall -Wno-char-subscripts -Wmissing-prototypes \
149                -Wstrict-prototypes -O2 -fomit-frame-pointer
150 HOSTCXXFLAGS = -O2
151
152 export CONFIG_SHELL HOSTCC HOSTCXX HOSTCFLAGS HOSTCXXFLAGS
153
154 # Beautify output
155 # ---------------------------------------------------------------------------
156 #
157 # Normally, we echo the whole command before executing it. By making
158 # that echo $($(quiet)$(cmd)), we now have the possibility to set
159 # $(quiet) to choose other forms of output instead, e.g.
160 #
161 #         quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@
162 #         cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<
163 #
164 # If $(quiet) is empty, the whole command will be printed.
165 # If it is set to "quiet_", only the short version will be printed. 
166 # If it is set to "silent_", nothing will be printed at all, since
167 # the variable $(silent_cmd_cc_o_c) doesn't exist.
168 #
169 # A simple variant is to prefix commands with $(Q) - that's useful
170 # for commands that shall be hidden in non-verbose mode.
171 #
172 #       $(Q)ln $@ :<
173 #
174 # If KBUILD_VERBOSE equals 0 then the above command will be hidden.
175 # If KBUILD_VERBOSE equals 1 then the above command is displayed.
176
177 ifeq ($(KBUILD_VERBOSE),1)
178   quiet =
179   Q =
180 else
181   quiet=quiet_
182   Q = @
183 endif
184 export quiet Q KBUILD_VERBOSE
185
186 # We need some generic definitions (do not try to remake the file).
187 $(srctree)/scripts/Kbuild.include: ;
188 include $(srctree)/scripts/Kbuild.include
189
190 # Akaros Build Environment
191 # =========================================================================
192 AKAROSINCLUDE   := \
193                                 -I$(srctree)/kern/arch/ \
194                                 -I$(srctree)/kern/include/
195
196 CROSS_COMPILE := $(ARCH)-ros-
197
198 CC          := $(CROSS_COMPILE)gcc 
199 CPP         := $(CROSS_COMPILE)g++
200 AS          := $(CROSS_COMPILE)as
201 AR          := $(CROSS_COMPILE)ar
202 LD          := $(CROSS_COMPILE)ld
203 OBJCOPY := $(CROSS_COMPILE)objcopy
204 OBJDUMP := $(CROSS_COMPILE)objdump
205 NM          := $(CROSS_COMPILE)nm
206 STRIP   := $(CROSS_COMPILE)strip
207
208 ifeq ($(goals-has-build-targets),1)
209 ifeq ($(shell which $(CROSS_COMPILE)gcc 2>/dev/null ),)
210 $(error Could not find a $(CROSS_COMPILE) version of GCC/binutils. \
211         Be sure to build the cross-compiler and update your PATH)
212 endif
213 # Computing these without a cross compiler complains loudly
214 gcc-lib := $(shell $(CC) -print-libgcc-file-name)
215 NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
216 # Note: calling this GCC_ROOT interferes with the host tools
217 XCC_ROOT := $(dir $(shell which $(CC)))../
218 endif
219
220 CFLAGS_KERNEL += -O2 -pipe -MD -gstabs
221 CFLAGS_KERNEL += -std=gnu99 -fgnu89-inline
222 CFLAGS_KERNEL += -fno-strict-aliasing -fno-omit-frame-pointer
223 CFLAGS_KERNEL += -fno-stack-protector
224 CFLAGS_KERNEL += -Wall -Wno-format -Wno-unused
225 CFLAGS_KERNEL += -DROS_KERNEL 
226 CFLAGS_KERNEL += -include include/generated/autoconf.h
227
228 # TODO: do we need this, or can we rely on the compiler's defines?
229 CFLAGS_KERNEL += -D$(ARCH)
230
231 # TODO: this requires our own strchr (kern/src/stdio.c), which is a potential
232 # source of bugs/problems.
233 # note we still pull in stdbool and stddef from the compiler
234 CFLAGS_KERNEL += -fno-builtin
235
236 AFLAGS_KERNEL := $(CFLAGS_KERNEL)
237
238 KBUILD_BUILTIN := 1
239 KBUILD_CHECKSRC := 0
240
241 export AKAROSINCLUDE CROSS_COMPILE
242 export CC CPP AS AR LD OBJCOPY OBJDUMP NM STRIP
243 export CFLAGS_KERNEL AFLAGS_KERNEL
244 export NOSTDINC_FLAGS XCC_ROOT
245 export KBUILD_BUILTIN KBUILD_CHECKSRC
246
247 CFLAGS_USER += -O2 -std=gnu99 -fno-stack-protector -fgnu89-inline
248 CXXFLAGS_USER += -O2
249
250 export CFLAGS_USER CXXFLAGS_USER
251
252 # Kbuild Target/Goals Parsing
253 # =========================================================================
254 # Need to figure out if we're a config or not, and whether or not to include
255 # our .config / auto.conf.  Configs are basically their own makefile, (ifeq),
256 # and cleans are allowed to proceed without worrying about the dot-config.
257
258 # Basic helpers built in scripts/
259 PHONY += scripts_basic
260 scripts_basic:
261         $(Q)$(MAKE) $(build)=scripts/basic
262
263 PHONY += scripts
264
265 scripts: scripts_basic include/config/auto.conf include/config/tristate.conf
266         $(Q)$(MAKE) $(build)=$(@)
267
268 config-targets := 0
269 mixed-targets  := 0
270 dot-config     := 1
271
272 no-dot-config-targets := $(clean-goals)
273
274 ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
275     ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
276         dot-config := 0
277     endif
278 endif
279
280 ifneq ($(filter config %config,$(MAKECMDGOALS)),)
281     config-targets := 1
282     ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)
283         mixed-targets := 1
284     endif
285 endif
286
287 ifeq ($(mixed-targets),1)
288 # ===========================================================================
289 # We're called with mixed targets (*config and build targets).
290 # Handle them one by one.
291
292 %:: FORCE
293         $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@
294
295 else
296 ifeq ($(config-targets),1)
297 # ===========================================================================
298 # *config targets only - make sure prerequisites are updated, and descend
299 # in scripts/kconfig to make the *config target
300 config: scripts_basic symlinks FORCE
301         $(Q)mkdir -p include/config
302         $(Q)$(MAKE) $(build)=scripts/kconfig $@
303
304 %config: scripts_basic symlinks FORCE
305         $(Q)mkdir -p include/config
306         $(Q)$(MAKE) $(build)=scripts/kconfig $@
307
308 else
309 # ===========================================================================
310 # Build targets only - this includes vmlinux, arch specific targets, clean
311 # targets and others. In general all targets except *config targets.
312
313 ifeq ($(dot-config),1)
314 KCONFIG_CONFIG ?= .config
315 export KCONFIG_CONFIG
316
317 # Read in config
318 -include include/config/auto.conf
319
320 # Read in dependencies to all Kconfig* files, make sure to run
321 # oldconfig if changes are detected.
322 -include include/config/auto.conf.cmd
323
324 # To avoid any implicit rule to kick in, define an empty command
325 $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
326
327 # If .config is newer than include/config/auto.conf, someone tinkered
328 # with it and forgot to run make oldconfig.
329 # if auto.conf.cmd is missing then we are probably in a cleaned tree so
330 # we execute the config step to be sure to catch updated Kconfig files
331 include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
332         $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
333
334 else
335 # Dummy target needed, because used as prerequisite
336 include/config/auto.conf: ;
337 endif # $(dot-config)
338
339 # Akaros include stuff (includes custom make targets and user overrides)
340 # =========================================================================
341
342 # The user can override this, though it won't apply for any of the in-tree
343 # kernel build output.  Right now, it's only passed down to tests/
344 OBJDIR ?= obj
345 dummy-1 := $(shell mkdir -p $(OBJDIR)/kern/)
346
347 # Don't need to export these, since the Makelocal is included.
348 KERNEL_OBJ := $(OBJDIR)/kern/akaros-kernel
349 CMP_KERNEL_OBJ := $(KERNEL_OBJ).gz
350
351 # TODO: have the KFS paths be determined in .config
352 # Give it a reasonable default path for initramfs to avoid build breakage
353 INITRAMFS_PATHS = kern/kfs
354 FIRST_INITRAMFS_PATH = $(firstword $(INITRAMFS_PATHS))
355
356 export OBJDIR INITRAMFS_PATHS FIRST_INITRAMFS_PATH
357
358 # Avoiding implicit rules
359 $(srctree)/Makeconfig $(srctree)/Makelocal: ;
360 include $(srctree)/Makeconfig
361 -include $(srctree)/Makelocal
362
363 # Akaros Kernel Build
364 # =========================================================================
365 # Add top level directories, either to an existing entry (core-y) or to its
366 # own. 
367 #
368 # From these, we determine deps and dirs.  We recursively make through the
369 # dirs, generating built-in.o at each step, which are the deps from which we
370 # link akaros.
371 #
372 # We have all-arch-dirs and all-dirs, so that we can still clean even without
373 # an arch symlink.
374
375 core-y += kern/src/
376 arch-y += kern/arch/$(ARCH)/
377
378 akaros-dirs     := $(patsubst %/,%,$(filter %/, $(core-y) $(arch-y)))
379
380 all-arch-dirs   := $(patsubst %,kern/arch/%/,$(valid-arches))
381 akaros-all-dirs := $(patsubst %/,%,$(filter %/, $(core-y) $(all-arch-dirs)))
382
383 core-y          := $(patsubst %/, %/built-in.o, $(core-y))
384 arch-y          := $(patsubst %/, %/built-in.o, $(arch-y))
385
386 kbuild_akaros_main := $(core-y) $(arch-y)
387 akaros-deps := $(kbuild_akaros_main)  kern/arch/$(ARCH)/kernel.ld
388
389 kern_cpio := $(OBJDIR)/kern/initramfs.cpio
390 kern_cpio_obj := $(kern_cpio).o
391 ifneq ($(EXT2_BDEV),)
392 ext2_bdev_obj := $(OBJDIR)/kern/$(shell basename $(EXT2_BDEV)).o
393 endif
394
395 kern_initramfs_files := $(shell mkdir -p $(INITRAMFS_PATHS); \
396                           find $(INITRAMFS_PATHS))
397
398 $(kern_cpio) initramfs: $(kern_initramfs_files)
399         @echo "  Building initramfs:"
400         @if [ "$(INITRAMFS_BIN)" != "" ]; then \
401         sh $(INITRAMFS_BIN); \
402     fi
403         $(Q)for i in $(INITRAMFS_PATHS); do cd $$i; \
404         echo "    Adding $$i to initramfs..."; \
405         find -L . | cpio --quiet -oH newc > \
406                         $(CURDIR)/$(kern_cpio); \
407         cd $$OLDPWD; \
408     done;
409
410 ld_emulation = $(shell $(OBJDUMP) -i | grep -v BFD | grep ^[a-z] |head -n1)
411 ld_arch = $(shell $(OBJDUMP) -i | grep -v BFD | grep "^  [a-z]" | head -n1)
412
413 $(kern_cpio_obj): $(kern_cpio)
414         $(Q)$(OBJCOPY) -I binary -B $(ld_arch) -O $(ld_emulation) $^ $@
415
416 $(ext2_bdev_obj): $(EXT2_BDEV)
417         $(Q)$(OBJCOPY) -I binary -B $(ld_arch) -O $(ld_emulation) $^ $@
418
419 # TODO super-bugged objdump!  Passing -S (intermix source) and having auto.conf
420 # be regenerated while the Makefile is running causes a segfault.  This would
421 # happen after touching .config and remaking.  For now, just pass -d...
422 quiet_cmd_link-akaros = LINK    $@
423       cmd_link-akaros = $(LD) -T kern/arch/$(ARCH)/kernel.ld -o $@ \
424                               $(akaros-deps) \
425                               $(gcc-lib) \
426                               $(kern_cpio_obj) \
427                               $(ext2_bdev_obj) ; \
428                               $(OBJDUMP) -d $@ > $@.asm
429
430 # For some reason, the if_changed doesn't work with FORCE (like it does in
431 # Linux).  It looks like it can't find the .cmd file or something (also
432 # complaints of $(targets), so that all is probably messed up).
433 $(KERNEL_OBJ): $(akaros-deps) $(kern_cpio_obj) $(ext2_bdev_obj)
434         $(call if_changed,link-akaros)
435
436 akaros-kernel: $(KERNEL_OBJ)
437
438 $(sort $(akaros-deps)): $(akaros-dirs) ;
439
440 # Recursively Kbuild all of our directories.  If we're changing arches
441 # mid-make, we might have issues ( := on akaros-dirs, etc).
442 PHONY += $(akaros-dirs)
443 $(akaros-dirs): scripts symlinks
444         $(Q)$(MAKE) $(build)=$@
445
446 $(CMP_KERNEL_OBJ): $(KERNEL_OBJ)
447         @echo "Compressing kernel image"
448         $(Q)gzip -c $^ > $@
449
450 # TODO: not sure what all we want to have available for config targets
451 # (anything after this is allowed.  We currently need clean targets available
452 # (config->symlinks->clean).
453 endif #ifeq ($(config-targets),1)
454 endif #ifeq ($(mixed-targets),1)
455
456 # Akaros Userspace Building and Misc Helpers
457 # =========================================================================
458 # Recursively make user libraries and tests.
459 #
460 # User library makefiles are built to expect to be called from their own
461 # directories.  The test code can be called from the root directory.
462
463 # List all userspace directories here, and state any dependencies between them,
464 # such as how pthread depends on parlib.
465
466 user-dirs = parlib pthread benchutil
467 pthread: parlib
468
469 ifeq ($(ARCH),i686)
470 user-dirs += c3po
471 c3po: parlib
472 endif
473
474 PHONY += install-libs $(user-dirs)
475 install-libs: $(user-dirs) symlinks
476
477 $(user-dirs):
478         @cd user/$@ && $(MAKE) && $(MAKE) install
479
480
481 PHONY += userclean $(clean-user-dirs)
482 clean-user-dirs := $(addprefix _clean_user_,$(user-dirs))
483 userclean: $(clean-user-dirs) testclean
484
485 $(clean-user-dirs):
486         @cd user/$(patsubst _clean_user_%,%,$@) && $(MAKE) clean
487
488 tests/: tests
489 tests: install-libs
490         @$(MAKE) -f tests/Makefile
491
492 testclean:
493         @$(MAKE) -f tests/Makefile clean
494
495 install-tests:
496         @$(MAKE) -f tests/Makefile install
497
498 # TODO: cp -u all of the .sos, but flush it on an arch change (same with tests)
499 fill-kfs: install-libs install-tests
500         @mkdir -p $(FIRST_INITRAMFS_PATH)/lib
501         @cp $(addprefix $(XCC_ROOT)/$(ARCH)-ros/lib/, \
502           libc.so.6 ld.so.1 libm.so libgcc_s.so.1) $(FIRST_INITRAMFS_PATH)/lib
503         $(Q)$(STRIP) --strip-debug $(addprefix $(FIRST_INITRAMFS_PATH)/lib/, \
504                                                libc.so.6 ld.so.1)
505
506 # Use doxygen to make documentation for ROS (Untested since 2010 or so)
507 doxygen-dir := $(CUR_DIR)/Documentation/doxygen
508 docs: 
509         @echo "  Making doxygen"
510         @doxygen-dir=$(doxygen-dir) doxygen $(doxygen-dir)/rosdoc.cfg
511         @if [ ! -d $(doxygen-dir)/rosdoc/html/img ]; \
512          then \
513                 ln -s ../../img $(doxygen-dir)/rosdoc/html; \
514          fi
515
516 doxyclean:
517         @echo + clean [ROSDOC]
518         @rm -rf $(doxygen-dir)/rosdoc
519
520 objclean:
521         @echo + clean [OBJDIR]
522         @rm -rf $(OBJDIR)/*
523
524 realclean: userclean mrproper doxyclean objclean
525
526 # Cleaning
527 # =========================================================================
528 # This is mostly the Linux kernel cleaning.  We could hook in to the userspace
529 # cleaning with the 'userclean' target attached to clean, though historically
530 # 'clean' means the kernel.
531
532 # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir
533 # Usage:
534 # $(Q)$(MAKE) $(clean)=dir
535 clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
536
537 # clean - Delete all generated files
538 #
539 clean-dirs         := $(addprefix _clean_,$(akaros-all-dirs))
540
541 PHONY += $(clean-dirs) clean
542 $(clean-dirs):
543         $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
544
545 RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \
546                    -o -name .pc -o -name .hg -o -name .git \) -prune -o
547 clean: $(clean-dirs)
548         @find $(patsubst _clean_%,%,$(clean-dirs)) $(RCS_FIND_IGNORE) \
549             \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
550             -o -name '*.ko.*' \
551             -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
552             -o -name '*.symtypes' -o -name 'modules.order' \
553             -o -name modules.builtin -o -name '.tmp_*.o.*' \
554             -o -name '*.gcno' \) -type f -print | xargs rm -f
555
556 # Could add in an archclean if we need arch-specific cleanup, or a userclean if
557 # we want to start cleaning that too.
558 #clean: archclean
559 #clean: userclean
560
561 # mrproper - Delete all generated files, including .config, and reset ARCH
562 #
563 mrproper-dirs      := $(addprefix _mrproper_,scripts)
564
565 PHONY += $(mrproper-dirs) mrproper
566 $(mrproper-dirs):
567         $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)
568
569 mrproper: $(mrproper-dirs) clean clean_symlinks
570         @-rm -f .config
571         @find $(patsubst _mrproper_%,%,$(mrproper-dirs)) $(RCS_FIND_IGNORE) \
572             \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
573             -o -name '*.ko.*' \
574             -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
575             -o -name '*.symtypes' -o -name 'modules.order' \
576             -o -name modules.builtin -o -name '.tmp_*.o.*' \
577             -o -name '*.gcno' \) -type f -print | xargs rm -f
578
579 # Epilogue
580 # =========================================================================
581
582 PHONY += FORCE
583 FORCE:
584
585 # Declare the contents of the .PHONY variable as phony.  We keep that
586 # information in a variable so we can use it in if_changed and friends.
587 .PHONY: $(PHONY)