2004-04-15 21:17:52

by Axel Weiß

[permalink] [raw]
Subject: compiling external modules

Hi,

after some study of kernel Makefiles, I'm able now to compile externel modules
for both, 2.4 and 2.6 kernels correctly. I'd like to share my Makefiles here,
maybe somebody finds them useful.

Starting point was http://lwn.net/Articles/driver-porting/ which provides very
good and useful information. But there were some difficulties which I briefly
describe:

2.6-compilation of drivers consisting of more than one module leaded to very
ugly warnings from scripts/Makefile.modpost, when make was invoked after
'make clean'. The reason were lying-around objects in .tmp_versions directory
which were not deleted by 'make clean'. Solution: clean must explicitly
delete the version-object in .tmp_versions.

2.4-compilation requires inclusion of Rules.make and an additional rule for
module-object linkage. In 2.6 Rules.make does not exist, and the linking rule
would conflict with an already defined one. Solution: distinct current kernel
version.

When I gave the rule:
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
the whole kernel tree was cleaned. This is not my intention, when I'm working
on external modules and want to make clean e.g. for cvs commits. So I defined
my own clean rule, kicking away everything but source files.

So far the difficulties. Next I propose an assumption about filenames, when a
module consists of several objects which will be linked together. Let
<module-name> be a basic name for the module, so <module-name>.(k)o (with k
for 2.6, without for 2.4) will be the final target. I assume that all
elementary object-filenames begin with <module-name>, for clarification. E.g.
the module adc64.ko is composed of adc64_module.o, adc64_device.o, adc64_io.o
and so on. Generally, the name of an object is <module-name>_<object-name>.o,
and the object-names can be collected in a symbol <module-name>-obj-names.
Some objects may export symbols to other modules, they can be collected in a
<module-name>-exp-names list.

Finally, all the modules' Makefiles were very similar, so I split them into
two files: one Makefile for every module and a common Makefile.module which
is included by each Makefile. Each module-specific Makefile contains the
definition of
- <module-name>
- <module-name>-obj-names
- <module-name>-exp-names
- EXTRA_CFLAGS
which makes up all information Makfile.module needs.

Here is my solution:

Module-specific Makefile example: adc64-Makefile

#/***************************************************************************
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU General Public License as published by *
# * the Free Software Foundation; either version 2 of the License, or *
# * (at your option) any later version. *
# * *
# ***************************************************************************/
#
#/*
# * (C) 2004 by Axel Weiss ([email protected])
# */

MOD_NAME := adc64

ifeq ($($(MOD_NAME)_PWD),)
export $(MOD_NAME)_PWD := $(shell pwd)
endif

$(MOD_NAME)-obj-names := device io mailbox module ringbuffer talker
#$(MOD_NAME)-exp-names := not defined (no symbols exported here)
EXTRA_CFLAGS := -I$($(MOD_NAME)_PWD)/../include \
$(if $(ADC64_DEBUG),-DADC64_DEBUG,)

include ../../Makefile.module #Path to Makefile.module

#*****************************************************************************

Makefile.module:

#/***************************************************************************
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU General Public License as published by *
# * the Free Software Foundation; either version 2 of the License, or *
# * (at your option) any later version. *
# * *
# ***************************************************************************/
#
#/*
# * (C) 2004 by Axel Weiss ([email protected])
# */

KERNELVERSION := $(shell uname -r)
KDIR := /lib/modules/$(KERNELVERSION)/build
PWD := $(shell pwd)

KERNELBASE := $(basename $(KERNELVERSION))
KERNELMINOR := $(suffix $(KERNELBASE))
KERNELMAJOR := $(basename $(KERNELBASE))
KERNELMINOR_0_3 := $(strip $(foreach V, .0 .1 .2 .3, $(shell [ "$(V)" = \
"$(KERNELMINOR)" ] && echo yes)))
KERNELMINOR_4_5 := $(strip $(foreach V, .4 .5, $(shell [ "$(V)" = \
"$(KERNELMINOR)" ] && echo yes)))

.PHONY: all clean

ifeq ($(KERNELMAJOR),2)
ifeq ($(KERNELMINOR_0_3),yes)

