The attached patch, and the use of bash rather than zsh, reduces the number of
failed tests to one - the last failure being hardcode.test, which I haven't
really looked at in any detail.

A fix for everybody's favourite darwin bug (the convenience lib. thingy) is
included. It's improved from my original submission in June and doesn't seem
to break anything. We even have the latest CVS glib & gtk+ building now!
(I'm told it fixes only the symptoms, not the problem, but it's a start.)

The module loader is derived from Dan Winship's gmodule-dyld. I've reworked
it as a dlopen/dlclose/etc. interface for direct inclusion in ltdl.c but also
as a standalone file in case anybody wants to use it elsewhere. (I'm very new
to modules and there are still some issues to be addressed, so to speak...)

The only thing I'm really uncertain about is the 'fix' (\\\"\1\\\" -> \"\1\")
for lt_cv_sys_global_symbol_to_c_name_address where I have changed the two
instances but perhaps it would be better to add a third darwin-specific case?

Anyway, I'd be grateful if people could test the patch. Here's a sample
ChangeLog entry:

2001-11-03  Francis J Franklin  <[EMAIL PROTECTED]>

        darwin updates:
        * libltdl/Makefile.am: add ltdyld.c & ltdyld.h
        * libltdl/ltdl.c: include ltdyld.c & ltdyld.h if HAVE_DYLD
        * libltdl/ltdyld.c: libdl-equiv. wrapper round NeXT module interface
        * libltdl/ltdyld.h: header, with LTDYLD_REPLACE_DLFCN option
        * libtool.m4:
        - check for NSLinkModule
        - copy darwin linker characteristics to CXX config section
        - lt_cv_sys_global_symbol_to_c_name_address fix (\\\"\1\\\" -> \"\1\")
        * ltdl.m4: check for NSLinkModule
        * ltmain.in:
        - fix infamous conv. library bug (a.k.a. Appalling Patch, Version 0.3)
        - don't add nothing after piecewise linking
        * tests/Makefile.am: propagate $(SHELL) to tests

Regards, Frank

Francis James Franklin
[EMAIL PROTECTED]

Deep in the human unconsciousness is a pervasive need for a logical
universe that makes sense. But the real universe is always one step
beyond logic.
          --- from `The Sayings of Muad'dib' by the Princess Irulan

diff -Naur libtool/libltdl/Makefile.am libtool.mod/libltdl/Makefile.am
--- libtool/libltdl/Makefile.am Tue Sep 11 02:26:44 2001
+++ libtool.mod/libltdl/Makefile.am     Sat Nov  3 21:07:39 2001
@@ -3,10 +3,10 @@
 AUTOMAKE_OPTIONS = no-dependencies foreign
 
 if INSTALL_LTDL
-include_HEADERS = ltdl.h
+include_HEADERS = ltdl.h ltdyld.h
 lib_LTLIBRARIES = libltdl.la
 else
-noinst_HEADERS = ltdl.h
+noinst_HEADERS = ltdl.h ltdyld.h
 endif
 
 if CONVENIENCE_LTDL
@@ -25,7 +25,7 @@
 libltdlc_la_LIBADD = $(LIBADD_DL)
 
 ## Because we do not have automatic dependency tracking:
-ltdl.lo: ltdl.h config.h
+ltdl.lo: ltdl.h config.h ltdyld.h ltdyld.c
 
 $(libltdl_la_OBJECTS) $(libltdlc_la_OBJECTS): libtool
 libtool: $(LIBTOOL_DEPS)
diff -Naur libtool/libltdl/ltdl.c libtool.mod/libltdl/ltdl.c
--- libtool/libltdl/ltdl.c      Sun Oct 28 02:35:22 2001
+++ libtool.mod/libltdl/ltdl.c  Sat Nov  3 21:07:39 2001
@@ -92,6 +92,7 @@
 #  define assert(arg)  ((void) 0)
 #endif
 
+#include "ltdyld.h"
 #include "ltdl.h"
 
 #if WITH_DMALLOC
@@ -809,6 +810,21 @@
   return errors;
 }
 
+
+
+/* --- DARWIN SUPPORT --- */
+
+/* "ltdyld.c" provides a dl* so-style interface/wrapper around darwin's NexT-style
+ * module load/lookup functions.
+ * 
+ * I can't figure out how to modify the underscore-detection properly, so I'm just
+ * going to specify the need for it here - for the moment, anyway...
+ */
+
+#if HAVE_DYLD
+#  include "ltdyld.c"
+#  define NEED_USCORE 1
+#endif
 
 
 
diff -Naur libtool/libltdl/ltdyld.c libtool.mod/libltdl/ltdyld.c
--- libtool/libltdl/ltdyld.c    Thu Jan  1 01:00:00 1970
+++ libtool.mod/libltdl/ltdyld.c        Sat Nov  3 21:07:39 2001
@@ -0,0 +1,214 @@
+/* Copyright (C) 2001 Francis James Franklin
+   This file is part of GNU Libtool.
+      This is based on the implementation of a module loader for Mac OS X by Dan 
+Winship
+      [glib/gmodule/gmodule-dyld.c in glib CVS, see http://www.gtk.org/ for details]
+         Copyright (C) 1998, 2000 Tim Janik
+         Copyright (C) 2001 Dan Winship
+
+  ChangeLog:
+    3rd November 2001
+      o Creation of ltdyld.c & ltdyld.h (fjf)
+
+  Notes & TODO:
+    (1) Dan's gmodule loader distinguishes the load-self case. I haven't, but I'm a
+        bit clueless about all this...
+    (2) I haven't a clue either about what to do with dlctl (), so the 
+'implementation'
+        is officially *broken*. (Not that the rest necessarily works, but...)
+
+  Handy References:
+    1. glib/gmodule/gmodule-dyld.c
+    2. Python/dynload_next.c
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+As a special exception to the GNU Lesser General Public License,
+if you distribute this file as part of a program or library that
+is built using GNU libtool, you may include it under the same
+distribution terms that you use for the rest of that program.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307  USA
+
+*/
+
+/* ltdyld.c
+ * 
+ * This file is designed to be included from ltdl.c, but I'll try to make it 
+standalone
+ * so that other applications can use it if they want.
+ */
+
+/* From the man page with Mac OS X.1:
+ * 
+ * DESCRIPTION
+ * 
+ * These functions provide an interface to the run-time linker ld.so.  They
+ * allow new shared objects to be loaded into the process' address space un-
+ * der program control.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include <mach-o/dyld.h>
+
+#include "ltdyld.h"
+
+#ifndef LT_STMT_START
+#define LT_STMT_START          do
+#endif
+
+#ifndef LT_STMT_END
+#define LT_STMT_END            while (0)
+#endif
+
+#ifndef LT_DLMALLOC
+#define LT_DLMALLOC(tp, n)     ((tp *) malloc ((n) * sizeof(tp)))
+#endif
+
+#ifndef LT_DLFREE
+#define LT_DLFREE(p)           LT_STMT_START { if (p) free ((void *) p); (p) = 0; } 
+LT_STMT_END
+#endif
+
+typedef struct _ltdyld_handle ltdyld_handle;
+
+struct _ltdyld_handle
+{
+  NSModule module;
+};
+
+/* From the man page with Mac OS X.1:
+ * 
+ * The dlopen() function takes a name of a shared ob-
+ * ject as the first argument. The shared object is mapped into the address
+ * space, relocated and its external references are resolved in the same way
+ * as is done with the implicitly loaded shared libraries at program start-
+ * up. The argument can either be an absolute pathname or it can be of the
+ * form ``lib<name>.so[.xx[.yy]]'' in which case the same library search
+ * rules apply that are used for ``intrinsic'' shared library searches.  The
+ * second argument has currently no effect, but should be set to DL_LAZY for
+ * future compatibility.  dlopen() returns a handle to be used in calls to
+ * dlclose(), dlsym() and dlctl().  If the named shared object has already
+ * been loaded by a previous call to dlopen() (and not yet unloaded by
+ * dlclose()), a handle refering to the resident copy is returned.
+ */
+void * ltdyld_dlopen (const char * path, int mode)
+{
+  ltdyld_handle * handle = LT_DLMALLOC (ltdyld_handle,1);
+  if (handle)
+    {
+      NSObjectFileImage image;
+      if (NSCreateObjectFileImageFromFile (path, &image) == NSObjectFileImageSuccess)
+       {
+         unsigned long options = (mode == DL_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW;
+         options |= NSLINKMODULE_OPTION_RETURN_ON_ERROR;
+         options |= NSLINKMODULE_OPTION_PRIVATE;
+
+         handle->module = NSLinkModule (image, path, options);
+         if (handle->module == 0)
+           {
+             LT_DLFREE (handle);
+             handle = 0;
+           }
+         NSDestroyObjectFileImage (image);
+       }
+      else
+       {
+         LT_DLFREE (handle);
+         handle = 0;
+       }
+    }
+  return (void *) handle;
+}
+
+/* From the man page with Mac OS X.1:
+ * 
+ * dlclose() unlinks and removes the object referred to by handle from the
+ * process address space. If multiple calls to have been done on this object
+ * (or the object was one loaded at startup time) the object is removed when
+ * its reference count drops to zero.
+ */
+int ltdyld_dlclose (void * v_handle)
+{
+  int ret = 1; /* assume failure */
+
+  ltdyld_handle * handle = (ltdyld_handle *) v_handle;
+  if (handle ? handle->module : 0)
+    {
+      if (NSUnLinkModule (handle->module, 0)) ret = 0;
+
+      LT_DLFREE (handle); /* Is this correct? - or only if unlinking succeeds? */
+    }
+  return ret;
+}
+
+/* From the man page with Mac OS X.1:
+ * 
+ * dlsym() looks for a definition of symbol in the shared object designated
+ * by handle. The symbols address is returned. If the symbol cannot be re-
+ * solved, NULL is returned.
+ */
+void * ltdyld_dlsym (void * v_handle, const char * symbol)
+{
+  void * address = 0;
+
+  ltdyld_handle * handle = (ltdyld_handle *) v_handle;
+  if (handle ? handle->module : 0)
+    {
+      NSSymbol sym = NSLookupSymbolInModule (handle->module, symbol);
+      if (sym)
+       {
+         address = NSAddressOfSymbol (sym);
+       }
+    }
+  return address;
+}
+
+/* From the man page with Mac OS X.1:
+ * 
+ * dlctl() provides an interface similar to ioctl(2) to control several as-
+ * pects of the run-time linker's operation. This interface is currently un-
+ * der development.
+ */
+int ltdyld_dlctl (void * v_handle, int cmd, void * data)
+{
+  ltdyld_handle * handle = (ltdyld_handle *) v_handle;
+  if (handle ? handle->module : 0)
+    {
+      /* */
+    }
+  return 0; /* What is the proper return value? */
+}
+
+/* From the man page with Mac OS X.1:
+ * 
+ * dlerror() return a character string representing the most recent error
+ * that has occurred while processing one of the other functions described
+ * here.
+ */
+char * ltdyld_dlerror (void)
+{
+  NSLinkEditErrors c;
+
+  int error_number;
+
+  char * file = 0;
+  char * error = 0;
+
+  NSLinkEditError (&c, &error_number, &file, &error);
+
+  return error;
+}
+
diff -Naur libtool/libltdl/ltdyld.h libtool.mod/libltdl/ltdyld.h
--- libtool/libltdl/ltdyld.h    Thu Jan  1 01:00:00 1970
+++ libtool.mod/libltdl/ltdyld.h        Sat Nov  3 21:07:39 2001
@@ -0,0 +1,56 @@
+/* Copyright (C) 2001 Francis James Franklin
+   This file is part of GNU Libtool.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+As a special exception to the GNU Lesser General Public License,
+if you distribute this file as part of a program or library that
+is built using GNU libtool, you may include it under the same
+distribution terms that you use for the rest of that program.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307  USA
+
+*/
+
+#ifndef LTDYLD_H
+#define LTDYLD_H
+
+#ifdef DL_LAZY
+#undef DL_LAZY
+#endif
+#define DL_LAZY 0 /* What is the usual value? */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+extern void * ltdyld_dlopen (const char * path, int mode);
+extern int    ltdyld_dlclose (void * handle);
+extern void * ltdyld_dlsym (void * handle, const char * symbol);
+extern int    ltdyld_dlctl (void * handle, int cmd, void * data);
+extern char * ltdyld_dlerror (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#ifdef LTDYLD_REPLACE_DLFCN
+#define dlopen  ltdyld_dlopen
+#define dlclose ltdyld_dlclose
+#define dlsym   ltdyld_dlsym
+#define dlctl   ltdyld_dlctl
+#define dlerror ltdyld_dlerror
+#endif /* LTDYLD_REPLACE_DLFCN */
+
+#endif /* ! LTDYLD_H */
diff -Naur libtool/libtool.m4 libtool.mod/libtool.m4
--- libtool/libtool.m4  Sun Oct 28 12:22:38 2001
+++ libtool.mod/libtool.m4      Sat Nov  3 21:08:40 2001
@@ -752,7 +752,10 @@
            [AC_CHECK_LIB([svld], [dlopen],
                  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
              [AC_CHECK_LIB([dld], [dld_link],
-                   [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
+                   [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"],
+               [AC_CHECK_FUNC([NSLinkModule],
+                     [lt_cv_dlopen="NSLinkModule"])
+               ])
              ])
            ])
          ])
@@ -2546,6 +2549,27 @@
        ;;
     esac
     ;;
+  darwin* | rhapsody*)
+    case "$host_os" in
+      rhapsody* | darwin1.[[012]])
+        _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress'
+        ;;
+      *) # Darwin 1.3 on
+        _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+       ;;
+    esac
+
+    # FIXME: Relying on posixy $() will cause problems for
+    #        cross-compilation, but unfortunately the echo tests do not
+    #        yet detect zsh echo's removal of \ escapes.  Also zsh mangles
+    #         `"' quotes if we put them in here... so don't!
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC $(test .$module = .yes && echo -bundle || 
+echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags 
+-install_name $rpath/$soname $verstring'
+    # We need to add '_' to the symbols in $export_symbols first
+    #_LT_AC_TAGVAR(archive_expsym_cmds, $1)="$_LT_AC_TAGVAR(archive_cmds, $1)"' && 
+strip -s $export_symbols'
+    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+    ;;
   dgux*)
     case $cc_basename in
       ec++)
