Patchwork total Makefile rewrite

login
register
about
Submitter Carl-Daniel Hailfinger
Date 2013-02-13 03:43:38
Message ID <511B0BEA.9080001@gmx.net>
Download mbox | patch
Permalink /patch/3853/
State New
Headers show

Comments

Carl-Daniel Hailfinger - 2013-02-13 03:43:38
I almost lost my sanity trying to beat the Makefile into submission
without using features only available in new GNU make versions. Some
functions are now outsourced to a shell script. In theory, things should
still work (except a few hardcoded dependencies which will be changed
into autodetections in the future). At least now we have a framework to
handle autodetection. It's not really hooked up yet, but it will allow
stuff like
make config CONFIG_WHATEVER=auto CONFIG_FOO=yes CONFIG_BAR=no

The new (TM) way to compile flashrom is:
make config
make

Please run "make distclean" the first time you test this patch.

Not for merge yet, but this mechanism at least will allow clean handling
of FTDI autodetect, libusb 1.x requirements and all that other pending
fun stuff.

Comments about the shell script are very appreciated, I tried to write
in POSIX sh.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>


Eigenschaftsänderungen: flashrom-Makefile_harddependencies_soft/config.sh
Carl-Daniel Hailfinger - 2013-02-13 04:30:32
Am 13.02.2013 04:43 schrieb Carl-Daniel Hailfinger:
> I almost lost my sanity trying to beat the Makefile into submission
> without using features only available in new GNU make versions. Some
> functions are now outsourced to a shell script. In theory, things should
> still work

Cross-compiling is semi-broken: You have to specify CC= both for "make
config" and "make".

Regards,
Carl-Daniel

Patch

Index: flashrom-Makefile_harddependencies_soft/hwaccess.h
===================================================================
--- flashrom-Makefile_harddependencies_soft/hwaccess.h	(Revision 1645)
+++ flashrom-Makefile_harddependencies_soft/hwaccess.h	(Arbeitskopie)
@@ -167,7 +167,7 @@ 
 #define le_to_cpu32 cpu_to_le32
 #define le_to_cpu64 cpu_to_le64
 
-#if NEED_PCI == 1
+#if (NEED_PCI == 1) || (NEED_IOPORT_ACCESS == 1)
 #if defined (__i386__) || defined (__x86_64__)
 
 #define __FLASHROM_HAVE_OUTB__ 1
Index: flashrom-Makefile_harddependencies_soft/Makefile
===================================================================
--- flashrom-Makefile_harddependencies_soft/Makefile	(Revision 1645)
+++ flashrom-Makefile_harddependencies_soft/Makefile	(Arbeitskopie)
@@ -103,28 +103,28 @@ 
 LIBS += ../libgetopt/libgetopt.a
 # Bus Pirate, Serprog and PonyProg are not supported under DOS (missing serial support).
 ifeq ($(CONFIG_BUSPIRATE_SPI), yes)
-UNSUPPORTED_FEATURES += CONFIG_BUSPIRATE_SPI=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_BUSPIRATE_SPI
 else
 override CONFIG_BUSPIRATE_SPI = no
 endif
 ifeq ($(CONFIG_SERPROG), yes)
-UNSUPPORTED_FEATURES += CONFIG_SERPROG=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_SERPROG
 else
 override CONFIG_SERPROG = no
 endif
 ifeq ($(CONFIG_PONY_SPI), yes)
-UNSUPPORTED_FEATURES += CONFIG_PONY_SPI=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_PONY_SPI
 else
 override CONFIG_PONY_SPI = no
 endif
 # Dediprog and FT2232 are not supported under DOS (missing USB support).
 ifeq ($(CONFIG_DEDIPROG), yes)
-UNSUPPORTED_FEATURES += CONFIG_DEDIPROG=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_DEDIPROG
 else
 override CONFIG_DEDIPROG = no
 endif
 ifeq ($(CONFIG_FT2232_SPI), yes)
-UNSUPPORTED_FEATURES += CONFIG_FT2232_SPI=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_FT2232_SPI
 else
 override CONFIG_FT2232_SPI = no
 endif
@@ -140,73 +140,73 @@ 
 LDFLAGS += -L/usr/local/lib
 # Serprog is not supported under Windows/MinGW (missing sockets support).
 ifeq ($(CONFIG_SERPROG), yes)
-UNSUPPORTED_FEATURES += CONFIG_SERPROG=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_SERPROG
 else
 override CONFIG_SERPROG = no
 endif
 # For now we disable all PCI-based programmers on Windows/MinGW (no libpci).
 ifeq ($(CONFIG_INTERNAL), yes)
-UNSUPPORTED_FEATURES += CONFIG_INTERNAL=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_INTERNAL
 else
 override CONFIG_INTERNAL = no
 endif
 ifeq ($(CONFIG_RAYER_SPI), yes)
-UNSUPPORTED_FEATURES += CONFIG_RAYER_SPI=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_RAYER_SPI
 else
 override CONFIG_RAYER_SPI = no
 endif
 ifeq ($(CONFIG_NIC3COM), yes)
-UNSUPPORTED_FEATURES += CONFIG_NIC3COM=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_NIC3COM
 else
 override CONFIG_NIC3COM = no
 endif
 ifeq ($(CONFIG_GFXNVIDIA), yes)
