GCC libm not working - c

I have a c program that calls sin, cos, and acos. When I compile I get the following errors:
/tmp/ccDfW98S.o: In function `zip_search':
main.c:(.text+0xf30): undefined reference to `sin'
main.c:(.text+0xf45): undefined reference to `sin'
main.c:(.text+0xf66): undefined reference to `cos'
main.c:(.text+0xf7b): undefined reference to `cos'
main.c:(.text+0xf9c): undefined reference to `cos'
main.c:(.text+0xfc6): undefined reference to `acos'
collect2: ld returned 1 exit status
I know this is common when you don't use the -lm gcc flag. I AM using this flag. I'm calling GCC like this:
gcc -o zipcode-server -lm main.c
When I compile on one of my computers this works fine. The only difference that I can think of is that this isn't working on x86_64 and the computer it does work on is i686. Both are Ubuntu. The file libm.a is present on the computer it isn't working on and I don't get any errors saying it can't be found. What could be causing this?

You should put -lm after main.c
In general, if you have multiple libraries, they should be written in order of their usage. For example, if library A uses library B, you should have -lA -lB.
In your case, the object file that is the result of compilation of main.c uses library m and therefore -lm should come after it.
For the curious, this is mostly for efficiency reasons. With this scheme, the linker can resolve currently unknown symbols with every new library seen in the argument list, and picking up new unknown symbols from that library on the way. This means that the linker can visit the libraries one by one, and therefore match the unknown symbols against a small number of symbols provided by each library.
On the contrast, the linker could load in symbols from all libraries at once, and then start matching unknown symbols. In that case however, the linker needs to deal with a much greater number of symbols, increasing both the memory footprint and the execution time of the linker.
Since the libraries could always be declared to the linker in the proper order of their dependencies1, there is no reason for the linker to choose the inefficient way.
1 Libraries normally have a one-way relationship, in the sense that one uses the other. Circular dependencies between libraries is rare, if at all existing, but it could still be used with this model by repeating certain libraries to be reinspected.

Related

(Cygwin) C program linked to custom header file having memory problems when trying to execute

I am using Cygwin. I have two files in the same directory, test.c and iah202_graphics.h. test.c uses functions from the header file, where I have used #include "iah202_graphics.h". I have added the Cygwin directory to my Environment Variables (PATH) already.
However I receive these errors for every function call:
$ gcc -o test test.c
/cygdrive/c/Users/Matthew/AppData/Local/Temp/cclm2bNk.o:test.c:(.text+0x27): undefined reference to `draw_line'.
/cygdrive/c/Users/Matthew/AppData/Local/Temp/cclm2bNk.o:test.c:(.text+0x27): relocation truncated to fit:
R_X86_64_PC32 against undefined symbol `draw_line'.
/cygdrive/c/Users/Matthew/AppData/Local/Temp/cclm2bNk.o:test.c:(.text+0x4a): undefined reference to
`draw_line'.
collect2: error: ld returned 1 exit status.
It's having trouble linking to the header file even though I've simply stated which file to use in the local directory. I don't understand what I'm doing wrong?
Undefined reference to 'blah' is a linker error rather than a compiler error and is almost always caused by not including a needed library.
Including a header file in your source file does not usually link in the code required to provided the functions declared in that header.
For example, were you to prevent linking of the C runtime library, you could include stdio.h as many times as you wanted to, and still not be able to resolve printf.
Bottom line, you generally need two steps:
include the relevant header file in your source code so it knows about the declarations of things provided; and
link against the relevant library or object file so it has access to the definitions of the things provided.
That could be something as simple as:
gcc -o test -I/path/to/iah202includes test.c -L/path/to/iah202libs -liah202
where -I indicates where include files can be found, -L adjusts the search path for library files, and -l actually specifies the library file to use.
Even simpler is if you have the source file for the graphics stuff (which seems to be the case based on your comments). In that case no library is needed, you can simply use:
gcc -o test test.c iab202_graphics.c
and that will compile both those translation units then link them together.

How does this C program compile and run with two main functions?

Today, while working with one custom library, I found a strange behavior.
A static library code contained a debug main() function. It wasn't inside a #define flag. So it is present in library also. And it is used link to another program which contained the real main().
When both of them are linked together, the linker didn't throw a multiple declaration error for main(). I was wondering how this could happen.
To make it simple, I have created a sample program which simulated the same behavior:
$ cat prog.c
#include <stdio.h>
int main()
{
printf("Main in prog.c\n");
}
$ cat static.c
#include <stdio.h>
int main()
{
printf("Main in static.c\n");
}
$ gcc -c static.c
$ ar rcs libstatic.a static.o
$ gcc prog.c -L. -lstatic -o 2main
$ gcc -L. -lstatic -o 1main
$ ./2main
Main in prog.c
$ ./1main
Main in static.c
How does the "2main" binary find which main to execute?
But compiling both of them together gives a multiple declaration error:
$ gcc prog.c static.o
static.o: In function `main':
static.c:(.text+0x0): multiple definition of `main'
/tmp/ccrFqgkh.o:prog.c:(.text+0x0): first defined here
collect2: ld returned 1 exit status
Can anyone please explain this behavior?
Quoting ld(1):
The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive.
When linking 2main, main symbol gets resolved before ld reaches -lstatic, because ld picks it up from prog.o.
When linking 1main, you do have undefined main by the time it gets to -lstatic, so it searches the archive for main.
This logic only applies to archives (static libraries), not regular objects.
When you link prog.o and static.o, all symbols from both objects are included unconditionally, so you get a duplicate definition error.
When you link a static library (.a), the linker only searches the archive if there were any undefined symbols tracked so far. Otherwise, it doesn't look at the archive at all. So your 2main case, it never looks at the archive as it doesn't have any undefined symbols for making the translation unit.
If you include a simple function in static.c:
#include <stdio.h>
void fun()
{
printf("This is fun\n");
}
int main()
{
printf("Main in static.c\n");
}
and call it from prog.c, then linker will be forced to look at the archive to find the symbol fun and you'll get the same multiple main definition error as linker would find the duplicate symbol main now.
When you directly compile the object files(as in gcc a.o b.o), the linker doesn't have any role here and all the symbols are included to make a single binary and obviously duplicate symbols are there.
The bottom line is that linker looks at the archive only if there are missing symbols. Otherwise, it's as good as not linking with any libraries.
After the linker loads any object files, it searches libraries for undefined symbols. If there are none, then no libraries need to be read. Since main has been defined, even if it finds a main in every library, there is no reason to load a second one.
Linkers have dramatically different behaviors, however. For example, if your library included an object file with both main () and foo () in it, and foo was undefined, you would very likely get an error for a multiply defined symbol main ().
Modern (tautological) linkers will omit global symbols from objects that are unreachable - e.g. AIX. Old style linkers like those found on Solaris, and Linux systems still behave like the unix linkers from the 1970s, loading all of the symbols from an object module, reachable or not. This can be a source of horrible bloat as well as excessive link times.
Also characteristic of *nix linkers is that they effectively search a library only once for each time it is listed. This puts a demand on the programmer to order the libraries on the command line to a linker or in a make file, in addition to writing a program. Not requiring an ordered listing of libraries is not modern. Older operating systems often had linkers that would search all libraries repeatedly until a pass failed to resolve a symbol.

