Link C++-Library dynamically with gcc crosscompiler
Posted: Sun Jul 18, 2010 3:44 am
Hi!
I'm trying to link my small C++-"standard"-library dynamically to my C++-user-applications. I have a working gcc crosscompiler and use libgcc and libsupc++ of it. When I link statically everything works.
Its not easy for me to describe the problem because there are many, depending on how I do things. But I'll try
So, gcc provides the crtbegin.o and crtend.o for me with .init and .fini, __do_global_ctors_aux, frame_dummy etc.. I provide the crt0.o with the _start symbol and some additional os-specific stuff. To build a real function in .init and .fini I provide a crt1.o and crtn.0 as well. They simply add the function-prolog and -eiplog to the calls of frame_dummy, __do_global_ctors_aux and __do_global_dtors_aux. To achieve that I tell gcc about the files in my gcc-config:
(Inspired by the linux-way of doing it)
So far, so good. As you can see, I want to use different files (crt*S.o) when building a shared library (like linux does). There's the first problem: who should provide crtbeginS.o and crtendS.o? Since gcc gives me crtbegin.o and crtend.o, I guess, gcc should give me that files, too. But how do I tell that gcc?
At the moment I have created a symlink from crtbeginS.o to crtbegin.o and the same for crtend. But that can't really work in the end. But anyway, perhaps there are other problems as well; therefore I'll tell you how I build the libstdc++.so and so on:(the object files are created with -fPIC)
I.e. since I don't specify -nostartfiles the crt*S.o are put into it, too. If I specify that flag ld complains about that __dso_handle is missing. When I look into the libstdc++.so of linux, there seem to be no startfiles except the stuff in .init and .fini. But I don't know how they achieve that; or in other words: why are there no references of __dso_handle? (they are put into my lib because I have some static objects for which the constructor is called at startup. This constructor has a call to atexit with __dso_handle as argument)
In this way it "works" so far. But I get a warning-message:
Thats correct, because I skip that symbol for shared libraries. When I don't skip it, the linker complains about "multiple definitions" when I try to link a userapp to libstdc++.so. There are some similar issues even without _start. If I try to link a userapp with the following:
I get:
I'm not sure whats correct and whats wrong here.
I hope I've described the problem well enough. If not, feel free to ask
Thanks in advance!
hrniels
I'm trying to link my small C++-"standard"-library dynamically to my C++-user-applications. I have a working gcc crosscompiler and use libgcc and libsupc++ of it. When I link statically everything works.
Its not easy for me to describe the problem because there are many, depending on how I do things. But I'll try
So, gcc provides the crtbegin.o and crtend.o for me with .init and .fini, __do_global_ctors_aux, frame_dummy etc.. I provide the crt0.o with the _start symbol and some additional os-specific stuff. To build a real function in .init and .fini I provide a crt1.o and crtn.0 as well. They simply add the function-prolog and -eiplog to the calls of frame_dummy, __do_global_ctors_aux and __do_global_dtors_aux. To achieve that I tell gcc about the files in my gcc-config:
Code: Select all
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{shared|pie:crt0S.o%s;:crt0.o%s} %{shared:crt1S.o%s;:crt1.o%s} %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "%{shared|pie:crtendS.o%s;:crtend.o%s} %{shared:crtnS.o%s;:crtn.o%s}"
So far, so good. As you can see, I want to use different files (crt*S.o) when building a shared library (like linux does). There's the first problem: who should provide crtbeginS.o and crtendS.o? Since gcc gives me crtbegin.o and crtend.o, I guess, gcc should give me that files, too. But how do I tell that gcc?
At the moment I have created a symlink from crtbeginS.o to crtbegin.o and the same for crtend. But that can't really work in the end. But anyway, perhaps there are other problems as well; therefore I'll tell you how I build the libstdc++.so and so on:
Code: Select all
i586-elf-escape-g++ -nodefaultlibs -shared -Wl,-soname,libstdc++.so -o libstdc++.so <many objectfiles> -lc -lsupc++ -lgcc -L../../build/dist/lib
I.e. since I don't specify -nostartfiles the crt*S.o are put into it, too. If I specify that flag ld complains about that __dso_handle is missing. When I look into the libstdc++.so of linux, there seem to be no startfiles except the stuff in .init and .fini. But I don't know how they achieve that; or in other words: why are there no references of __dso_handle? (they are put into my lib because I have some static objects for which the constructor is called at startup. This constructor has a call to atexit with __dso_handle as argument)
In this way it "works" so far. But I get a warning-message:
Code: Select all
/home/hrniels/escape/source/build/dist/bin/../lib/gcc/i586-elf-escape/4.4.3/../../../../i586-elf-escape/bin/ld: warning: cannot find entry symbol _start; defaulting to 00002820
Code: Select all
i586-elf-escape-g++ -o user_cpptest.bin cppmain.o
Code: Select all
/home/hrniels/escape/source/build/dist/bin/../lib/gcc/i586-elf-escape/4.4.3/crtend.o:(.dtors+0x0): multiple definition of `__DTOR_END__'
/home/hrniels/escape/source/build/dist/bin/../lib/gcc/i586-elf-escape/4.4.3/../../../../i586-elf-escape/lib/libstdc++.so:/home/hrniels/escape/source/cross/src/gcc/libgcc/../gcc/unwind-dw2-fde.c:228: first defined here
/home/hrniels/escape/source/build/dist/bin/../lib/gcc/i586-elf-escape/4.4.3/../../../../i586-elf-escape/bin/ld: error in /home/hrniels/escape/source/build/dist/bin/../lib/gcc/i586-elf-escape/4.4.3/../../../../i586-elf-escape/lib/libstdc++.so(.eh_frame); no .eh_frame_hdr table will be created.
/home/hrniels/escape/source/build/debug/user/cpp/cpptest/./cppmain.o: In function `main':
/home/hrniels/escape/source/user/cpp/cpptest/cppmain.cpp:67: undefined reference to `__dynamic_cast'
/home/hrniels/escape/source/user/cpp/cpptest/cppmain.cpp:77: undefined reference to `__dynamic_cast'
/home/hrniels/escape/source/user/cpp/cpptest/cppmain.cpp:157: undefined reference to `typeinfo for int'
/home/hrniels/escape/source/user/cpp/cpptest/cppmain.cpp:66: undefined reference to `typeinfo for int'
collect2: ld returned 1 exit status
I hope I've described the problem well enough. If not, feel free to ask
Thanks in advance!
hrniels