-UNSUPPORTED_FEATURES += CONFIG_GFXNVIDIA=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_GFXNVIDIA
 else
 override CONFIG_GFXNVIDIA = no
 endif
 ifeq ($(CONFIG_SATASII), yes)
-UNSUPPORTED_FEATURES += CONFIG_SATASII=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_SATASII
 else
 override CONFIG_SATASII = no
 endif
 ifeq ($(CONFIG_ATAHPT), yes)
-UNSUPPORTED_FEATURES += CONFIG_ATAHPT=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_ATAHPT
 else
 override CONFIG_ATAHPT = no
 endif
 ifeq ($(CONFIG_DRKAISER), yes)
-UNSUPPORTED_FEATURES += CONFIG_DRKAISER=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_DRKAISER
 else
 override CONFIG_DRKAISER = no
 endif
 ifeq ($(CONFIG_NICREALTEK), yes)
-UNSUPPORTED_FEATURES += CONFIG_NICREALTEK=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_NICREALTEK
 else
 override CONFIG_NICREALTEK = no
 endif
 ifeq ($(CONFIG_NICNATSEMI), yes)
-UNSUPPORTED_FEATURES += CONFIG_NICNATSEMI=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_NICNATSEMI
 else
 override CONFIG_NICNATSEMI = no
 endif
 ifeq ($(CONFIG_NICINTEL), yes)
-UNSUPPORTED_FEATURES += CONFIG_NICINTEL=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_NICINTEL
 else
 override CONFIG_NICINTEL = no
 endif
 ifeq ($(CONFIG_NICINTEL_SPI), yes)
-UNSUPPORTED_FEATURES += CONFIG_NICINTEL_SPI=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_NICINTEL_SPI
 else
 override CONFIG_NICINTEL_SPI = no
 endif
 ifeq ($(CONFIG_OGP_SPI), yes)
-UNSUPPORTED_FEATURES += CONFIG_OGP_SPI=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_OGP_SPI
 else
 override CONFIG_OGP_SPI = no
 endif
 ifeq ($(CONFIG_SATAMV), yes)
-UNSUPPORTED_FEATURES += CONFIG_SATAMV=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_SATAMV
 else
 override CONFIG_SATAMV = no
 endif
@@ -215,28 +215,28 @@ 
 ifeq ($(TARGET_OS), libpayload)
 FLASHROM_CFLAGS += -DSTANDALONE
 ifeq ($(CONFIG_DUMMY), yes)
-UNSUPPORTED_FEATURES += CONFIG_DUMMY=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_DUMMY
 else
 override CONFIG_DUMMY = no
 endif
 ifeq ($(CONFIG_BUSPIRATE_SPI), yes)
-UNSUPPORTED_FEATURES += CONFIG_BUSPIRATE_SPI=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_BUSPIRATE_SPI
 else
 override CONFIG_BUSPIRATE_SPI = no
 endif
 ifeq ($(CONFIG_SERPROG), yes)
-UNSUPPORTED_FEATURES += CONFIG_SERPROG=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_SERPROG
 else
 override CONFIG_SERPROG = no
 endif
 # Dediprog and FT2232 are not supported with libpayload (missing libusb support)
 ifeq ($(CONFIG_DEDIPROG), yes)
-UNSUPPORTED_FEATURES += CONFIG_DEDIPROG=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_DEDIPROG
 else
 override CONFIG_DEDIPROG = no
 endif
 ifeq ($(CONFIG_FT2232_SPI), yes)
-UNSUPPORTED_FEATURES += CONFIG_FT2232_SPI=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_FT2232_SPI
 else
 override CONFIG_FT2232_SPI = no
 endif
@@ -244,7 +244,7 @@ 
 
 ifneq ($(TARGET_OS), Linux)
 ifeq ($(CONFIG_LINUX_SPI), yes)
-UNSUPPORTED_FEATURES += CONFIG_LINUX_SPI=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_LINUX_SPI
 else
 override CONFIG_LINUX_SPI = no
 endif
@@ -260,32 +260,32 @@ 
 # Right now this means the drivers below only work on x86.
 ifneq ($(ARCH), x86)
 ifeq ($(CONFIG_NIC3COM), yes)
-UNSUPPORTED_FEATURES += CONFIG_NIC3COM=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_NIC3COM
 else
 override CONFIG_NIC3COM = no
 endif
 ifeq ($(CONFIG_NICREALTEK), yes)
-UNSUPPORTED_FEATURES += CONFIG_NICREALTEK=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_NICREALTEK
 else
 override CONFIG_NICREALTEK = no
 endif
 ifeq ($(CONFIG_NICNATSEMI), yes)
-UNSUPPORTED_FEATURES += CONFIG_NICNATSEMI=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_NICNATSEMI
 else
 override CONFIG_NICNATSEMI = no
 endif
 ifeq ($(CONFIG_RAYER_SPI), yes)
-UNSUPPORTED_FEATURES += CONFIG_RAYER_SPI=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_RAYER_SPI
 else
 override CONFIG_RAYER_SPI = no
 endif
 ifeq ($(CONFIG_ATAHPT), yes)
-UNSUPPORTED_FEATURES += CONFIG_ATAHPT=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_ATAHPT
 else
 override CONFIG_ATAHPT = no
 endif
 ifeq ($(CONFIG_SATAMV), yes)
