[LWN Logo]

To:	torvalds@transmeta.com
Subject: [Patch] module compilation infrastructure
Date:	Mon, 17 Apr 2000 23:46:38 +0200
From:	Olaf Titz <olaf@bigred.inka.de>

Hi Linus,

please consider the following patch (against 2.3.99-pre3) or a similar
thing for inclusion into the kernel. It fixes the long-standing
problem of finding out the right compiler options to compile external
modules.

This patch causes "make dep" to write a makefile fragment which can be
included from a module makefile. Documentation (a little) included.

Olaf

--- Makefile.orig	Wed Mar 22 08:38:26 2000
+++ Makefile	Mon Apr 17 22:14:46 2000
@@ -347,6 +347,26 @@
 	rm -f $$MODLIB/.misc $$MODLIB/.allmods; \
 	)

+include/config/module.mak: dummy
+	@echo VERSION = $(VERSION) > .ver
+	@echo PATCHLEVEL = $(PATCHLEVEL) >> .ver
+	@echo SUBLEVEL = $(SUBLEVEL) >> .ver
+	@echo EXTRAVERSION = $(EXTRAVERSION) >> .ver
+	@echo ARCH = $(ARCH) >> .ver
+	@echo CC = $(CC) >> .ver
+	@echo LD = $(LD) >> .ver
+	@echo GENKSYMS = $(GENKSYMS) >> .ver
+ifdef CONFIG_SMP
+	@echo CONFIG_SMP = 1 >> .ver
+endif
+ifdef CONFIG_MODVERSIONS
+	@echo CONFIG_MODVERSIONS = 1 >> .ver
+endif
+	@(echo CFLAGS = $(CFLAGS) $(MODFLAGS) | sed 's,$(TOPDIR)/include,$$(KINCDIR),g') >> .ver
+	@echo LINUX_COMPILER = \"`$(CC) -v 2>&1 | tail -1`\" >> .ver
+	@echo include '$$(KINCDIR)/linux/module.mak' >> .ver
+	@mv -f .ver $@
+
 # modules disabled....

 else
@@ -357,6 +377,12 @@
 	@echo "Then build a kernel with module support enabled."
 	@echo
 	@exit 1
+
+include/config/module.mak: dummy
+	@echo modules modules_install: > .ver
+	@$(MAKE) -n modules | sed -n "s/^e/	@e/p" >> .ver
+	@mv -f .ver $@
+
 endif

 clean:	archclean
@@ -376,7 +402,7 @@
 	rm -rf modules

 mrproper: clean archmrproper
-	rm -f include/linux/autoconf.h include/linux/version.h
+	rm -f include/linux/autoconf.h include/linux/version.h include/config/module.mak
 	rm -f drivers/net/hamradio/soundmodem/sm_tbl_{afsk1200,afsk2666,fsk9600}.h
 	rm -f drivers/net/hamradio/soundmodem/sm_tbl_{hapn4800,psk4800}.h
 	rm -f drivers/net/hamradio/soundmodem/sm_tbl_{afsk2400_7,afsk2400_8}.h
@@ -427,7 +453,7 @@
 endif
 export	MODVERFILE

-depend dep: dep-files $(MODVERFILE)
+depend dep: dep-files $(MODVERFILE) include/config/module.mak

 # make checkconfig: Prune 'scripts' directory to avoid "false positives".
 checkconfig:
