delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2000/12/04/07:51:21

Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT sources DOT redhat DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT sources DOT redhat DOT com>
List-Help: <mailto:cygwin-help AT sources DOT redhat DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT sources DOT redhat DOT com
Delivered-To: mailing list cygwin AT sources DOT redhat DOT com
Message-ID: <001401c05df0$e4dd0c80$95698cd4@emerald>
From: "Steven O'Brien" <steven_obrien AT lineone DOT net>
To: <cygwin AT cygwin DOT com>
Subject: building dlls, C and C++
Date: Mon, 4 Dec 2000 12:51:15 -0000
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.00.2615.200
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2615.200

Hi

The current cygwin release of gcc/binutils (gcc-2.95.2-5,
binutils-20001029-2) have some difficulty in generating DLLs, especially for
C++ sources. The problem appears to be with the --export-dynamic
and/or --export-all options to ld which do not always "do the right thing".
I can produce correct DLLs by generating the ".def" file using nm with an
awk script - this works for both C and C++ sources (although I haven't tried
mixing then in the same DLL).

Here's the script:

<SCRIPT>
#! /bin/awk -f

BEGIN                 { count = 1; print "EXPORTS" }

/^........ [T] _/     { printf("%s @%d\n", substr($3,2), count++); next }

/^........ [BDR] _/   { printf("%s @%d DATA\n", substr($3,2), count++) }

</SCRIPT>


An example makefile to use this script:
assume the following variables:
LINK      = the link driver to use (gcc or g++ as appropriate)
DLLEXPORT = file containing the above awk script
OBJECTS   = list of .o files to link into the DLL
LIBS      = list of library dependencies of this DLL
SHAREDLIB = target DLL
SHAREDDEF = .def file defining the export list
IMPLIB    = import library (.dll.a)

<MAKEFILE>

$(SHAREDLIB) : $(IMPLIB)

$(IMPLIB) : $(SHAREDDEF) $(OBJECTS)
 $(LINK) -shared -o $(SHAREDLIB) \
 -Wl,--out-implib=$(IMPLIB) \
 -Wl,--enable-auto-image-base \
 $(SHAREDDEF) $(OBJECTS) $(LIBS)

$(SHAREDDEF) : $(OBJECTS)
 nm $^ | $(DLLEXPORT) > $@

</MAKEFILE>

This all relies on the source header files used by applications linking to
this DLL having "__declspec(dllimport)" in appropriate places. Without this,
functions will link correctly (but less efficiently) but imported data will
result in segmentation faults.

I have tested this approach using ncurses (ncurses-5.2-2-src.tar.gz) and
also another large c++ library (unfortunately not in the public domain) with
excellent results.

The awk script generates index numbers for the symbols. Indexes are useful
mainly for release management, because as long as each exported symbol keeps
the same index across releases the users of the DLL do not have to re-link
their applications when upgrading the DLL. A great improvement to this
approach, then, would be to be able to give the "old" def file as input so
that index numbers are maintained rather than simply generated sequentially.

If enough people try this and find it useful, maybe the functionality could
be included directly into ld ?

Steve.




--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe AT sourceware DOT cygnus DOT com

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019