Back: A for DLLs
Forward: Handling Data Exports from DLLs
FastBack: Handling Data Exports from DLLs
Up: DLLs with Libtool
FastForward: Package Installation
Top: Autoconf, Automake, and Libtool
Contents: Table of Contents
Index: Index
About: About this document

25.4.3 A for DLLs

`' is used to generate the `configure' script:
# Process this file with autoconf to create configure.

AM_INIT_AUTOMAKE(hello, 1.0)



The `AC_PROG_CC' and `AM_PROG_CC_STDC' macros in the `' above will conspire to find a suitable compiler for the C code in this example, and to discover any extra switches required to put that compiler into an ANSI mode. I have used the const keyword in the sources, so I need to specify the `AC_C_CONST' macro, in case the compiler doesn't understand it, and finally I have specified the `AM_PROG_LIBTOOL' macro since I want the library to be built with Libtool.

In order to set the build environment up we need to create the autogenerated files:

$ ls    hello.c   main.c   hello.h
$ aclocal
$ autoheader
$ libtoolize --force --copy
$ automake --foreign --add-missing --copy
automake: installing ./install-sh
automake: installing ./mkinstalldirs
automake: installing ./missing
$ autoconf
$ ls    config.hin     hello.c    config.sub     hello.h       main.c
aclocal.m4     configure      install-sh    missing
config.guess   ltconfig      mkinstalldirs

If you have already tried to build DLLs with Libtool, you have probably noticed that the first point of failure is during the configuration process. For example, running the new configure script you might see:

checking if libtool supports shared libraries... yes
checking if package supports dlls... no
checking whether to build shared libraries... no

libtool provides a macro, `AC_LIBTOOL_WIN32_DLL', which must be added to a package's `' to communicate to the libtool machinery that the package supports DLLs. Without this macro, libtool will never try to build a DLL on Windows. Add this macro to `' before the `AM_PROG_LIBTOOL' macro, and try again:

$ make
cd . && aclocal
cd . && automake --foreign Makefile
cd . && autoconf
checking if libtool supports shared libraries... yes
checking if package supports dlls... yes
checking whether to build shared libraries... yes
gcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -Wp,-MD,.deps/hello.pp \
-c  -DDLL_EXPORT -DPIC hello.c -o .libs/hello.lo
gcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -Wp,-MD,.deps/hello.pp \
-c hello.c -o hello.o >/dev/null 2>&1
mv -f .libs/hello.lo hello.lo
gcc -g -O2 -o ./libs/hello main.o .libs/libimp-hello-0-0-0.a \
-Wl,--rpath -Wl,/usr/local/lib
creating hello
$ ./hello
Hello, World!

If you run this and watch the full output of the `make' command, Libtool uses a rather contorted method of building DLLs, with several invocations each of dlltool and gcc. I have omitted these from the example above, since they really are very ugly, and in any case are almost incomprehensible to most people. To see it all in its full horror you can always examine the output after running the commands yourself! In a future release of Cygwin, recent work on the binutils linker by DJ Delorie, will allow gcc to link DLLs in a single pass using the same syntax used on other systems to produce shared libraries. Libtool will adopt this method when it becomes available, deprecating the use of dlltool.

I have extracted the interesting lines from amongst the many calls to dlltool(67) and gcc generated by make in the shell log. The main thing to notice is that we have a `hello' binary, which is executable, and which gives the right result when we run it! From the partial log above, it certainly appears that it has built `libhello' as a DLL and linked that into `hello', but just to double check we can use ldd(68):

$ libtool --mode=execute ldd ./hello
lt-hello.exe    -> /tmp/.libs/lt-hello.exe
libhello-0-0-0.dll      -> /tmp/.libs/libhello-0-0-0.dll
cygwin1.dll     -> /usr/bin/cygwin1.dll
kernel32.dll    -> /WINNT/system32/kernel32.dll
ntdll.dll       -> /WINNT/system32/ntdll.dll
advapi32.dll    -> /WINNT/system32/advapi32.dll
user32.dll      -> /WINNT/system32/user32.dll
gdi32.dll       -> /WINNT/system32/gdi32.dll
rpcrt4.dll      -> /WINNT/system32/rpcrt4.dll

So now you know how to build and link a simple Windows DLL using GNU Autotools: You add `-no-undefined' to the Libtool library `LDFLAGS', and include the `AC_LIBTOOL_WIN32_DLL' macro in your `'.

This document was generated by Gary V. Vaughan on February, 8 2006 using texi2html