all:
@echo *** kernel $(KERNELVERSION) not supported
@echo please upgrade to kernel 2.4 or newer

else # ifeq ($(KERNELMINOR_0_3),yes)

ifneq ($(KERNELRELEASE),)

obj-m = $(MOD_NAME).o
$(MOD_NAME)-objs := $($(MOD_NAME)-obj-names:%=$(MOD_NAME)_%.o)
export-objs := $($(MOD_NAME)-exp-names:%=$(MOD_NAME)_%.o)

ifeq ($(KERNELMINOR_4_5),yes)

include $(KDIR)/Rules.make

$(MOD_NAME).o: $($(MOD_NAME)-objs)
$(Q)$(LD) $(LD_RFLAG) -r -o $@ $($(MOD_NAME)-objs)

endif # ifeq ($(KERNELMINOR_4_5),yes)
else # ifneq ($(KERNELRELEASE),)

all:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

clean:
# $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
rm -f $(MOD_NAME).ko *.o .*.cmd .*.o.flags $(MOD_NAME).mod.c
$(KDIR)/.tmp_versions/$(MOD_NAME).mod

endif # ifneq ($(KERNELRELEASE),)
endif # ifeq ($(KERNELMINOR_0_3),yes)
else # ifeq ($(KERNELMAJOR),2)

all:
@echo *** kernel $(KERNELVERSION) not supported
@echo please upgrade to kernel 2.4 or newer

endif #ifeq ($(KERNELMAJOR),2)

#*****************************************************************************

Regards,
Axel




2004-04-15 21:50:57

by Sam Ravnborg

[permalink] [raw]
Subject: Re: compiling external modules

On Thu, Apr 15, 2004 at 11:05:49PM +0200, Axel Weiss wrote:
> Hi,
>
> after some study of kernel Makefiles, I'm able now to compile externel modules
> for both, 2.4 and 2.6 kernels correctly. I'd like to share my Makefiles here,
> maybe somebody finds them useful.
Thanks.

> 2.6-compilation of drivers consisting of more than one module leaded to very
> ugly warnings from scripts/Makefile.modpost, when make was invoked after
> 'make clean'. The reason were lying-around objects in .tmp_versions directory
> which were not deleted by 'make clean'. Solution: clean must explicitly
> delete the version-object in .tmp_versions.
With 2.6.5-rc1 the warning are gone.

> 2.4-compilation requires inclusion of Rules.make and an additional rule for
> module-object linkage. In 2.6 Rules.make does not exist, and the linking rule
> would conflict with an already defined one. Solution: distinct current kernel
> version.
You should be able to use:
-include Rules.make

See 'info make' - look after the include directive.

> When I gave the rule:
> clean:
> $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
> the whole kernel tree was cleaned. This is not my intention, when I'm working
> on external modules and want to make clean e.g. for cvs commits. So I defined
> my own clean rule, kicking away everything but source files.
With 2.6.5-rc1 this will only cause files in the $(PWD) dir to be deleted,
not the kernel tree.

> So far the difficulties. Next I propose an assumption about filenames, when a
> module consists of several objects which will be linked together. Let
> <module-name> be a basic name for the module, so <module-name>.(k)o (with k
> for 2.6, without for 2.4) will be the final target. I assume that all
> elementary object-filenames begin with <module-name>, for clarification. E.g.
> the module adc64.ko is composed of adc64_module.o, adc64_device.o, adc64_io.o
> and so on. Generally, the name of an object is <module-name>_<object-name>.o,
> and the object-names can be collected in a symbol <module-name>-obj-names.
> Some objects may export symbols to other modules, they can be collected in a
> <module-name>-exp-names list.
I really do not see the benefit compared to the current more free
naming scheme - which works.

>
> Finally, all the modules' Makefiles were very similar, so I split them into
> two files: one Makefile for every module and a common Makefile.module which
> is included by each Makefile. Each module-specific Makefile contains the
> definition of
> - <module-name>
> - <module-name>-obj-names
> - <module-name>-exp-names
> - EXTRA_CFLAGS
> which makes up all information Makfile.module needs.

The general feedback is that it looks like you have
made it less simple than it ought to be.

You should also consider that you end up with files
that does not look like ordinary kbuild makefiles.

When I get some spare time I will try to come up with a simpler example.

Sam

2004-04-16 07:22:59

by Duncan Sands

[permalink] [raw]
Subject: Re: compiling external modules

> When I get some spare time I will try to come up with a simpler example.

Please do, that would be very helpful, especially if it works for both 2.4 and
2.6.

All the best,

Duncan.

2004-04-16 12:08:38

by Axel Weiß

[permalink] [raw]
Subject: Re: compiling external modules

Hi, Sam,

I have patched to 2.6.6-rc1 (patch-2.6.6-rc1 over kernel 2.6.5 - am I right or
am I missing some patches in between?), and now symbol exports between
modules fails. An example with two module-objects - one exports some symbols
used by the other - shows compile output:

scripts/Makefile.build:36: kbuild: /home/axel/freeSP-1.0.4/drivers/linux/
adc64/busmaster/Makefile - Usage of export-objs is obsolete in 2.6. Please
fix!

8<

*** Warning: "adc64_count" [/home/axel/freeSP-1.0.4/drivers/linux/adc64/
driver/adc64.ko] undefined!
*** Warning: "release_adc64_busmaster" [/home/axel/freeSP-1.0.4/drivers/linux/
adc64/driver/adc64.ko] undefined!
*** Warning: "get_adc64_busmaster" [/home/axel/freeSP-1.0.4/drivers/linux/
adc64/driver/adc64.ko] undefined!

8<

The first (exporting) module loads cleanly (lsmod shows the loaded module),
but insmod'ing the second fails with:

insmod: error inserting './adc64.ko': -1 Unknown symbol in module

What's the trick in 2.6.6?

Regards,
Axel

On Thursday 15 April 2004 23:59, Sam Ravnborg wrote:
> On Thu, Apr 15, 2004 at 11:05:49PM +0200, Axel Weiss wrote:
> > Hi,
> >
> > after some study of kernel Makefiles, I'm able now to compile externel
> > modules for both, 2.4 and 2.6 kernels correctly. I'd like to share my
> > Makefiles here, maybe somebody finds them useful.
>
> Thanks.
>
> > 2.6-compilation of drivers consisting of more than one module leaded to
> > very ugly warnings from scripts/Makefile.modpost, when make was invoked
> > after 'make clean'. The reason were lying-around objects in .tmp_versions
> > directory which were not deleted by 'make clean'. Solution: clean must
> > explicitly delete the version-object in .tmp_versions.
>
> With 2.6.5-rc1 the warning are gone.
>
> > 2.4-compilation requires inclusion of Rules.make and an additional rule
> > for module-object linkage. In 2.6 Rules.make does not exist, and the
> > linking rule would conflict with an already defined one. Solution:
> > distinct current kernel version.
>
> You should be able to use:
> -include Rules.make
>
> See 'info make' - look after the include directive.
>
> > When I gave the rule:
> > clean:
> > $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
> > the whole kernel tree was cleaned. This is not my intention, when I'm
> > working on external modules and want to make clean e.g. for cvs commits.
> > So I defined my own clean rule, kicking away everything but source files.
>
> With 2.6.5-rc1 this will only cause files in the $(PWD) dir to be deleted,
> not the kernel tree.
>
> > So far the difficulties. Next I propose an assumption about filenames,
> > when a module consists of several objects which will be linked together.
> > Let <module-name> be a basic name for the module, so <module-name>.(k)o
> > (with k for 2.6, without for 2.4) will be the final target. I assume that
> > all elementary object-filenames begin with <module-name>, for
> > clarification. E.g. the module adc64.ko is composed of adc64_module.o,
> > adc64_device.o, adc64_io.o and so on. Generally, the name of an object is
> > <module-name>_<object-name>.o, and the object-names can be collected in a
> > symbol <module-name>-obj-names. Some objects may export symbols to other
> > modules, they can be collected in a <module-name>-exp-names list.
>
> I really do not see the benefit compared to the current more free
> naming scheme - which works.
>
> > Finally, all the modules' Makefiles were very similar, so I split them
> > into two files: one Makefile for every module and a common
> > Makefile.module which is included by each Makefile. Each module-specific
> > Makefile contains the definition of
> > - <module-name>
> > - <module-name>-obj-names
> > - <module-name>-exp-names
> > - EXTRA_CFLAGS
> > which makes up all information Makfile.module needs.
>
> The general feedback is that it looks like you have
> made it less simple than it ought to be.
>
> You should also consider that you end up with files
> that does not look like ordinary kbuild makefiles.
>
> When I get some spare time I will try to come up with a simpler example.
>
> Sam
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

