[Mingw-users] Re: Solving the "relink exe's" libtool problem [take 3]

Earnie Boyd earnie_boyd@yahoo.com
Mon Jan 20 21:02:00 GMT 2003


This patch passes my test.  What do we need to do to get this accepted 
into libtool cvs HEAD?

Earnie.

Charles Wilson wrote:
> Okay, this version
> 
> 1) puts lt-foo.c into .libs
> 
> 2) "libtool --mode=clean" does the right thing --- cleans up foo, 
> foo.exe, .libs/foo.exe, .libs/lt-foo.c, plus whatever else it already 
> took care of.
> 
> 3) lt-foo.c actually passes its own arguments to the shell wrapper -- it 
> didn't, before. (Oops)
> 
> libtool regression tests: no new failures (on cygwin)
> briefly tested on another project; worked fine.
> 
> Binary packages for cygwin (libtool-devel-20030103-4, 
> libltdl3-20030103-4) available by pointing setup.exe at 
> http://www.neuro.gatech.edu/users/cwilson/cygutils/testing/
> 
> --Chuck
> 
> 
> ------------------------------------------------------------------------
> 
> Index: ltmain.in
> ===================================================================
> RCS file: /cvsroot/libtool/libtool/ltmain.in,v
> retrieving revision 1.318
> diff -u -r1.318 ltmain.in
> --- ltmain.in	1 Jan 2003 01:57:47 -0000	1.318
> +++ ltmain.in	13 Jan 2003 04:48:39 -0000
> @@ -4284,6 +4284,207 @@
>  	    outputname=`echo $outputname|${SED} 's,.exe$,,'` ;;
>  	  *) exeext= ;;
>  	esac
> +	case $host in
> +	  *cygwin* | *mingw* )
> +	    cwrappersource=`echo ${objdir}/lt-${output}.c`
> +	    cwrapper=`echo ${output}.exe`
> +	    $rm $cwrappersource $cwrapper
> +	    trap "$rm $cwrappersource $cwrapper; exit 1" 1 2 15
> +
> +	    cat > $cwrappersource <<EOF
> +
> +/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
> +   Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
> +
> +   The $output program cannot be directly executed until all the libtool
> +   libraries that it depends on are installed.
> +   
> +   This wrapper executable should never be moved out of the build directory.
> +   If it is, it will not operate correctly.
> +
> +   Currently, it simply execs the wrapper *script* "/bin/sh $output",
> +   but could eventually absorb all of the scripts functionality and
> +   exec $objdir/$outputname directly.
> +*/
> +EOF
> +	    cat >> $cwrappersource<<"EOF"
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <malloc.h>
> +#include <stdarg.h>
> +#include <assert.h>
> +
> +#if defined(PATH_MAX)
> +# define LT_PATHMAX PATH_MAX
> +#elif defined(MAXPATHLEN)
> +# define LT_PATHMAX MAXPATHLEN
> +#else
> +# define LT_PATHMAX 1024
> +#endif
> +
> +#ifndef DIR_SEPARATOR
> +#define DIR_SEPARATOR '/'
> +#endif
> +
> +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
> +  defined (__OS2__)
> +#define HAVE_DOS_BASED_FILE_SYSTEM
> +#ifndef DIR_SEPARATOR_2 
> +#define DIR_SEPARATOR_2 '\\'
> +#endif
> +#endif
> +
> +#ifndef DIR_SEPARATOR_2
> +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
> +#else /* DIR_SEPARATOR_2 */
> +# define IS_DIR_SEPARATOR(ch) \
> +        (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
> +#endif /* DIR_SEPARATOR_2 */
> +
> +#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
> +#define XFREE(stale) do { \
> +  if (stale) { free ((void *) stale); stale = 0; } \
> +} while (0)
> +
> +const char *program_name = NULL;
> +
> +void * xmalloc (size_t num);
> +char * xstrdup (const char *string);
> +char * basename (const char *name);
> +char * fnqualify(const char *path);
> +char * strendzap(char *str, const char *pat);
> +void lt_fatal (const char *message, ...);
> +
> +int
> +main (int argc, char *argv[])
> +{
> +  char **newargz;
> +  int i;
> +  
> +  program_name = (char *) xstrdup ((char *) basename (argv[0]));
> +  newargz = XMALLOC(char *, argc+2);
> +  newargz[0] = xstrdup("/bin/sh");
> +  newargz[1] = fnqualify(argv[0]);
> +  /* we know the script has the same name, without the .exe */
> +  /* so make sure newargz[1] doesn't end in .exe */
> +  strendzap(newargz[1],".exe"); 
> +  for (i = 1; i < argc; i++)
> +    newargz[i+1] = xstrdup(argv[i]);
> +  newargz[argc+1] = NULL;
> +  execv("/bin/sh",newargz);
> +}
> +
> +void *
> +xmalloc (size_t num)
> +{
> +  void * p = (void *) malloc (num);
> +  if (!p)
> +    lt_fatal ("Memory exhausted");
> +
> +  return p;
> +}
> +
> +char * 
> +xstrdup (const char *string)
> +{
> +  return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
> +;
> +}
> +
> +char *
> +basename (const char *name)
> +{
> +  const char *base;
> +
> +#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
> +  /* Skip over the disk name in MSDOS pathnames. */
> +  if (isalpha (name[0]) && name[1] == ':') 
> +    name += 2;
> +#endif
> +
> +  for (base = name; *name; name++)
> +    if (IS_DIR_SEPARATOR (*name))
> +      base = name + 1;
> +  return (char *) base;
> +}
> +
> +char * 
> +fnqualify(const char *path)
> +{
> +  size_t size;
> +  char *p;
> +  char tmp[LT_PATHMAX + 1];
> +
> +  assert(path != NULL);
> +
> +  /* Is it qualified already? */
> +#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
> +  if (isalpha (path[0]) && path[1] == ':')
> +    return xstrdup (path);
> +#endif
> +  if (IS_DIR_SEPARATOR (path[0]))
> +    return xstrdup (path);
> +
> +  /* prepend the current directory */
> +  /* doesn't handle '~' */
> +  if (getcwd (tmp, LT_PATHMAX) == NULL)
> +    lt_fatal ("getcwd failed");
> +  size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */
> +  p = XMALLOC(char, size);
> +  sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path);
> +  return p;
> +}
> +
> +char *
> +strendzap(char *str, const char *pat) 
> +{
> +  size_t len, patlen;
> +
> +  assert(str != NULL);
> +  assert(pat != NULL);
> +
> +  len = strlen(str);
> +  patlen = strlen(pat);
> +
> +  if (patlen <= len)
> +  {
> +    str += len - patlen;
> +    if (strcmp(str, pat) == 0)
> +      *str = '\0';
> +  }
> +  return str;
> +}
> +
> +static void
> +lt_error_core (int exit_status, const char * mode, 
> +          const char * message, va_list ap)
> +{
> +  fprintf (stderr, "%s: %s: ", program_name, mode);
> +  vfprintf (stderr, message, ap);
> +  fprintf (stderr, ".\n");
> +
> +  if (exit_status >= 0)
> +    exit (exit_status);
> +}
> +
> +void
> +lt_fatal (const char *message, ...)
> +{
> +  va_list ap;
> +  va_start (ap, message);
> +  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
> +  va_end (ap);
> +}
> +EOF
> +	  # we should really use a build-platform specific compiler
> +	  # here, but OTOH, the wrappers (shell script and this C one)
> +	  # are only useful if you want to execute the "real" binary.
> +	  # Since the "real" binary is built for $host, then this
> +	  # wrapper might as well be built for $host, too.
> +	  $run $LTCC -s -o $cwrapper $cwrappersource
> +	  ;;
> +	esac
>  	$rm $output
>  	trap "$rm $output; exit 1" 1 2 15
>  
> @@ -5064,10 +5265,17 @@
>  	  notinst_deplibs=
>  	  relink_command=
>  
> +	  # To insure that "foo" is sourced, and not "foo.exe",
> +	  # finese the cygwin/MSYS system by explicitly sourcing "foo."
> +	  # which disallows the automatic-append-.exe behavior.
> +	  case $host in
> +	  *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
> +	  *) wrapperdot=${wrapper} ;;
> +	  esac
>  	  # If there is no directory component, then add one.
>  	  case $file in
> -	  */* | *\\*) . $wrapper ;;
> -	  *) . ./$wrapper ;;
> +	  */* | *\\*) . ${wrapperdot} ;;
> +	  *) . ./${wrapperdot} ;;
>  	  esac
>  
>  	  # Check the variables that should have been set.
> @@ -5095,10 +5303,17 @@
>  	  done
>  
>  	  relink_command=
> +	  # To insure that "foo" is sourced, and not "foo.exe",
> +	  # finese the cygwin/MSYS system by explicitly sourcing "foo."
> +	  # which disallows the automatic-append-.exe behavior.
> +	  case $host in
> +	  *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
> +	  *) wrapperdot=${wrapper} ;;
> +	  esac
>  	  # If there is no directory component, then add one.
>  	  case $file in
> -	  */* | *\\*) . $file ;;
> -	  *) . ./$file ;;
> +	  */* | *\\*) . ${wrapperdot} ;;
> +	  *) . ./${wrapperdot} ;;
>  	  esac
>  
>  	  outputname=
> @@ -5541,15 +5756,31 @@
>  	;;
>  
>        *)
> -	# Do a test to see if this is a libtool program.
> -	if test "$mode" = clean &&
> -	   (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
> -	  relink_command=
> -	  . $dir/$file
> -
> -	  rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
> -	  if test "$fast_install" = yes && test -n "$relink_command"; then
> -	    rmfiles="$rmfiles $objdir/lt-$name"
> +	if test "$mode" = clean ; then
> +	  noexename=$name
> +	  case $file in
> +	  *.exe) 
> +	    file=`echo $file|${SED} 's,.exe$,,'`
> +	    noexename=`echo $name|${SED} 's,.exe$,,'`
> +	    # $file with .exe has already been added to rmfiles,
> +	    # add $file without .exe
> +	    rmfiles="$rmfiles $file"
> +	    ;;
> +	  esac
> +	  # Do a test to see if this is a libtool program.
> +	  if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
> +	    relink_command=
> +	    . $dir/$file
> +
> +	    # note $name still contains .exe if it was in $file originally
> +	    # as does the version of $file that was added into $rmfiles
> +	    rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
> +	    if test "$fast_install" = yes && test -n "$relink_command"; then
> +	      rmfiles="$rmfiles $objdir/lt-$name"
> +	    fi
> +	    if test "X$noexename" != "X$name" ; then
> +	      rmfiles="$rmfiles $objdir/lt-${noexename}.c"
> +	    fi
>  	  fi
>  	fi
>  	;;
> 
> 
> ------------------------------------------------------------------------
> 
> 2003-01-12  Charles Wilson  <cwilson@ece.gatech.edu>
> 
> 	* ltmain.in: add code for a binary wrapper
> 	to use with uninstalled executables on cygwin/mingw.
> 	Make sure that --mode=clean gets shell wrapper and
> 	binary wrapper.  When sourcing the shell wrapper, 
> 	invoke using a terminal `.' on cygwin/mingw to 
> 	avoid the automatic append-.exe behavior.


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/



More information about the Cygwin mailing list