Creating a shared library with an undefined reference on Cygwin - c

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?

Related

C libm.a not needed to be linked when compiling

I was trying to compile a source file that includes <math.h>.
However I succeeded in creating an executable, no error without linking to libm.a.
The command I typed was gcc -Wall filename.c -o executablename
I was told to link to the external libraries (i.e/ libraries other than libc.a)
What's going on?
#include <math.h>
#include <stdio.h>
int main(void)
{
double x = sqrt(2.0);
printf ("The sqrt of 2 is: %f\n", x);
return 0;
}
The math functions you call are implemented by compiler built-in functions. Try the following if you want to see an error message:
gcc -fno-builtin -Wall filename.c -o executablename
For example, on my platform (Ubuntu 14.04.3 LTS), I get this error message:
$ cat x.c
#include <math.h>
#include <stdio.h>
int main(void)
{
double x = sqrt(2.0);
printf ("The sqrt of 2 is: %f\n", x);
return 0;
}
$ gcc -fno-builtin x.c
/tmp/ccpjG2Pb.o: In function `main':
x.c:(.text+0x1c): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
Some compilers, like the current clang on OS X (which masquerades as gcc) do not need to be told to link your executable with the math library.
The clang on OS X will link your executable with /usr/lib/libSystem.B.dylib (and only this for a simple program). This library in turn uses the library /usr/lib/system/libsystem_m.dylib which is the math library.
The functions in <math.h> (or the preferable <tgmath.h>) are part of the C library just as many other functions. It is platform dependent if all the functions in the C library are actually linked in one single library or separately in multiple chunks.
In ancient times the size of the libraries was a problem for link time, the larger a library was, the longer it took to link executables that had many unresolved symbols. These times are long gone, but the separation on some platforms into libc.a and libm.a prevails.
If your platform doesn't need -lm for linking it should have a dummy (empty) version of libm.a just that there is no error when you have that on your link command line. This is for example the case for the musl C library that is at the base of Alpine Linux.

Working with Influxdb connection in C Programming raising undefined referece to influxdb_client_new

This is main.c file I am trying to work with influxdb library I hope I installed it clearly with my knowledge here are the screen shots of library
This is linked library
This is the path of the library
This is the code file
#include <influxdb/influxdb.h>
int main() {
int status;
s_influxdb_client *client = influxdb_client_new("xxxxxxxxxx", "influxdb", "xxxxxxxxxxxxxx", "", 0);
status = influxdb_create_database(client, "toto");
influxdb_client_free(client);
return status != 201;
}
This is how I executing the command in gcc to compile and run
gcc -I/usr/local/include/ -L/usr/local/lib -linfluxdb -o john john.c
Even though I included the library it raising undefined reference
This is what my error is
/tmp/cce9K1Kh.o: In function `main':
john.c:(.text+0x23): undefined reference to `influxdb_client_new'
john.c:(.text+0x38): undefined reference to `influxdb_create_database'
john.c:(.text+0x47): undefined reference to `influxdb_client_free'
collect2: error: ld returned 1 exit status
This is where I found library and Followed the instructions in Read Me file Everything is performed smooth Influxdb
Please let me know if you need more information
The influxdb README.md is b0rken. Ordering of command-line arguments to gcc (or the linker actually) matters; the -linfluxdb must come after your john.c on the command line.
Thus, try compiling/linking with with
gcc -I/usr/local/include/ -L/usr/local/lib -o john john.c -linfluxdb

Linking fails with gcc 4.8.2 / ld 2.24, succeeds with gcc 4.4.7 / ld 2.20

In a chroot based on CentOS 6.4 I'm working in, linking against ncurses with ld 2.20 succeeds, but linking with ld 2.24 fails. I don't directly invoke the linker, gcc is handling it -- gcc 4.4.7 is using ld 2.20, and gcc 4.8.2 is using ld 2.24.
Here is a minimal example that fails to link with gcc 4.8.2 / ld 2.24 in my particular environment.
#include <ncurses.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
WINDOW* window = NULL;
if (!(window = initscr())) {
printf("Error initializing ncurses.");
exit(1);
}
halfdelay(50);
getch();
endwin();
}
Success (ld 2.20):
$ gcc main.c -lncurses -Wl,--verbose | grep "ncurses.*succeeded"
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libncurses.so succeeded
$
Failure (ld 2.24):
$ /opt/gcc/4.8.2/bin/gcc48 main.c -lncurses -Wl,--verbose | grep "ncurses.*succeeded"
attempt to open /usr/lib/../lib64/libncurses.so succeeded
/opt/binutils/2.24/bin/ld24: /tmp/ccCxUFxl.o: undefined reference to symbol 'halfdelay'
/lib64/libtinfo.so.5: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
$
Note that both commands appear to link against the same libncurses.so.
For what it's worth, in a different chroot based on CentOS 5.4, there is a different libncurses version, and it links fine with ld 2.24, but unfortunately, building in that chroot is not an option. The nm utility shows that the (static) libncurses.a here does have the required symbols (nm lists no symbols for libncurses.so -- so I'm just assuming they are similar).
In the CentOS 6.4 chroot, however, nm shows that all of the ncurses symbols I'm getting "undefined reference" messages for are indeed undefined or not present in libncurses.a in the Centos 6.4 chroot, which is confusing, because linking with gcc 4.4.7 works. Something is not right.
Also, I tried producing an object with gcc 4.4.7, and then linking with gcc 4.8.2, but that did not help.
I'm confused as to why the one compiler / linker would succeed while the other would fail. Is this an ABI issue? Does anyone know what is happening here? Are there any flags I can pass to gcc to make the new linker work?
Your libncurses library is itself linked to libtinfo, which causes your older toolchain to also look for symbols in libtinfo.
But newer toolchains normally runs the linker with the --as-needed, and the --no-copy-dt-needed-entries, the latter which probably causes the difference you're seeing.
Basically you'll need to link to libtinfo as well, which is where the halfdelay function resides.
gcc main.c -lncurses -ltinfo

How do I link to FreeImage?

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.

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.

Resources