Reputation: 79
I have a makefile that uses "-lm" flag to include the math library. I also included #include for each .c file. I am still getting error and "undefined reference" to the math such as exp, floor, and pow etc.
Using bash on windows Ubuntu.
Copy of my terminal output:
labyu@DESKTOP-U037B9F:~/software/BICseq2/NBICseq-norm_v0.2.4$ make
gcc -g -O2 -Wall -lm -c -o combineFile/combine.o combineFile/combine.c
gcc -g -O2 -Wall -lm -c -o lib/read.o lib/read.c
lib/read.c: In function ‘read_table’:
lib/read.c:74:14: warning: variable ‘flag’ set but not used [-Wunused-but-set-variable]
int i=0,j=0,flag=1,low_mmry = 40000, is_num=0,k;
^
gcc -g -O2 -Wall -lm combineFile/combine.o lib/read.o -o combineFile/combineFile
gcc -g -O2 -Wall -lm -c -o DataPrepare/DtaPrep.o DataPrepare/DtaPrep.c
gcc -g -O2 -Wall -lm -c -o lib/statlib.o lib/statlib.c
gcc -g -O2 -Wall -lm DataPrepare/DtaPrep.o lib/read.o lib/statlib.o -o DataPrepare/PrepPois
DataPrepare/DtaPrep.o: In function `print_oneline':
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/DataPrepare/DtaPrep.c:593: undefined reference to `pow'
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/DataPrepare/DtaPrep.c:591: undefined reference to `log'
DataPrepare/DtaPrep.o: In function `calculate_bias':
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/DataPrepare/DtaPrep.c:685: undefined reference to `pow'
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/DataPrepare/DtaPrep.c:690: undefined reference to `exp'
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/DataPrepare/DtaPrep.c:681: undefined reference to `log'
DataPrepare/DtaPrep.o: In function `fprint_gc_bin':
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/DataPrepare/DtaPrep.c:810: undefined reference to `floor'
DataPrepare/DtaPrep.o: In function `fprintf_predicted':
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/DataPrepare/DtaPrep.c:850: undefined reference to `exp'
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/DataPrepare/DtaPrep.c:860: undefined reference to `floor'
DataPrepare/DtaPrep.o: In function `calculate_bias':
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/DataPrepare/DtaPrep.c:749: undefined reference to `exp'
lib/statlib.o: In function `db_shuffle':
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/lib/statlib.c:56: undefined reference to `floor'
lib/statlib.o: In function `db_shuffle_int':
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/lib/statlib.c:71: undefined reference to `floor'
lib/statlib.o: In function `rgamma1':
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/lib/statlib.c:99: undefined reference to `log'
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/lib/statlib.c:100: undefined reference to `pow'
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/lib/statlib.c:103: undefined reference to `pow'
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/lib/statlib.c:104: undefined reference to `exp'
/home/labyu/software/BICseq2/NBICseq-norm_v0.2.4/lib/statlib.c:90: undefined reference to `log'
collect2: error: ld returned 1 exit status
make: *** [PrepPois] Error 1
But, when I make a sample program, such as this: test.c
#include <stdio.h>
#include <math.h>
int main(void)
{
int number;
number = pow(10,2);
printf("%d\n", number);
return 0;
}
I can use gcc test.c even without the -lm flag and it compiles fine.
Is this a bug?
Upvotes: 1
Views: 1295
Reputation: 140226
In your test case, since all data is constant, it seems the compiler computes directly the value (it may depend on the compiler, but recent versions of gcc seem to handle this fine)
When disassembling the code (x86) we see it clearly
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 30 sub $0x30,%rsp
8: e8 00 00 00 00 callq d <main+0xd>
direct 100 value passed to printf at the line below
d: c7 45 fc 64 00 00 00 movl $0x64,-0x4(%rbp)
14: 8b 45 fc mov -0x4(%rbp),%eax
17: 89 c2 mov %eax,%edx
19: 48 8d 0d 00 00 00 00 lea 0x0(%rip),%rcx # 20 <main+0x20>
20: e8 00 00 00 00 callq 25 <main+0x25>
25: b8 00 00 00 00 mov $0x0,%eax
2a: 90 nop
2b: 48 83 c4 30 add $0x30,%rsp
2f: 5d pop %rbp
30: c3 retq
31: 90 nop
i have changed the code to this:
#include <stdio.h>
#include <math.h>
int main(void)
{
int number;
int v=10;
number = pow(v,2);
printf("%d\n", number);
return 0;
}
And now when I nm the file I get:
>nm simplemath.o
0000000000000000 b .bss
0000000000000000 d .data
0000000000000000 p .pdata
0000000000000000 r .rdata
0000000000000000 r .rdata$zzz
0000000000000000 t .text
0000000000000000 r .xdata
U __main
0000000000000000 T main
U pow
U printf
Before I introduced the variable, the pow
symbol was not referenced. The compiler did the math statically.
The disassembly shows a more complex code, using float registers and all.
0000000000000000 <main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 40 sub $0x40,%rsp
8: e8 00 00 00 00 callq d <main+0xd>
d: c7 45 fc 0a 00 00 00 movl $0xa,-0x4(%rbp)
14: 66 0f ef c0 pxor %xmm0,%xmm0
18: f2 0f 2a 45 fc cvtsi2sdl -0x4(%rbp),%xmm0
1d: 48 b8 00 00 00 00 00 movabs $0x4000000000000000,%rax
24: 00 00 40
27: 48 89 45 e8 mov %rax,-0x18(%rbp)
2b: f2 0f 10 4d e8 movsd -0x18(%rbp),%xmm1
30: e8 00 00 00 00 callq 35 <main+0x35> <== the linker wil add the call to pow here
35: f2 0f 2c c0 cvttsd2si %xmm0,%eax
39: 89 45 f8 mov %eax,-0x8(%rbp)
3c: 8b 45 f8 mov -0x8(%rbp),%eax
3f: 89 c2 mov %eax,%edx
41: 48 8d 0d 00 00 00 00 lea 0x0(%rip),%rcx # 48 <main+0x48>
48: e8 00 00 00 00 callq 4d <main+0x4d>
4d: b8 00 00 00 00 mov $0x0,%eax
52: 90 nop
53: 48 83 c4 40 add $0x40,%rsp
57: 5d pop %rbp
58: c3 retq
But to my surprise, no need of -lm
, it links OK without it.
Newest gcc versions must include it by default since it's often used. Maybe someone can confirm. You version seems to need it, mine doesn't (gcc 4.9.4)
Upvotes: 1