2004-04-16 12:36:43

by Axel Weiß

[permalink] [raw]
Subject: Re: compiling external modules

Hi, Sam,

excuse me (and forget my previous mail), I've found the reason for the missing
exported symbols in the C-source.

I will continue simplifying the Makefile...

Regards,
Axel

On Friday 16 April 2004 14:06, Axel Weiss wrote:
> Hi, Sam,
>
> I have patched to 2.6.6-rc1 (patch-2.6.6-rc1 over kernel 2.6.5 - am I right
> or am I missing some patches in between?), and now symbol exports between
> modules fails. An example with two module-objects - one exports some
> symbols used by the other - shows compile output:
>
> scripts/Makefile.build:36: kbuild: /home/axel/freeSP-1.0.4/drivers/linux/
> adc64/busmaster/Makefile - Usage of export-objs is obsolete in 2.6. Please
> fix!
>
> 8<
>
> *** Warning: "adc64_count" [/home/axel/freeSP-1.0.4/drivers/linux/adc64/
> driver/adc64.ko] undefined!
> *** Warning: "release_adc64_busmaster"
> [/home/axel/freeSP-1.0.4/drivers/linux/ adc64/driver/adc64.ko] undefined!
> *** Warning: "get_adc64_busmaster" [/home/axel/freeSP-1.0.4/drivers/linux/
> adc64/driver/adc64.ko] undefined!
>
> 8<
>
> The first (exporting) module loads cleanly (lsmod shows the loaded module),
> but insmod'ing the second fails with:
>
> insmod: error inserting './adc64.ko': -1 Unknown symbol in module
>
> What's the trick in 2.6.6?
>
> Regards,
> Axel
>
> On Thursday 15 April 2004 23:59, Sam Ravnborg wrote:
> > On Thu, Apr 15, 2004 at 11:05:49PM +0200, Axel Weiss wrote:
> > > Hi,
> > >
> > > after some study of kernel Makefiles, I'm able now to compile externel
> > > modules for both, 2.4 and 2.6 kernels correctly. I'd like to share my
> > > Makefiles here, maybe somebody finds them useful.
> >
> > Thanks.
> >
> > > 2.6-compilation of drivers consisting of more than one module leaded to
> > > very ugly warnings from scripts/Makefile.modpost, when make was invoked
> > > after 'make clean'. The reason were lying-around objects in
> > > .tmp_versions directory which were not deleted by 'make clean'.
> > > Solution: clean must explicitly delete the version-object in
> > > .tmp_versions.
> >
> > With 2.6.5-rc1 the warning are gone.
> >
> > > 2.4-compilation requires inclusion of Rules.make and an additional rule
> > > for module-object linkage. In 2.6 Rules.make does not exist, and the
> > > linking rule would conflict with an already defined one. Solution:
> > > distinct current kernel version.
> >
> > You should be able to use:
> > -include Rules.make
> >
> > See 'info make' - look after the include directive.
> >
> > > When I gave the rule:
> > > clean:
> > > $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
> > > the whole kernel tree was cleaned. This is not my intention, when I'm
> > > working on external modules and want to make clean e.g. for cvs
> > > commits. So I defined my own clean rule, kicking away everything but
> > > source files.
> >
> > With 2.6.5-rc1 this will only cause files in the $(PWD) dir to be
> > deleted, not the kernel tree.
> >
> > > So far the difficulties. Next I propose an assumption about filenames,
> > > when a module consists of several objects which will be linked
> > > together. Let <module-name> be a basic name for the module, so
> > > <module-name>.(k)o (with k for 2.6, without for 2.4) will be the final
> > > target. I assume that all elementary object-filenames begin with
> > > <module-name>, for
> > > clarification. E.g. the module adc64.ko is composed of adc64_module.o,
> > > adc64_device.o, adc64_io.o and so on. Generally, the name of an object
> > > is <module-name>_<object-name>.o, and the object-names can be collected
> > > in a symbol <module-name>-obj-names. Some objects may export symbols to
> > > other modules, they can be collected in a <module-name>-exp-names list.
> >
> > I really do not see the benefit compared to the current more free
> > naming scheme - which works.
> >
> > > Finally, all the modules' Makefiles were very similar, so I split them
> > > into two files: one Makefile for every module and a common
> > > Makefile.module which is included by each Makefile. Each
> > > module-specific Makefile contains the definition of
> > > - <module-name>
> > > - <module-name>-obj-names
> > > - <module-name>-exp-names
> > > - EXTRA_CFLAGS
> > > which makes up all information Makfile.module needs.
> >
> > The general feedback is that it looks like you have
> > made it less simple than it ought to be.
> >
> > You should also consider that you end up with files
> > that does not look like ordinary kbuild makefiles.
> >
> > When I get some spare time I will try to come up with a simpler example.
> >
> > Sam
> > -
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel"
> > in the body of a message to [email protected]
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at http://www.tux.org/lkml/
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

