views:

1586

answers:

9

While compiling Linux kernel modules that depend on each other, linker gives undefined symbol warnings like

 Building modules, stage 2.
 MODPOST
*** Warning: "function_name1" [module_name] undefined!
*** Warning: "function_name2" [module_name] undefined!
*** Warning: "function_name3" [module_name] undefined!

The unresolved symbols are resolved as soon as module is inserted into kernel using insmod or modprobe. Is there any way to get rid of the linker warning, though?

I have read through 3 Google SERP's on this issue - it seems nobody knows the answer. Are these linker warnings supposed to be this way when you build a kernel module?

+1  A: 

No they are not. Wheter you build your code in-tree or out of tree, this message should not be displayed.I think you should fix your Makefile. Here is an example makefile. Not perfect, but used to work (until 2.6.26, did not try it since) :

ifneq ($(KERNELRELEASE),)
# We were called by kbuild

obj-m += mymodule.o 
mymodule-objs := mymodule_usb.o a.o b.o c.o

else  # We were called from command line

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

default:
    @echo '    Building FOO drivers for 2.6 kernel.'
    @echo '    PLEASE IGNORE THE "Overriding SUBDIRS" WARNING'
    $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

install:
    ./do_install.sh *.ko

endif  # End kbuild check

clean:
    rm -f -r *.o *.ko .*cmd .tmp* core *.i

For further documentation, you can check the kernel tree, the kbuild process is documented

shodanex
Thanks for the answer. Any idea how exactly?
Gary
I'm sorry, but it doesn't really work. The warnings are still there.Also, the @echo ' PLEASE IGNORE THE "Overriding SUBDIRS" WARNING' troubles me. I could use the same approach to echo 'PLEASE IGNORE the [module_name] undefined!' warning, but obviously this is not the way I'm looking for.
Gary
A: 

Any other ideas?

Gary
A: 

I'll be honest - they drive me crazy, too, but we just filter them out of the our make output. If someone does have a "correct" answer, though, I'd love to hear it.

Mike Heinz
+4  A: 

Finally, I got it. Thanks to shodanex for putting me on the right track.

Update: Be very careful when applying this fix to builds for older versions of kernel, as there is a bug in Makefile.modpost file in older versions of the kernel which makes your build misbehave and build wrong targets when you specify KBUILD_EXTMOD option.

You have to specify the paths to the source of the modules you depend on in KBUILD_EXTMOD make parameter.

Say, you have a module foo that depends on symbols from module bar.

Source files for foo are in foo/module/ and source files for bar are in bar/module/

The make command in Makefile for foo probably looks like

make ARCH=$$ARCH CROSS_COMPILE=$$CROSS_COMPILE -C $$LINUX_DIR \
 M=`pwd`/module \
 modules

(the exact line may differ in your project).

Change it to

make ARCH=$$ARCH CROSS_COMPILE=$$CROSS_COMPILE -C $$LINUX_DIR \
 M=`pwd`/module \
 KBUILD_EXTMOD=`pwd`/../bar/module \
 modules

(we added the KBUILD_EXTMOD=pwd/../bar/module \ line, where pwd/../bar/module is a path to sources of kernel module we depend on.

One would expect KBUILD_EXTRA_SYMBOLS parameter to work this way, however it's KBUILD_EXTMOD.

Gary
from which version of linux does this start to work? i tried to use this method on 2.6.12 kernel building external modules, but to no avail, it only build to bar modules, totally ignore the foo module, any help?
andycjw
A: 

My need to be tailored to your tree. In our source we created a SYMBOLSDIR that is a path to all the modules

SYMBOLSDIR = 'some path'

make (same as above example) $(KERNELDIR) MODVERDIR=$(SYMBOLSDIR) modules

A: 

on my case, using MODVEDIR will remove the depended module. so, there's any idea how to resolve this problem ??

sfog
A: 

using KBUILD_EXTMOD on my case, just compile the foo modules, and not bar

sfog
+1  A: 

Use KBUILD_EXTRA_SYMBOLS as below: KBUILD_EXTRA_SYMBOLS='your module path'/Module.symvers

sinoj
A: 

Related to the above technique of using KBUILD_EXTMOD, and the question of which kernel versions it works under:

  • andycjw indicated it didn't work for him in 2.6.12
  • It didn't work for me in 2.6.15 (broke my module build)
  • Looking through the kernel commits, I see a number of changes to Makefile.modpost that seem related in 2.6.26 and 2.6.28, so I expect one of those is the limit.
odinguru