-UNSUPPORTED_FEATURES += CONFIG_SATAMV=yes
+UNSUPPORTED_TARGET_FEATURES += CONFIG_SATAMV
 else
 override CONFIG_SATAMV = no
 endif
@@ -411,6 +411,128 @@ 
 ###############################################################################
 # Programmer drivers and programmer support infrastructure.
 
+ifeq ($(CONFIG_INTERNAL), yes)
+NEED_PCI += CONFIG_INTERNAL
+endif
+
+ifeq ($(CONFIG_SERPROG), yes)
+NEED_SERIAL += CONFIG_SERPROG
+NEED_NET += CONFIG_SERPROG
+endif
+
+ifeq ($(CONFIG_RAYER_SPI), yes)
+NEED_IOPORT_ACCESS += CONFIG_RAYER_SPI
+endif
+
+ifeq ($(CONFIG_PONY_SPI), yes)
+NEED_SERIAL += CONFIG_PONY_SPI
+endif
+
+ifeq ($(CONFIG_BITBANG_SPI), yes)
+endif
+
+ifeq ($(CONFIG_NIC3COM), yes)
+NEED_PCI += CONFIG_NIC3COM
+endif
+
+ifeq ($(CONFIG_GFXNVIDIA), yes)
+NEED_PCI += CONFIG_GFXNVIDIA
+endif
+
+ifeq ($(CONFIG_SATASII), yes)
+NEED_PCI += CONFIG_SATASII
+endif
+
+ifeq ($(CONFIG_ATAHPT), yes)
+NEED_PCI += CONFIG_ATAHPT
+endif
+
+ifeq ($(CONFIG_FT2232_SPI), yes)
+NEED_FTDI += CONFIG_FT2232_SPI
+endif
+
+ifeq ($(CONFIG_DUMMY), yes)
+endif
+
+ifeq ($(CONFIG_DRKAISER), yes)
+NEED_PCI += CONFIG_DRKAISER
+endif
+
+ifeq ($(CONFIG_NICREALTEK), yes)
+NEED_PCI += CONFIG_NICREALTEK
+endif
+
+ifeq ($(CONFIG_NICNATSEMI), yes)
+NEED_PCI += CONFIG_NICNATSEMI
+endif
+
+ifeq ($(CONFIG_NICINTEL), yes)
+NEED_PCI += CONFIG_NICINTEL
+endif
+
+ifeq ($(CONFIG_NICINTEL_SPI), yes)
+NEED_PCI += CONFIG_NICINTEL_SPI
+endif
+
+ifeq ($(CONFIG_OGP_SPI), yes)
+NEED_PCI += CONFIG_OGP_SPI
+endif
+
+ifeq ($(CONFIG_BUSPIRATE_SPI), yes)
+NEED_SERIAL += CONFIG_BUSPIRATE_SPI
+endif
+
+ifeq ($(CONFIG_DEDIPROG), yes)
+NEED_USB += CONFIG_DEDIPROG
+endif
+
+ifeq ($(CONFIG_SATAMV), yes)
+NEED_PCI += CONFIG_SATAMV
+endif
+
+ifeq ($(CONFIG_LINUX_SPI), yes)
+endif
+
+ifneq ($(NEED_SERIAL), )
+endif
+
+ifneq ($(NEED_NET), )
+endif
+
+ifneq ($(NEED_PCI), )
+CHECK_LIBPCI = yes
+endif
+
+ifneq ($(NEED_USB), )
+CHECK_LIBUSB0 = yes
+endif
+
+ifneq ($(NEED_FTDI), )
+CHECK_LIBFTDI = yes
+endif
+
+#############################################################################################################################################################################
+
+defaulttarget: all
+
+config: compiler
+	@printf "" > .availablefeatures
+	@./config.sh utsname
+ifneq ($(CHECK_LIBPCI), )
+	@./config.sh libpci
+endif
+ifneq ($(CHECK_LIBUSB0), )
+	@./config.sh libusb0
+endif
+ifeq ($(CHECK_LIBFTDI), yes)
+	@./config.sh libftdi
+endif
+ifeq ($(CONFIG_LINUX_SPI), yes)
+	@./config.sh linuxspi
+endif
+
+-include .availablefeatures
+
 FEATURE_CFLAGS += -D'CONFIG_DEFAULT_PROGRAMMER=$(CONFIG_DEFAULT_PROGRAMMER)'
 
 ifeq ($(CONFIG_INTERNAL), yes)
@@ -421,27 +543,21 @@ 
 PROGRAMMER_OBJS += ichspi.o ich_descriptors.o
 else
 endif
-NEED_PCI := yes
 endif
 
 ifeq ($(CONFIG_SERPROG), yes)
 FEATURE_CFLAGS += -D'CONFIG_SERPROG=1'
 PROGRAMMER_OBJS += serprog.o
-NEED_SERIAL := yes
-NEED_NET := yes
 endif
 
 ifeq ($(CONFIG_RAYER_SPI), yes)
 FEATURE_CFLAGS += -D'CONFIG_RAYER_SPI=1'
 PROGRAMMER_OBJS += rayer_spi.o
