Undefined link to "only some math.h functions"

I have a strange problem.

Math libraries have been added to my makefile.

# include standard C library LDFLAGS += -lc # include standard math library LDFLAGS += -lm 

and in the output file (.map) I see that everything was correctly connected:

 LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/nof\libgcc.a LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/../../../../powerpc-eabi/lib/nof\libc.a LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/../../../../powerpc-eabi/lib/nof\libm.a 

when i do

 z = pow((double) 2, (double) 3); 

It works great. But if I test another function, for example:

 double result = asin(x); 

I will get:

 undefined reference to `asin' collect2: ld returned 1 exit status 

How can it be? as pow and asin are available in math.h , see below:

 /* Non reentrant ANSI C functions. */ #ifndef _REENT_ONLY #ifndef __math_6881 extern double acos _PARAMS((double)); extern double asin _PARAMS((double)); extern double atan2 _PARAMS((double, double)); extern double cosh _PARAMS((double)); extern double sinh _PARAMS((double)); extern double exp _PARAMS((double)); extern double ldexp _PARAMS((double, int)); extern double log _PARAMS((double)); extern double log10 _PARAMS((double)); extern double pow _PARAMS((double, double)); extern double sqrt _PARAMS((double)); extern double fmod _PARAMS((double, double)); #endif /* ! defined (__math_68881) */ #endif /* ! defined (_REENT_ONLY) */ 

how can one work and the other with the linker problem? If I run -nm on libm.a , I get the following result: (sorry for the huge output, I just copied sections with the word sin )

 lib_a-e_asin.o: U __adddf3 U __divdf3 U __gtdf2 00000000 T __ieee754_asin U __ieee754_sqrt U __muldf3 U __subdf3 U fabs lib_a-e_j0.o: U __adddf3 U __divdf3 U __gtdf2 00000470 T __ieee754_j0 U __ieee754_log U __ieee754_sqrt 000009b8 T __ieee754_y0 U __ltdf2 U __muldf3 U __subdf3 U cos U fabs 000000b0 r pR2 00000108 r pR3 00000058 r pR5 00000000 r pR8 000000e0 r pS2 00000138 r pS3 00000088 r pS5 00000030 r pS8 00000004 t pzero 00000220 r qR2 00000280 r qR3 000001c0 r qR5 00000160 r qR8 00000250 r qS2 000002b0 r qS3 000001f0 r qS5 00000190 r qS8 00000218 t qzero U sin lib_a-e_j1.o: U __adddf3 U __divdf3 U __gtdf2 00000470 T __ieee754_j1 U __ieee754_log U __ieee754_sqrt 00000950 T __ieee754_y1 U __muldf3 U __subdf3 U cos U fabs 00000004 t pone 000000b0 r pr2 00000108 r pr3 00000058 r pr5 00000000 r pr8 000000e0 r ps2 00000138 r ps3 00000088 r ps5 00000030 r ps8 00000218 t qone 00000220 r qr2 00000280 r qr3 000001c0 r qr5 00000160 r qr8 00000250 r qs2 000002b0 r qs3 000001f0 r qs5 00000190 r qs8 U sin lib_a-e_jn.o: U __adddf3 U __divdf3 U __floatsidf U __gedf2 U __gtdf2 U __ieee754_j0 U __ieee754_j1 00000434 T __ieee754_jn U __ieee754_log U __ieee754_sqrt U __ieee754_y0 U __ieee754_y1 00000000 T __ieee754_yn U __ltdf2 U __muldf3 U __subdf3 U cos U fabs U sin lib_a-e_sinh.o: U __adddf3 U __divdf3 U __gtdf2 U __ieee754_exp 00000000 T __ieee754_sinh U __muldf3 U __subdf3 U expm1 U fabs lib_a-ef_asin.o: U __addsf3 U __divsf3 U __gtsf2 00000000 T __ieee754_asinf U __ieee754_sqrtf U __mulsf3 U __subsf3 U fabsf lib_a-ef_j0.o: U __addsf3 U __divsf3 U __gtsf2 0000035c T __ieee754_j0f U __ieee754_logf U __ieee754_sqrtf 000006cc T __ieee754_y0f U __ltsf2 U __mulsf3 U __subsf3 U cosf U fabsf 00000058 r pR2 00000084 r pR3 0000002c r pR5 00000000 r pR8 00000070 r pS2 0000009c r pS3 00000044 r pS5 00000018 r pS8 00000004 t pzerof 00000110 r qR2 00000140 r qR3 000000e0 r qR5 000000b0 r qR8 00000128 r qS2 00000158 r qS3 000000f8 r qS5 000000c8 r qS8 000001a0 t qzerof U sinf lib_a-ef_j1.o: U __addsf3 U __divsf3 U __gtsf2 0000031c T __ieee754_j1f U __ieee754_logf U __ieee754_sqrtf 0000062c T __ieee754_y1f U __mulsf3 U __subsf3 U cosf U fabsf 00000004 t ponef 00000058 r pr2 00000084 r pr3 0000002c r pr5 00000000 r pr8 00000070 r ps2 0000009c r ps3 00000044 r ps5 00000018 r ps8 000001a0 t qonef 000000b0 r qr2 000000e0 r qr8 000000c8 r qs2 000000f8 r qs8 U sinf lib_a-ef_sinh.o: U __addsf3 U __divsf3 U __gtsf2 U __ieee754_expf 00000000 T __ieee754_sinhf U __mulsf3 U __subsf3 U expm1f U fabsf lib_a-er_lgamma.o: U __adddf3 U __divdf3 U __eqdf2 U __fixdfsi U __floatsidf 00000004 T __ieee754_lgamma_r U __ieee754_log U __kernel_cos U __kernel_sin U __ltdf2 U __muldf3 U __nedf2 U __subdf3 U fabs U floor lib_a-erf_lgamma.o: U __addsf3 U __divsf3 U __eqsf2 U __fixsfsi U __floatsisf 00000004 T __ieee754_lgammaf_r U __ieee754_logf U __kernel_cosf U __kernel_sinf U __ltsf2 U __mulsf3 U __nesf2 U __subsf3 U fabsf U floorf lib_a-k_sin.o: U __adddf3 U __fixdfsi 00000000 T __kernel_sin U __muldf3 U __subdf3 lib_a-kf_sin.o: U __addsf3 U __fixsfsi 00000000 T __kernel_sinf U __mulsf3 U __subsf3 lib_a-s_asinh.o: U __adddf3 U __divdf3 U __gtdf2 U __ieee754_log U __ieee754_sqrt U __muldf3 00000000 T asinh U fabs U log1p lib_a-s_cos.o: U __ieee754_rem_pio2 U __kernel_cos U __kernel_sin U __subdf3 00000000 T cos lib_a-s_isinf.o: 00000000 T isinf lib_a-s_isinfd.o: 00000000 T __isinfd lib_a-s_sin.o: U __ieee754_rem_pio2 U __kernel_cos U __kernel_sin U __subdf3 00000000 T sin lib_a-sf_asinh.o: U __addsf3 U __divsf3 U __gtsf2 U __ieee754_logf U __ieee754_sqrtf U __mulsf3 00000000 T asinhf U fabsf U log1pf lib_a-sf_cos.o: U __ieee754_rem_pio2f U __kernel_cosf U __kernel_sinf U __subsf3 00000000 T cosf lib_a-sf_isinf.o: 00000000 T isinff lib_a-sf_isinff.o: 00000000 T __isinff lib_a-sf_sin.o: U __ieee754_rem_pio2f U __kernel_cosf U __kernel_sinf U __subsf3 00000000 T sinf lib_a-w_asin.o: U __errno U __fdlib_version U __gtdf2 U __ieee754_asin U __isnand 00000004 T asin U fabs U matherr U nan lib_a-w_sincos.o: U cos U sin 00000000 T sincos lib_a-w_sinh.o: U __errno U __fdlib_version U __gtdf2 U __ieee754_sinh U finite U matherr 00000004 T sinh lib_a-wf_asin.o: U __errno U __extendsfdf2 U __fdlib_version U __gtsf2 U __ieee754_asinf U __truncdfsf2 00000004 T asinf U fabsf U isnanf U matherr U nan lib_a-wf_sincos.o: U cosf 00000000 T sincosf U sinf lib_a-wf_sinh.o: U __errno U __extendsfdf2 U __fdlib_version U __gtsf2 U __ieee754_sinhf U __truncdfsf2 U finitef U matherr 00000004 T sinhf 

EDIT1: I tested a few more, and the problem is the following (not what I originally stated above):

 double aa; double bb = 1.0; double cc; aa = sin(1.0); cc = sin (bb); 

What happens when I try to build is that I get the "undefined" link on the last line, which means that when I use constants, this is fine, but when I pass the variables to sin functions, they will not be connected. I also tested many other math functions and I will get the same problem with the linker. As soon as I pass the variable into a mathematical function, I can no longer bind it. any ideas?

+8
c gcc math embedded newlib
source share
4 answers

The component does not complain about pow((double) 2, (double) 3) , because the compiler replaces it with a constant of 8.0 . You should not depend on this behavior; instead, you should always use the -lm option. (BTW, which is more clearly identified as pow(2.0, 3.0) .

Consider the following program:

 #include <stdio.h> #include <math.h> int main(void) { double x = 0.1; printf("%g\n", pow(2.0, 3.0)); printf("%g\n", asin(x)); return 0; } 

When I compile and link it to my system using

 gcc cc -oc 

I get:

 /tmp/ccXx8ZRL.o: In function `main': cc:(.text+0x36): undefined reference to `asin' collect2: ld returned 1 exit status 

