2016-08-12 7 views
1

У меня есть файл makefile, который использует флаг -lm для включения математической библиотеки. Я также включил #include для каждого .c файла. Я по-прежнему получаю ошибку и «неопределенную ссылку» на математику, такую ​​как exp, floor и pow и т. Д.Проблема с gcc на Ubuntu Bash на окнах с математической библиотекой

Использование bash на окнах Ubuntu.

Копия моего вывода терминала:

[email protected]:~/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 

Но, когда я делаю пример программы, например, следующим образом: test.c

#include <stdio.h> 
#include <math.h> 

int main(void) 
{ 
    int number; 
    number = pow(10,2); 
    printf("%d\n", number); 
    return 0; 
} 

я могу использовать GCC test.c даже без -lm, и он отлично компилируется.

Это ошибка?

+1

Установите флаг после всех объектов, которые вы связываете – FreeStyle4

+0

Установите флажок [\ [this \]] (http://stackoverflow.com/q/ 19508136/1620779) подобный вопрос. – sjsam

+0

@cxw флаг '-lm' бесполезен в вашей командной строке, которая является линией компиляции BTW. –

ответ

1

В тестовом случае, так как все данные постоянно, кажется, компилятор вычисляет непосредственно значение (это может зависеть от компилятора, но последние версии GCC, кажется, справиться с этим штрафом)

При разборке кода (x86) мы видим ясно

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> 

прямой 100 значение, передаваемое PRINTF на линии ниже

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 

я изменил код так:

#include <stdio.h> 
#include <math.h> 

int main(void) 
{ 
    int number; 
    int v=10; 
    number = pow(v,2); 
    printf("%d\n", number); 
    return 0; 
} 

И теперь, когда я нм файл я получаю:

>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 

Прежде чем я ввел переменную, то pow символ не ссылается. Компилятор сделал математически статически.

Разборка показывает более сложный код, используя регистры с плавающей точкой и все.

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 

Но к моему удивлению, нет необходимости в -lm, она связывает OK без него. Новые версии gcc должны включать его по умолчанию, поскольку он часто используется. Может быть, кто-то может подтвердить. Вам, похоже, нужна эта версия, у меня нет (gcc 4.9.4)