--- /dev/null	Mon Jan 10 00:08:22 2000
+++ Documentation/compiling-modules.txt	Mon Apr 17 23:20:18 2000
@@ -0,0 +1,33 @@
+To compile external modules, you need the include tree of a configured
+kernel (after doing at least "make dep").
+
+Set up a Makefile in the module's directory which contains at least
+these lines:
+
+  # Object files which make up the module: without exported symbols
+  M_OBJS=foo.o bar.o
+  # ...and with exported symbols
+  MX_OBJS=fred.o
+  # Target into which the .o files are linked
+  M_TARGET=squish.o
+
+  # set this to your kernel include directory
+  KINCDIR=/var/export/src/linux-2.3.99-pre3/include
+  include $(KINCDIR)/config/module.mak
+
+
+Then you can do...      to do...
+
+make dep                update the ksym tables if needed,
+                        generate a dependencies file
+make modules            compile the objects and link them into a module
+make modules_install    install the module into its final location
+make clean              to clean up everything
+
+The module Makefile can define other variables, such as:
+
+EXTRA_CFLAGS            additional CFLAGS for all objects
+CFLAGS_foo.o            additional CFLAGS for foo.o
+PRE_CFLAGS              additional CFLAGS for all objects, set first on
+                        CC command line
+INSTALL_MOD_PATH        module installation root (default /)
--- /dev/null	Mon Jan 10 00:08:22 2000
+++ include/linux/module.mak	Sun Apr 16 21:02:45 2000
@@ -0,0 +1,114 @@
+KERNELRELEASE = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+
+.PHONY: dummy
+
+ALL_OBJS = $(M_OBJS) $(MX_OBJS)
+ifdef M_TARGET
+I_OBJ = $(M_TARGET)
+else
+I_OBJ = $(ALL_OBJS)
+endif
+
+# Generate dependencies first if necessary
+
+ifeq (.depend, $(wildcard .depend))
+all modules: modules_compile
+include .depend
+else
+all modules:
+	$(MAKE) depend
+	$(MAKE) modules_compile
+endif
+
+dep fastdep depend:: .depend
+
+.depend: $(wildcard *.[hc])
+	@$(CC) $(CFLAGS) -M $(ALL_OBJS:.o=.c) > .tmp
+	@for i in $(SYMTAB_OBJS); do echo CFLAGS_$$i += -DEXPORT_SYMTAB; done >> .tmp
+	@mv -f .tmp .depend
+
+# Compilation targets
+
+modules_compile: check_compiler_version $(I_OBJ)
+
+modules_install: modules
+	@( \
+	if [ "$(MOD_GROUP)" ]; then \
+	 MODLIB=$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)/$(MOD_GROUP);\
+	else \
+	 MODLIB=$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)/misc;\
+	fi; \
+	echo Installing modules under $$MODLIB; \
+	mkdir -p $$MODLIB; \
+	cp $(I_OBJ) $$MODLIB; \
+	)
+
+check_compiler_version:
+	@if [ "`$(CC) -v 2>&1 | tail -1`" != $(LINUX_COMPILER) ]; \
+		then echo WARNING: compiler mismatch; \
+	fi
+
+dummy $(M_TARGET): $(ALL_OBJS)
+	$(LD) -r -o $(M_TARGET) $(ALL_OBJS)
+
+%.s: %.c
+	$(CC) $(PRE_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -S $< -o $@
+
+%.i: %.c
+	$(CC) $(PRE_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -E $< > $@
+
+%.o: %.c
+	$(CC) $(PRE_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -c -o $@ $<
+
+%.o: %.S
+	$(CC) $(PRE_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -c -o $@ $<
+
+# Update the symbol version tables
+
+SYMTAB_OBJS = $(MX_OBJS)
+
+ifdef CONFIG_MODVERSIONS
+ifneq "$(strip $(SYMTAB_OBJS))" ""
+
+MODINCL = $(KINCDIR)/linux/modules
+
+ifdef CONFIG_SMP
+	genksyms_smp_prefix := -p smp_
+else
+	genksyms_smp_prefix :=
+endif
+
+$(MODINCL)/%.ver: %.c
+	@if [ ! -r $(MODINCL)/$*.stamp -o $(MODINCL)/$*.stamp -ot $< ]; then \
+		echo '$(CC) $(CFLAGS) -E -D__GENKSYMS__ $<'; \
+		echo '| $(GENKSYMS) $(genksyms_smp_prefix) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp'; \
+		$(CC) $(CFLAGS) -E -D__GENKSYMS__ $< \
+		| $(GENKSYMS) $(genksyms_smp_prefix) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp; \
+		if [ -r $@ ] && cmp -s $@ $@.tmp; then echo $@ is unchanged; rm -f $@.tmp; \
+		else echo mv $@.tmp $@; mv -f $@.tmp $@; fi; \
+	fi; touch $(MODINCL)/$*.stamp
+
+$(addprefix $(MODINCL)/,$(SYMTAB_OBJS:.o=.ver)): $(KINCDIR)/linux/autoconf.h
+
+$(KINCDIR)/linux/modversions.h: $(addprefix $(MODINCL)/,$(SYMTAB_OBJS:.o=.ver))
+	@echo updating $(KINCDIR)/linux/modversions.h
+	@(echo "#ifndef _LINUX_MODVERSIONS_H";\
+	  echo "#define _LINUX_MODVERSIONS_H"; \
+	  echo "#include <linux/modsetver.h>"; \
+	  cd $(KINCDIR)/linux/modules; \
+	  for f in *.ver; do \
+	    if [ -f $$f ]; then echo "#include <linux/modules/$${f}>"; fi; \
+	  done; \
+	  echo "#endif"; \
+	) > $@
+
+dep fastdep depend:: $(KINCDIR)/linux/modversions.h
+
+endif
+endif
+
+# Clean
+
+clean mrproper::
+	-rm -f *.o *.a .depend
+


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/