'ld' cannot link symbols, although they are in library - c

I have a problem while trying to compile and link my program with "dmalloc".
bin
+--dmalloc
include
+--dmalloc.h
lib
+--libdmalloc.a
+--libdmallocth.a
main.c
I have the following directory structure
Now I try to compile my program with the following command:
gcc -Iinclude -Llib -ldmalloc -DDMALLOC main.c
/tmp/ccSDFmWj.o: In function `main':
main.c:(.text+0x29): undefined reference to `dmalloc_malloc'
collect2: ld returned 1 exit status
Okay, I get that there's a problem with linking the symbols, ld simply cannot find reference to dmalloc_malloc. However...
nm lib/libdmalloc.a | grep dmalloc_malloc
0000000000001170 T dmalloc_malloc
0000000000000fe0 t dmalloc_malloc.part.6
I am puzzled... The symbol is there in that library. Why does 'ld' has problem with it?

List the libraries last:
gcc -Iinclude -Llib -DDMALLOC main.c -ldmalloc

Related

/usr/bin/ld: cannot find -lRTU_Module Linux / Shared library C code

I have a problem compiling the following line of code :
gcc -o main.c -ldl -lpthread -lRTU_Module main.o
I have the following error message :
/usr/bin/ld: cannot find -lRTU_Module
collect2: error: ld returned 1 exit status
When i try to find the location of my .so it returns this :
locate libRTU_Module.so
/home/owasys/workspace/AccelTest/libRTU_Module.so
/home/owasys/workspace/Compiler_gcc-linaro-5.3_patch/files/lib/libRTU_Module.so
/home/owasys/workspace/Compiler_gcc-linaro-5.3_patch/files/lib/libRTU_Module.so.1.0.11
/opt/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/libRTU_Module.so
/opt/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/libRTU_Module.so.0
/opt/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/libRTU_Module.so.0.0.0
/opt/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/libRTU_Module.so.1.0.11
I have red multiple of answer to a similar question but i have not solve my problem.
Thank you.
ld normally scans a default/configured set of dirs, generally wouldn't know about custom stuff like /home/a/b/c
Should be easy enough to fix; does this work?
dir=/home/owasys/workspace/Compiler_gcc-linaro-5.3_patch/files/lib
gcc -o main.c -ldl -lpthread -lRTU_Module.so main.o -L $dir
May need to tell the runtime link editor to search there as well, eg adding this to gcc cmd-line:
-Wl,-rpath=$dir

Linking 2 object files in c to create an executable

I am having an issue with a makefile for something I am making. My makefile looks like this
bag: main.o bow.o
gcc bow.o main.o -o bag
main.o: main.c bow.h
gcc -Wall -ansi -pedantic main.c -o main.o
bow.o: bow.c bow.h
gcc -Wall -ansi -pedantic -c bow.c -o -bow.o
I also have a header file called "bow.h" that is used in both bow.o and main.o. bow.h consists of 8 function definitions and 2 structs, bow.c contains the 8 functions and NO MAIN file. main.c is suppose to be a minimal main file so it only consists of
#include "bow.h"
When I run my makefile in the Terminal with
make
I get this message
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
makefile:2: recipe for target 'bag' failed
make: *** [bag] Error 1
What exactly does this mean, how is it caused and how can I fix it?
Even a minimal program (executable) needs a point to start. For a C program, this is the main() function. Thus, the linker seeks for that function (more precisely, it links the start-up object where main is an unresolved symbol), does not find it, and issues an error.
Thus, you have to provide a main(). Alternatively, you may not generate an executable but a library.

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.

How do I change my makefile to avoid the undefined reference to a function in the maths library?