2004-04-16 15:43:15

by Axel Weiß

[permalink] [raw]
Subject: Re: compiling external modules

On Thursday 15 April 2004 23:59, Sam Ravnborg wrote:
> The general feedback is that it looks like you have
> made it less simple than it ought to be.
>
> You should also consider that you end up with files
> that does not look like ordinary kbuild makefiles.

Hi, Sam,

seems you don't like my style putting things into variables ;)

Here's my latest work, I have tested this Makefile with vanilla-2.6.5, -2.6.6-rc1 and suse-2.4.21-199 (SuSE 9.0).

Regards,
Axel

#/***************************************************************************
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU General Public License as published by *
# * the Free Software Foundation; either version 2 of the License, or *
# * (at your option) any later version. *
# * *
# ***************************************************************************/
#
# Template Makefile for external module compilation
#
# (C) 2004 by Axel Weiss ([email protected])
#

KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

K_MAJOR := $(shell uname -r | sed -e "s/\..*//")
K_MINOR := $(shell uname -r | sed -e "s/$(K_MAJOR)\.//" -e "s/\..*//")
K_REV := $(shell uname -r | sed -e "s/$(K_MAJOR)\.$(K_MINOR)\.//" -e "s/-.*//")

NEED_EXPORT := $(strip $(shell [[ "$(K_MAJOR)" = "2" \
&& "$(K_MINOR)" < "7" \
&& "$(K_REV)" < "6" ]] && echo yes || echo no))

NEED_CLEAN := $(strip $(shell [[ "$(K_MAJOR)" = "2" \
&& "$(K_MINOR)" < "7" \
&& "$(K_REV)" < "6" ]] && echo yes))

.PHONY: all clean


ifneq ($(KERNELRELEASE),)

obj-m := <mod-name>.o
<mod-name>-objs := <mod-object-list>
ifeq ($(NEED_EXPORT),yes)
export-objs := <mod-export-list>
endif # ifeq ($(NEED_EXPORT),yes)

-include $(KDIR)/Rules.make

<mod-name>.o: $(<mod-name>-objs)
$(Q)$(LD) $(LD_RFLAG) -r -o $@ $(<mod-name>-objs)


else # ifneq ($(KERNELRELEASE),)

all:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

clean:
ifeq ($(NEED_CLEAN),yes)
rm -f <mod-name>.ko *.o .*.cmd .*.o.flags <mod-name>.mod.c $(KDIR)/.tmp_versions/<mod-name>.mod
else
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
endif # ifeq ($(NEED_CLEAN),yes)
endif # ifneq ($(KERNELRELEASE),)


2004-04-16 16:45:57

