Linking Math Library in GCC 4.6.1 (Ubuntu 11.10) - c

I find a problem in the linking process of my application. I did not have the same with gcc 4.5. It tries to link math library with the following command.
gcc -Wall -Wno-unused -MD -o mems_seektest mems_seektest.o -lm -L. -g -DASSERTS -I../src// -I../ -I../src//src -DDEBUG -lmems_internals
and report following error massages:
undefined reference to `sqrt'
Any idea ?

recent gcc/ld uses the --as-needed linker flag as default. Practically, that means libraries have to be specified in the reverse order of dependencies on the command line. If the mems_internals library needs the sqrt function your -lm after -lmems_internals.
gcc -Wall -Wno-unused -MD -o mems_seektest mems_seektest.o -L. -g -DASSERTS -I../src// -I../ -I../src//src -DDEBUG -lmems_internals -lm

I've had the same problem with gcc 4.6.1, even with only one library. This doesn't work:
$ gcc -lm eg.o -o eg
eg.o: In function `foo':
/home/nick/tmp/eg.c:5: undefined reference to `sqrt'
collect2: ld returned 1 exit status
But this does:
$ gcc eg.o -o eg -lm
I hit this because I was using "LDFLAGS=-lm" in my Makefile. Works fine if you use "LDLIBS=-lm" instead.

You didn't tell us what -lmems_internals is, but maybe the unresolved symbol comes from there. The order of the -l options is generally important to the linker, you should always put system libraries last.
You can check where the unresolved symbol comes from by using something like
nm yourLibrary | grep sqrt
if there is a U in front of sqrt the symbol is undefined.

I'd say the linker is using the wrong libm.

Related

Properly Linking a static library with the C math library

I have a library which uses the log function from math.h. When I compile and package this library, I get no compilation errors, which is normal (I think).
Now when I try to use the library in an application, gcc gives me linker errors:
Compiling mytestlist using "mytestlist.o":
gcc mytestlist.o -I/student/cmpt332/pthreads -I. -std=c99 -Wall -pedantic -L. -L/student/cmpt332/pthreads/lib/linuxx86_64/ -llist -o mytestlist
./liblist.a(list_adders.o): In function `NodeCreate':
list_adders.c:(.text+0x343): undefined reference to `log'
./liblist.a(list_adders.o): In function `ListCreate':
list_adders.c:(.text+0x62f): undefined reference to `log'
./liblist.a(list_adders.o): In function `ListFree':
list_adders.c:(.text+0xdcc): undefined reference to `log'
list_adders.c:(.text+0xe55): undefined reference to `log'
list_adders.c:(.text+0xefb): undefined reference to `log'
./liblist.a(list_adders.o):list_adders.c:(.text+0xf96): more undefined references to `log' follow
collect2: error: ld returned 1 exit status
Makefile:47: recipe for target 'mytestlist' failed
make: *** [mytestlist] Error 1
Why is this happening? The only solution that works is that I have to supply the -lm option to gcc when I compile the program that uses the library (even though the program itself makes no use of math.h), however I find this cumbersome to do.
I've also tried supplying the -lm option when compiling the library, but when the application is compiled using the library, I get the same linker errors.
Is there a way to compile the library with math.h without having to supply -lm to other programs that make use of the library?
In case you're wondering, I compile each object that makes up the library using:
gcc -std=c99 -Wall -pedantic -static -I. -c list_adders.c -o list_something.o -lm
And the library is packaged using:
ar cvfr liblist.a list_something.o ...
In your gcc -c command, the -lm isn't doing anything. It's a linker option, and -c means "don't link".
The proper place to put -lm is in fact after the -llist whenever you use it. That's how static library dependencies are done. Put it in the documentation for liblist.
If you want something fancier, there's pkg-config. With the appropriate configuration files, pkg-config --static --libs liblist will output -llist -lm.