Note that he complains about asin , but not pow .

If I change the pow call to pow(x, 3.0) , I get:

 /tmp/ccOeSaBK.o: In function `main': cc:(.text+0x24): undefined reference to `pow' cc:(.text+0x52): undefined reference to `asin' collect2: ld returned 1 exit status 

Usually, if you want to call a standard library function, you need to have #include <math.h> at the top of the source file (suppose you already have one), and you need to pass the -lm parameter -lm compiler after the file that it needs. (The component tracks links that have not yet been resolved, so you first need to see the object file that references asin so that it can solve it when it sees the math library.)

The component does not complain about calling pow(2.0, 3.0) because gcc is smart enough to allow its constant 8.0 . There is no call to the pow function in the compiled object file, so the linker does not need to allow it. If I change pow(2.0, 3.0) to pow(x, 3.0) , the compiler does not know what the result will be, so it generates a call.

+5
source share

Do you <math.h> everywhere?

Note that the names in the library are prefixed with __ieee754_ , but those that the linker cannot find are not.

What happens when compiling this code?

 #include <math.h> int main(void) { double d = pow(2, 3); double e = asin(1.0 / d); return (int)(e+1); } 

If the file is mathtest.c , then compile with:

 gcc -o mathtest mathtest.c -lm 

(Given that this fails to compile, what characters are defined in mathtest.o ?)


I added a comment to the main question:

What platform are you working on? Which C compiler are you using? Do you cross compile? What is the command line executed for the connection? (I see DOS / Windows C: the paths and architecture of PowerPC.) Is there any chance that you are using typical math?

Looking at the LOAD paths you specify, I see:

 LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/../../../../powerpc-eabi/lib/nof\libm.a 

What can I simplify if:

 LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/powerpc-eabi/lib/nof\libm.a 

One part of this path that intrigues me is part nof ; could it be "without a floating point"? Another part that really intrigues me is the presence of powerpc with the c: prefix; he applies cross-compilation for PowerPC on the Windows platform. It is important to be frank and frank in such things; we need such information to help you reasonably.

Was this library tested by libm.a or were you experimenting with another file?

+7
source share

The sequence for -lm -lc -lgcc plays a very important role. Only this sequence works for me.

These commands go to the linker options!

+6
source share

You can use "filename.c -lm" to solve this problem. And please remember to use the math.h header file

0
source share

All Articles