by Sam Ravnborg

[permalink] [raw]
Subject: Re: compiling external modules

On Fri, Apr 16, 2004 at 05:41:07PM +0200, Axel Weiss wrote:
> On Thursday 15 April 2004 23:59, Sam Ravnborg wrote:
> > The general feedback is that it looks like you have
> > made it less simple than it ought to be.
> >
> > You should also consider that you end up with files
> > that does not look like ordinary kbuild makefiles.
>
> Hi, Sam,
>
> seems you don't like my style putting things into variables ;)
>
> Here's my latest work, I have tested this Makefile with vanilla-2.6.5, -2.6.6-rc1 and suse-2.4.21-199 (SuSE 9.0).
>
> Regards,
> Axel
>
> #/***************************************************************************
> # * *
> # * This program is free software; you can redistribute it and/or modify *
> # * it under the terms of the GNU General Public License as published by *
> # * the Free Software Foundation; either version 2 of the License, or *
> # * (at your option) any later version. *
> # * *
> # ***************************************************************************/
> #
> # Template Makefile for external module compilation
> #
> # (C) 2004 by Axel Weiss ([email protected])
> #
>
> KDIR := /lib/modules/$(shell uname -r)/build
> PWD := $(shell pwd)
>
> K_MAJOR := $(shell uname -r | sed -e "s/\..*//")
> K_MINOR := $(shell uname -r | sed -e "s/$(K_MAJOR)\.//" -e "s/\..*//")
> K_REV := $(shell uname -r | sed -e "s/$(K_MAJOR)\.$(K_MINOR)\.//" -e "s/-.*//")
>
> NEED_EXPORT := $(strip $(shell [[ "$(K_MAJOR)" = "2" \
> && "$(K_MINOR)" < "7" \
> && "$(K_REV)" < "6" ]] && echo yes || echo no))
>
> NEED_CLEAN := $(strip $(shell [[ "$(K_MAJOR)" = "2" \
> && "$(K_MINOR)" < "7" \
> && "$(K_REV)" < "6" ]] && echo yes))

What about testing for the precense of Rules.make.
If present we know it is 2.4, if not it's 2.6.

Something like:
KERNEL_26 := $(if $(wildcard $(TOPDIR)/Rules.make),0,1)
Much simpler than all the above.

Then your test would look like this:

ifeq ($(KERNEL_26),0)

export-objs := <mod-export-list>

include $(KDIR)/Rules.make

<mod-name>.o: $(<mod-name>-objs)
$(Q)$(LD) $(LD_RFLAG) -r -o $@ $(<mod-name>-objs)
endif


And later:

> else # ifneq ($(KERNELRELEASE),)

ifeq ($(KERNEL_26),1)

all:
$(MAKE) -C $(KDIR) M=$(PWD)
%:
$(MAKE) -C $(KDIR) M=$(PWD) $@

else

clean:
rm -f <mod-name>.ko *.o .*.cmd .*.o.flags <mod-name>.mod.c


Care to try mix something working out of these clues.

Thanks,
Sam

2004-04-16 16:47:30

by Sam Ravnborg

[permalink] [raw]
Subject: Re: compiling external modules

On Fri, Apr 16, 2004 at 02:06:17PM +0200, Axel Weiss wrote:
>
> *** Warning: "adc64_count" [/home/axel/freeSP-1.0.4/drivers/linux/adc64/
> driver/adc64.ko] undefined!
> *** Warning: "release_adc64_busmaster" [/home/axel/freeSP-1.0.4/drivers/linux/
> adc64/driver/adc64.ko] undefined!
> *** Warning: "get_adc64_busmaster" [/home/axel/freeSP-1.0.4/drivers/linux/
> adc64/driver/adc64.ko] undefined!

modpost was fixed to actually report undefined symbols.
Previously this was only done during modules_install - so much earlier
warning.

Sam

2004-04-16 20:15:24

by Axel Weiß

[permalink] [raw]
Subject: Re: compiling external modules

