[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: questions about DLLs built with libtool - multiple output files...

From: Brian Dessent
Subject: Re: questions about DLLs built with libtool - multiple output files...
Date: Thu, 01 Jun 2006 09:50:38 -0700

Ed Hartnett wrote:

>   -rw-rw-rw-   1 ed       root  1043050 Jun  1 07:44 libnetcdf.a
>   -rw-rw-rw-   1 ed       root   360432 Jun  1 07:44 libnetcdf.dll.a
>   -rw-rw-rw-   1 ed       root   632482 Jun  1 07:44 cygnetcdf-1.dll

libnetcdf.a is the static archive for static linking, and gets placed in

libnetcdf.dll.a is the import library for the DLL and also gets placed
in /usr/lib.  This is what the linker will actually find when the user
specifies -lnetcdf to link, and it essentially just contains a list of
the functions that the DLL exports -- it does not contain any code.

Both of the above are developer files only needed at link time, not

cygnetcdf-1.dll is the dynamic library itself and gets placed into
/usr/bin.  This is important because on Windows there is no RPATH
embedded in the library.  Instead the search order is pretty much just
"current directory then PATH", with a couple of really obscure
modifiers.  This means that DLLs have to be in the PATH, and /usr/lib is
not typically in the path, but /usr/bin is.

Recent versions of ld can link against DLLs directly without needing an
import library, but the traditional way is to include them.  This is an
important distinction when you have multiple ABI versions hanging around
-- for example, there might be cygnetcdf-{1,2,3}.dll installed in
/usr/bin to support compiled binaries of various vintages.  However, the
import library filename is not versioned, and there is only a singular
one on the system, typically of the current/latest ABI.

There are also some things (such as symbol aliasing) that can only be
achieved with an import library that are not possible by directly
linking to a DLL.  There is a section in the ld manual that explains

> Which one do I give to the user as "the" dll for the library.
> Also, I seem to recall reading that it was possible to generate dlls
> which either did or did not depend on the cygwin dll being present on
> the machine. True?

It is possible, but it's not quite that simple.  There are essentially
two separate toolchains: cygwin and mingw.  Cygwin implements its own C
library and POSIX emulation layer (cygwin1.dll), whereas mingw targets
the existing Microsoft-provided C library (MSVCRT.DLL) and provides
essentially zero compatibility/emulation layering.

The tradeoff here is that most posix source code can be compiled
unmodified under Cygwin at the cost of a dependancy on cygwin1.dll. 
With Mingw there is no dependance on emulation libraries, however there
is often significant porting work to be done because MSVCRT includes
*very* little of the posix API beyond the minimum required by C89.  For
example, fork() and exec() flat out do not exist, and signals are so
crippled as to not exist (see
<> for
details on this.)  And when using sockets you must use the Winsock API,
which is very similar to the posix socket API, but has some gotchas
(e.g. socket handles are not regular fds and so you can't mix and match
files and sockets in a select().)  In summary, when using Mingw you
typically must target -- or at least be aware of -- the Windows API to
accomplish most nontrivial tasks.

Cygwin's gcc provides the necessary framework for using both toolchains
at once, via the -mno-cygwin switch, which is what you are probably
referring to.  So it is true that under Cygwin you can create a DLL that
does not depend on cygwin1.dll by simply using -mno-cygwin.  However, it
does not just magically remove this dependancy, it switches the compiler
to a very different toolchain, with an associated set of issues as
explained above.  This means it's not a magic bullet that can just
surgically remove Cygwin without any other changes.

Also be aware that you can't mix and match cygwin and mingw object files
in a given project, as these two toolchains have entirely different C
runtimes.  Invoking -mno-cygwin switches over a completely different set
of system headers and link options, so you should really treat them as
two different compilers.  In other words, if you configure with "CC=gcc
-mno-cygwin", do it in its own build tree away from the Cygwin build
tree, just as if you were cross compiling.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]