-# Actually, NEED_PCI is wrong. NEED_IOPORT_ACCESS would be more correct.
-NEED_PCI := yes
 endif
 
 ifeq ($(CONFIG_PONY_SPI), yes)
 FEATURE_CFLAGS += -D'CONFIG_PONY_SPI=1'
 PROGRAMMER_OBJS += pony_spi.o
-NEED_SERIAL := yes
 endif
 
 ifeq ($(CONFIG_BITBANG_SPI), yes)
@@ -452,36 +568,29 @@ 
 ifeq ($(CONFIG_NIC3COM), yes)
 FEATURE_CFLAGS += -D'CONFIG_NIC3COM=1'
 PROGRAMMER_OBJS += nic3com.o
-NEED_PCI := yes
 endif
 
 ifeq ($(CONFIG_GFXNVIDIA), yes)
 FEATURE_CFLAGS += -D'CONFIG_GFXNVIDIA=1'
 PROGRAMMER_OBJS += gfxnvidia.o
-NEED_PCI := yes
 endif
 
 ifeq ($(CONFIG_SATASII), yes)
 FEATURE_CFLAGS += -D'CONFIG_SATASII=1'
 PROGRAMMER_OBJS += satasii.o
-NEED_PCI := yes
 endif
 
 ifeq ($(CONFIG_ATAHPT), yes)
 FEATURE_CFLAGS += -D'CONFIG_ATAHPT=1'
 PROGRAMMER_OBJS += atahpt.o
-NEED_PCI := yes
 endif
 
 ifeq ($(CONFIG_FT2232_SPI), yes)
-FTDILIBS := $(shell pkg-config --libs libftdi 2>/dev/null || printf "%s" "-lftdi -lusb")
-# This is a totally ugly hack.
-FEATURE_CFLAGS += $(shell LC_ALL=C grep -q "FTDISUPPORT := yes" .features && printf "%s" "-D'CONFIG_FT2232_SPI=1'")
-FEATURE_CFLAGS += $(shell LC_ALL=C grep -q "FT232H := yes" .features && printf "%s" "-D'HAVE_FT232H=1'")
-FEATURE_LIBS += $(shell LC_ALL=C grep -q "FTDISUPPORT := yes" .features && printf "%s" "$(FTDILIBS)")
+FEATURE_CFLAGS += -D'CONFIG_FT2232_SPI=1'
+ifeq ($(FT232H), yes)
+FEATURE_CFLAGS += -D'HAVE_FT232H=1'
+endif
 PROGRAMMER_OBJS += ft2232_spi.o
-# We can't set NEED_USB here because that would transform libftdi auto-enabling
-# into a hard requirement for libusb, defeating the purpose of auto-enabling.
 endif
 
 ifeq ($(CONFIG_DUMMY), yes)
@@ -492,75 +601,64 @@ 
 ifeq ($(CONFIG_DRKAISER), yes)
 FEATURE_CFLAGS += -D'CONFIG_DRKAISER=1'
 PROGRAMMER_OBJS += drkaiser.o
-NEED_PCI := yes
 endif
 
 ifeq ($(CONFIG_NICREALTEK), yes)
 FEATURE_CFLAGS += -D'CONFIG_NICREALTEK=1'
 PROGRAMMER_OBJS += nicrealtek.o
-NEED_PCI := yes
 endif
 
 ifeq ($(CONFIG_NICNATSEMI), yes)
 FEATURE_CFLAGS += -D'CONFIG_NICNATSEMI=1'
 PROGRAMMER_OBJS += nicnatsemi.o
-NEED_PCI := yes
 endif
 
 ifeq ($(CONFIG_NICINTEL), yes)
 FEATURE_CFLAGS += -D'CONFIG_NICINTEL=1'
 PROGRAMMER_OBJS += nicintel.o
-NEED_PCI := yes
 endif
 
 ifeq ($(CONFIG_NICINTEL_SPI), yes)
 FEATURE_CFLAGS += -D'CONFIG_NICINTEL_SPI=1'
 PROGRAMMER_OBJS += nicintel_spi.o
-NEED_PCI := yes
 endif
 
 ifeq ($(CONFIG_OGP_SPI), yes)
 FEATURE_CFLAGS += -D'CONFIG_OGP_SPI=1'
 PROGRAMMER_OBJS += ogp_spi.o
-NEED_PCI := yes
 endif
 
 ifeq ($(CONFIG_BUSPIRATE_SPI), yes)
 FEATURE_CFLAGS += -D'CONFIG_BUSPIRATE_SPI=1'
 PROGRAMMER_OBJS += buspirate_spi.o
-NEED_SERIAL := yes
 endif
 
 ifeq ($(CONFIG_DEDIPROG), yes)
 FEATURE_CFLAGS += -D'CONFIG_DEDIPROG=1'
 PROGRAMMER_OBJS += dediprog.o
-NEED_USB := yes
 endif
 
 ifeq ($(CONFIG_SATAMV), yes)
 FEATURE_CFLAGS += -D'CONFIG_SATAMV=1'
 PROGRAMMER_OBJS += satamv.o
-NEED_PCI := yes
 endif
 
 ifeq ($(CONFIG_LINUX_SPI), yes)
-# This is a totally ugly hack.
-FEATURE_CFLAGS += $(shell LC_ALL=C grep -q "LINUX_SPI_SUPPORT := yes" .features && printf "%s" "-D'CONFIG_LINUX_SPI=1'")
+FEATURE_CFLAGS += -D'CONFIG_LINUX_SPI=1'
 PROGRAMMER_OBJS += linux_spi.o
 endif
 
