I know this question has been asked a few times, but none of the solutions have worked for me. I have a statically linked library that I would like to use with a JNI layer with versions pre Java 8. Based on my reading of "how to link static library into dynamic library in gcc", it seems possible. Here is my command line:
/usr/bin/g++ -shared -std=c++0x -D__extern_always_inline=inline -Wall -pedantic -O3 -fomit-frame-pointer -fno-strict-aliasing -D_FILE_OFFSET_BITS=64 -DNDEBUG -fPIC -Wl,--whole-archive target/vw_jni.a -o target/vw_jni.lib
This is based on writing a JNI layer to the Vowpal Wabbit library.
At this point in the build process I have statically created a file called target/vw_jni.a
through static linking
target/vw_jni.a: In function `_fini':
(.fini+0x0): multiple definition of `_fini'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:(.fini+0x0): first defined here
target/vw_jni.a: In function `data_start':
(.data+0x8): multiple definition of `__dso_handle'
/usr/lib/gcc/x86_64-linux-gnu/4.9/crtbeginS.o:(.data.rel.local+0x0): first defined here
target/vw_jni.a: In function `_init':
(.init+0x0): multiple definition of `_init'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:(.init+0x0): first defined here
/usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0x0): multiple definition of `__libc_csu_init'
target/vw_jni.a:(.text+0x1cea20): first defined here
/usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS): In function `__libc_csu_fini':
(.text+0x70): multiple definition of `__libc_csu_fini'
target/vw_jni.a:(.text+0x1ceab0): first defined here
/usr/lib/gcc/x86_64-linux-gnu/4.9/crtendS.o:(.tm_clone_table+0x0): multiple definition of `__TMC_END__'
target/vw_jni.a:(.data+0x2630): first defined here
/usr/bin/ld: target/vw_jni.a: .preinit_array section is not allowed in DSO
/usr/bin/ld: failed to set dynamic section sizes: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
I'm not sure what this means and when I search around for it find results such as "C program no longer compiles in Ubuntu" that seem to suggest that I forgot a -o
flag, but I know I have not.
- Is what I'm trying to do possible?
- What am I doing wrong?
I'm doing this on a Docker instance obtained through docker pull ubuntu:14.04
UPDATE:
I'm able to get rid of a few of the errors with the following command line
/usr/bin/g++ -shared -std=c++0x -D__extern_always_inline=inline -Wall -pedantic -O3 -fomit-frame-pointer -fno-strict-aliasing -D_FILE_OFFSET_BITS=64 -DNDEBUG -fPIC -nostdlib -Wl,--whole-archive target/vw_jni.a -o target/vw_jni.lib
This generates the following output
/usr/bin/ld: warning: Cannot create .note.gnu.build-id section, --build-id ignored.
/usr/bin/ld: target/vw_jni.a: .preinit_array section is not allowed in DSO
/usr/bin/ld: failed to set dynamic section sizes: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
The reason I think this works is that by excluding the standard lib I don't have the redefinitions. I'm not sure where to go from here though.
This is practically not wise, because if you put the object files extracted from some static library these object files still remain position dependent code.
Shared libraries should very preferably contain position independent code (because the dynamic linker
ld-linux.so
ismmap
-ing segments inside the.so
at some random address, e.g. because of ASLR), otherwise the dynamic linker would have to process a big lot of relocations (so dynamic linking becomes very inefficient).So even if you succeed to convert your static library into a shared one, it won't be wise to do so.
So keep your static library as is, or recompile their source code with
-fPIC
to build a shared object.