@@ -3733,7 +3757,7 @@
 lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
 
 # Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  
{\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", 
(lt_ptr) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\"\1\", 
+(lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) 
+\&\2},/p'"
 
 # Define system-specific variables.
 case $host_os in
@@ -3748,7 +3772,7 @@
     symcode='[[ABCDEGRST]]'
   fi
   lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 
's/^$symcode* .* \(.*\)$/extern char \1;/p'"
-  lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  
{\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", 
(lt_ptr) \&\2},/p'"
+  lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\"\1\", 
+(lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) 
+\&\2},/p'"
   ;;
 irix* | nonstopux*)
   symcode='[[BCDEGRST]]'
diff -Naur libtool/ltdl.m4 libtool.mod/ltdl.m4
--- libtool/ltdl.m4     Sun Oct 28 01:00:00 2001
+++ libtool.mod/ltdl.m4 Sat Nov  3 21:07:39 2001
@@ -324,7 +324,17 @@
          [AC_CHECK_LIB([dld], [dld_link],
                [AC_DEFINE([HAVE_DLD], [1],
                           [Define if you have the GNU dld library.])
-               LIBADD_DL="$LIBADD_DL -ldld"
+               LIBADD_DL="$LIBADD_DL -ldld"],
+           [AC_CHECK_FUNC([NSLinkModule],
+                 [AC_DEFINE([HAVE_LIBDL], [1],
+                            [Define if you have the libdl library or equivalent.])
+                  AC_DEFINE([HAVE_DYLD], [1],
+                            [Define for darwin/NeXT dyld.])
+                  AC_DEFINE([LTDYLD_REPLACE_DLFCN], [1],
+                            [Define to replace libdl names with ltdyld equivalents.])
+                  AC_DEFINE([HAVE_DLERROR], [1],
+                            [Define if you have the `dlerror' function.])
+            ])
           ])
         ])
       ])
diff -Naur libtool/ltmain.in libtool.mod/ltmain.in
--- libtool/ltmain.in   Sun Oct 28 12:22:39 2001
+++ libtool.mod/ltmain.in       Sat Nov  3 21:07:39 2001
@@ -1878,7 +1878,13 @@
 
        if test "$pass" = conv; then
          # Only check for convenience libraries
-         deplibs="$lib $deplibs"
+         if test "$linkmode" = "lib"; then
+           if test "$libdir"; then
+             deplibs="$lib $deplibs"
+           fi
+         else
+           deplibs="$lib $deplibs"
+         fi
          if test -z "$libdir"; then
            if test -z "$old_library"; then
              $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
@@ -4331,7 +4337,10 @@
          done
          RANLIB=$save_RANLIB
          oldobjs=$objlist
+         save_AR=$AR
+         AR=:
          eval cmds=\"\$concat_cmds~$old_archive_cmds\"
+         AR=$save_AR
        fi
       fi
       save_ifs="$IFS"; IFS='~'
diff -Naur libtool/tests/Makefile.am libtool.mod/tests/Makefile.am
--- libtool/tests/Makefile.am   Fri Jun 29 18:09:04 2001
+++ libtool.mod/tests/Makefile.am       Sat Nov  3 21:07:39 2001
@@ -58,10 +58,14 @@
 LIBS = @LIBS@
 
 # Be sure to reexport important environment variables.
+# The tests are shell scripts; run them using $(SHELL) rather than
+# letting them default to /bin/sh - do this by appending $(SHELL)
+# to TESTS_ENVIRONMENT:
 TESTS_ENVIRONMENT = MAKE="$(MAKE)" CC="$(CC)" CFLAGS="$(CFLAGS)" \
        CPPFLAGS="$(CPPFLAGS)" LD="$(LD)" LDFLAGS="$(LDFLAGS)" \
        LIBS="$(LIBS)" LN_S="$(LN_S)" NM="$(NM)" RANLIB="$(RANLIB)" \
-       OBJEXT="$(OBJEXT)" EXEEXT="$(EXEEXT)"
+       OBJEXT="$(OBJEXT)" EXEEXT="$(EXEEXT)" SHELL="$(SHELL)" \
+       $(SHELL)
 
 EXTRA_DIST = defs $(COMMON_TESTS) $(CXX_TESTS)
 

Reply via email to