-ifeq ($(NEED_SERIAL), yes)
+ifneq ($(NEED_SERIAL), )
 LIB_OBJS += serial.o
 endif
 
-ifeq ($(NEED_NET), yes)
+ifneq ($(NEED_NET), )
 ifeq ($(TARGET_OS), SunOS)
 LIBS += -lsocket
 endif
 endif
 
-ifeq ($(NEED_PCI), yes)
-CHECK_LIBPCI = yes
+ifneq ($(NEED_PCI), )
 FEATURE_CFLAGS += -D'NEED_PCI=1'
 PROGRAMMER_OBJS += pcidev.o physmap.o hwaccess.o
 ifeq ($(TARGET_OS), NetBSD)
@@ -589,32 +687,45 @@ 
 endif
 endif
 
-ifeq ($(NEED_USB), yes)
-CHECK_LIBUSB0 = yes
+ifneq ($(NEED_USB), )
 FEATURE_CFLAGS += -D'NEED_USB=1'
 USBLIBS := $(shell pkg-config --libs libusb 2>/dev/null || printf "%s" "-lusb")
 endif
 
+ifneq ($(NEED_FTDI), )
+FEATURE_CFLAGS += -D'NEED_FTDI=1'
+FTDILIBS := $(shell pkg-config --libs libftdi 2>/dev/null || libftdi-config --libs 2>/dev/null || printf "%s" "-lftdi")
+endif
+
+ifneq ($(NEED_IOPORT_ACCESS), )
+FEATURE_CFLAGS += -D'NEED_IOPORT_ACCESS=1'
+PROGRAMMER_OBJS += hwaccess.o
+endif
+
 ifeq ($(CONFIG_PRINT_WIKI), yes)
 FEATURE_CFLAGS += -D'CONFIG_PRINT_WIKI=1'
 CLI_OBJS += print_wiki.o
 endif
 
-FEATURE_CFLAGS += $(shell LC_ALL=C grep -q "UTSNAME := yes" .features && printf "%s" "-D'HAVE_UTSNAME=1'")
+ifeq ($(UTSNAME), yes)
+FEATURE_CFLAGS += -D'HAVE_UTSNAME=1'
+endif
 
 # We could use PULLED_IN_LIBS, but that would be ugly.
-FEATURE_LIBS += $(shell LC_ALL=C grep -q "NEEDLIBZ := yes" .libdeps && printf "%s" "-lz")
+ifeq ($(NEEDLIBZ), yes)
+FEATURE_LIBS += -lz
+endif
 
-LIBFLASHROM_OBJS = $(CHIP_OBJS) $(PROGRAMMER_OBJS) $(LIB_OBJS)
+LIBFLASHROM_OBJS = $(CHIP_OBJS) $(sort $(PROGRAMMER_OBJS)) $(LIB_OBJS)
 OBJS = $(CLI_OBJS) $(LIBFLASHROM_OBJS)
 
-all: hwlibs features $(PROGRAM)$(EXEC_SUFFIX)
+all: $(PROGRAM)$(EXEC_SUFFIX)
 ifeq ($(ARCH), x86)
 	@+$(MAKE) -C util/ich_descriptors_tool/ TARGET_OS=$(TARGET_OS) EXEC_SUFFIX=$(EXEC_SUFFIX)
 endif
 
 $(PROGRAM)$(EXEC_SUFFIX): $(OBJS)
-	$(CC) $(LDFLAGS) -o $(PROGRAM)$(EXEC_SUFFIX) $(OBJS) $(FEATURE_LIBS) $(LIBS) $(PCILIBS) $(USBLIBS)
+	$(CC) $(LDFLAGS) -o $(PROGRAM)$(EXEC_SUFFIX) $(OBJS) $(FTDILIBS) $(USBLIBS) $(PCILIBS) $(FEATURE_LIBS) $(LIBS)
 
 libflashrom.a: $(LIBFLASHROM_OBJS)
 	$(AR) rcs $@ $^
@@ -625,7 +736,11 @@ 
 # stored files, they can be handled here as well.
 TAROPTIONS = $(shell LC_ALL=C tar --version|grep -q GNU && echo "--owner=root --group=root")
 
-%.o: %.c .features
+%.o: %.c
+ifeq ($(wildcard .availablefeatures), )
+	@echo 'You have to run "make config" first'
+	@false
+endif
 	$(CC) -MMD $(CFLAGS) $(CPPFLAGS) $(FLASHROM_CFLAGS) $(FEATURE_CFLAGS) $(SVNDEF) -o $@ -c $<
 
 # Make sure to add all names of generated binaries here.
@@ -636,7 +751,7 @@ 
 	@+$(MAKE) -C util/ich_descriptors_tool/ clean
 
 distclean: clean
-	rm -f .features .libdeps
+	rm -f .availablefeatures
 
 strip: $(PROGRAM)$(EXEC_SUFFIX)
 	$(STRIP) $(STRIP_ARGS) $(PROGRAM)$(EXEC_SUFFIX)
@@ -699,60 +814,6 @@ 
 endef
 export LIBUSB0_TEST
 
-hwlibs: compiler
-	@printf "" > .libdeps
-ifeq ($(CHECK_LIBPCI), yes)
-	@printf "Checking for libpci headers... "
-	@echo "$$LIBPCI_TEST" > .test.c
-	@$(CC) -c $(CPPFLAGS) $(CFLAGS) .test.c -o .test.o >/dev/null &&		\
-		echo "found." || ( echo "not found."; echo;			\
-		echo "Please install libpci headers (package pciutils-devel).";	\
-		echo "See README for more information."; echo;			\
-		rm -f .test.c .test.o; exit 1)
-	@printf "Checking if libpci is present and sufficient... "
-	@$(CC) $(LDFLAGS) .test.o -o .test$(EXEC_SUFFIX) $(LIBS) $(PCILIBS) >/dev/null &&		\
-		echo "yes." || ( echo "no.";							\
-		printf "Checking if libz+libpci are present and sufficient...";	\
-		$(CC) $(LDFLAGS) .test.o -o .test$(EXEC_SUFFIX) $(LIBS) $(PCILIBS) -lz >/dev/null &&	\
-		( echo "yes."; echo "NEEDLIBZ := yes" > .libdeps ) || ( echo "no."; echo;	\
-		echo "Please install libpci (package pciutils) and/or libz.";			\
-		echo "See README for more information."; echo;				\
-		rm -f .test.c .test.o .test$(EXEC_SUFFIX); exit 1) )
-	@rm -f .test.c .test.o .test$(EXEC_SUFFIX)
-endif
-ifeq ($(CHECK_LIBUSB0), yes)
-	@printf "Checking for libusb-0.1/libusb-compat headers... "
-	@echo "$$LIBUSB0_TEST" > .test.c
-	@$(CC) -c $(CPPFLAGS) $(CFLAGS) .test.c -o .test.o >/dev/null &&		\
-		echo "found." || ( echo "not found."; echo;				\
-		echo "Please install libusb-0.1 headers or libusb-compat headers.";	\
-		echo "See README for more information."; echo;				\
-		rm -f .test.c .test.o; exit 1)
-	@printf "Checking if libusb-0.1 is usable... "
-	@$(CC) $(LDFLAGS) .test.o -o .test$(EXEC_SUFFIX) $(LIBS) $(USBLIBS) >/dev/null &&	\
-		echo "yes." || ( echo "no.";						\
-		echo "Please install libusb-0.1 or libusb-compat.";			\
-		echo "See README for more information."; echo;				\
-		rm -f .test.c .test.o .test$(EXEC_SUFFIX); exit 1)
-	@rm -f .test.c .test.o .test$(EXEC_SUFFIX)
-endif
-
-.features: features
-
-# If a user does not explicitly request a non-working feature, we should
-# silently disable it. However, if a non-working (does not compile) feature
-# is explicitly requested, we should bail out with a descriptive error message.
-# We also have to check that at least one programmer driver is enabled.
-featuresavailable:
-ifeq ($(PROGRAMMER_OBJS),)
-	@echo "You have to enable at least one programmer driver!"
-	@false
-endif
-ifneq ($(UNSUPPORTED_FEATURES), )
-	@echo "The following features are unavailable on your machine: $(UNSUPPORTED_FEATURES)"
-	@false
-endif
-
 define FTDI_TEST
 #include <ftdi.h>
 struct ftdi_context *ftdic = NULL;
@@ -771,60 +832,47 @@ 
 endef
 export FTDI_232H_TEST
 
-define UTSNAME_TEST
-#include <sys/utsname.h>
-struct utsname osinfo;
+define LINUX_SPI_TEST
+#include <linux/types.h>
+#include <linux/spi/spidev.h>
+
 int main(int argc, char **argv)
 {
 	(void) argc;
 	(void) argv;
-	uname (&osinfo);
 	return 0;
 }
 endef
-export UTSNAME_TEST
+export LINUX_SPI_TEST
 
-define LINUX_SPI_TEST
-#include <linux/types.h>
-#include <linux/spi/spidev.h>
-
+define UTSNAME_TEST
+#include <sys/utsname.h>
+struct utsname osinfo;
 int main(int argc, char **argv)
 {
 	(void) argc;
 	(void) argv;
+	uname (&osinfo);
 	return 0;
 }
 endef
-export LINUX_SPI_TEST
+export UTSNAME_TEST
 
-features: compiler
-	@echo "FEATURES := yes" > .features.tmp
-ifeq ($(CONFIG_FT2232_SPI), yes)
-	@printf "Checking for FTDI support... "
-	@echo "$$FTDI_TEST" > .featuretest.c
-	@$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) .featuretest.c -o .featuretest$(EXEC_SUFFIX) $(FTDILIBS) $(LIBS) >/dev/null 2>&1 &&	\
-		( echo "found."; echo "FTDISUPPORT := yes" >> .features.tmp ) ||	\
-		( echo "not found."; echo "FTDISUPPORT := no" >> .features.tmp )
-	@printf "Checking for FT232H support in libftdi... "
-	@echo "$$FTDI_232H_TEST" >> .featuretest.c
-	@$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) .featuretest.c -o .featuretest$(EXEC_SUFFIX) $(FTDILIBS) $(LIBS) >/dev/null 2>&1 &&	\
-		( echo "found."; echo "FT232H := yes" >> .features.tmp ) ||	\
-		( echo "not found."; echo "FT232H := no" >> .features.tmp )
+export CC
+
+# If a user does not explicitly request a non-working feature, we should
+# silently disable it. However, if a non-working (does not compile) feature
+# is explicitly requested, we should bail out with a descriptive error message.
+# We also have to check that at least one programmer driver is enabled.
+featuresavailable:
+ifeq ($(PROGRAMMER_OBJS),)
+	@echo "You have to enable at least one programmer driver!"
+	@false
 endif