Am Freitag, 16. April 2004 18:54 schrieb Sam Ravnborg:
> On Fri, Apr 16, 2004 at 05:41:07PM +0200, Axel Weiss wrote:
> What about testing for the precense of Rules.make.
> If present we know it is 2.4, if not it's 2.6.
>
> Something like:
> KERNEL_26 := $(if $(wildcard $(TOPDIR)/Rules.make),0,1)
> Much simpler than all the above.

Sure, but compilation with 2.6.5 would fail again, missing export-objs.
If I got you right, we should simplify things so that 2.6 means >= 2.6.6?

So, the following is tested on 2.6.6-rc1 and suse-2.4.21-199:

# Template Makefile for external module compilation

KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
KERNEL_24 := $(if $(wildcard $(KDIR)/Rules.make),1,0)

ifneq ($(KERNELRELEASE),)

obj-m := <mod-name>.o
<mod-name>-objs := <mod-object-list>

endif # ifneq ($(KERNELRELEASE),)

.PHONY: all clean

ifeq ($(KERNEL_24),1)
ifneq ($(KERNELRELEASE),)

export-objs := <mod-export-list>

include $(KDIR)/Rules.make
adc64_bm.o: $(<mod-name>-objs)
$(Q)$(LD) $(LD_RFLAG) -r -o $@ $(<mod-name>-objs)
else # ifneq ($(KERNELRELEASE),)
all:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -f *.ko *.o .*.cmd .*.o.flags *.mod.c
endif # ifneq ($(KERNELRELEASE),)

else #################### ifeq ($(KERNEL_24),1)

ifeq ($(KERNELRELEASE),)
all:
$(MAKE) -C $(KDIR) M=$(PWD)
clean:
$(MAKE) -C $(KDIR) M=$(PWD) $@
endif # ifeq ($(KERNELRELEASE),)

endif #################### ifeq ($(KERNEL_24),1)

# end of Makefile Template

I reordered the cases a bit so that
1. kernel-version dependend branches stay together
2. <mod-object-list> needs only be written once

Now everything fits on a single screen-page :)

Sam, please note two things:
1. the clean rule must be explicit to be recognized (GNU Make 3.80).
2. 2.6 compilation requires root privileges for compilation, 2.4 does not.
Can we relax some file accesses (e.g. $(KDIR)/.__modpost.cmd and the
local .tmp_versions) to allow non-privileged users to compile external
modules and to be able to make clean?

Regards,
Axel


2004-04-16 20:44:55

by Sam Ravnborg

[permalink] [raw]
Subject: Re: compiling external modules

On Fri, Apr 16, 2004 at 10:09:56PM +0200, Axel Weiss wrote:
>
> Sure, but compilation with 2.6.5 would fail again, missing export-objs.
export-objs has not been needed by 2.6.*, only during earlier 2.5.*

> If I got you right, we should simplify things so that 2.6 means >= 2.6.6?
Yup.

> # Template Makefile for external module compilation
>
> KDIR := /lib/modules/$(shell uname -r)/build
> PWD := $(shell pwd)
> KERNEL_24 := $(if $(wildcard $(KDIR)/Rules.make),1,0)
>


> ifneq ($(KERNELRELEASE),)
>
> obj-m := <mod-name>.o
> <mod-name>-objs := <mod-object-list>
>
> endif # ifneq ($(KERNELRELEASE),)
I do not see why you need to wrap this in KERNELRELEASE.


> .PHONY: all clean
>
> ifeq ($(KERNEL_24),1)

Hide the backward compatibility stuff in the bottom (= 2.4 stuff).
Just MO.

> ifneq ($(KERNELRELEASE),)
>
> export-objs := <mod-export-list>
>
> include $(KDIR)/Rules.make
> adc64_bm.o: $(<mod-name>-objs)
> $(Q)$(LD) $(LD_RFLAG) -r -o $@ $(<mod-name>-objs)
> else # ifneq ($(KERNELRELEASE),)
> all:
> $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
> clean:
> rm -f *.ko *.o .*.cmd .*.o.flags *.mod.c
> endif # ifneq ($(KERNELRELEASE),)
>
> else #################### ifeq ($(KERNEL_24),1)
>
> ifeq ($(KERNELRELEASE),)
> all:
> $(MAKE) -C $(KDIR) M=$(PWD)
> clean:
Here you should add modules_install also.

