Subject: Re: MATH.H
To: Harrison, Shawn <shawn_harrison@tyndale.com>
From: Keith Jolley <kjolley@qualcomm.com>
List: port-mac68k
Date: 09/26/1997 07:12:56
> 
> The compiler apparently does not include the math functions. When I try 
> to use a math function, such as sqrt(), I get a message like the 
> following:
> 
> 	var/tmp/cc0002091.o: Undefined symbol '_sqrt' referenced from text 
> segment
> 
> Does anyone know why this is happening and what I can do to fix it?
> 

You need to use the math library, as follows:


[pong 70] > cat a.c
#include <stdio.h>
#include <math.h>

int main(int argc, char *argv[])
{
        printf ("Math is hard! Here is the sqrt of 2.0: %f\n", sqrt(2.0));
        return 0;
}

[pong 71] > gcc a.c
Undefined                       first referenced
 symbol                             in file
sqrt                                /var/tmp/cca001pu1.o
ld: fatal: Symbol referencing errors. No output written to a.out
[pong 72] > gcc a.c -lm
[pong 73] > ./a.out
Math is hard! Here is the sqrt of 2.0: 1.414214



There is a great chapter on linking in 'Expert C Programming, Deep C Secrets'
by Peter Van Der Linden. He shows how you can find which libraries you need
to link to. You got the _sqrt error so it's pretty easy to figure out you 
need the math lib (not so easy to know it's called m!). Here's you he suggests
to find the libs you need (page 120):

> cd /usr/lib
> foreach i (lib?*)
? echo $i
? nm $i | grep sqrt | grep -v UNDEF
? end
...
...
libm.a
libm.a[e_sqrt.o]:
[7]     |         0|      32|FUNC |GLOB |0    |2      |__ieee754_sqrt
[1]     |         0|       0|FILE |LOCL |0    |ABS    |e_sqrt.c
[3]     |        48|       8|OBJT |LOCL |0    |3      |invsqrtpi
[23]    |        64|       8|OBJT |LOCL |0    |3      |invsqrtpi
[13]    |        48|       8|OBJT |LOCL |0    |3      |invsqrtpi
libm.a[w_sqrt.o]:
[10]    |         0|     192|FUNC |GLOB |0    |2      |__sqrt
[8]     |         0|     192|FUNC |WEAK |0    |2      |sqrt
[1]     |         0|       0|FILE |LOCL |0    |ABS    |w_sqrt.c
libm.so
[968]   |     13848|      32|FUNC |GLOB |0    |6      |__ieee754_sqrt
[821]   |     67100|     208|FUNC |GLOB |0    |6      |__sqrt
[25]    |         0|       0|FILE |LOCL |0    |ABS    |e_sqrt.c
[334]   |     76832|       8|OBJT |LOCL |0    |7      |invsqrtpi
[366]   |     76920|       8|OBJT |LOCL |0    |7      |invsqrtpi
[406]   |     77872|       8|OBJT |LOCL |0    |7      |invsqrtpi
[879]   |     67100|     208|FUNC |WEAK |0    |6      |sqrt
[726]   |         0|       0|FILE |LOCL |0    |ABS    |w_sqrt.c
libm.so.1
[968]   |     13848|      32|FUNC |GLOB |0    |6      |__ieee754_sqrt
[821]   |     67100|     208|FUNC |GLOB |0    |6      |__sqrt
[25]    |         0|       0|FILE |LOCL |0    |ABS    |e_sqrt.c
[334]   |     76832|       8|OBJT |LOCL |0    |7      |invsqrtpi
[366]   |     76920|       8|OBJT |LOCL |0    |7      |invsqrtpi
[406]   |     77872|       8|OBJT |LOCL |0    |7      |invsqrtpi
[879]   |     67100|     208|FUNC |WEAK |0    |6      |sqrt
[726]   |         0|       0|FILE |LOCL |0    |ABS    |w_sqrt.c
libmail.a
libmakestate.so.1
libmapmalloc.a
libmapmalloc.so
libmapmalloc.so.1
libmp.a
libmp.a[msqrt.o]:
[13]    |         0|     524|FUNC |GLOB |0    |2      |msqrt
[1]     |         0|       0|FILE |LOCL |0    |ABS    |msqrt.c
libmp.so
[65]    |      7612|     532|FUNC |GLOB |0    |6      |msqrt
[44]    |         0|       0|FILE |LOCL |0    |ABS    |msqrt.c
libmp.so.1
[65]    |      7612|     532|FUNC |GLOB |0    |6      |msqrt
[44]    |         0|       0|FILE |LOCL |0    |ABS    |msqrt.c
libnisdb.a
libnisdb.so
libnisdb.so.2
...


from looking at the output you see the 'sqrt' funtion in the libm.a and libm.so
files, using the C lib calling convention, you drop the lib and the .* and
prepend an -l to get this: -lm. Always have your libraries added after the
code where you need them, otherwise the symbols will not get used and you may
as well not have included the library (on some compilers). This means:
> cc -lm a.c    (will bomb)
> cc a.c -lm    (will compile)

Good luck!
Keith