-ifeq ($(CONFIG_LINUX_SPI), yes)
-	@printf "Checking if Linux SPI headers are present... "
-	@echo "$$LINUX_SPI_TEST" > .featuretest.c
-	@$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) .featuretest.c -o .featuretest$(EXEC_SUFFIX) >/dev/null 2>&1 &&	\
-		( echo "yes."; echo "LINUX_SPI_SUPPORT := yes" >> .features.tmp ) ||	\
-		( echo "no."; echo "LINUX_SPI_SUPPORT := no" >> .features.tmp )
+ifneq ($(UNSUPPORTED_TARGET_FEATURES), )
+	@echo "The following features are unavailable on the target machine: $(UNSUPPORTED_TARGET_FEATURES)"
+	@false
 endif
-	@printf "Checking for utsname support... "
-	@echo "$$UTSNAME_TEST" > .featuretest.c
-	@$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) .featuretest.c -o .featuretest$(EXEC_SUFFIX) >/dev/null 2>&1 &&	\
-		( echo "found."; echo "UTSNAME := yes" >> .features.tmp ) ||	\
-		( echo "not found."; echo "UTSNAME := no" >> .features.tmp )
-	@$(DIFF) -q .features.tmp .features >/dev/null 2>&1 && rm .features.tmp || mv .features.tmp .features
-	@rm -f .featuretest.c .featuretest$(EXEC_SUFFIX)
 
 install: $(PROGRAM)$(EXEC_SUFFIX)
 	mkdir -p $(DESTDIR)$(PREFIX)/sbin
@@ -849,6 +897,10 @@ 
 libpayload: clean
 	make CC="CC=i386-elf-gcc lpgcc" AR=i386-elf-ar RANLIB=i386-elf-ranlib
 
-.PHONY: all clean distclean compiler hwlibs features export tarball dos featuresavailable
+.PHONY: all clean distclean compiler config export tarball dos featuresavailable
 
+.EXPORT_ALL_VARIABLES:
+
+-include .availablefeatures
+
 -include $(OBJS:.o=.d)
