EmbDev.net

Forum: ARM programming with GCC/GNU tools underfined reference to 'pow'


von Roman M. (romez777)


Rate this post
useful
not useful
Hello,

I grabbed the latest YAGARTO toolchain based on gcc-4.2.1 for
AT91SAM7256 chip (AT91SAM7 evaluation board to be more precise).

So I'm now trying to compile the example TWI code (I took the example
Makefile from "Getting started" appnote), and always get stuck with the
same message:

"undefined reference to 'pow'"

Sure, math.h is included and '-lm' is added to linker. None of it helps.
It seems compiler/linker don't find the library 'libm.a' at all.

Has anyone faced with this, what's the reason?

Thanks.

von Clifford S. (clifford)


Rate this post
useful
not useful
Post the build log.

Note that pow() is floating point function. Unless you are using
hardware with FPA or VFP hardware, floating point operations are
laboriously slow. Only use this if you really need to or the performance
of the code is not critical.

Clifford

von Roman M. (romez777)


Rate this post
useful
not useful
The code I fetched from Atmel web-site was originally based on IAR
compiler, so I'm now trying to port it on arm-gcc (YAGARTO package).

And I used Makefile from 'AT91SAM7 getting started' document. By now I
implemented 'pow' function as bit-shifting, and it suffice the
requirements so far, but I'd like to do it right. I have a feeling the
whole 'libm.a' is not linked in anyway.

Here's build log:

rm -f *.o *.bin *.elf *.map
arm-elf-gcc -D__ASSEMBLY__ -DAT91SAM7S256 -g -mcpu=arm7tdmi -c -Os -Wall
-I./include cstartup.S -o cstartup.o
arm-elf-gcc -c -g -mcpu=arm7tdmi -Os -Wall -I./include -DAT91SAM7S256
lowlevel.c -o lowlevel.o
arm-elf-gcc -c -g -mcpu=arm7tdmi -Os -Wall -I./include -DAT91SAM7S256
init.c -o init.o
arm-elf-gcc -c -g -mcpu=arm7tdmi -Os -Wall -I./include -DAT91SAM7S256
lib_twi.c -o lib_twi.o
lib_twi.c: In function 'AT91F_TWI_WriteSingleIadr':
lib_twi.c:172: warning: suggest parentheses around arithmetic in operand
of |
lib_twi.c: In function 'AT91F_TWI_WriteMultipleIadr':
lib_twi.c:300: warning: suggest parentheses around arithmetic in operand
of |
arm-elf-gcc -c -g -mcpu=arm7tdmi -Os -Wall -I./include -DAT91SAM7S256
lm75.c -o lm75.o
arm-elf-gcc -c -g -mcpu=arm7tdmi -Os -Wall -I./include -DAT91SAM7S256
main.c -o main.o
arm-elf-gcc -nostartfiles -Wl,--cref -lc -lgcc  -T elf32-littlearm.lds
-Ttext 0x201000 -Tdata 0x200000 -n -o twi_sram.elf cstartup.o lowlevel.o
init.o lib_twi.o lm75.o main.o

Cross Reference Table

Symbol                                            File
AT91F_DBGU_Get                                    init.o
AT91F_DBGU_Init                                   init.o

[skipping rest of table]

lib_twi.o: In function `AT91F_SetTwiClock':
C:\Wrk\usbdongle\twi/lib_twi.c:85: undefined reference to `pow'
collect2: ld returned 1 exit status
make: *** [sram] Error 1

Clifford Slocombe wrote:
> Post the build log.
>
> Note that pow() is floating point function. Unless you are using
> hardware with FPA or VFP hardware, floating point operations are
> laboriously slow. Only use this if you really need to or the performance
> of the code is not critical.
>
> Clifford

von Martin T. (mthomas) (Moderator)


Rate this post
useful
not useful
Roman Mashak wrote:

> Sure, math.h is included and '-lm' is added to linker. None of it helps.
> It seems compiler/linker don't find the library 'libm.a' at all.

Really sure? I do not see a -lm:

> arm-elf-gcc -nostartfiles -Wl,--cref -lc -lgcc  -T elf32-littlearm.lds
> -Ttext 0x201000 -Tdata 0x200000 -n -o twi_sram.elf cstartup.o lowlevel.o
> init.o lib_twi.o lm75.o main.o

von Clifford S. (clifford)


Rate this post
useful
not useful
Roman Mashak wrote:
> And I used Makefile from 'AT91SAM7 getting started' document. By now I
> implemented 'pow' function as bit-shifting, and it suffice the
> requirements so far, but I'd like to do it right. I have a feeling the
> whole 'libm.a' is not linked in anyway.
>

