GCC - Linking is unsuccessful - gcc

and sorry for my not really good english. I'll try my best :)
I am trying to compile a addin for my Casio graphic calculator in C. This works without problems when using the official SDK. Because it is only available for Windows, I want to use gcc.
So I got sh-rtems-gcc and it's binutils from macports and tried to compile my program according to this instructions. I copy-pasted the described addin.ld and crt0.s and placed my main.c and libfxsys.a (from the same guys as the instructions mentioned above) in the same directory. The sub-dir include contains fxsys' headers. I verified the presence of all the functions of the library in the .a file with nm.
When using this command for compilation:
sh-rtems-gcc-4.2.3 -m3 -mb -nostdlib -I./include -c crt0.s main.c
Everything works fine. But then im trying to link:
sh-rtems-gcc-4.2.3 -m3 -mb -nostdlib -L. -o myaddin.elf -Taddin.ld crt0.o main.o -lfxsys
and get the following error:
main.o: In function `__main':
main.c:(.text+0x248): undefined reference to `_Bdisp_AllClr_VRAM'
...
... (--- cut 16 other errors in the same format ---)
...
main.c:(.text+0x360): undefined reference to `_Sleep'
./libfxsys.a(locate.o): In function `_locate':
locate.c:(.text+0x28): undefined reference to `_locate_OS'
collect2: ld gab 1 als Ende-Status zurück
All the missing symbols are in the libfxsys.a. I have verified this with nm.
I have already played with the positions of the library in the command, as this is often mentioned as a source of failure in other posts found in google, but without success. I also tried adding and removing the -lgcc option that is used in the above mentioned instructions, without success.
My Host-Machine is a Intel Mac, OS X 10.6
Because I have no idea how to solve this problem, and get to compile my program, I have to ask: What am I doing wrong? How can I compile my program without using the SDK?
Thanks in advance,
xythobuz
Edit:
I have also tried linking with:
sh-rtems-ld -EB -L. -o myaddin.elf -Taddin.ld crt0.o --start-group main.o libfxsys.a --end-group
But it produces the same output as above.

I can't say the exact problem, but would investigate like this:
Find the library that contains the missing symbols. Use nm to see symbol names
Once you know which library contains the symbols make sure you're linking to it, and in the correct order. Try using recursive symbol resolution options -( -) with your linker.

Related

How to create .so shared libraries with undefined references - gcc

I have inherited a Makefile which builds a .so file. It is linking with -lcrypto from OpenSSL on Ubuntu with gcc 4.7.4. Critically, it is NOT linking with -lssl nor -ldl, and when I run nm -g thelib.so, it only has the ~15 symbols from openssl crypto. However, they are all U (undefined).
I'm refactoring the Makefile on another Ubuntu machine. When I link with -lcrypto, it fails due to undefined symbols needed from dl. When I add linking to -ldl, those errors go away and linking succeeds. However, my .so file is 1.5 MB bigger than the original, and there are at least a hundred symbols related to SSL, which are all T (defined), which seem to indicate that -lssl is happening implicitly somehow.
While it would seem prudent and good that they are all defined in my case, I need to figure out how to produce the same result just as it is.
So, my question is, how does one get GCC to allow the linking of a .so file and accept undefined references? I've compared our commands, and there are little differences which I've tried to eliminate, but nothing seems to work. I read that it might be related to -Wl,--no-as-needed, but i'm using that. Here's my linker flags.
g++ -shared -o mylib.so myobjs.o -fPIC -lstdc++ -lm -z defs -Wl,-soname,mylib -Wl,--no-as-needed -lpthread -lcrypto -lz
On the other system (the one with the larger result), OpenSSL has apparently not been built as a shared object, only as a static library (but maybe as PIC, so that you can link the result into a shared object). You will have to install the packages that provide the shared object and the corresponding .so symbolic link.

OSX: How do I convert a static library to a dynamic one?

Suppose I have a third party library called somelib.a on a Mac running Mountain Lion with Xcode 4.4 installed. I want to get a dynamic library out of it called somelib.dylib. An appropriate Linux command would be:
g++ -fpic -shared -Wl,-whole-archive somelib.a -Wl,-no-whole-archive -o somelib.so
where -whole-archive and -no-whole-archive are passed to the linker.
When I do the equivalent for Mac:
g++ -fpic -shared -Wl,-whole-archive somelib.a -Wl,-no-whole-archive -o somelib.dylib
ld fails with an error:
ld: unknown option: -whole-archive
It seems that the ld on OSX is different from GNU ld. How do I have to modify above command so I will get the desired result?
Thank you in advance!
I found out the solution to my problem:
g++ -fpic -shared -Wl,-force_load somelib.a -o somelib.dylib
The required argument is -force_load:
Which needs to be followed by a single library you wanna ensure gets loaded.
I mean, it needs to be repeated for each library (unlike -noall_load approach, which wrapped them).
For example, -Wl,-force_load libYetAnotherFile.a (where -Wl, part is only required because we don't pass parameter directly to linker).
Note that Old answer (before edit) was using -noall_load instead, but nowadays that causes a linker error (as -noall_load has been removed, was obsolete previously).
Note: A link for the documentation of the OSX ld linker.
http://www.unix.com/man-page/osx/1/ld/
I know it is late to give an answer for this, but I do not have enough reputation to make a comment on #hanslovsky answer.
However, it helps me a lot to have the docs of the options too.
It helps what the options do exactly, and that other options the ld linker also has.
So I just wanted to share with others who finds linking an issue.
UPDATE:
After the comment from #GhostCat I have decided to expand my answer.
The docs for -all_load is:
-all_load
Loads all members of static archive libraries.
So it loads for all static libraries that you note.
If you want something similar to --whole-archive and --no-whole-archive, then you need to use -force_load and -noall_load.
-force_load "path_to_archive"
Loads all members of the specified static archive library. Note: -
all_load forces all members of all archives to be loaded.
This option allows you to target a specific archive.
-noall_load
This is the default. This option is obsolete.
Then you can define which libraries to fully load with -force_load and then later turn it off again with -noall_load.
According to the ld manual, -noall_load is the default and is ignored. (If you use it, you get an error message: ld: warning: option -noall_load is obsolete and being ignored)
Apparently the way to get -all_load to apply to only one library is as follows:
-Wl,-force_load,somelib.a

undefined reference to `dl_iterate_phdr'