Index: flashrom-Makefile_harddependencies_soft/config.sh
===================================================================
--- flashrom-Makefile_harddependencies_soft/config.sh	(Revision 0)
+++ flashrom-Makefile_harddependencies_soft/config.sh	(Revision 0)
@@ -0,0 +1,199 @@ 
+#!/bin/sh
+libpci() {
+	printf "Checking for libpci headers... "
+	echo "$LIBPCI_TEST" > .test.c
+	${CC} -c ${CPPFLAGS} ${CFLAGS} .test.c -o .test.o >.testresult 2>&1 && {
+		echo "found."
+	} || {
+		echo "not found."
+		if [ ${CHECK_LIBPCI} = yes ]; then
+			echo
+			echo "Please install libpci headers (package pciutils-devel)"
+			echo "or disable the following features: ${NEED_PCI}"
+			echo "See README for more information."
+			echo
+			rm -f .test.o
+			exit 1
+		else
+			for a in ${NEED_PCI}; do
+				echo "${a} := no" >> .availablefeatures
+			done
+			echo
+			echo "The following features have been automatically disabled: ${NEED_PCI}"
+			echo "See README for more information."
+			echo
+			rm -f .test.c .test.o
+			return 0
+		fi
+	}
+	printf "Checking if libpci is present and sufficient... "
+	${CC} ${LDFLAGS} .test.o -o .test${EXEC_SUFFIX} ${PCILIBS} ${LIBS} >.testresult 2>&1 && {
+		echo "yes."
+	} || {
+		echo "no."
+		printf "Checking if libz+libpci are present and sufficient..."
+		${CC} ${LDFLAGS} .test.o -o .test${EXEC_SUFFIX} ${PCILIBS} -lz ${LIBS} >.testresult 2>&1 && {
+			echo "yes."
+			echo "NEEDLIBZ := yes" > .availablefeatures
+		} || {
+			echo "no."
+			if [ ${CHECK_LIBPCI} = yes ]; then
+				echo
+				echo "Please install libpci (package pciutils) and/or libz"
+				echo "or disable the following features: ${NEED_PCI}"
+				echo "See README for more information."
+				echo
+				rm -f test.o .test${EXEC_SUFFIX}
+				exit 1
+			else
+				for a in ${NEED_PCI}; do
+					echo "${a} := no" >> .availablefeatures
+				done
+				echo
+				echo "The following features have been automatically disabled: ${NEED_PCI}"
+				echo "See README for more information."
+				echo
+				rm -f .test.c .test.o; .test${EXEC_SUFFIX}
+				return 0
+			fi
+		}
+	}
+	rm -f .test.c .test.o .test${EXEC_SUFFIX} .testresult
+}
+
+libusb0() {
+	printf "Checking for libusb-0.1/libusb-compat headers... "
+	echo "$LIBUSB0_TEST" > .test.c
+	${CC} -c ${CPPFLAGS} ${CFLAGS} .test.c -o .test.o >.testresult 2>&1 && {
+		echo "found."
+	} || {
+		echo "not found."
+		if [ ${CHECK_LIBUSB0} = yes ]; then
+			echo
+			echo "Please install libusb-0.1 headers or libusb-compat headers"
+			echo "or disable the following features: ${NEED_USB}"
+			echo "See README for more information."
+			echo
+			rm -f .test.o
+			exit 1
+		else
+			for a in ${NEED_USB}; do
+				echo "${a} := no" >> .availablefeatures
+			done
+			echo
+			echo "The following features have been automatically disabled: ${NEED_USB}"
+			echo "See README for more information."
+			echo
+			rm -f .test.c .test.o
+			return 0
+		fi
+	}
+	printf "Checking if libusb-0.1/libusb-compat is usable... "
+	${CC} ${LDFLAGS} .test.o -o .test${EXEC_SUFFIX} ${USBLIBS} ${LIBS} >.testresult 2>&1 && {
+		echo "yes."
+	} || {
+		echo "no."
+		if [ ${CHECK_LIBUSB0} = yes ]; then
+			echo
+			echo "Please install libusb-0.1 or libusb-compat"
+			echo "or disable the following features: ${NEED_USB}"
+			echo "See README for more information."
+			echo
+			rm -f .test.o .test${EXEC_SUFFIX}
+			exit 1
+		else
+			for a in ${NEED_USB}; do
+				echo "${a} := no" >> .availablefeatures
+			done
+			echo
+			echo "The following features have been automatically disabled: ${NEED_USB}"
+			echo "See README for more information."
+			echo
+			rm -f .test.c .test.o
+			return 0
+		fi
+	}
+	rm -f .test.c .test.o .test${EXEC_SUFFIX} .testresult
+}
+
+libftdi() {
+	printf "Checking for libftdi support... "
+	echo "$FTDI_TEST" > .test.c
+	${CC} ${CPPFLAGS} ${CFLAGS} ${LDFLAGS} .test.c -o .test${EXEC_SUFFIX} ${FTDILIBS} ${LIBS} >.testresult 2>&1 && {
+		echo "found."
+	} || {
+		echo "not found."
+		if [ ${CHECK_LIBFTDI} = yes ]; then
+			echo
+			echo "Please install libftdi headers"
+			echo "or disable the following features: ${NEED_FTDI}"
+			echo "See README for more information."
+			echo
+			rm -f .test${EXEC_SUFFIX}
+			exit 1
+		else
+			for a in ${NEED_FTDI}; do
+				echo "${a} := no" >> .availablefeatures
+			done
+			echo
+			echo "The following features have been automatically disabled: ${NEED_FTDI}"
+			echo "See README for more information."
+			echo
+			rm -f .test.c .test${EXEC_SUFFIX}
+			return 0
+		fi
+	}
+	printf "Checking for FT232H support in libftdi... "
+	echo "$FTDI_232H_TEST" >> .test.c
+	${CC} ${CPPFLAGS} ${CFLAGS} ${LDFLAGS} .test.c -o .test${EXEC_SUFFIX} ${FTDILIBS} ${LIBS} >.testresult 2>&1 && {
+		echo "found."
+		echo "FT232H := yes" >> .availablefeatures
+	} || {
+		echo "not found."
+	}
+	rm -f .test.c .test${EXEC_SUFFIX} .testresult
+}
+
+linuxspi() {
+	printf "Checking for Linux kernel SPI headers... "
+	echo "$LINUX_SPI_TEST" > .test.c
+	${CC} ${CPPFLAGS} ${CFLAGS} ${LDFLAGS} .test.c -o .test${EXEC_SUFFIX} >.testresult 2>&1 && {
+		echo "found."
+	} || {
+		echo "not found."
+		if [ ${CONFIG_LINUX_SPI} = yes ]; then
+			echo
+			echo "Please install Linux kernel SPI headers (linux/spi/spidev.h, part of recent glibc)"
+			echo "or disable the following features: CONFIG_LINUX_SPI"
+			echo "See README for more information."
+			echo
+			rm -f .test${EXEC_SUFFIX}
+			exit 1
+		else
+			for a in CONFIG_LINUX_SPI; do
+				echo "${a} := no" >> .availablefeatures
+			done
+			echo
+			echo "The following features have been automatically disabled: CONFIG_LINUX_SPI"
+			echo "See README for more information."
+			echo
+			rm -f .test.c .test${EXEC_SUFFIX}
+			return 0
+		fi
+	}
+	rm -f .test.c .test${EXEC_SUFFIX} .testresult
+}
+
+utsname() {
+	printf "Checking for utsname support... "
+	echo "$UTSNAME_TEST" > .test.c
+	${CC} ${CPPFLAGS} ${CFLAGS} ${LDFLAGS} .test.c -o .test${EXEC_SUFFIX} >/dev/null 2>&1 && {
+		echo "found."
+		echo "UTSNAME := yes" >> .availablefeatures
+	} || {
+		echo "not found."
+	}
+	rm -f .test.c .test${EXEC_SUFFIX} .testresult
+}
+
+eval $1