On Fri, 23 May 2025 17:41:02 +0100
Jon Turney wrote:
> This hasn't substantially been revised since (at least) 2004, and
> doesn't really represent normal usage of modern gcc and binutils.
> ---
>  winsup/doc/dll.xml | 168 ++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 127 insertions(+), 41 deletions(-)
> 
> diff --git a/winsup/doc/dll.xml b/winsup/doc/dll.xml
> index f0369760f..7117b65bd 100644
> --- a/winsup/doc/dll.xml
> +++ b/winsup/doc/dll.xml
> @@ -19,26 +19,47 @@ variables, etc.  All these are merged together, like if 
> you were
>  building one big object files, and put into the dll.  They are not
>  put into your .exe at all.</para>
>  
> -<para>The exports contains a list of functions and variables that the
> +<para>The exports is a list of functions and variables that the
>  dll makes available to other programs.  Think of this as the list of
> -"global" symbols, the rest being hidden.  Normally, you'd create this
> -list by hand with a text editor, but it's possible to do it
> -automatically from the list of functions in your code.  The
> -<filename>dlltool</filename> program creates the exports section of
> -the dll from your text file of exported symbols.</para>
> -
> -<para>The import library is a regular UNIX-like
> -<filename>.a</filename> library, but it only contains the tiny bit of
> -information needed to tell the OS how your program interacts with
> -("imports") the dll.  This information is linked into your
> -<filename>.exe</filename>.  This is also generated by
> -<filename>dlltool</filename>.</para>
> +"public" symbols, the rest being hidden.
> +
> +<footnote>
> +  <para>
> +    Note that <filename>ld</filename>'s default behaviour is to export all
> +    global symbols, if there otherwise wouldn't be any exported symbols
> +    (i.e. because you haven't specified a def file or made any export
> +    annotations). (See <code>--export-all-symbols</code> in the
> +    <filename>ld</filename> man page for more details.)
> +  </para>
> +</footnote>
> +
> +This list can be in a module definition (.def) file, which you can write by 
> hand
> +with a text editor, but it's also possible to have it generated automatically
> +from the functions and variables in your code, by annotating the declarations
> +with <code>__attribute__ ((dllexport))</code>.
> +
> +<footnote>
> +  <para>
> +    If you're making these annotations on the declarations in a header which 
> is
> +    also installed to be included by users of your library, you probably 
> want to
> +    use macros to do the right thing and increase portability.  See <ulink
> +    url="https://gcc.gnu.org/wiki/Visibility";>this example</ulink> for 
> details.
> +  </para>
> +</footnote>
> +
> +</para>
> +
> +<para>The import library is a regular UNIX-like <filename>.a</filename> 
> library,
> +but it only contains the tiny bit of information ("a stub") needed to tell 
> the
> +OS how your program interacts with ("imports") the dll.  This information is
> +linked into your <filename>.exe</filename>.
> +</para>
>  
>  <sect2 id="dll-build"><title>Building DLLs</title>
>  
> -<para>This page gives only a few simple examples of gcc's DLL-building 
> +<para>This page gives only a few simple examples of gcc's DLL-building
>  capabilities. To begin an exploration of the many additional options,
> -see the gcc documentation and website, currently at 
> +see the gcc documentation and website, currently at
>  <ulink url="http://gcc.gnu.org/";>http://gcc.gnu.org/</ulink>
>  </para>
>  
> @@ -49,8 +70,8 @@ For this example, we'll use a single file
>  <filename>mydll.c</filename> for the contents of the dll
>  (<filename>mydll.dll</filename>).</para>
>  
> -<para>Fortunately, with the latest gcc and binutils the process for building 
> a dll
> -is now pretty simple. Say you want to build this minimal function in 
> mydll.c:</para>
> +<para>Say you want to build this minimal function in
> +<filename>mydll.c</filename>:</para>
>  
>  <screen>
>  #include &lt;stdio.h&gt;
> @@ -59,28 +80,44 @@ int
>  hello()
>  {
>    printf ("Hello World!\n");
> -}  
> +}
>  </screen>
>  
> -<para>First compile mydll.c to object code:</para>
> +<para>First compile <filename>mydll.c</filename> to the object
> +<filename>mydll.o</filename>:</para>
>  
>  <screen>gcc -c mydll.c</screen>
>  
>  <para>Then, tell gcc that it is building a shared library:</para>
>  
> -<screen>gcc -shared -o mydll.dll mydll.o</screen>
> +<screen>gcc -shared -o mydll.dll mydll.o -Wl,--out-implib libmydll.a</screen>
>  
>  <para>
> -That's it! To finish up the example, you can now link to the
> -dll with a simple program:
> +  That's it! You now have the dll (<filename>mydll.dll</filename>) and the
> +  import library (<filename>libmydll.a</filename>).
> +
> +<footnote>
> +  <para>
> +    In fact, <code>--out-implib</code> is optional in this simple example,
> +    because <filename>ld</filename> can automatically generate import stubs 
> when
> +    told to link directly to a .dll.  (See <code>--enable-auto-import</code> 
> in
> +    the <filename>ld</filename> man page for more details.)
> +  </para>
> +</footnote>
> +
> +</para>
> +
> +<para>
> +To finish up the example, you can now link to the dll with a simple program,
> +<filename>myprog.c</filename>:
>  </para>
>  
>  <screen>
> -int 
> +int
>  main ()
>  {
>    hello ();
> -}  
> +}
>  </screen>
>  
>  <para>
> @@ -89,35 +126,84 @@ Then link to your dll with a command like:
>  
>  <screen>gcc -o myprog myprog.c -L./ -lmydll</screen>
>  
> -<para>However, if you are building a dll as an export library,
> -you will probably want to use the complete syntax:</para>
> +<para>
> +  Try it out:
> +</para>
> +
> +<screen>
> +$ ./myprog
> +Hello World!
> +</screen>
> +
> +<para>However, if you are building a dll for installation,
> +you will probably want to use a more complex syntax:</para>
>  
>  <screen>gcc -shared -o cyg${module}.dll \
>      -Wl,--out-implib=lib${module}.dll.a \
> -    -Wl,--export-all-symbols \
> -    -Wl,--enable-auto-import \
> -    -Wl,--whole-archive ${old_libs} \
> -    -Wl,--no-whole-archive ${dependency_libs}</screen>
> +    -Wl,--whole-archive ${objs_libs} -Wl,--no-whole-archive \
> +    ${dependency_libs}</screen>
>  
> -<para>
> +<itemizedlist spacing="compact">
> +<listitem>
>  The name of your library is <literal>${module}</literal>, prefixed with
>  <literal>cyg</literal> for the DLL and <literal>lib</literal> for the
> -import library. Cygwin DLLs use the <literal>cyg</literal> prefix to 
> -differentiate them from native-Windows MinGW DLLs, see 
> -<ulink url="http://mingw.org";>the MinGW website</ulink> for more details.
> -<literal>${old_libs}</literal> are all
> -your object files, bundled together in static libs or single object
> -files and the <literal>${dependency_libs}</literal> are import libs you 
> -need to link against, e.g 
> -<userinput>'-lpng -lz -L/usr/local/special -lmyspeciallib'</userinput>.
> +import library. Cygwin DLLs use the <literal>cyg</literal> prefix to
> +differentiate them from native-Windows MinGW DLLs.
> +</listitem>
> +<listitem>
> +<literal>${objs_libs}</literal> are all your object files, bundled together 
> in
> +static libs or single object files
> +</listitem>
> +<listitem>
> +<literal>${dependency_libs}</literal> are static or import libs you need to 
> link
> +against, e.g <userinput>'-lpng -lz -L/usr/local/special -lmyspeciallib'
> +</userinput>.
> +</listitem>
> +</itemizedlist>
> +
> +<para>
> +  When the import library is installed into <filename>/usr/lib</filename>, it
> +  can be linked to with just <code>-l${module}</code>. The dll itself is
> +  installed into <filename>/usr/bin</filename> so it can be found on
> +  <code>PATH</code> by the loader when a linked .exe is run.
> +</para>
> +
> +</sect2>
> +
> +<sect2 id="dll-tool"><title>dlltool</title>
> +
> +<para>
> +Historically, the process for building a dll with <filename>gcc</filename> 
> and
> +<filename>binutils</filename> wasn't so simple, and the
> +<filename>dlltool</filename> tool was used:
> +</para>
> +
> +<itemizedlist spacing="compact">
> +  <listitem>
> +    <para>
> +      To create the exports section of the dll, from the module definition 
> file
> +      or by scanning object files.
> +    </para>
> +  </listitem>
> +
> +  <listitem>
> +    <para>
> +      To generate the import library.
> +    </para>
> +  </listitem>
> +</itemizedlist>
> +
> +<para>
> +  (See the <filename>dlltool</filename> man page for more details.)
>  </para>
> +
>  </sect2>
>  
> -<sect2 id="dll-link"><title>Linking Against DLLs</title>
> +<sect2 id="dll-link"><title>Linking Against Foreign DLLs</title>
>  
>  <para>If you have an existing DLL already, you need to build a
>  Cygwin-compatible import library.  If you have the source to compile
> -the DLL, see <xref linkend="dll-build"></xref> for details on having 
> +the DLL, see <xref linkend="dll-build"></xref> for details on having
>  <filename>gcc</filename> build one for you.  If you do not have the
>  source or a supplied working import library, you can get most of
>  the way by creating a .def file with these commands (you might need to
> -- 
> 2.45.1

Thanks! LGTM. Please push.

-- 
Takashi Yano <[email protected]>

Reply via email to