I need an help!! I am trying to build a standalone executable ie without ANY dynamic linking.
I wrote a small test program, generated a relocatable object file for it called test.o. When I try to build the standalone executable using GNU linker I get the below error:
$ld -static -o test test.o /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/libc.a /usr/lib/gcc/i486-linux-gnu/4.4/libgcc.a /usr/lib/gcc/i486-linux-gnu/4.4/libgcc_eh.a
/usr/lib/gcc/i486-linux-gnu/4.4/libgcc_eh.a(unwind-dw2-fde-glibc.o): In function _Unwind_Find_FDE':
(.text+0x190b): undefined reference todl_iterate_phdr'
How to resolve the undefined symbol dl_iterate_phdr. In which archive this symbol is present?
Thanks!!!
EDIT1:
Just in case if I am not very clear, my motive is to generate a standalone executable ie an executable which is completely ready for execution while it gets loaded into memory i.e.) all symbol resolution and relocation is done by program linker itself instead of dynamic linker. Is it possible to generate such an executable?
FINAL UPDATE:
Now I got it to get complied with ld directly using the below command:
$ld -static -o test /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.4.3/crtbeginT.o /usr/lib/gcc/i486-linux-gnu/4.4.3/crtend.o test.o --start-group /usr/lib/gcc/i486-linux-gnu/4.4.3/libgcc.a /usr/lib/gcc/i486-linux-gnu/4.4.3/libgcc_eh.a /usr/lib/libc.a --end-group
man ld says --start-group archives --endgroup is used to resolve circular references!! Also i find symbol dl_iterate_phdr is defined in libc.a.
Thanks all for your help!!
When I try to build the standalone executable using GNU linker
Don't. Use of ld to link any user-space program is most often a bug. Your link line is certainly incorrect.
Use compiler driver to do the heavy lifting for you. This should work:
gcc -static -o test test.o
I am looking to use ld since I wanted to build a standalone executable
What makes you believe that GCC-built executable is less stand-alone than ld-built one? Whatever it is, you are mistaken: gcc simply invokes ld with correct arguments.
If you're getting this error when targeting android, you need to link against libdl.so (-ldl)
gcc -o main main.c -L . -static-libgcc -Wl,-static -lhello -lc

Order of objects in a static library

