Click to See Complete Forum and Search --> : Problem with -lm and complex.h


pecenin
07-14-2005, 11:23 AM
Hello,

I'm writing a simple 2.6.7 kernel module that use complex.h (cexp, cimag, creal, etc...). It compile correct, see below:

--------------
make -C /usr/src/linux SUBDIRS=/home/pecenin/modulo modules
make[1]: Entering directory `/usr/src/linux-2.6.7'
CC [M] /home/pecenin/modulo/mat.o
CC [M] /home/pecenin/modulo/modu.o
LD [M] /home/pecenin/modulo/modcalc.o
Building modules, stage 2.
MODPOST
CC /home/pecenin/modulo/modcalc.mod.o
LD [M] /home/pecenin/modulo/modcalc.ko
make[1]: Leaving directory `/usr/src/linux-2.6.7'
----------------

but when I load with 'insmod modcalc.ko' I get, from 'dmesg':

----------
modcalc: Unknown symbol __fixdfsi
modcalc: Unknown symbol cexp
----------

The makefile used is:

-------------
EXTRA_CFLAGS := -I$(src) -I/usr/include
EXTRA_LDFLAGS := -L/usr/lib --start-group -lm --end-group

obj-m := modcalc.o
modcalc-objs := mat.o modu.o

KDIR := /usr/src/linux
LDIR := $(PWD)

all:
make -C $(KDIR) SUBDIRS=$(LDIR) modules

clean:
rm -rf *.o *.ko *.mod.o *.mod.c
-------------

and the source code:

----------- mat.c ----------
#include <mat.h>
#include <complex.h>

int valor = 0;

int calculo(void)
{
valor = (int)creal(cexp(0));
return ++valor;
}
-----------------
--------- mat.h ----------
#ifndef MAT_H
#define MAT_H

extern int valor;

int calculo(void);

#endif
---------------------
---------- modu.c ------
#include <mat.h>
#include <linux/module.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");

int __init modu_init(void)
{
int x = 1;

printk("<0>Carregou\n");
x = calculo();
return x - x;
}

void __exit modu_cleanup(void)
{
printk("<0>Descarregou\n");
}

module_init(modu_init);
module_exit(modu_cleanup);
----------

Someone know what I'm doing wrong?

All helps will be appreciated!

Pecenin

bwkaz
07-14-2005, 06:13 PM
Kernel code can't call into userspace libraries (libc, libm, or libanything-else).

If you need some functions in the kernel, then you have to either write them yourself (you can sometimes copy from the library in question, but the license on the kernel and the library would have to be compatible), or redo your design, moving the stuff that needs libm to userspace.

FWIW, if you ever try to get this into the "official" kernel, I would say the odds are about 1 in 100 that they'll let you implement functions from libm inside the kernel. And if there's a fairly obvious way to split your module up into kernel and userspace parts (keeping the libm stuff in userspace), then the chances are just about nil that it'll end up in the kernel.

(Plus, kernel modules don't get fully-linked like a userspace program does. Your EXTRA_LDFLAGS stuff probably won't even be used by the linker, because of the way kbuild runs it. But if it is used, then your references will still be unresolved at runtime, because only symbols inside the kernel can be referenced by modules.)