How do I link to FreeImage? - c

I am using Kubuntu 14.04, and installed the FreeImage library with
sudo apt-get install libfreeimage-dev
As far as I can tell, it is correctly installed, with FreeImage.h in /usr/include and libfreeimage.a in /usr/lib. However, this trivial C program
#include <FreeImage.h>
int main(int argc, char **argv) {
FreeImage_Initialise(FALSE);
FreeImage_DeInitialise();
return 0;
}
fails to compile. Running
gcc -lfreeimage fitest.c -o fitest
outputs
/tmp/ccFbb0HQ.o: In function `main':
fitest.c:(.text+0x15): undefined reference to `FreeImage_Initialise'
fitest.c:(.text+0x1a): undefined reference to `FreeImage_DeInitialise'
collect2: error: ld returned 1 exit status
What am I doing wrong?

This wouldn't normally be the case with shared libraries but only static ones, but I'm going to give it a shot anyway since it matches your symptoms, and you also mention libfreeimage.a instead of libfreeimage.so, indicating that you're trying to use the static library.
When linking against static libraries, you need to give the library arguments after the explcit source/object arguments to the compiler, because the compiler will only process yet unresolved symbols from the library:
gcc -o fitest fitest.c -lfreeimage
If you give a static library argument before any source/object arguments, then, no symbols will yet be unresolved, nothing will be picked from the library, and the symbols will instead be seen as unresolved at the end.

Related

Creating a shared library with an undefined reference on Cygwin

I'm porting what's primarily a very central (kind of like a libc extension) library from Linux to Cygwin and since I have a lot of setup and teardown and since I don't want to be using ctor/dtor attribute becaus of tcc compatibility, my library provides a main function and the user is supposed to be using a "my_main" function that gets called by the main function in the library.
It has worked very well on Linux but on Cygwin, I'm getting linker errors.
Here's an MCVE for building the library:
#!/bin/sh -eu
cat > libmain.c <<EOF
#include <stdio.h>
long my_main(int, char**);
int main(int C, char**V)
{
int r = 0;
puts("setup");
if(0>my_main(C,V))
r=-1;
puts("teardown");
return r;
}
EOF
gcc -shared -fpic -o libmain.so libmain.c -Wl,--allow-shlib-undefined
The above works on Linux, but on Cygwin, I'm getting:
/tmp/cc0s6qei.o:libmain.c:(.text+0x32): undefined reference to `my_main'
/tmp/cc0s6qei.o:libmain.c:(.text+0x32): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `my_main'
collect2: error: ld returned 1 exit status
Can this be made to work on Cygwin?

C compiler gcc gives linker command failed error [duplicate]

I'm getting the following error and can't for the life of me figure out what I'm doing wrong.
$ gcc main.c -o main
Undefined symbols:
"_wtf", referenced from:
_main in ccu2Qr2V.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
main.c:
#include <stdio.h>
#include "wtf.h"
main(){
wtf();
}
wtf.h:
void wtf();
wtf.c:
void wtf(){
printf("I never see the light of day.");
}
Now, if I include the entire function in the header file instead of just the signature, it complies fine so I know wtf.h is being included. Why doesn't the compiler see wtf.c? Or am I missing something?
Regards.
You need to link wtf with your main. Easiest way to compile it together - gcc will link 'em for you, like this:
gcc main.c wtf.c -o main
Longer way (separate compilation of wtf):
gcc -c wtf.c
gcc main.c wtf.o -o main
Even longer (separate compilation and linking)
gcc -c wtf.c
gcc -c main.c
gcc main.o wtf.o -o main
Instead of last gcc call you can run ld directly with the same effect.
You are missing the fact that merely including a header doesn't tell the compiler anything about where the actual implementation (the definitions) of the things declared in the header are.
They could be in a C file next to the one doing the include, they could come from a pre-compiled static link library, or a dynamic library loaded by the system linker when reading your executable, or they could come at run-time user programmer-controlled explicit dynamic loading (the dlopen() family of function in Linux, for instance).
C is not like Java, there is no implicit rule that just because a C file includes a certain header, the compiler should also do something to "magically" find the implementation of the things declared in the header. You need to tell it.

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.

Linker issue while compiling source using hunspell library

I'm trying to compile this pure C source code which used hunspell library with gcc (version 4.6.3) on Ubuntu 10.10:
#include <stdlib.h>
#include <stdio.h>
#include <hunspell/hunspell.h>
int main() {
Hunhandle *spellObj = Hunspell_create("/home/artem/en_US.aff", "/home/artem/en_US.dic");
char str[60];
scanf("%s", str);
int result = Hunspell_spell(spellObj, str);
if(result == 0)
printf("Spelling error!\n");
else
printf("Correct Spelling!");
Hunspell_destroy(spellObj);
return 0;
}
With command:
gcc -lhunspell-1.3 example.c
But I've got some linker issues:
/tmp/cce0QZnA.o: In function `main':
example.c:(.text+0x22): undefined reference to `Hunspell_create'
example.c:(.text+0x52): undefined reference to `Hunspell_spell'
example.c:(.text+0x85): undefined reference to `Hunspell_destroy'
collect2: ld returned 1 exit status
Also, I checked /usr/include/hunspell/ folder, file hunspell.h exists and contains all functions from my source.
What I'm doing wrong, and why I can't compile this source?
Try:
$ gcc example.c -lhunspell-1.3
See the documentation for the -l option:
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.
So, you asked GCC to first search the library, then compile your code. You need to do it the other way around, you generally specify the libraries to link against last on the command line.
Also verify the on-disk name of the library file, often there are symlinks that remove the version number from the name, so perhaps your command should just be:
$ gcc example.c -lhunspell
to link against the "current" library version available on your system.

Undefined symbols error when using a header file

I'm getting the following error and can't for the life of me figure out what I'm doing wrong.
$ gcc main.c -o main
Undefined symbols:
"_wtf", referenced from:
_main in ccu2Qr2V.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
main.c:
#include <stdio.h>
#include "wtf.h"
main(){
wtf();
}
wtf.h:
void wtf();
wtf.c:
void wtf(){
printf("I never see the light of day.");
}
Now, if I include the entire function in the header file instead of just the signature, it complies fine so I know wtf.h is being included. Why doesn't the compiler see wtf.c? Or am I missing something?
Regards.
You need to link wtf with your main. Easiest way to compile it together - gcc will link 'em for you, like this:
gcc main.c wtf.c -o main
Longer way (separate compilation of wtf):
gcc -c wtf.c
gcc main.c wtf.o -o main
Even longer (separate compilation and linking)
gcc -c wtf.c
gcc -c main.c
gcc main.o wtf.o -o main
Instead of last gcc call you can run ld directly with the same effect.
You are missing the fact that merely including a header doesn't tell the compiler anything about where the actual implementation (the definitions) of the things declared in the header are.
They could be in a C file next to the one doing the include, they could come from a pre-compiled static link library, or a dynamic library loaded by the system linker when reading your executable, or they could come at run-time user programmer-controlled explicit dynamic loading (the dlopen() family of function in Linux, for instance).
C is not like Java, there is no implicit rule that just because a C file includes a certain header, the compiler should also do something to "magically" find the implementation of the things declared in the header. You need to tell it.

Resources