Initial commit
This commit is contained in:
231
TBE/MinGW/doc/a2dll/a2dll.html
Normal file
231
TBE/MinGW/doc/a2dll/a2dll.html
Normal file
@@ -0,0 +1,231 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
a2dll: An utility (to help) to convert static library into Win32 DLL
|
||||
</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
a2dll: An utility (to help) to convert static library into Win32 DLL
|
||||
</h1>
|
||||
<h2>
|
||||
Synopsis
|
||||
</h2>
|
||||
<p>
|
||||
a2dll is shell script (see <a href="#requirements">requirements</a>) to
|
||||
automotize process of converting existing static libraries (produced
|
||||
by gnu-win32 tools, of course) into DLL. First of all, yes it's possible:
|
||||
if you have binary static distribution of some library (i.e. library
|
||||
itself and its headers), that's all you need to convert it to DLL and
|
||||
use in your programs. Read <a href="static2dll_howto.txt">HOWTO</a> for
|
||||
underlying magic. So, you may not waste time if you need DLL: just
|
||||
grab existing static distribution and convert. Also, you may use it to
|
||||
build Win32 DLL of your library. Also, until GNU libtool will allow
|
||||
seamless building of Win32 DLLs, you may build static lib (what
|
||||
libtool of course supports) and then convert it to DLL.
|
||||
<blockquote>
|
||||
<tt>
|
||||
a2dll <static_lib> [-o <dll_name>] [<linker_flags>] [--relink]
|
||||
</tt>
|
||||
</blockquote>
|
||||
where:
|
||||
<dl>
|
||||
<dt>
|
||||
<tt><static_lib></tt>
|
||||
</dt>
|
||||
<dd>
|
||||
Static library you want to convert
|
||||
</dd>
|
||||
<dt>
|
||||
<tt>-o <dll_name></tt>
|
||||
</dt>
|
||||
<dd>
|
||||
Name of resulting dll. If not given, three first chars of input
|
||||
name are stripped and <tt>.a</tt> suffix replaced with <tt>.dll</tt> .
|
||||
So, from '<tt>libfoo.a</tt>' you'll get '<tt>foo.dll</tt>'.
|
||||
</dd>
|
||||
<dt>
|
||||
<tt><linker_flags></tt>
|
||||
</dt>
|
||||
<dd>
|
||||
Linker flags:
|
||||
<ul>
|
||||
<li>Use '<tt>-s</tt>' to get library without debugging symbols and information.
|
||||
<li>Use '<tt>--driver-name=<name></tt>' to link library with specified
|
||||
linker (well, compiler, to be precise). For example, for C++ library use
|
||||
<tt>--driver-name=g++</tt> .
|
||||
<li>You should list all libraries on which your library depends with
|
||||
<tt>-l</tt> switches and directories they are reside in with <tt>-L</tt>
|
||||
switches. For example, if your library uses PCRE library you just built and
|
||||
not yet installed, use something like <tt>-L../pcre -lpcre</tt>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt>
|
||||
<tt>--relink</tt>
|
||||
</dt>
|
||||
<dd>
|
||||
Skip exploding library stage (see below). Use this flag to continue
|
||||
process after some error occured.
|
||||
</dd>
|
||||
</dl>
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
Performing
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
a2dll works in following way:
|
||||
<ol>
|
||||
<li>If you did not specify <tt>--relink</tt> option,
|
||||
explodes source library under newly-created <tt>.dll</tt> subdirectory.
|
||||
|
||||
<li>Links all resulting objects into DLL with exporting all non-static
|
||||
symbols. On this stage, link errors
|
||||
(such as underfined symbols) may occur. In such case, a2dll terminates
|
||||
and all linker messages are available in '<tt>ld.err</tt>' file. You
|
||||
should correct errors (mostly by finding out additional
|
||||
dependecies, but sometimes by deleting 'superfluos' objects under .dll)
|
||||
and re-run a2dll with all the options you gave it before,
|
||||
plus new dependencies, plus <tt>--relink</tt> flag. You may need to
|
||||
repeat this several times.
|
||||
|
||||
<li>Renames original static library with suffix <tt>.static</tt> .
|
||||
|
||||
<li>Creates import library for produced DLL with the name of original
|
||||
static library.
|
||||
|
||||
<li>Check whether DLL exports data symbols. If no, congratulations,
|
||||
you've done. However, if some present, it lists all of them in file
|
||||
'<tt><dll_name>.data</tt>' . Presense of such symbols generally
|
||||
means that you should patch library's headers to mark those symbols
|
||||
as dll-imported. But don't hurry with that, first, do following:
|
||||
<ol>
|
||||
<li>Look into <tt><dll_name>.data</tt> file. If all what you see
|
||||
is something like '<tt>internal_counter_of_bogons</tt>' or
|
||||
'<tt>_ksdauso</tt>', don't worry - those symbols are hardly part of
|
||||
external interface of the library.
|
||||
<li>If all you need is to link your application against that
|
||||
library, try it. If it succeeds, congratulation.
|
||||
<li>Only if above is failed, or you are going to distribute produced
|
||||
library, so you need to be sure that everything is ok, proceed with
|
||||
marking symbols in headers. Read <a href="static2dll_howto.txt">Static2DLL
|
||||
HOWTO</a> for more information on suggested ways of doing this. Use
|
||||
'<tt>grep -f <tt><dll_name>.data</tt> *.h</tt>' command to find
|
||||
out where offending symbols defined in library headers.
|
||||
</ol>
|
||||
</ol>
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
Examples
|
||||
</h2>
|
||||
<p>
|
||||
Since converting static libraries to DLLs is not fully automated and
|
||||
formal process, some experience with it is required. Learing
|
||||
by example is known to be one of the efficient way of communicating
|
||||
experince, so I would like to provide some realistic examples of
|
||||
converting statics to DLLs with the help of a2dll.
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
Zlib
|
||||
</h3>
|
||||
<p>
|
||||
Build libz.a . Now, run '<tt>a2dll libz.a</tt>'. It builds cleanly,
|
||||
but warns us about data symbols. Let's look at them:
|
||||
<blockquote>
|
||||
<pre>
|
||||
inflate_mask
|
||||
z_errmsg
|
||||
</pre>
|
||||
</blockquote>
|
||||
What they could be. The first one is probably some internal variable,
|
||||
while second is probably array of error messages. As we know, zlib
|
||||
provides functional way of getting error messages, something like. So
|
||||
our hypothesis is that job's done. Let's prove it:
|
||||
'<tt>grep -f z.dll.data zlib.h</tt>'. Yes, we're right: no mentioning
|
||||
of those symbols in interface header file.
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
libstdc++
|
||||
</h3>
|
||||
<p>
|
||||
I've got an idea to DLLize libstdc++ coming with my mingw32 distribution.
|
||||
'<tt>a2dll "libstdc++.a"</tt>'. Note that we don't use
|
||||
<tt>--driver-name=g++</tt> - that option need to be used when we link
|
||||
something <i>against</i> libstdc++ . But when we link libstdc++
|
||||
<i>itself</i>, we need libc (whatever it is in mingw32), nothing else.
|
||||
But, process aborts due to linker errors. <tt>ld.err</tt> tells us:
|
||||
<blockquote>
|
||||
<pre>
|
||||
strerror.o(.text+0x303): undefined reference to `sys_nerr'
|
||||
vfork.o(.text+0x7): undefined reference to `fork'
|
||||
waitpid.o(.text+0x15): undefined reference to `wait'
|
||||
</pre>
|
||||
</blockquote>
|
||||
Well, strerror, vfork, waitpid are libc functions, what they do in
|
||||
libstdc++? Probably, stubs, delete them and
|
||||
'<tt>a2dll "libstdc++.a" --relink</tt>'. Of course,
|
||||
<tt>stdc++.dll.data</tt> is here. Looking into it, I may tell you
|
||||
that everything starting with '<tt>__ti<digit></tt>' is RTTI
|
||||
internal data structures and everything starting with
|
||||
'<tt>_vt$</tt>' is virtual tables (use c++filt if in doubt),
|
||||
you can leave them alone.
|
||||
(If so, why I don't filter them? Because "you can leave them alone"
|
||||
is hypothesis for now, I haven't linked too much C++ libraries to
|
||||
be sure). From the rest, there's stuff starting
|
||||
with '<tt>_IO_</tt>'. That's probably some internal variables, let's
|
||||
don't do anything about them, unless we'll be forced to. Than, as
|
||||
c++filt shows, there're some static members of templated classes. Darkness.
|
||||
Forget for now. Than, there's '<tt>io_defs__</tt>'. Does your C++ application
|
||||
reference something like that? Mine not. So, what is left? Our four
|
||||
happy friends, <tt>cin, cout, cerr,</tt> and <tt>clog</tt>. Do mark them as
|
||||
__declspec(dllimport) in <tt>iostream.h</tt>.
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
Some C++ library
|
||||
</h3>
|
||||
<p>
|
||||
Suppose we have following file:
|
||||
<pre>
|
||||
#include <iostream.h>
|
||||
|
||||
void foo()
|
||||
{
|
||||
cout<<"hi!"<<endl;
|
||||
}
|
||||
</pre>
|
||||
and want to turn it into DLL. Create static liba.a from it. Now,
|
||||
'<tt>a2dll liba.a --driver-name=g++</tt>'. Well, our DLL contains
|
||||
single function, why then it complains about data symbols? Oh, it's
|
||||
those stupid RTTI structures. Next time, compile with <tt>-fno-rtti</tt> unless
|
||||
you really need it, ok? Ditto for <tt>-fno-exceptions</tt> .
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="requirements">
|
||||
Requirements
|
||||
</h2>
|
||||
<p>
|
||||
a2dll requires POSIX shell (<tt>sh</tt>) to run. It is developed and
|
||||
tested with <tt>ash</tt> from
|
||||
<a href="http://pw32.sourceforge.net">PW32</a> distribution. Additionally,
|
||||
a2dll requires following utilities to perform its tasks:
|
||||
<ul>
|
||||
<li>GNU fileutils: mkdir, mv, rm
|
||||
<li>GNU textutils: wc
|
||||
<li>GNU grep
|
||||
<li>GNU awk
|
||||
<li>GNU binutils: dllwrap, dlltool (and the rest of binutils and gcc, of course)
|
||||
<li>pexports, an utility to dump symbols exported by dll. You'll need a
|
||||
version 0.43 or above, capable of distinguishing between code and data symbols, as one
|
||||
from <a href="http://www.is.lg.ua/~paul/devel/binutils.html">here</a>.
|
||||
</ul>
|
||||
</p>
|
||||
<hr noshade>
|
||||
<i><a href="mailto:Paul.Sokolovsky@technologist.com">Paul Sokolovsky</a></i>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user