https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=04f4da794de2f7fee0e8b813db031bb7ac8513c7

commit 04f4da794de2f7fee0e8b813db031bb7ac8513c7
Author: Jon Turney <[email protected]>
Date:   Fri May 23 13:54:18 2025 +0100

    Cygwin: doc: Update "building DLLs" section
    
    This hasn't been substantially revised since (at least) 2004, and
    doesn't really represent normal usage of modern gcc and binutils.

Diff:
---
 winsup/doc/dll.xml | 174 ++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 133 insertions(+), 41 deletions(-)

diff --git a/winsup/doc/dll.xml b/winsup/doc/dll.xml
index f0369760f..66d65f7d8 100644
--- a/winsup/doc/dll.xml
+++ b/winsup/doc/dll.xml
@@ -19,26 +19,53 @@ 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>
+
+<para>
+  Refer to the <ulink
+  url="https://sourceware.org/binutils/docs/ld/WIN32.html";>section of the ld
+  manual</ulink> discussing Win32 PE specifics for more details.
+</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 +76,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 +86,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! 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>
-That's it! To finish up the example, you can now link to the
-dll with a simple program:
+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 +132,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

Reply via email to