This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: ld --auto-import for cygwin and libtool
- To: binutils at sources dot redhat dot com
- Subject: Re: ld --auto-import for cygwin and libtool
- From: Charles Wilson <cwilson at ece dot gatech dot edu>
- Date: Tue, 24 Jul 2001 16:59:52 -0400
- References: <020601c0f27b$d579ea90$0200a8c0@lifelesswks> <3B5CFA42.9050902@ece.gatech.edu>
Danny Smith wrote:
> With an older version of auto-import, there were some backward
> compatability problems, ie, the patched ld choked on import libs
> produced with standard ld. Has that been tested?
It hadn't, at least not by me. But, I just relinked xemacs.exe using
the new ld. xemacs (as I have it configured) depends on libtiff,
libjpeg, libpng, libz, libgdbm, libdb, libncurses, libpq -- all of which
were created as dll's/import libs using the old ld. The new xemacs
binary links and runs fine.
> Has the patch been tested on C++ code?
Well, there's Ralf's kde-1.1.x port. I also used dllhelpers-0.2.6
(old-style, .def's and __declspec()'s) c++ example and THAT worked. I
then hacked it up to be "new style" (no __declspecs, use auto-import
functionality) and it worked that way, as well.
dllhelpers-0.2.6 is an updated version of Mumit Khan's original, and is
available here:
http://www.neuro.gatech.edu/users/cwilson/cygutils/V1.1/dll-stuff/
It was originally developed to demonstrate the "new" 'gcc -shared'
behavior; Mumit's version used dlltool. The patch to turn this 'gcc
-shared with declspec()' dllhelpers into one that will excercise the
auto-imports functionality is attached. It only addresses C and C++,
not F77(*)
--Chuck
(*) the f77 example in the "original" dllhelpers-0.2.6 explicitly
filters _bss_end__ and related symbols by using --exclude-symbols=_...
in the Makefile. This is no longer necessary since this ld has the
auto-filter-of-exports patch as well as the auto-import, since
auto-import doesn't work properly without the filtering (but conversely,
the filtering can exist without the auto-import).
diff -urN dllhelpers-0.2.6-orig/c/Makefile dllhelpers-0.2.6/c/Makefile
--- dllhelpers-0.2.6-orig/c/Makefile Sat Nov 4 16:59:12 2000
+++ dllhelpers-0.2.6/c/Makefile Tue Jul 24 16:46:04 2001
@@ -35,7 +35,7 @@
# Must define BUILDING_DLL when building the DLL. Otherwise import/exports
# will not work correctly. See dllclass.h for more info.
-DLL_CFLAGS = -DBUILDING_DLL=1
+DLL_CFLAGS =
# The default entry point defined by dllwrap; the default user callback
# is DllMain, and there is stub in dllinit.c.
DLL_LDFLAGS =
@@ -53,7 +53,7 @@
###
$(DLL_NAME) $(DLL_EXP_DEF) $(DLL_EXP_LIB): $(DLL_OBJS)
- gcc -shared -Wl,--export-dynamic -Wl,--output-def=$(DLL_EXP_DEF) \
+ gcc -shared -Wl,--export-all \
-Wl,--out-implib=$(DLL_EXP_LIB) -Wl,--enable-auto-image-base \
-o $(DLL_NAME) $(DLL_OBJS) $(DLL_LDFLAGS) $(DLL_LDLIBS)
diff -urN dllhelpers-0.2.6-orig/c/cdll.c dllhelpers-0.2.6/c/cdll.c
--- dllhelpers-0.2.6-orig/c/cdll.c Mon Dec 4 10:17:01 2000
+++ dllhelpers-0.2.6/c/cdll.c Tue Jul 24 16:44:15 2001
@@ -1,34 +1,34 @@
#include "cdll.h"
-DLLIMPORT int
+int
dll_int_square (int i)
{
return i * i;
}
-DLLIMPORT double
+double
dll_double_square (double d)
{
return d * d;
}
-DLLIMPORT float
+float
dll_float_square (float f)
{
return f * f;
}
-DLLIMPORT int
+int
dll_global_int_var = 99;
-DLLIMPORT void
+void
dll_set_global_int_var (int new_value)
{
dll_global_int_var = new_value;
}
-DLLIMPORT int
+int
dll_get_global_int_var ()
{
return dll_global_int_var;
diff -urN dllhelpers-0.2.6-orig/c/cdll.h dllhelpers-0.2.6/c/cdll.h
--- dllhelpers-0.2.6-orig/c/cdll.h Mon Dec 4 10:17:11 2000
+++ dllhelpers-0.2.6/c/cdll.h Tue Jul 24 16:47:42 2001
@@ -16,20 +16,14 @@
* __attribute__((dllimport))
*/
-#if BUILDING_DLL
-# define DLLIMPORT __declspec (dllexport)
-#else /* Not BUILDING_DLL */
-# define DLLIMPORT __declspec (dllimport)
-#endif /* Not BUILDING_DLL */
+extern int dll_int_square (int) ;
+extern double dll_double_square (double);
+extern float dll_float_square (float);
-DLLIMPORT int dll_int_square (int) ;
-DLLIMPORT double dll_double_square (double);
-DLLIMPORT float dll_float_square (float);
+extern int dll_global_int_var;
-DLLIMPORT int dll_global_int_var;
-
-DLLIMPORT void dll_set_global_int_var (int);
-DLLIMPORT int dll_get_global_int_var ();
+extern void dll_set_global_int_var (int);
+extern int dll_get_global_int_var ();
#endif /* cdll_h_included */
diff -urN dllhelpers-0.2.6-orig/c++/Makefile dllhelpers-0.2.6/c++/Makefile
--- dllhelpers-0.2.6-orig/c++/Makefile Sat Nov 4 17:03:37 2000
+++ dllhelpers-0.2.6/c++/Makefile Tue Jul 24 16:38:48 2001
@@ -35,7 +35,7 @@
# Must define BUILDING_DLL when building the DLL. Otherwise import/exports
# will not work correctly. See dllclass.h for more info.
-DLL_CFLAGS = -DBUILDING_DLL=1
+DLL_CFLAGS =
# The default entry point defined by dllwrap; the default user callback
# is DllMain, and there is stub in dllinit.c.
DLL_LDFLAGS =
@@ -53,7 +53,7 @@
###
$(DLL_NAME) $(DLL_EXP_LIB): $(DLL_OBJS)
- c++ -shared -Wl,--export-dynamic -Wl,--output-def=$(DLL_EXP_DEF) \
+ g++ -shared -Wl,--export-all \
-Wl,--out-implib=$(DLL_EXP_LIB) -Wl,--enable-auto-image-base \
-o $(DLL_NAME) $(DLL_OBJS) $(DLL_LDFLAGS) $(DLL_LDLIBS)
diff -urN dllhelpers-0.2.6-orig/c++/Makefile~ dllhelpers-0.2.6/c++/Makefile~
--- dllhelpers-0.2.6-orig/c++/Makefile~ Wed Dec 31 19:00:00 1969
+++ dllhelpers-0.2.6/c++/Makefile~ Sat Nov 4 17:03:37 2000
@@ -0,0 +1,91 @@
+#
+# Makefile for Cygwin.
+#
+CC = gcc
+CXX = c++
+
+DEBUG = -g #-O2
+CXXFLAGS = $(DEBUG)
+CFLAGS = $(DEBUG)
+CPPFLAGS = -I.
+
+exeext = .exe
+
+#
+# Various targets to build.
+#
+DLL_NAME = cygcxxdll.dll
+DLL_EXP_LIB = libcxxdll.dll.a
+DLL_EXP_DEF = libcxxdll.def
+
+TESTPROGS = usedll$(exeext)
+
+all: $(DLL_NAME) $(TESTPROGS)
+
+#
+# sources, objects, etc.
+#
+SRCS = $(wildcard *.cc *.c)
+OBJS = $(SRCS:.cc=.o)
+OBJS := $(OBJS:.c=.o)
+
+#
+# DLL related variables. These are used when building the DLL. See later.
+#
+
+# Must define BUILDING_DLL when building the DLL. Otherwise import/exports
+# will not work correctly. See dllclass.h for more info.
+DLL_CFLAGS = -DBUILDING_DLL=1
+# The default entry point defined by dllwrap; the default user callback
+# is DllMain, and there is stub in dllinit.c.
+DLL_LDFLAGS =
+# any extra libraries that your DLL may depend on.
+DLL_LDLIBS =
+
+DLL_SRCS = dllclass.cc dllexterns.cc
+DLL_OBJS = $(DLL_SRCS:.cc=.o)
+DLL_OBJS := $(DLL_OBJS:.c=.o)
+
+###
+#
+# Making DLL
+#
+###
+
+$(DLL_NAME) $(DLL_EXP_LIB): $(DLL_OBJS)
+ c++ -shared -Wl,--export-dynamic -Wl,--output-def=$(DLL_EXP_DEF) \
+ -Wl,--out-implib=$(DLL_EXP_LIB) -Wl,--enable-auto-image-base \
+ -o $(DLL_NAME) $(DLL_OBJS) $(DLL_LDFLAGS) $(DLL_LDLIBS)
+
+#
+# making exec
+#
+usedll$(exeext): usedll.o $(DLL_EXP_LIB)
+ $(CXX) -o $@ $(CXXFLAGS) $(LDFLAGS) usedll.o -L./ -lcxxdll
+
+#
+# dependencies.
+#
+
+$(OBJS): dllclass.h
+dllclass.o: dllclass.cc
+dllexterns.o: dllexterns.cc
+usedll.o: usedll.cc
+
+#
+# default rules for building DLL objects. Note that client programs (ie.,
+# the ones that *use* the DLL) have to be compiled without the DLL_CFLAGS
+# flags.
+#
+.cc.o:
+ $(CXX) -c $(DLL_CFLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
+.c.o:
+ $(CC) -c $(DLL_CFLAGS) $(CPPFLAGS) $(CFLAGS) -o $@ $<
+
+# Note that we omit the $(DLL_CFLAGS) for client programs.
+usedll.o: %o: %cc
+ $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
+
+clean:
+ -rm -f $(OBJS) $(DLL_NAME) $(DLL_EXP_LIB) $(TESTPROGS) $(DLL_EXP_DEF)
+
diff -urN dllhelpers-0.2.6-orig/c++/dllclass.h dllhelpers-0.2.6/c++/dllclass.h
--- dllhelpers-0.2.6-orig/c++/dllclass.h Sat Nov 4 17:02:42 2000
+++ dllhelpers-0.2.6/c++/dllclass.h Tue Jul 24 16:36:51 2001
@@ -5,27 +5,18 @@
# error This example needs newer egcs 1.1 or newer. Sorry.
#endif
-#if BUILDING_DLL
-# define DLLIMPORT __declspec (dllexport)
-#else /* Not BUILDING_DLL */
-# define DLLIMPORT __declspec (dllimport)
-#endif /* Not BUILDING_DLL */
-
-struct DLLIMPORT
+struct
DllClassBase {
virtual int virtual_method () const;
};
-class DLLIMPORT
+class
DllClass : public DllClassBase {
public:
DllClass (int i = 0);
~DllClass ();
int non_virtual_method () const;
virtual int virtual_method () const;
-#ifdef __GNUC__
-// DLLIMPORT // work around an egcs-1.1 bug
-#endif
static int instances;
private:
int i_;
diff -urN dllhelpers-0.2.6-orig/c++/dllexterns.cc dllhelpers-0.2.6/c++/dllexterns.cc
--- dllhelpers-0.2.6-orig/c++/dllexterns.cc Thu Aug 20 17:43:33 1998
+++ dllhelpers-0.2.6/c++/dllexterns.cc Tue Jul 24 16:37:04 2001
@@ -1,5 +1,5 @@
#include "dllclass.h"
-DllClass DLLIMPORT global_dllclass1 (1);
-DllClass DLLIMPORT global_dllclass2 (2);
-int DLLIMPORT global_int_variable = 5;
+DllClass global_dllclass1 (1);
+DllClass global_dllclass2 (2);
+int global_int_variable = 5;
diff -urN dllhelpers-0.2.6-orig/c++/usedll.cc dllhelpers-0.2.6/c++/usedll.cc
--- dllhelpers-0.2.6-orig/c++/usedll.cc Thu Aug 20 17:43:33 1998
+++ dllhelpers-0.2.6/c++/usedll.cc Tue Jul 24 16:41:48 2001
@@ -2,9 +2,9 @@
#include <stdlib.h>
#include "dllclass.h"
-DLLIMPORT DllClass global_dllclass1;
-DLLIMPORT DllClass global_dllclass2;
-DLLIMPORT int global_int_variable;
+extern DllClass global_dllclass1;
+extern DllClass global_dllclass2;
+extern int global_int_variable;
int main () {
cout
diff -urN dllhelpers-0.2.6-orig/c++/usedll.cc~ dllhelpers-0.2.6/c++/usedll.cc~
--- dllhelpers-0.2.6-orig/c++/usedll.cc~ Wed Dec 31 19:00:00 1969
+++ dllhelpers-0.2.6/c++/usedll.cc~ Tue Jul 24 16:37:20 2001
@@ -0,0 +1,32 @@
+#include <iostream.h>
+#include <stdlib.h>
+#include "dllclass.h"
+
+DllClass global_dllclass1;
+DllClass global_dllclass2;
+int global_int_variable;
+
+int main () {
+ cout
+ << "Global integer variable = " << global_int_variable << endl
+ << "DllClass 1 (Imported from DLL):" << endl
+ << " virtual_method = " << global_dllclass1.virtual_method () << endl
+ << " non_virtual_method = " << global_dllclass1.non_virtual_method ()
+ << endl
+ << " instances = " << global_dllclass1.instances << endl
+ << "DllClass 2 (Imported from DLL):" << endl
+ << " virtual_method = " << global_dllclass2.virtual_method () << endl
+ << " non_virtual_method = " << global_dllclass2.non_virtual_method ()
+ << endl
+ << " instances = " << global_dllclass2.instances << endl;
+
+ DllClass local_dllclass (3);
+ cout
+ << "DllClass (Local):" << endl
+ << " virtual_method = " << local_dllclass.virtual_method () << endl
+ << " non_virtual_method = " << local_dllclass.non_virtual_method ()
+ << endl
+ << " instances = " << DllClass::instances << endl;
+ return 0;
+}
+