I'm trying to install PintOS on my local Ubuntu 14.04 machine. When I try to run make to compile the utilities. I get the following error.
ankitkal#ankitkal-Inspiron-5521:~/os/pintos/src/utils$ ls
backtrace Makefile pintos pintos.~1.55.~ pintos-mkdisk setitimer-helper.o squish-unix.c
CVS Makefile~ pintos~ pintos-gdb setitimer-helper.c squish-pty.c
ankitkal#ankitkal-Inspiron-5521:~/os/pintos/src/utils$ make
gcc -lm setitimer-helper.o -o setitimer-helper
setitimer-helper.o: In function `main':
setitimer-helper.c:(.text+0xbe): undefined reference to `floor'
collect2: error: ld returned 1 exit status
make: *** [setitimer-helper] Error 1
ankitkal#ankitkal-Inspiron-5521:~/os/pintos/src/utils$
The maths library (for the <math.h> header which is used in setitimer-helper.c) is not getting linked properly. When I look into the Makefile, this is the output.
ankitkal#ankitkal-Inspiron-5521:~/os/pintos/src/utils$ cat Makefile
all: setitimer-helper squish-pty squish-unix
CC = gcc
CFLAGS = -Wall -W
LDFLAGS = -lm
setitimer-helper: setitimer-helper.o
squish-pty: squish-pty.o
squish-unix: squish-unix.o
clean:
rm -f *.o setitimer-helper squish-pty squish-unix
Please tell me how to fix it. I'm using gcc-4.8.6 by the way.
gcc -lm setitimer-helper.o -o setitimer-helper
The problem is in the order of your arguments to GCC. Try this:
gcc -o setitimer-helper setitimer-helper.o -lm
This is because of the way that ld resolves undefined symbols when linking. Basically, the way you had it before, ld first sees -lm and says "I have no reason to include this library". It then includes your setitimer-helper.o which has an unresolved reference to floor. After that, there are no more libraries to consider, and floor remains unresolved.
If -lm comes afterward, it is able to resolve the reference to floor.

Linker error: undefined reference to shared object

I am trying to use an external library called iniparser in my C program. I'm using gcc 4.4.
I put the iniparser library in a subdirectory called lib/ header files are in lib/iniparser/src and the library is compiled to lib/iniparser/libiniparser.so.0.
I wrote a short Makefile to compile it, here's the output of make:
gcc -Wall -Wextra -Werror -c -I include/ src/smag_main.c -L lib/iniparser -liniparser -I lib/iniparser/src
gcc -Wall -Wextra -Werror -c -I include/ -L lib/iniparser -liniparser -I lib/iniparser/src src/agros.c
gcc -Wall -Wextra -Werror -c -I include/ -L lib/iniparser -liniparser -I lib/iniparser/src src/main.c
gcc -Wall -Wextra -Werror -L lib/iniparser -liniparser -o agros smag_main.o main.o agros.o
smag_main.o: In function `sec_haskey':
smag_main.c:(.text+0xa9): undefined reference to `iniparser_find_entry'
smag_main.o: In function `parse_config':
smag_main.c:(.text+0x153): undefined reference to `iniparser_load'
smag_main.c:(.text+0x18b): undefined reference to `iniparser_getint'
smag_main.c:(.text+0x1c6): undefined reference to `iniparser_getstring'
smag_main.c:(.text+0x202): undefined reference to `iniparser_getstring'
smag_main.c:(.text+0x261): undefined reference to `iniparser_getstring'
smag_main.c:(.text+0x2c2): undefined reference to `iniparser_getint'
smag_main.c:(.text+0x2d5): undefined reference to `iniparser_freedict'
collect2: ld returned 1 exit status
make: *** [agros] Error 1
First call to gcc compiles smag_main.o successfully, the second one compiles agros.o and the third one main.o. The 4th call is the linker, that will link all those objects into an executable agros. It obviously fails.
It looks like it has problems locating iniparser.so at linking time. How's my call wrong?
I am confused.
(Alternate question, if anyone could explain how to the linking by calling ld directly it would be great).
Try putting a symlink from libiniparser.so.0 to libiniparser.so
cd lib/iniparser/
ln -s libiniparser.so.0 libiniparser.so

Resources