As I have used MinGW and Cygwin to compile GNU/Linux software in Windows, sometimes I only get static libraries, but not a shared library. After some research, I found several ways to convert a static library to a shared library. Using GCC with the -shared
parameter is one way. libtool is another tool for such a task. In this post, I will write about dllwrap
because that's what I have used and known to work.
Using dllwrap
Suppose the name of the static library is libpango-1.0.a This library is just an archive of many object files. Running “ar t libpango-1.0.a
” will display the contents of the archive.
ar t libpango-1.0.a
Now, we have to extract the contents of the archive into an empty folder. Create a new folder.
mkdir temp
Change to the newly created folder and extract the static library.
cd temp
ar x libpango-1.0.a
Use dllwrap to create a shared library from the object files in the following manner:
dllwrap --verbose --export-all-symbols --add-stdcall-alias \
-o /usr/bin/cygpango-1.0-0.dll --dllname cygpango-1.0-0.dll \
--output-lib /usr/lib/libpango-1.0.dll.a *.o -L/usr/lib \
-lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -luser32 -lkernel32 -lintl -liconv
This creates a shared library cygpango-1.0-0.dll
and an import library libpango-1.0.dll.a
. To learn more about dllwrap, read the output of “dllwrap --help
”
Using GCC to convert a static library to shared library
You can also use GCC to do a library conversion with GCC. Here's an example. It's certainly a lot of typing:
ar x /usr/lib/libpango-1.0.a
gcc -shared -o libpango-1.0-0.dll -Wl,--out-implib=libpango-1.0.dll.a \
-Wl,--export-all-symbols -Wl,--add-stdcall-alias -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc \
*.o -L/usr/lib \
-lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -luser32 -lkernel32 -lintl -liconv
This creates the same set of files as with dllwrap
above, but with slightly different sizes. For more information, read the GCC manual and the output from ld --help
Using a2dll to Convert a Static Library
a2dll is a little tool from mingw-utils that can be used to convert a static library to a dynamic library. For example,
a2dll libmp3lame.a -o lame_enc.dll
Is it possible to do this in the other direction too and create a static lib from the dll/so?
ReplyDeleteI think it's extremely difficult, if not impossible. My limited knowledge suggests that one may use objdump or dumpbin on a .so or .dll, then somehow reverse-engineer and extract object codes from the shared library and construct a static library from them as long as all symbols are still present. Sorry but I don't have a clear answer for your question.
ReplyDeleteI'm trying both with dllwrap and a2dll but I came across the same error:
ReplyDeletefoo.o: file not recognized: File format not recognized.
Any suggestion?
Sorry, but I haven't seen such an error when I used dllwrap or a2dll. My best approach is to simply use "gcc -shared".
Deletegcc -shared -o libfoo.dll -Wl,--out-implib,libfoo.dll.a -Wl,--whole-archive foo.a -Wl,--no-whole-archive -L/mingw/lib -lbar
where foo.a is the static library, libfoo.dll is the DLL you want to create and -lbar means you want to link it with /mingw/lib/libbar.a.
Thank you for your reply.
DeleteI try to explain you my situation a bit more in detail, so maybe you can help me, or at least give me an advice,since I'm screwed.
I am trying to compile the umfpack library, that is a solver for sparse matrices, under windows.
What I have is the static library under linux, that is libumfpack.a, and its dependances, that are libblas.a and libamd.a
I don't know so much about how this libraries were compiled and more in general I don't know anything about cross-compilation, MinGW ecc..
Can you please explain me if is possible to port directly this libraries under windows and - if so - what's the easiest way.
It has been 3 days that I am wandering around the whole web without succeding, and this stuff is driving me nuts.