Hello all. I had run into problem creating the shared library using common data and g++. Here is code snippet:
file 1.c: int i;
extern void Set(int param) { i = param; }
file 2.c: int i;
extern int Get() { return i; }
I am compiling it using the command: gcc -single_module -dynamiclib -o libcommon.dylib 1.c 2.c
everything builds nice, test programm calling Set(123) then Get() is getting 123 as a result.
Then i try to compile with: g++ -single_module -dynamiclib -o libcommon.dylib 1.c 2.c and getting errors: ld: multiple definitions of symbol _i /var/tmp//ccTkzUQE.o definition of _i in section (__DATA,__common) /var/tmp//ccH8kBtk.o definition of _i in section (__DATA,__common) /usr/bin/libtool: internal link edit command failed
So g++ failed to compile this shared library. I tryed to break problem down and use separate compile/build stage. Use C approach Compile: gcc -c 1.c 2.c Link: g++ -single_module -dynamiclib -o libcommon.dylib 1.o 2.o This worked (as well as using other link commands, like "gcc -single_module -dynamiclib -o libcommon.dylib 1.o 2.o" or ld -single_module -dylib -o libcommon.dylib 1.o 2.o
Use C++ approach Compile: g++ -c 1.c 2.c Link: g++ -single_module -dynamiclib -o libcommon.dylib 1.o 2.o This failed with error: ld: multiple definitions of symbol _i 1.o definition of _i in section (__DATA,__common) 2.o definition of _i in section (__DATA,__common) /usr/bin/libtool: internal link edit command failed
I tryed to use gcc -single_module -dynamiclib -o libcommon.dylib 1.o 2.o and ld -single_module -dylib -o libcommon.dylib 1.o 2.o They failed with same diagnostics
So, C does like -single_module. C++ does not.
Next step i went to watch to the object files. nm -mg 1.o 2.o For files compiled with g++ 1.o: 00000000 (__TEXT,__text) external __Z3Seti 00000000 (absolute) external [no dead strip] __Z3Seti.eh 00000018 (__TEXT,__textcoal_nt) weak private external ___i686.get_pc_thunk.cx 0000001c (__DATA,__common) external _i
2.o: 00000000 (__TEXT,__text) external __Z3Getv 00000000 (absolute) external [no dead strip] __Z3Getv.eh 00000016 (__TEXT,__textcoal_nt) weak private external ___i686.get_pc_thunk.cx 0000001c (__DATA,__common) external _i
For files compiled with gcc 1.o: 00000000 (__TEXT,__text) external _Set 0000001e (__TEXT,__textcoal_nt) weak private external ___i686.get_pc_thunk.cx 00000010 (common) external _i
2.o: 00000000 (__TEXT,__text) external _Get 0000001b (__TEXT,__textcoal_nt) weak private external ___i686.get_pc_thunk.cx 00000010 (common) external _i
So as far as I see, gcc generate symbol which is (common) external g++ generates symbol which is (__DATA,__common) external
A question is: How can I use g++ compiler and still be able to link dylibs with common symbols? I do know about "-m" linker flag, but man warns that it could produce error-prone result, plus i failed to find the way to supress "duplicated symbols" warning.
Any ideas, please? Thank you in advance. -- Sincerely, Rustam Muginov |