I have a C project using several object files that needs to be linked in a specific order to find all needed symbols.
For example this command works fine (lib2.o depends on lib1.o etc.)
gcc -o my_app main.o lib1.o lib2.o lib3.o -lm
but
gcc -o my_app main.o lib3.o lib2.o lib1.o -lm
ends with undefined reference to `my_variable' errors.
This is a known behavior and can be solved for example by adding these objects to GROUP section in a linker script.
Now I'd like to share these object as a static library with my colleagues. So...
ar -rcs mylib.a lib1.o lib2.o lib3.o
gcc -o my_app main.o mylib.a -lm
Unfortunately this gives the same undefined reference errors like the specifying the objects in incorrect order.
I have not found any linker or archiver options to make it working and also no solution by googling even if I think that this problem should be relatively common.
Do please anybody know a solution?
regards
Jan
This might be a link order problem. When the GNU linker sees a library, it discards all symbols that it doesn't need. It also does that in the sequential order form left to right.
Recent versions of gcc/ld default to linking with --as-needed flag.
This means if you write -lmylib.a before the C file the library will automatically get excluded (the order matters when testing if things are "needed" like this)
You can fix this with either:
gcc -L. -o example example.c -lmylib.a
gcc -L. -Wl,--no-as-needed -o example example.c -lmylib.a
The latter of which passes --no-as-needed to the linker, which would cause the library to still be linked, even if you didn't call any function external from it.
Your error implies that the problem is in one of your lib?.o files [lib{later}.o depends on lib{earlier}.o]
How did you manage to compile them?
Were there any compilation warnings?
It has been a while since I used C, but I think that you will need to include dependent libraries within the library that has the dependency - this may be the reason why you can't find too many references to the problem, because it does not really exist.

Very strange linker behavior

This is strange because I was able to get the error below to go away by removing the reference to libm.
gcc -o example example.o -Wl -L/home/kensey/cdev/lib -L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lz -L/usr/lib/x86_64-linux-gnu -lm -lrt -ldl -lcdev -L/home/kensey/www.tools/gplot-lib -lgplot -L/home/kensey/www.tools/gd1_3ret -lgd -lxml2 -lcurl
/usr/bin/ld: /home/kensey/www.tools/gplot-lib/libgplot.a(set.o): undefined reference to symbol 'floor##GLIBC_2.2.5'
/usr/bin/ld: note: 'floor##GLIBC_2.2.5' is defined in DSO /usr/lib/x86_64-linux-gnu/libm.so so try adding it to the linker command line
/usr/lib/x86_64-linux-gnu/libm.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status
So, if I remove the -lm part of the command, I do not get the error. However, I wonder if anyone knows as to why removing a reference to a library that is needed would fix this. How does the linker know which library to look in? Also - is there a way to query a built executable and say 'which library did you resolve the reference to 'floor'? obviously, there is something going on that I don't understand, and that bothers me...
The explanation to what's happening is very simple:
Your libgplot.a depends on libm.so, yet the order of -lm and -lgplot on the link line is wrong.
The order of libraries on the link line does matter. In general, system libraries (-lpthread, -lm, -lrt, -ldl) should follow everything else on the link line.
When you remove -lm from the link line, libm.so.6 is still pulled into the link by some other library that appears later on the link line (libgd, libxml2 or libcurl) because that library depends on libm.so.6. But now libm.so.6 is in correct place on the link line, and so everything works.
if I put -lm at the end of the link command, listing it as the last library, I do not get the error.
That confirms above explanation.
I've solved the same problem with export LDFLAGS="$LDFLAGS -lm"
Perhaps, your library search paths (/usr/local/lib/ or /usr/lib/, ...) do not contain 64bit libm so gcc cannot locate it if you specify with l flag. If you only specify only the directory it looks like it can find the right one. So you can try:
LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu
and use -lm
Hard to tell. Because there are custom library directories in the command line it's conceivable that -lm links an incompatible alternative version. Without -lm the linker could pull in another version of it because it's needed by one of the libraries you link.
To make sure strace both invocations and see where libm.so is coming from in both cases.
BTW, -Wl switch seems to do nothing and -L/usr/lib/x86_64-linux-gnu is mentioned twice.
Just to add to the list of answers, http://fedoraproject.org/wiki/UnderstandingDSOLinkChange It is informative. It isn't relevant to the question asked above, but, the explanation relates to the error message /usr/bin/ld: note: 'some_reference' is defined in DSO some.so so try adding it to the linker command line
One explanation could be:
It's possibly there is a weakly linked function foo defined outside of libm that is replaced by a strongly linked version of foo defined inside libm, and it is this strongly linked version that calls the undefined function.
This would explain how adding a library can cause an undefined function error.
I just ran into a similar problem; I remember that the order of the libraries did not matter (at least not in the cases I worked with) in the past for gcc. In this question here somebody noticed that the behaviour seems to have changed between 4.4 and 4.5 .
In my case, I got rid of the error message by doing the linking at:
g++ -Wl,--copy-dt-needed-entries [options] [libraries] [object files] -o executable-file
I faced the similar issue because I had manually updated the dev toolchain on my centOS machine to solve a VScode Remote dependency and was linking C++ library with c code.
In my case, I solved this by adding in the Makefile:
LDFLAG=-Wl,--copy-dt-needed-entries
I also pointed my gcc to the version I wanted (After updating toolchain, gcc pointed to the toolchain : /opt/rh/devtoolset-2/root/usr/bin/gcc)
CC=\usr\bin\gcc which is (gcc version 4.4.7)
Use this:
administrator#administrator-Veriton-M200-H81:~/ishan$ gcc polyscanline1.cpp -lglut -lGLU -lGL -lm

Resources