--- a/tools/80211debug.c
+++ b/tools/80211debug.c
@@ -48,6 +48,7 @@
 #include <ctype.h>
 #include <getopt.h>
 #include <err.h>
+#include "do_multi.h"
 
 #undef ARRAY_SIZE
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
@@ -185,7 +186,7 @@
 #endif /* __linux__ */
 
 int
-main(int argc, char *argv[])
+CMD(a80211debug)(int argc, char *argv[])
 {
 	const char *ifname = "ath0";
 	const char *cp, *tp;
--- a/tools/80211stats.c
+++ b/tools/80211stats.c
@@ -59,6 +59,7 @@
 #include "net80211/ieee80211.h"
 #include "net80211/ieee80211_crypto.h"
 #include "net80211/ieee80211_ioctl.h"
+#include "do_multi.h"
 
 #ifndef SIOCG80211STATS
 #define	SIOCG80211STATS	(SIOCDEVPRIVATE + 2)
@@ -240,7 +241,7 @@
 }
 
 int
-main(int argc, char *argv[])
+CMD(a80211stats)(int argc, char *argv[])
 {
 	int c, len;
 	struct ieee80211req_sta_info *si;
--- a/tools/athchans.c
+++ b/tools/athchans.c
@@ -58,6 +58,7 @@
 #include "net80211/ieee80211.h"
 #include "net80211/ieee80211_crypto.h"
 #include "net80211/ieee80211_ioctl.h"
+#include "do_multi.h"
 
 static	int s = -1;
 static const char *progname;
@@ -140,8 +141,9 @@
 }
 
 #define	MAXCHAN	((int)(sizeof(struct ieee80211req_chanlist) * NBBY))
+
 int
-main(int argc, char *argv[])
+CMD(athchans)(int argc, char *argv[])
 {
 	const char *ifname = "wifi0";
 	struct ieee80211req_chanlist chanlist;
--- a/tools/athctrl.c
+++ b/tools/athctrl.c
@@ -52,6 +52,7 @@
 #include <err.h>
 
 #include <net/if.h>
+#include "do_multi.h"
 
 static int
 setsysctrl(const char *dev, const char *control , u_long value)
@@ -88,7 +89,7 @@
 }
 
 int
