LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-20-2006, 04:35 PM   #1
oneandoneis2
Senior Member
 
Registered: Nov 2003
Location: London, England
Distribution: Ubuntu
Posts: 1,460

Rep: Reputation: 48
Why is "-lm" needed?


I've made a start on learning C, and (to my surprise) so far so good.

I was testing my understanding by writing a quadratic-equation solver, which makes use of the sqrt() function.

If I put a number into sqrt(), I can compile with just "gcc quadratic.c", but if I ask it to sqrt() a variable, which is what I actually want, I get the error "undefined reference to 'sqrt'"

I googled it, and found that I needed to add "-lm" to the end of the gcc command, and that did indeed solve the problem.

But I don't understand WHY, and neither Google nor that gcc man page is helping me. What does -lm do, and why is it needed in this instance when I've never needed it before?

Thanks in advance!
 
Old 09-20-2006, 05:09 PM   #2
silent_cutthroat
LQ Newbie
 
Registered: Nov 2005
Distribution: Arch
Posts: 27

Rep: Reputation: 15
By passing -lm to gcc you tell it to link against the shared library libm.so which contains the code for sqrt and other mathematical functions. (basicly if you use math.h you need to link against libm) In the case when you used sqrt with a constant(numeric literal) probably gcc optimizes the call at compile time so actually you don't use any function.
 
Old 09-20-2006, 05:19 PM   #3
pankaj99
Member
 
Registered: Mar 2006
Location: India
Distribution: Fedora
Posts: 47

Rep: Reputation: 15
sqrt() is a function which is *defined* in the maths library.
when you use -lm to link your executable against the math library.

In simpler terms,
somebody has written the sqrt() function (so that you do not need
to write it)and compiled it .the compiled code is there in a
file named libm.so.* along with many other functions like
pow(),log(),sin() etc.

Now when you call the function sqrt() from your code ,the
compiler needs to know where to find the code for sqrt().
You tell the compiler to look for it in the file libm.so.*
by using the compiler flag '-lm'.

All the library file names start with 'lib' like libm.so.*,libc.so.*,
etc. look under the folder /usr/lib or /usr/include/lib to see
how the library files are named.

If you had to link with library file libxyz.so.* you had to
compile it with '-lxyz' .

Hope it clears your doubts.
The '*' in the end of the library file name is just a number.
So the actual name for the math library is like
libm.so.1 or libm.so.2 .
 
Old 09-20-2006, 05:46 PM   #4
silent_cutthroat
LQ Newbie
 
Registered: Nov 2005
Distribution: Arch
Posts: 27

Rep: Reputation: 15
Just a small correction - when linking with '-lxxx', GNU ld searches for 'libxxx.so'. Usually the shared libraries are named 'libxxx.so.version' and symlinked to 'libxxx.so'.
 
Old 09-21-2006, 03:30 AM   #5
oneandoneis2
Senior Member
 
Registered: Nov 2003
Location: London, England
Distribution: Ubuntu
Posts: 1,460

Original Poster
Rep: Reputation: 48
Okay.. I now understand what the "-lm" is actually doing. Thanks to all who replied for that.

So am I right in thinking that the "#include <math.h>" at the start of the code declares the function sqrt() but doesn't define it, and then libm.so.* actually defines it, hence both being needed?
 
Old 09-21-2006, 03:44 AM   #6
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
Quote:
Originally Posted by oneandoneis2
Okay.. I now understand what the "-lm" is actually doing. Thanks to all who replied for that.

So am I right in thinking that the "#include <math.h>" at the start of the code declares the function sqrt() but doesn't define it, and then libm.so.* actually defines it, hence both being needed?
Indeed, include files usually do not define functions.

Your confusion probably comes from the fact that the library functions you used before (say printf, malloc, ...) are present in the standard C library.
This library (libc/glibc) is included by default in the linker list of libraries to use, so linking is done transparently (no need to use -lc).
When you call any function that isn't in this standard library, like maths, X11, gtk or whatever, you need to explicitely tell the linker what to use.
 
Old 09-21-2006, 03:57 AM   #7
oneandoneis2
Senior Member
 
Registered: Nov 2003
Location: London, England
Distribution: Ubuntu
Posts: 1,460

Original Poster
Rep: Reputation: 48
Quote:
Your confusion probably comes from the fact that the library functions you used before (say printf, malloc, ...) are present in the standard C library.
Yep, I think that nails it dead-on! I couldn't quite grasp why printf, scanf, and the like all worked with just an #include while sqrt didn't.

Quote:
This library (libc/glibc) is included by default
That explains everything. Many thanks!
 
Old 09-22-2006, 02:28 AM   #8
jspenguin
Member
 
Registered: Feb 2003
Location: Wichita, KS
Distribution: Heavily modified Redhat
Posts: 194

Rep: Reputation: 30
Some of the functions in libm.so can be inlined by gcc if you use the "fast-math" option (-ffast-math). This causes gcc to emit floating-point instructions instead of function calls for instructions that are implemented on the FPU (such as sqrt, sin, cos, atan2). It's usually a good idea to use this unless strict IEEE compliance is required.
 
Old 09-22-2006, 03:06 AM   #9
oneandoneis2
Senior Member
 
Registered: Nov 2003
Location: London, England
Distribution: Ubuntu
Posts: 1,460

Original Poster
Rep: Reputation: 48
I begin to get the impression that after I learn C, I'll be spending at least as long on learning how to compile it

Cheers!
 
Old 09-22-2006, 09:09 PM   #10
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940
Learning any language is a mind-blowing experience, but it does get easier.

You're right in observing that the ".h" files declare the function's existence. They provide all that the compiler needs in order to produce a program that expects to know (say...) how to calculate a square-root.

In some funky cases, the ".h" file actually includes declarations that enable the compiler to outright generate the code that (say) does the square-root calculation. Although you write it as a function-call, sometimes the compiler is told how to "inline" that function - to generate the code itself.

In the more general case, however, what the compiler does is to generate a program that will "make a call to an external function named 'sqrt.'" The term "external" means that the output-file generated by the compiler refers to the function but does not, itself, contain it. Therefore, before the program can actually run and produce square-roots, it must be linked to the appropriate function -- which was written by very smart people somewhere far away and put into a library.

There are actually several ways that this linking can occur. One way is static linking, where the 'sqrt' routine is found in its library, inserted into the program file, and made a part of it so that the program no longer refers to 'sqrt' but rather contains it. Each program therefore contains its own (redundant) copy of the 'sqrt' code. The library is only needed by the developer who's building the program.

Another way to do it is dynamic linking, a la the "DLL" files in Microsoft Windows. In this scenario, the link to the appropriate 'sqrt' routine actually occurs as the program is being loaded into memory. A single, shared copy of the library will live in the computer's memory and be used by all. A program that relies upon a shared-library routine can't run on a system that doesn't have that library.

Last edited by sundialsvcs; 09-22-2006 at 09:10 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
bash script: using "select" to show multi-word options? (like "option 1"/"o zidane_tribal Programming 7 12-19-2015 01:03 AM
what is "sticky bit mode" , "SUID" , "SGID" augustus123 Linux - General 10 08-03-2012 04:40 AM
Telling people to use "Google," to "RTFM," or "Use the search feature" Ausar General 77 03-21-2010 11:26 AM
"Xlib: extension "XFree86-DRI" missing on display ":0.0"." zaps Linux - Games 9 05-14-2007 03:07 PM
Any way to get "Alice"; "Call of Duty" series and "Descent 3" to work? JBailey742 Linux - Games 13 06-23-2006 01:34 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:26 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration