How can I force gcc/ld to go ahead and link a (partially) usable executable despite a missing shared library (and associated missing symbols)?
Context: I have a hardware driver that is distributed only as a 32 bit ELF binary blob (libEposCmd.so). It depends on a library (libftd2xx.so) that I know from context is not actually used (the ftdi stuff is for usb-serial adapters, which I'm not using).
gcc main.o -o epos_server -m32 -L/usr/lib32 -L/usr/local/lib32 -lEposCmd
/usr/bin/ld: warning: libftd2xx.so.0, needed by /usr/local/lib32/libEposCmd.so, not found (try using -rp
ath or -rpath-link)
main.o: In function `main':
/usr/local/lib32/libEposCmd.so: undefined reference to `FT_Write'
/usr/local/lib32/libEposCmd.so: undefined reference to `FT_SetDataCharacteristics'
/usr/local/lib32/libEposCmd.so: undefined reference to `FT_GetDeviceInfoDetail'
/usr/local/lib32/libEposCmd.so: undefined reference to `FT_SetFlowControl'
...
My only undefined references are FT_*, which I am fairly certain all belong to libftd2xx.
Ugly hacks are acceptable; this is research code and we hope to replace this hardware (maxon epos2 motor driver) with something with better linux support ASAP.
Update: The .so is ~not stripped, so it should be possible to extract prototypes for the missing functions...
The quickest way is to create a dummy lib with the missing functions and link with it.
Related
a.out call function fooA() using dlopen function to open libA.so.
fooA() is defined in libA.so //dynamic library
fooA() call function fooB();
fooB() is defined in libB.a //statistic library
fooB() call function fooC();
fooC() is defined in libC.so //dynamic library
libA.so libB.a libC.so are not in the same folder.
****
It's ok when i compile them .But i got runtime error which is "symbol lookup error: libA.so: undefined symbol: fooC()" .I dont know why . And how to solve this problem that functions called between dynamic library and statistic library?
I am sorry . My English is poor .I don't know whether i describe my question clearly or not.
Is anything in your binary bringing in libC.so? (directly or through dlopen() with RTLD_GLOBAL)? If not, that's your problem.
libA.so should be built to link to libC (and it was not).
On building Glibc on my toolchain . The libraries make succesfully (and test ok) all FLAGS unset except for those specified for building default glibc. then i start building the programs both with and without FLAGS on seperate fresh build attempts and every time something in the iconv folder always breaks...
I'll diverge for a second to moan how its always iconv that breaks in GLibc for me and always has done for as long as i can remember... moving on though....
When gcc-4.8.0 is passed gcc -nostdlib -nostartfiles -o /glibc-build/iconv/iconvconfig -Wl,-dynamic-linker=/tools/lib/ld-linux-x86-64.so.2 -Wl,--hash-style=both -Wl,--warn-shared-textrel,--fatal-warnings /glibc-build/csu/Scrt1.o /glibc-build/csu/crti.o gcc --print-file-name=crtbeginS.o /glibc-build/iconv/iconvconfig.o /glibc-build/iconv/strtab.o /glibc-build/iconv/xmalloc.o /glibc-build/iconv/hash-string.o -Wl,-rpath-link=/glibc-build:/glibc-build/math:/glibc-build/elf:/glibc-build/dlfcn:/glibc-build/nss:/glibc-build/nis:/glibc-build/rt:/glibc-build/resolv:/glibc-build/crypt:/glibc-build/nptl /glibc-build/libc.so.6 /glibc-build/libc_nonshared.a -Wl,--as-needed /glibc-build/elf/ld.so -Wl,--no-as-needed -lgcc gcc --print-file-name=crtendS.o /glibc-build/csu/crtn.o
gcc -nostdlib -nostartfiles -o /glibc-build/iconv/iconv_prog -Wl,-dynamic-linker=/tools/lib/ld-linux-x86-64.so.2 -Wl,--hash-style=both -Wl,--warn-shared-textrel,--fatal-warnings /mnt/lfs/glibc-build/csu/Scrt1.o /glibc-build/csu/crti.o gcc --print-file-name=crtbeginS.o /glibc-build/iconv/iconv_prog.o /glibc-build/iconv/iconv_charmap.o /glibc-build/iconv/charmap.o /glibc-build/iconv/charmap-dir.o /glibc-build/iconv/linereader.o /glibc-build/iconv/dummy-repertoire.o /glibc-build/iconv/simple-hash.o /glibc-build/iconv/xstrdup.o /glibc-build/iconv/xmalloc.o -Wl,-rpath-link=/glibc-build:/glibc-build/math:/glibc-build/elf:/glibc-build/dlfcn:/glibc-build/nss:/glibc-build/nis:/glibc-build/rt:/glibc-build/resolv:/glibc-build/crypt:/glibc-build/nptl /glibc-build/libc.so.6 /glibc-build/libc_nonshared.a -Wl,--as-needed /glibc-build/elf/ld.so -Wl,--no-as-needed -lgcc gcc --print-file-name=crtendS.o /glibc-build/csu/crtn.o
i get 2 pages of referencing issues
/glibc-build/iconv/iconvconfig.o: In function more_help':
iconvconfig.c:(.text+0x12e): undefined reference to__tsan_func_entry'
iconvconfig.c:(.text+0x136): undefined reference to __tsan_write8'
iconvconfig.c:(.text+0x150): undefined reference to__tsan_func_exit'
iconvconfig.c:(.text+0x1cc): undefined reference to __tsan_read8'
/glibc-build/iconv/iconvconfig.o: In functionalias_compare':
iconvconfig.c:(.text+0x226): undefined reference to __tsan_func_entry'
iconvconfig.c:(.text+0x233): undefined reference to__tsan_read1'
iconvconfig.c:(.text+0x246): undefined reference to __tsan_read8'
iconvconfig.c:(.text+0x25d): undefined reference to__tsan_read1'
iconvconfig.c:(.text+0x26e): undefined reference to __tsan_read8'
iconvconfig.c:(.text+0x282): undefined reference to__tsan_func_exit'
iconvconfig.c:(.text+0x2b4): undefined reference to __asan_report_load8'
iconvconfig.c:(.text+0x2b9): undefined reference to__asan_report_load8'
/glibc-build/iconv/iconvconfig.o: In function module_compare':
iconvconfig.c:(.text+0x2fb): undefined reference to__tsan_func_entry'
iconvconfig.c:(.text+0x308): undefined reference to __tsan_read1'
iconvconfig.c:(.text+0x326): undefined reference to__tsan_read8'
iconvconfig.c:(.text+0x337): undefined reference to __tsan_read1'
iconvconfig.c:(.text+0x34a): undefined reference to__tsan_read8'
iconvconfig.c:(.text+0x36f): undefined reference to __tsan_func_exit'
iconvconfig.c:(.text+0x3a6): undefined reference to__asan_report_load8'
iconvconfig.c:(.text+0x3ab): undefined reference to __asan_report_load8'
/glibc-build/iconv/iconvconfig.o: In functionname_compare':
after 2 weeks of trying to get it to compile every which way possible im getting a bit fed up. Any ideas please?
Emma
A bit late, but hopefully useful.
The symbols with tsan and asan in their name are related to the address sanitizer project that provides LLVM clang and gcc with tools to detect and report a whole range of problems related to illegal memory access.
To use them you have to install tools and libraries, use the correct versions of the compilers and the correct combinations of flags during compile and linking depending on your version.
In my experience the documentation is only so useful, and the topic is pretty advanced. In my project over which I have full control, I ended up disabling all but the one commandline parameter -fsanitize=address together with the recommended -fno-omit-frame-pointer for both compile and link (gcc 4.8 on x64 ubuntu 14.04LTS).
Since you are attempting to build an existing project, you are at the mercy of their settings. I would look at docs for that project and try to determine the recommended versions of compiler and sanitizer tools from there, or maybe some configuration options to disable it if you don't care.
I'm trying to compile an example programme using tk. I have nearly all of the libraries sorted, but I think I'm missing one.
Command:
gcc ./tk.c -I/usr/include/tcl8.5/ -ltk8.5 -ltcl8.5 -lm -lpthread -lfontconfig -lX11 -lXft -lXss
Output:
/tmp/cc78MM6w.o: In function `Tk_AppInit':
tk.c:(.text+0xf5): undefined reference to `ClockCmd'
tk.c:(.text+0x120): undefined reference to `ClockObjDestroy'
tk.c:(.text+0x130): undefined reference to `ClockObjCmd'
There's nothing on Google -- anyone recognise ClockCmd? Thanks.
I think those are part of the implementation of Tcl, and should not be referred to outside the Tcl library itself. (The linker is instructed to remove the external reference to them when building the DLL/shared object.) Either that or they are part of your code, and you've simply not supplied them for some reason, but I think you'd know if that was the case.
It would be far easier to work out what's going on if we could actually see the code of tk.c; it's clearly not part of any Tcl or Tk code distribution.
Something wrong with the example code I think; none of the other examples had a problem.
I am trying to build a tool called sscep (http://www.klake.org/~jt/sscep/) for Windows. It does not run natively and I have a "patch" that changes sscep to make it compile on Windows.
After applying the patch, it does compile perfectly but the linker screws. I am using gcc in minGW/msys
The original messsage was that it couldn't find the crypto lib so I added the library with "-L../openssl-mingw/lib" which then didn't create any more errors. I also have the command line switch -lcrypto in my command: gcc -L../openssl-mingw/lib -lcrypto sscep.o init.o net.o sceputils.o pkcs7.o ias.o fileutils.o -o sscep.In this directory is a libcrypto.a. OpenSSL itself was compiled with the exact same compiler just running ./config && make && make test && make install. Also the sources were extracted using the minGW tar and not 7-zip.
After following all documentation this is my (truncated) output:
sscep.o:sscep.c:(.text+0x83): undefined reference to `WSAStartup#8'
sscep.o:sscep.c:(.text+0xa5): undefined reference to `WSACleanup#0'
sscep.o:sscep.c:(.text+0x3d5): undefined reference to `BIO_new_mem_buf'
sscep.o:sscep.c:(.text+0x3e0): undefined reference to `ASN1_INTEGER_new'
sscep.o:sscep.c:(.text+0x414): undefined reference to `a2i_ASN1_INTEGER'
sscep.o:sscep.c:(.text+0x432): undefined reference to `ASN1_INTEGER_to_BN'
sscep.o:sscep.c:(.text+0x448): undefined reference to `BN_bn2dec'
sscep.o:sscep.c:(.text+0xb7e): undefined reference to `EVP_des_cbc'
sscep.o:sscep.c:(.text+0xbaf): undefined reference to `EVP_bf_cbc'
sscep.o:sscep.c:(.text+0xbda): undefined reference to `EVP_des_cbc'
sscep.o:sscep.c:(.text+0xc02): undefined reference to `EVP_des_ede3_cbc'
sscep.o:sscep.c:(.text+0xc48): undefined reference to `EVP_md5'
sscep.o:sscep.c:(.text+0xc79): undefined reference to `EVP_md5'
sscep.o:sscep.c:(.text+0xca1): undefined reference to `EVP_sha1'
This goes on for every file in there and supposedly every function called.
Searching here and google resulted in a missing library but omitting the -L directive from above I get another error about not finding libcrypto. So I assume that the library is actually found but somewhat with wrong addresses or something?
Here my compiler/linker knowledge actually ends.
If it is possible that the patch is responsible for that (which I do not believe since these are all openssl functions and the compiling works) then I can provide you with it.
Edit: Is there any information that I should provide so someone can help me? The version of openssl is 1.0.1 if this makes any difference.
On this topic: If it does make a difference, could this error occur because of a wrong version. As far as I understand linker theory, this error should not originate from a wrong version unless all of the below functions were replaced by differently named ones (but then the compiler would have complained, I guess?).
Another addition: Since I am on a 64 bit Windows 7, I tried to compile it with -m32 flag but that did not help. I assume since mingw is already 32 bit only, I can't even build x64. Another question is whether it is a problem that I am running in a virtualized environment on an AMD Opteron while openssl is built with the command "-march=i486"?
With some help I could finally figure this out! It was a problem of the order AND a problem of missing libraries. The combination killed me.
The libraries had to be -lcrypto -lws2_32 -lgdi32 not just -lcrypto. Furthermore, I had to append the libraries after the object files, so: $(CC) $(CFLAGS) $(OBJS) -lcrypto -lws2_32 -lgdi32 -o $(PROG) was the right make line.
Finally with this, it compiles fine. I didn't even need any architecture flags and such.
I am trying to link a C++ module using GCC, essentially like this:
gcc -c hello.c
g++ -c world.cpp
gcc -ohello -lstdc++ hello.o world.o
Note that I use -lstdc++ to link the C++ module in, so that I can use gcc instead of g++. The problem is that I'm getting the error:
undefined reference to `operator new(unsigned long)'
(Assuming that world.cpp contains at least one call to new.)
This error is fixed if I put -lstdc++ at the end of the linker line, like this:
gcc -ohello hello.o world.o -lstdc++
I am aware that this question has been asked many times here, but I have a special requirement. I am not directly calling GCC. I am using a build system for a different programming language (Mercury) which is calling GCC on my behalf, and I can't easily modify the way it calls GCC (though I can specify additional libraries using the LDFLAGS environment variable). So I have two additional requirements:
I cannot use g++ to link (only gcc) -- that is why I am doing the -lstdc++ trick above rather than simply linking with g++).
I don't think that I can control the order of the linker commands -- Mercury will put the .o files on the command-line after any libraries.
I understand the basic reason why the order is important, but what is baffling me is why did this break now? I just updated to Ubuntu 11.10 / GCC 4.6.1. I have been successfully compiling this program for years using precisely the above technique (putting -lstdc++ first). Only now has this error come up. An unrelated program of mine links against OpenGL using -lgl and that too broke when I upgraded and I had to move -lgl to the end of the command-line. I'm probably going to discover that dozens of my programs no longer compile. Why did this change? Is there something wrong with my new system or is that the way it is now? Note that these are ordinary shared libraries, not statically linked.
Is there anything I can do to make GCC go back to the old way, where the order of libraries doesn't matter? Is there any other way I can convince GCC to link libstdc++ properly without moving it after the .o files on the command-line?
If Mercury puts object files after libraries, Mercury is broken. Libraries belong after object files - always. You may sometimes get away with the reverse order, but not reliably. (Static libraries must go after the object files that reference symbols in the static library. Sometimes, a linker will note the symbols defined by a shared library even when none of the symbols are used; sometimes, the linker will only note the shared library symbols if the shared library provides at least one symbol.)