If you have a problem, you really should read the build log - that is
rather what it is for. It is plain to see that there is no -lm in the
linker invocation despite your earlier assertion - you don't have to
"have a feeling". Perhaps you are adding it in the wrong place in the
makefile. If you are not sure what you need to do, then perhaps you
might post the makefile (or a link to the document or file)

However, if you can perform the operation you need using bit shifting,
then presumably you want an integer operation. The standard library
pow() is not an integer operation and I would advise against using it.
Implementing what you need yourself is "doing it properly".

Here is a discussion on implementing integer exponentiation
http://www.thescripts.com/forum/thread214835.html, however, if all your
exponents are powers of two, then bit shifting is by far the most
efficient implementation.

Clifford

von Roman M. (romez777)


Rate this post
useful
not useful
Martin Thomas wrote:
> Roman Mashak wrote:
>
>> Sure, math.h is included and '-lm' is added to linker. None of it helps.
>> It seems compiler/linker don't find the library 'libm.a' at all.
>
> Really sure? I do not see a -lm:
>
>> arm-elf-gcc -nostartfiles -Wl,--cref -lc -lgcc  -T elf32-littlearm.lds
>> -Ttext 0x201000 -Tdata 0x200000 -n -o twi_sram.elf cstartup.o lowlevel.o
>> init.o lib_twi.o lm75.o main.o

I bet the '-lm' was there, probably lost while posting. Anyway, here is
fresh build log with all necessary components and still with the
problem:

rm -f *.o *.bin *.elf *.map
arm-elf-gcc -D__ASSEMBLY__ -DAT91SAM7S256 -g -mcpu=arm7tdmi -c -Os -Wall
-I./include cstartup.S -o cstartup.o
arm-elf-gcc -c -g -mcpu=arm7tdmi -Os -Wall -I./include -DAT91SAM7S256
lowlevel.c -o lowlevel.o
arm-elf-gcc -c -g -mcpu=arm7tdmi -Os -Wall -I./include -DAT91SAM7S256
init.c -o init.o
arm-elf-gcc -c -g -mcpu=arm7tdmi -Os -Wall -I./include -DAT91SAM7S256
lib_twi.c -o lib_twi.o
lib_twi.c: In function 'AT91F_TWI_WriteSingleIadr':
lib_twi.c:172: warning: suggest parentheses around arithmetic in operand
of |
lib_twi.c: In function 'AT91F_TWI_WriteMultipleIadr':
lib_twi.c:300: warning: suggest parentheses around arithmetic in operand
of |
arm-elf-gcc -c -g -mcpu=arm7tdmi -Os -Wall -I./include -DAT91SAM7S256
lm75.c -o lm75.o
arm-elf-gcc -c -g -mcpu=arm7tdmi -Os -Wall -I./include -DAT91SAM7S256
main.c -o main.o
arm-elf-gcc -nostartfiles -Wl,--cref -lc -lgcc -lm -T
elf32-littlearm.lds -Ttext 0x201000 -Tdata 0x200000 -n -o twi_sram.elf
cstartup.o lowlevel.o init.o lib_twi.o lm75.o main.o

[skip cross reference table]

lib_twi.o: In function `AT91F_SetTwiClock':
C:\Wrk\usbdongle\twi/lib_twi.c:85: undefined reference to `pow'

collect2: ld returned 1 exit status
make: *** [sram] Error 1

==================
I'd like to get things done in correct way, not just put workarounds.

von Clifford S. (clifford)


Rate this post
useful
not useful
Roman Mashak wrote:
> I'd like to get things done in correct way, not just put workarounds.

There is nothing 'incorrect' about implementing your own function to do
this! I would suggest that using a floating point operation to perform
an integer calculation is in fact exactly the wrong way of doing things.
How many times does that need saying, and why don't you understand that
yet?

If you Copy & Paste the log directly I cannot see how it could possibly
have got 'lost', so I am now not sure whether to believe what you have
posted now is 'real'.

I strongly suggest that you change your link order to "-lm -lc -lgcc",
since libm may be dependent on libc or libgcc, so must be listed first.


Unrelated to your question, this warning:

> warning: suggest parentheses around arithmetic in operand of |

is most often in fact an error. The operator precedence of | is lower
than that of ==, and many other operators, and you may get unexpected
results if you expect that not to be so. Even if the code is correct, it
is as well to fix the warning to indicate intent. Especially before you
post your log on a public forum - lest people get distracted from your
real problem! ;-)

Clifford

von Pablo G. (macgup)


Rate this post
useful
not useful
This may help for this:

LIBS =  -lm -lc -lgcc

(but not this LIBS = -lc -lgcc -lm, the order metters!)
This way I got math.h working.

Pablo

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.