"undefined reference to `pow'" even with math.h and the library link -lm [duplicate]

This question already has answers here:
Undefined reference to `pow' and `floor'
(6 answers)
Closed 2 years ago.
I'm using math.h and the -lm option to compile. I have tried all of:
gcc -o ssf ssf_tb.c ssf.c -lm
gcc -o ssf ssf_tb.c -lm ssf.c
gcc -o -lm ssf -lm ssf_tb.c ssf.c
but the error:
undefined reference to 'pow'
happens on all cases.
Put the -lm at the end of the line.
gcc processes the arguments that specify inputs to the final program in the order they appear on the command line. The -lm argument is passed to the linker, and the ssf.c argument, for example, is compiled, and the resulting object file is passed to the linker.
The linker also processes inputs in order. When it sees a library, as -lm specifies, it looks to see if that library supplies any symbols that the linker currently needs. If so, it copies the modules with those symbols from the library and builds them into the program. When the linker sees an object module, it builds that object module into the program. After bringing an object module into the program, the linker does not go back and see if it needs anything from earlier libraries.
Because you listed the library first, the linker did not see anything that it needed from the library. If you list the object module first, the linker will bring the object module into the program. In the process of doing this, the linker will make a list of all the undefined symbols that the object needs. Then, when the linker sees the library, it will see that the library supplies definitions for those symbols, and it will bring the modules with those symbols into the program.

Statically linking against LAPACK

I'm attempting to do a release of some software and am currently working through a script for the build process. I'm stuck on something I never thought I would be, statically linking LAPACK on x86_64 linux. During configuration AC_SEARCH_LIB([main],[lapack]) works, but compilation of the lapack units do not work, for example undefiend reference to 'dsyev_' --no lapack/blas routine goes unnoticed.
I've confirmed I have the libraries installed and even compiled them myself with the appropriate options to make them static with the same results.
Here is an example I had used in my first experience with LAPACK a few years ago that works dynamically, but not statically: http://pastebin.com/cMm3wcwF
The two methods I'm using to compile are the following,
gcc -llapack -o eigen eigen.c
gcc -static -llapack -o eigen eigen.c
Your linking order is wrong. Link libraries after the code that requires them, not before. Like this:
gcc -o eigen eigen.c -llapack
gcc -static -o eigen eigen.c -llapack
That should resolve the linkage problems.
To answer the subsequent question why this works, the GNU ld documentation say this:
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 libraryz' after
file foo.o but before bar.o. If bar.o refers to functions in `z',
those functions may not be loaded.
........
Normally the files found this way are library files—archive files
whose members are object files. The linker handles an archive file by
scanning through it for members which define symbols that have so far
been referenced but not defined. But if the file that is found is an
ordinary object file, it is linked in the usual fashion.
ie. the linker is going to make one pass through a file looking for unresolved symbols, and it follows files in the order you provide them (ie. "left to right"). If you have not yet specified a dependency when a file is read, the linker will not be able to satisfy the dependency. Every object in the link list is parsed only once.
Note also that GNU ld can do reordering in cases where circular dependencies are detected when linking shared libraries or object files. But static libraries are only parsed for unknown symbols once.

Problem in compiling C function with threading on Fedora

When I try to compile a C-program with multithreading in Fedora, I get the following error.
The file name is abc.c
abc.c:(.text+0x39): undefined reference to `pthread_create'
abc.c:(.text+0x61): undefined reference to `pthread_create'
abc.c:(.text+0x79): undefined reference to `pthread_join'
abc.c:(.text+0x8d): undefined reference to `pthread_join'
I checked in /usr/include and I found that pthread.h is present. Also I tried copying pthread.h to the same directory as abc.c
How do I resolve these linking errors?
As pointed out by George you must link with the thread library
gcc -o abc abc.c -pthread
The reason you are getting those errors is because during the linking stage the compiler tries to fill in all the slots where it had placed placeholders for method calls that it knew were defined but currently did not know their locations because the appropriate library had not been linked yet. As pointed out by caf using the -pthread flag in both compiling and linking stages allows for the compiler to make smarter choices about what it needs to use to be thread-safe in certain conditions.

Resources