> $(MAKE) -C $(KDIR) M=$(PWD) $@
> endif # ifeq ($(KERNELRELEASE),)
>
> endif #################### ifeq ($(KERNEL_24),1)
>
> # end of Makefile Template
>
> I reordered the cases a bit so that
> 1. kernel-version dependend branches stay together
> 2. <mod-object-list> needs only be written once
>
> Now everything fits on a single screen-page :)
Good!

>
> Sam, please note two things:
> 1. the clean rule must be explicit to be recognized (GNU Make 3.80).
I had some problems with this, but I do not remeber how i solved it.


> 2. 2.6 compilation requires root privileges for compilation, 2.4 does not.
I never ever compile as root - so something is broken here.

> Can we relax some file accesses (e.g. $(KDIR)/.__modpost.cmd and the
> local .tmp_versions) to allow non-privileged users to compile external
> modules and to be able to make clean?
I do not have a file named .__modpost.cmd???
And root should not be required??

Sam

2004-04-16 20:57:07

by Sam Ravnborg

[permalink] [raw]
Subject: Re: compiling external modules

> I do not have a file named .__modpost.cmd???

Because I did not have CONFIG_MODVERSIONS enabled - sory.
But I see no problem?

Sam

2004-04-16 23:26:43

by Axel Weiß

[permalink] [raw]
Subject: Re: compiling external modules

On Friday 16 April 2004 22:51, Sam Ravnborg wrote:
> On Fri, Apr 16, 2004 at 10:09:56PM +0200, Axel Weiss wrote:
> > 2. 2.6 compilation requires root privileges for compilation, 2.4 does
> > not.
>
> I never ever compile as root - so something is broken here.

Oh, yes! This is the old weird thing! SuSE uses to install kernel sources
in /usr/src, and I blindly followed :( fixed now :).

So, finally, we have a nice Makefile suitable for 2.4 and 2.6 (>= 2.6.6) kernels:

#/***************************************************************************
# * ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? *
# * ? This program is free software; you can redistribute it and/or modify ?*
# * ? it under the terms of the GNU General Public License as published by ?*
# * ? the Free Software Foundation; either version 2 of the License, or ? ? *
# * ? (at your option) any later version. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? *
# * ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? *
# ***************************************************************************/
#
# ?(C) 2004 by Axel Weiss ([email protected])
#
#
# ?Template Makefile for external module compilation
#
# replace <mod-name> with the prefix of the target module
# replace <mod-object-list> with the list of object files to be linked together
# replace <mod-export-list> with all symbol-exporting object filenames
# additionally specify EXTRA_CFLAGS, if needed
#

KDIR ? ? ?:= /lib/modules/$(shell uname -r)/build
PWD ? ? ? := $(shell pwd)
KERNEL_24 := $(if $(wildcard $(KDIR)/Rules.make),1,0)

obj-m ? ? ? ? ? := <mod-name>.o
<mod-name>-objs := <mod-object-list>

.PHONY: all clean modules_install

ifeq ($(KERNEL_24),0)
ifeq ($(KERNELRELEASE),)
all:
$(MAKE) -C $(KDIR) M=$(PWD)
clean modules_install:
$(MAKE) -C $(KDIR) M=$(PWD) $@
endif # ifeq ($(KERNELRELEASE),)

else ?### ifeq ($(KERNEL_24),0)

ifneq ($(KERNELRELEASE),)

export-objs := <mod-export-list>

include $(KDIR)/Rules.make
adc64_bm.o: $(<mod-name>-objs)
$(Q)$(LD) $(LD_RFLAG) -r -o $@ $(<mod-name>-objs)
else ?# ifneq ($(KERNELRELEASE),)
all:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
modules_install:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $@
clean:
rm -f *.ko *.o .*.cmd .*.o.flags *.mod.c
endif # ifneq ($(KERNELRELEASE),)
endif ### ifeq ($(KERNEL_24),0)
# end of Makefile Template

Regards, thanks for your helpful advice and

have a nice weekend,

Axel