-main(int argc, char *argv[])
+CMD(athctrl)(int argc, char *argv[])
 {
 	char device[IFNAMSIZ + 1];
 	int distance = -1;
--- a/tools/athdebug.c
+++ b/tools/athdebug.c
@@ -51,6 +51,7 @@
 #include <ctype.h>
 #include <getopt.h>
 #include <err.h>
+#include "do_multi.h"
 
 #undef ARRAY_SIZE
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
@@ -194,7 +195,7 @@
 #endif /* __linux__ */
 
 int
-main(int argc, char *argv[])
+CMD(athdebug)(int argc, char *argv[])
 {
 #ifdef __linux__
 	const char *ifname = "wifi0";
--- a/tools/athkey.c
+++ b/tools/athkey.c
@@ -58,6 +58,7 @@
 #include "net80211/ieee80211.h"
 #include "net80211/ieee80211_crypto.h"
 #include "net80211/ieee80211_ioctl.h"
+#include "do_multi.h"
 
 static int s = -1;
 static const char *progname;
@@ -213,8 +214,7 @@
 	exit(-1);
 }
 
-int
-main(int argc, char *argv[])
+int CMD(athkey)(int argc, char *argv[])
 {
 	const char *ifname = "wifi0";
 	struct ieee80211req_key setkey;
--- a/tools/athstats.c
+++ b/tools/athstats.c
@@ -65,6 +65,7 @@
 
 #undef ARRAY_SIZE
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#include "do_multi.h"
 
 static const struct {
 	u_int		phyerr;
@@ -228,7 +229,7 @@
 }
 
 int
-main(int argc, char *argv[])
+CMD(athstats)(int argc, char *argv[])
 {
 #ifdef __linux__
 	const char *ifname = "wifi0";
--- /dev/null
+++ b/tools/do_multi.c
@@ -0,0 +1,33 @@
+#include <string.h>
+#include <libgen.h>
+#include "do_multi.h"
+
+int
+main(int argc, char *argv[])
+{
+    char *progname;
+    int ret = 0;
+
+    progname = basename(argv[0]);
+
+    if(strcmp(progname, "80211debug") == 0)
+	ret = a80211debug_init(argc, argv);
+    if(strcmp(progname, "80211stats") == 0)
+	ret = a80211stats_init(argc, argv);
+    if(strcmp(progname, "athchans") == 0)
+	ret = athchans_init(argc, argv);
+    if(strcmp(progname, "athctrl") == 0)
+	ret =  athctrl_init(argc, argv);
+    if(strcmp(progname, "athdebug") == 0)
+	ret =  athdebug_init(argc, argv);
+    if(strcmp(progname, "athkey") == 0)
+	ret =  athkey_init(argc, argv);
+    if(strcmp(progname, "athstats") == 0)
+	ret =  athstats_init(argc, argv);
+    if(strcmp(progname, "wlanconfig") == 0)
+	ret =  wlanconfig_init(argc, argv);
+    if(strcmp(progname, "ath_info") == 0)
+	ret =  athinfo_init(argc, argv);
+
+    return ret;
+}
--- /dev/null
+++ b/tools/do_multi.h
@@ -0,0 +1,15 @@
+#ifdef DO_MULTI
+int a80211debug_init(int argc, char *argv[]);
+int a80211stats_init(int argc, char *argv[]);
+int athchans_init(int argc, char *argv[]);
+int athctrl_init(int argc, char *argv[]);
+int athdebug_init(int argc, char *argv[]);
+int athkey_init(int argc, char *argv[]);
+int athstats_init(int argc, char *argv[]);
+int wlanconfig_init(int argc, char *argv[]);
+int athinfo_init(int argc, char *argv[]);
+
+#define CMD(name) name##_init
+#else
+#define CMD(name) main
+#endif
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -46,56 +46,55 @@
 HAL=   $(TOP)/hal
 endif
 
+all: compile
 
-ALL=	athstats 80211stats athkey athchans athctrl \
+ALLPROGS=	athstats 80211stats athkey athchans athctrl \
 	athdebug 80211debug wlanconfig ath_info
 
-all:	$(ALL)
+OBJS=	$(patsubst %,%.o,$(ALLPROGS))
 
-INCS=	-I. -I$(HAL) -I$(TOP) -I$(ATH_HAL)
+INCS=	-I. -I../ath -I$(HAL) -I$(TOP) -I$(ATH_HAL)
 CFLAGS=	-g -O2 -Wall
 ALL_CFLAGS= $(CFLAGS) $(INCS)
 LDFLAGS=
 
-all:	$(ALL)
 
-athstats: athstats.c
-	$(CC) -o athstats $(ALL_CFLAGS) -I$(TOP)/ath $(LDFLAGS) athstats.c
-80211stats: 80211stats.c
-	$(CC) -o 80211stats $(ALL_CFLAGS) $(LDFLAGS) 80211stats.c
-athkey: athkey.c
-	$(CC) -o athkey $(ALL_CFLAGS) $(LDFLAGS) athkey.c
-athchans: athchans.c
-	$(CC) -o athchans $(ALL_CFLAGS) $(LDFLAGS) athchans.c
-athctrl: athctrl.c
-	$(CC) -o athctrl $(ALL_CFLAGS) $(LDFLAGS) athctrl.c
-athdebug: athdebug.c
-	$(CC) -o athdebug $(ALL_CFLAGS) $(LDFLAGS) athdebug.c
-wlanconfig: wlanconfig.c
-	$(CC) -o wlanconfig $(ALL_CFLAGS) $(LDFLAGS) wlanconfig.c
-80211debug: 80211debug.c
-	$(CC) -o 80211debug $(ALL_CFLAGS) $(LDFLAGS) 80211debug.c
-ath_info: ath_info.c
-	$(CC) -o ath_info $(CFLAGS) ath_info.c
+ifneq ($(DO_MULTI),)
+ALL_CFLAGS += -DDO_MULTI=1
+%.o: %.c
+	${CC} $(ALL_CFLAGS) -c -o $@  $<
+
+madwifi_multi: $(OBJS) do_multi.o
+	$(CC) -o $@ $^
+
+compile: madwifi_multi
+	for i in $(ALLPROGS); do \
+		ln -s -f madwifi_multi $$i; \
+	done
+else
+$(ALLPROGS):
+	$(CC) $(ALL_CFLAGS) -o $@ $@.c
+
+compile: $(ALLPROGS)
+endif
 
 
 install: $(ALL) 
 	install -d $(DESTDIR)$(BINDIR)
-	for i in $(ALL); do \
+	for i in $(ALLPROGS) $(if $(DO_MULTI),madwifi_multi); do \
 		install $$i $(DESTDIR)$(BINDIR)/$$i; \
-		$(STRIP) $(DESTDIR)$(BINDIR)/$$i; \
 	done
 	install -d $(DESTDIR)$(MANDIR)/man8
 	install -m 0644 man/*.8 $(DESTDIR)$(MANDIR)/man8
 	install $(TOP)/scripts/madwifi-unload $(DESTDIR)$(BINDIR)/madwifi-unload
 
 uninstall:
-	for i in $(ALL); do \
+	for i in $(ALLPROGS) $(if $(DO_MULTI),madwifi_multi); do \
 		rm -f $(DESTDIR)$(BINDIR)/$$i; \
 	done
-	for i in $(ALL:=.8); do \
-		rm -f $(DESTDIR)$(MANDIR)/man8/$$i; \
+	for i in $(ALLPROGS); do \
+		rm -f $(DESTDIR)$(MANDIR)/man8/$$i.8; \
 	done
 
 clean:
-	rm -f $(ALL) core a.out
+	rm -f $(ALLPROGS) madwifi_multi *.o core a.out
--- a/tools/wlanconfig.c
+++ b/tools/wlanconfig.c
@@ -61,6 +61,7 @@
 #include "net80211/ieee80211.h"
 #include "net80211/ieee80211_crypto.h"
 #include "net80211/ieee80211_ioctl.h"
+#include "do_multi.h"
 
 /*
  * These are taken from ieee80211_node.h
@@ -100,7 +101,7 @@
 static int verbose = 0;
 
 int
-main(int argc, char *argv[])
+CMD(wlanconfig)(int argc, char *argv[])
 {
 	const char *ifname, *cmd;
 	unsigned char bnounit = 0;
--- a/tools/ath_info.c
+++ b/tools/ath_info.c
@@ -98,6 +98,7 @@
 #include <sys/mman.h>
 #include <endian.h>
 #include <byteswap.h>
+#include "do_multi.h"
 
 #undef ARRAY_SIZE
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
@@ -738,7 +739,8 @@
 		"unlawful radio transmissions!\n\n");
 }
 
-int main(int argc, char *argv[])
+int
+CMD(athinfo)(int argc, char *argv[])
 {
 	u_int32_t dev_addr;
 	u_int16_t eeprom_header, srev, phy_rev_5ghz, phy_rev_2ghz;