Undefined reference to `initscr' Ncurses

I'm trying to compile my project and I use the lib ncurse. And I've got some errors when compiler links files.
Here is my flags line in Makefile:
-W -Wall -Werror -Wextra -lncurses
I've included ncurses.h
Some layouts :
prompt$> dpkg -S curses.h
libslang2-dev:amd64: /usr/include/slcurses.h
libncurses5-dev: /usr/include/ncurses.h
libncurses5-dev: /usr/include/curses.h
prompt$> dpkg -L libncurses5-dev | grep .so
/usr/lib/x86_64-linux-gnu/libncurses.so
/usr/lib/x86_64-linux-gnu/libcurses.so
/usr/lib/x86_64-linux-gnu/libmenu.so
/usr/lib/x86_64-linux-gnu/libform.so
/usr/lib/x86_64-linux-gnu/libpanel.s
And here are my erros :
gcc -W -Wall -Werror -Wextra -I./Includes/. -lncurses -o Sources/NCurses/ncurses_init.o -c Sources/NCurses/ncurses_init.c
./Sources/NCurses/ncurses_init.o: In function `ncruses_destroy':
ncurses_init.c:(.text+0x5): undefined reference to `endwin'
./Sources/NCurses/ncurses_init.o: In function `ncurses_write_line':
ncurses_init.c:(.text+0xc5): undefined reference to `mvwprintw'
./Sources/NCurses/ncurses_init.o: In function `ncurses_init':
ncurses_init.c:(.text+0xee): undefined reference to `initscr'
collect2: error: ld returned 1 exit status
Thanks a lot
You need to change your makefile so that the -lncurses directive comes after your object code on the gcc command line, i.e. it needs to generate the command:
gcc -W -Wall -Werror -Wextra -I./Includes/. -o Sources/NCurses/ncurses_init.o -c Sources/NCurses/ncurses_init.c -lncurses
This is because object files and libraries are linked in order in a single pass.
In C++ , I fixed it just by linking the ncurses library .
Here is the command :
g++ main.cpp -lncurses
I got flags to correct order by using LDLIBS variable:
ifndef PKG_CONFIG
PKG_CONFIG=pkg-config
endif
CFLAGS+=-std=c99 -pedantic -Wall
LDLIBS=$(shell $(PKG_CONFIG) --libs ncurses)
man gcc | grep -A10 "\-l library"
-l library
Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX
compliance and is not recommended.)
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files
in the order they are specified. Thus, foo.o -lz bar.o searches
library z after file foo.o but
before bar.o. If bar.o refers to functions in z, those functions may not be loaded.

C: Undefined reference to floor

I am using Eclipse on Ubuntu to write/compile/run C code.
I am trying to build my project.
Following is the output in the Eclipse console.
22:18:31 **** Build of configuration Debug for project Project1 ****
make all
Building file: ../project1.c
Invoking: GCC C Compiler
gcc -I/lib/i386-linux-gnu -O0 -g3 -Wall -c -fmessage-length=0 -pthread -lm -MMD -MP -MF"project1.d" -MT"project1.d" -o "project1.o" "../project1.c"
../project1.c: In function ‘main’:
../project1.c:146:6: warning: unused variable ‘this_thread_id’ [-Wunused-variable]
../project1.c: In function ‘_pre_init’:
../project1.c:126:1: warning: control reaches end of non-void function [-Wreturn-type]
Finished building: ../project1.c
Building file: ../scheduler.c
Invoking: GCC C Compiler
gcc -I/lib/i386-linux-gnu -O0 -g3 -Wall -c -fmessage-length=0 -pthread -lm -MMD -MP -MF"scheduler.d" -MT"scheduler.d" -o "scheduler.o" "../scheduler.c"
Finished building: ../scheduler.c
Building target: Project1
Invoking: GCC C Linker
gcc -L/lib/i386-linux-gnu -lm -pthread -o "Project1" ./project1.o ./scheduler.o
./project1.o: In function `advance_global_time':
/home/akshay/Cworkspace/Project1/Debug/../project1.c:50: undefined reference to `floor'
collect2: ld returned 1 exit status
make: *** [Project1] Error 1
Can anyone please help me figure out what the problem is and how to solve it?
You need to link libraries after the object files.
You have:
gcc -L/lib/i386-linux-gnu -lm -pthread -o "Project1" ./project1.o ./scheduler.o
You need:
gcc -L/lib/i386-linux-gnu -pthread -o "Project1" ./project1.o ./scheduler.o -lm
There seems to have been a change in the way the linkers work — at some time, it was possible to specify shared libraries (such as the maths library) before the object files, and all would work. However, nowadays, if the shared library doesn't satisfy any symbols when it is scanned, it is omitted from the link process. Ensuring that the object files are listed before the libraries fixes this.
See also Undefined reference to 'pthread_create'; same problem, same solution. And I doubt if that is the only such question in SO.
You need to link against the mathematical library, i.e., add -lm at the end of the link line. No idea how to do that in Eclipse, sorry.
Note, the linking flags in your output look out of order. Perhaps you attempted to add the -lm via the Linker Flags in Eclipse. This causes issues in Eclipse. I suggest you try...
Right click on your project -> properties -> C/C++ Build -> Settings
-> GCC Linker -> Libraies -> add "m" -> Apply -> build
OR, at the very list, make sure that the -L and -l parameters come after your .o files in the Linking process.
I just got hit by this today and it eluded me for a while.

GCC linker issue with -lm flag

I'm having issues with the GCC linker, specifically using the -lm flag since I'm using some functions from math.h. I get the following errors:
main.c:(.text+0x8e5): undefined
reference to `floor'
main.c:(.text+0x901): undefined
reference to `ceil'
Here's the relevant portion of my makefile:
myprogram: main.o
gcc -Wall -pedantic -o myprogram main.o
main.o: main.c foo.h bar.h
gcc -Wall -pedantic -lm main.c
Probably something silly I'm overlooking, but I'm definitely not an expert when it comes to makefiles.
Furthermore, library specifications have to come after the objects referencing them (cf. Linker flags in wrong place ).
-lm is a linker flag, so you should add it to the linking rule above (i.e., you added it to the wrong rule).

Oh no, not another Undefined Reference question!

Unfortunately yes.
I have my shared library compiled, the linker doesn't complain about not finding it but still I get undefined reference error. Thinking that I might be doing something wrong I did a little research and found this nice, simple walkthrough:
http://www.adp-gmbh.ch/cpp/gcc/create_lib.html
which I've followed to the letter but still I get:
$ gcc -Wall main.c -o dynamically_linked -L.\ -lmean
/tmp/ccZjkkkl.o: In function `main':
main.c:(.text+0x42): undefined reference to `mean'
collect2: ld returned 1 exit status
This is pretty simple stuff so what's going wrong?! Is there something in my set up that might need checking/tweeking?
GCC 4.3.2 Fedora 10 64-bit
Change:
$ gcc -Wall main.c -o dynamically_linked -L.\ -lmean
to:
$ gcc -Wall main.c -o dynamically_linked -L. -lmean
You probably meant to do this:
$ gcc -Wall main.c -o dynamically_linked -L./ -lmean
which is OK, but the trailing / is redundant
How was the library created? Libtool?
Show us an ls -l of your current directory, and look at what gcc -v <rest of your command> says (that gives details of what gcc is doing).

Resources