Commit 77c83c75 authored by Kai Germaschewski's avatar Kai Germaschewski

kbuild: Split Makefile into needs / needs not .config

The current top-level Makefile has a fundamental problem which
makes "make oldconfig vmlinux" impossible:

It includes .config, which is changed by "oldconfig". So after "oldconfig"
.config has changed and the .config the Makefile had read is obsolete.
make provides a mechanism to cope with this, it'll restart automatically 
if any of the files it included changed, if you let it know that you
changed it, just using a normal rule which has .config as its target.

However, once you tell make that "make oldconfig" changes .config, you
have another problem: oldconfig always uses .config to be remade, there's
no mechanism to tell if it's up to date. So makes notices that .config
has changed, restarts, makes oldconfig again, notices that .config has
changed, restarts, ... you get the picture.

The way to solve this is to do a proper two-stage approach: If you just
say "make oldconfig", there's no need for the Makefile to even read the
.config. If it does not, it won't restart and recurse infintely.
So we divide the Makefile into two sections: One for targets which don't
need the variables from .config, like *config, clean, mrproper and
one section which does the actual build, which needs to know the
CONFIG_ options.

If one of the "noconfig" targets is given, we handle those, without
reading .config. From there, we call make again, filtering out the already
handled targets, to do the main work.

The fact that this actually works correctly can be seen by trying
"make vmlinux oldconfig" which will execute things in the right
order - and this is not just nitpicking, it means that "-j" will
get this case right, too.

The $(CONFIGURATION) hack used to start "make config" automatically
can go away now, too. Since we don't know which of make *config the
user prefers, we'll just ask him call "make whatever-config" himself,
instead of forcing "make config" on him.
parent ea1e2d62
......@@ -37,6 +37,10 @@ HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
CROSS_COMPILE =
# That's our default target when none is given on the command line
all: vmlinux
#
# Include the make variables (CC, etc...)
#
......@@ -69,20 +73,31 @@ export CPPFLAGS EXPORT_FLAGS
export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
all: do-it-all
noconfig_targets := oldconfig xconfig menuconfig config clean mrproper \
distclean
ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
# Here goes the main Makefile
# ===========================================================================
#
# Make "config" the default target if there is no configuration file or
# "depend" the target if there is no top-level dependency information.
#
# If the user gave a *config target, it'll be handled in another
# section below, since in this case we cannot include .config
# Same goes for other targets like clean/mrproper etc, which
# don't need .config, either
ifeq (.config,$(wildcard .config))
include .config
do-it-all: vmlinux
else
CONFIGURATION = config
do-it-all: config
endif
# In this section, we need .config
-include .config
# If .config doesn't exist - tough luck
.config:
@echo '***'
@echo '*** You have not yet configured your kernel!'
@echo '*** Please run "make xconfig/menuconfig/config/oldconfig"'
@echo '***'
@exit 1
#
# INSTALL_PATH specifies where to place the updated kernel and system map
......@@ -172,7 +187,7 @@ define rule_link_vmlinux
$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
endef
vmlinux: $(CONFIGURATION) $(vmlinux-objs) FORCE
vmlinux: $(vmlinux-objs) FORCE
$(call if_changed_rule,link_vmlinux)
# The actual objects are generated when descending,
......@@ -223,6 +238,16 @@ include/config/MARKER: scripts/split-include include/linux/autoconf.h
scripts/split-include include/linux/autoconf.h include/config
@ touch include/config/MARKER
# if .config is newer than include/linux/autoconf.h, someone tinkered
# with it and forgot to run make oldconfig
include/linux/autoconf.h: .config
@echo '***'
@echo '*** You changed .config w/o running make *config?'
@echo '*** Please run "make oldconfig"'
@echo '***'
@exit 1
# Generate some files
# ---------------------------------------------------------------------------
......@@ -412,13 +437,36 @@ rpm: clean spec
rpm -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
rm $(TOPDIR)/../$(KERNELPATH).tar.gz
else # ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
# Targets which don't need .config
# ===========================================================================
#
# These targets basically have their own Makefile - not quite, but at
# least its own exclusive section in the same Makefile. The reason for
# this is the following:
# To know the configuration, the main Makefile has to include
# .config. That's a obviously a problem when .config doesn't exist
# yet, but that could be kludged around with only including it if it
# exists.
# However, the larger problem is: If you run make *config, make will
# include the old .config, then execute your *config. It will then
# notice that a piece it included (.config) did change and restart from
# scratch. Which will cause execution of *config again. You get the
# picture.
# If we don't explicitly let the Makefile know that .config is changed
# by *config (the old way), it won't reread .config after *config,
# thus working with possibly stale values - we don't that either.
#
# So we divide things: This part here is for making *config targets,
# and other targets which should work when no .config exists yet.
# The main part above takes care of the rest after a .config exists.
# Kernel configuration
# ---------------------------------------------------------------------------
.PHONY: oldconfig xconfig menuconfig config
.PHONY: oldconfig xconfig menuconfig config \
make_with_config
oldconfig:
$(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in
......@@ -434,6 +482,22 @@ menuconfig:
config:
$(CONFIG_SHELL) scripts/Configure arch/$(ARCH)/config.in
# How we generate .config depends on which *config the
# user chose when calling make
.config: $(filter oldconfig xconfig menuconfig config,$(MAKECMDGOALS)) ;
# If the user gave commands from both the need / need not
# .config sections, we need to call make again after
# .config is generated, now to take care of the remaining
# targets we know nothing about in this section
remaining_targets := $(filter-out $(noconfig_targets),$(MAKECMDGOALS))
$(remaining_targets) : make_with_config
make_with_config: .config
@$(MAKE) $(remaining_targets)
# Cleaning up
# ---------------------------------------------------------------------------
......@@ -492,6 +556,9 @@ MRPROPER_DIRS += \
include/config \
$(TOPDIR)/include/linux/modules
# That's our way to know about arch specific cleanup.
include arch/$(ARCH)/Makefile
clean: archclean
find . \( -name '*.[oas]' -o -name core -o -name '.*.cmd' \) -type f -print \
......@@ -512,6 +579,8 @@ distclean: mrproper
-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
-o -name '.*.rej' -o -name '.SUMS' -o -size 0 \) -type f -print` TAGS tags
endif # ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
# FIXME Should go into a make.lib or something
# ===========================================================================
......
......@@ -114,12 +114,12 @@ endif
export SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS PARAMS_PHYS
Image: $(CONFIGURE) $(SYSTEM)
Image: $(SYSTEM)
$(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) $@
bzImage: zImage
zImage: $(CONFIGURE) compressed/vmlinux
zImage: compressed/vmlinux
$(OBJCOPY) -O binary -R .note -R .comment -S compressed/vmlinux $@
bootpImage: bootp/bootp
......@@ -135,10 +135,10 @@ initrd:
@test "$(INITRD_PHYS)" != "" || (echo This architecture does not support INITRD; exit -1)
@test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1)
install: $(CONFIGURE) Image
install: Image
sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
zinstall: $(CONFIGURE) zImage
zinstall: zImage
sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
clean:
......
......@@ -133,6 +133,7 @@ bzdisk: vmlinux
@$(MAKEBOOT) BOOTIMAGE=bzImage zdisk
install: vmlinux
@echo 'Cleaning up (arch)'
@$(MAKEBOOT) BOOTIMAGE=bzImage install
archclean:
......
......@@ -31,11 +31,11 @@ BOOT_INCL = $(TOPDIR)/include/linux/config.h \
$(TOPDIR)/include/linux/autoconf.h \
$(TOPDIR)/include/asm/boot.h
zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build
zImage: bootsect setup compressed/vmlinux tools/build
$(OBJCOPY) compressed/vmlinux compressed/vmlinux.out
tools/build bootsect setup compressed/vmlinux.out $(ROOT_DEV) > zImage
bzImage: $(CONFIGURE) bbootsect bsetup compressed/bvmlinux tools/build
bzImage: bbootsect bsetup compressed/bvmlinux tools/build
$(OBJCOPY) compressed/bvmlinux compressed/bvmlinux.out
tools/build -b bbootsect bsetup compressed/bvmlinux.out $(ROOT_DEV) > bzImage
......@@ -48,14 +48,14 @@ compressed/bvmlinux: $(TOPDIR)/vmlinux
zdisk: $(BOOTIMAGE)
dd bs=8192 if=$(BOOTIMAGE) of=/dev/fd0
zlilo: $(CONFIGURE) $(BOOTIMAGE)
zlilo: $(BOOTIMAGE)
if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
cp $(TOPDIR)/System.map $(INSTALL_PATH)/
if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
install: $(CONFIGURE) $(BOOTIMAGE)
install: $(BOOTIMAGE)
sh -x ./install.sh $(KERNELRELEASE) $(BOOTIMAGE) $(TOPDIR)/System.map "$(INSTALL_PATH)"
tools/build: tools/build.c
......@@ -100,7 +100,8 @@ bsetup.s: setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.
dep:
clean:
rm -f tools/build
rm -f setup bootsect zImage compressed/vmlinux.out
rm -f bsetup bbootsect bzImage compressed/bvmlinux.out
@echo 'Cleaning up (boot)'
@rm -f tools/build
@rm -f setup bootsect zImage compressed/vmlinux.out
@rm -f bsetup bbootsect bzImage compressed/bvmlinux.out
@$(MAKE) -C compressed clean
......@@ -47,4 +47,4 @@ piggy.o: $(SYSTEM)
rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
clean:
rm -f vmlinux bvmlinux _tmp_*
@rm -f vmlinux bvmlinux _tmp_*
......@@ -26,7 +26,7 @@ strip-flags = $(addprefix --remove-section=,$(drop-sections))
all: vmlinux.ecoff addinitrd
vmlinux.ecoff: $(CONFIGURE) elf2ecoff $(TOPDIR)/vmlinux
vmlinux.ecoff: elf2ecoff $(TOPDIR)/vmlinux
./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff $(E2EFLAGS)
elf2ecoff: elf2ecoff.c
......
......@@ -17,7 +17,7 @@ endif
all: vmlinux.ecoff addinitrd
vmlinux.ecoff: $(CONFIGURE) elf2ecoff $(TOPDIR)/vmlinux
vmlinux.ecoff: elf2ecoff $(TOPDIR)/vmlinux
./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff $(E2EFLAGS)
elf2ecoff: elf2ecoff.c
......
#
# arch/s390/boot/Makefile
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definition is now in the main makefile...
OBJCOPY = $(CROSS_COMPILE)objcopy
......@@ -21,7 +16,7 @@ include $(TOPDIR)/Rules.make
%.boot: %.lnk
$(OBJCOPY) -O binary $< $@
image: $(CONFIGURE) $(TOPDIR)/vmlinux \
image: $(TOPDIR)/vmlinux \
iplfba.boot ipleckd.boot ipldump.boot
$(OBJCOPY) -O binary $(TOPDIR)/vmlinux image
$(NM) $(TOPDIR)/vmlinux | grep -v '\(compiled\)\|\( [aUw] \)\|\(\.\)\|\(LASH[RL]DI\)' | sort > $(TOPDIR)/System.map
......
#
# Makefile for the linux s390-specific parts of the memory manager.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definition is now in the main makefile...
OBJCOPY = $(CROSS_COMPILE)objcopy
......@@ -21,7 +16,7 @@ EXTRA_AFLAGS := -traditional
%.boot: %.lnk
$(OBJCOPY) -O binary $< $@
image: $(CONFIGURE) $(TOPDIR)/vmlinux \
image: $(TOPDIR)/vmlinux \
iplfba.boot ipleckd.boot ipldump.boot
$(OBJCOPY) -O binary $(TOPDIR)/vmlinux image
$(NM) $(TOPDIR)/vmlinux | grep -v '\(compiled\)\|\( [aUw] \)\|\(\.\)\|\(LASH[RL]DI\)' | sort > $(TOPDIR)/System.map
......
......@@ -10,19 +10,19 @@
SYSTEM =$(TOPDIR)/vmlinux
Image: $(CONFIGURE) $(SYSTEM)
Image: $(SYSTEM)
$(OBJCOPY) $(SYSTEM) Image
zImage: $(CONFIGURE) compressed/vmlinux
zImage: compressed/vmlinux
$(OBJCOPY) compressed/vmlinux zImage
compressed/vmlinux: $(TOPDIR)/vmlinux
$(MAKE) -C compressed vmlinux
install: $(CONFIGURE) Image
install: Image
sh -x ./install.sh $(KERNELRELEASE) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
zinstall: $(CONFIGURE) zImage
zinstall: zImage
sh -x ./install.sh $(KERNELRELEASE) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
dep:
......
......@@ -31,11 +31,11 @@ BOOT_INCL = $(TOPDIR)/include/linux/config.h \
$(TOPDIR)/include/linux/autoconf.h \
$(TOPDIR)/include/asm/boot.h
zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build
zImage: bootsect setup compressed/vmlinux tools/build
$(OBJCOPY) compressed/vmlinux compressed/vmlinux.out
tools/build bootsect setup compressed/vmlinux.out $(ROOT_DEV) > zImage
bzImage: $(CONFIGURE) bbootsect bsetup compressed/bvmlinux tools/build
bzImage: bbootsect bsetup compressed/bvmlinux tools/build
$(OBJCOPY) compressed/bvmlinux compressed/bvmlinux.out
tools/build -b bbootsect bsetup compressed/bvmlinux.out $(ROOT_DEV) > bzImage
......@@ -51,14 +51,14 @@ compressed/bvmlinux: $(TOPDIR)/vmlinux
zdisk: $(BOOTIMAGE)
dd bs=8192 if=$(BOOTIMAGE) of=/dev/fd0
zlilo: $(CONFIGURE) $(BOOTIMAGE)
zlilo: $(BOOTIMAGE)
if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
cp $(TOPDIR)/System.map $(INSTALL_PATH)/
if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
install: $(CONFIGURE) $(BOOTIMAGE)
install: $(BOOTIMAGE)
sh -x ./install.sh $(KERNELRELEASE) $(BOOTIMAGE) $(TOPDIR)/System.map "$(INSTALL_PATH)"
tools/build: tools/build.c
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment