* ltmain.m4sh (func_emit_libtool_wrapper_script): add

code block to handle cases when wrapper script is in $objdir.
(func_emit_libtool_cwrapperexe_source): replace DEBUG() macro
with namespace-safe LTWRAPPER_DEBUGPRINTF(). Call
func_emit_libtool_wrapper_script() with appropriate filters to
embed script text in C char* static variable.
(f_e_l_c_s: main): add new option --lt-dump-script, parse argv[]
for it, and take appropriate action.  Call chase_symlinks()
on argv[0], in case this.exe was launched via one.  Use chased
value to determine full absolute pathname of wrapper script, in
$objdir. Unconditionally write script out to this pathname and
set permission bits.  Remove extraneous ';' from debugging loop.
(f_e_l_c_s: main) [mingw]: DOS-ize $SHELL before populating
newargv[0]; if $TARGETSHELL environment variable is set, use
it instead of $SHELL and do not DOS-ize.  Ensure newargv[1]
(wrapper script absolute path) uses only '/', not '\'.  Make
sure to call execv() with DOS-ized $SHELL (or un-DOS-ized
$TARGETSHELL, if set)
(f_e_l_c_s: make_executable): new function
(f_e_l_c_s: chase_symlinks): new function (no-op if !S_ISLNK)
This commit is contained in:
Charles Wilson 2007-06-07 08:47:11 +00:00
parent b1ce2a5e6a
commit d9033b1759
2 changed files with 249 additions and 24 deletions

View File

@ -1,3 +1,26 @@
2007-04-27 Charles Wilson <libtool@cwilson.fastmail.fm>
* ltmain.m4sh (func_emit_libtool_wrapper_script): add
code block to handle cases when wrapper script is in $objdir.
(func_emit_libtool_cwrapperexe_source): replace DEBUG() macro
with namespace-safe LTWRAPPER_DEBUGPRINTF(). Call
func_emit_libtool_wrapper_script() with appropriate filters to
embed script text in C char* static variable.
(f_e_l_c_s: main): add new option --lt-dump-script, parse argv[]
for it, and take appropriate action. Call chase_symlinks()
on argv[0], in case this.exe was launched via one. Use chased
value to determine full absolute pathname of wrapper script, in
$objdir. Unconditionally write script out to this pathname and
set permission bits. Remove extraneous ';' from debugging loop.
(f_e_l_c_s: main) [mingw]: DOS-ize $SHELL before populating
newargv[0]; if $TARGETSHELL environment variable is set, use
it instead of $SHELL and do not DOS-ize. Ensure newargv[1]
(wrapper script absolute path) uses only '/', not '\'. Make
sure to call execv() with DOS-ized $SHELL (or un-DOS-ized
$TARGETSHELL, if set)
(f_e_l_c_s: make_executable): new function
(f_e_l_c_s: chase_symlinks): new function (no-op if !S_ISLNK)
2007-06-03 Peter O'Gorman <peter@pogma.com>
* libltdl/m4/libtool.m4 (old_archive_cmds): Remove

View File

@ -2301,6 +2301,20 @@ else
file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
done
# cygwin/mingw cwrapper will rewrite this line:
WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
# special case for '.'
if test \"\$thisdir\" = \".\"; then
thisdir=\`pwd\`
fi
# remove .libs from thisdir
case \"\$thisdir\" in
*[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;;
$objdir ) thisdir=. ;;
esac
fi
# Try to get the absolute directory name.
absdir=\`cd \"\$thisdir\" && pwd\`
test -n \"\$absdir\" && thisdir=\"\$absdir\"
@ -2424,7 +2438,7 @@ func_emit_libtool_cwrapperexe_source ()
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",
Currently, it simply execs the wrapper *script* "$SHELL $output",
but could eventually absorb all of the scripts functionality and
exec $objdir/$outputname directly.
*/
@ -2438,6 +2452,7 @@ EOF
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>
#if defined(PATH_MAX)
@ -2482,12 +2497,11 @@ EOF
if (stale) { free ((void *) stale); stale = 0; } \
} while (0)
/* -DDEBUG is fairly common in CFLAGS. */
#undef DEBUG
#undef LTWRAPPER_DEBUGPRINTF
#if defined DEBUGWRAPPER
# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__)
# define LTWRAPPER_DEBUGPRINTF(format, ...) fprintf(stderr, format, __VA_ARGS__)
#else
# define DEBUG(format, ...)
# define LTWRAPPER_DEBUGPRINTF(format, ...)
#endif
const char *program_name = NULL;
@ -2496,42 +2510,145 @@ void * xmalloc (size_t num);
char * xstrdup (const char *string);
const char * base_name (const char *name);
char * find_executable(const char *wrapper);
char * chase_symlinks(const char *pathspec);
int make_executable(const char *path);
int check_executable(const char *path);
char * strendzap(char *str, const char *pat);
void lt_fatal (const char *message, ...);
static const char* script_text =
EOF
func_emit_libtool_wrapper_script |
$SED -e 's/\([\\"]\)/\\\1/g' \
-e 's/\(WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\)=.*/\1=yes/' \
-e 's/^/"/' -e 's/$/\\n"/'
echo ";"
cat <<EOF
int
main (int argc, char *argv[])
{
char **newargz;
char *tmp_pathspec;
char *actual_cwrapper_path;
char *shwrapper_name;
FILE *shwrapper;
const char* dumpscript_opt = "--lt-dump-script";
int i;
program_name = (char *) xstrdup (base_name (argv[0]));
DEBUG("(main) argv[0] : %s\n",argv[0]);
DEBUG("(main) program_name : %s\n",program_name);
LTWRAPPER_DEBUGPRINTF("(main) argv[0] : %s\n",argv[0]);
LTWRAPPER_DEBUGPRINTF("(main) program_name : %s\n",program_name);
/* very simple arg parsing; don't want to rely on getopt */
for (i=1; i<argc; i++)
{
if (strcmp(argv[i], dumpscript_opt) == 0)
{
printf("%s", script_text);
return 0;
}
}
newargz = XMALLOC(char *, argc+2);
EOF
if test -n "$TARGETSHELL" ; then
# no path translation at all
lt_newargv0=$TARGETSHELL
else
case "$host" in
*mingw* )
# awkward: cmd appends spaces to result
lt_sed_strip_trailing_spaces="s/[ ]*\$//"
lt_newargv0=`( cmd //c echo $SHELL | $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo $SHELL`
case $lt_newargv0 in
*.exe | *.EXE) ;;
*) lt_newargv0=$lt_newargv0.exe ;;
esac
;;
* ) lt_newargv0=$SHELL ;;
esac
fi
cat <<EOF
newargz[0] = (char *) xstrdup("$SHELL");
newargz[0] = (char *) xstrdup("$lt_newargv0");
EOF
cat <<"EOF"
newargz[1] = find_executable(argv[0]);
if (newargz[1] == NULL)
tmp_pathspec = find_executable (argv[0]);
if (tmp_pathspec == NULL)
lt_fatal("Couldn't find %s", argv[0]);
DEBUG("(main) found exe at : %s\n",newargz[1]);
/* 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");
LTWRAPPER_DEBUGPRINTF("(main) found exe (before symlink chase) at : %s\n",tmp_pathspec);
actual_cwrapper_path = chase_symlinks (tmp_pathspec);
LTWRAPPER_DEBUGPRINTF("(main) found exe (after symlink chase) at : %s\n",actual_cwrapper_path);
XFREE(tmp_pathspec);
shwrapper_name = (char *) xstrdup (base_name (actual_cwrapper_path));
strendzap( actual_cwrapper_path, shwrapper_name );
/* shwrapper_name transforms */
strendzap(shwrapper_name,".exe");
tmp_pathspec = XMALLOC( char, strlen ( shwrapper_name ) +
strlen ( "_ltshwrapper" ) + 1 );
strcpy ( tmp_pathspec, shwrapper_name );
strcat ( tmp_pathspec, "_ltshwrapper" );
XFREE( shwrapper_name );
shwrapper_name = tmp_pathspec;
tmp_pathspec = 0;
LTWRAPPER_DEBUGPRINTF("(main) libtool shell wrapper name: %s\n",shwrapper_name);
EOF
cat <<EOF
newargz[1] = XMALLOC( char, strlen ( actual_cwrapper_path ) +
strlen ( "$objdir" ) + 1 +
strlen ( shwrapper_name ) + 1 );
strcpy ( newargz[1], actual_cwrapper_path );
strcat ( newargz[1], "$objdir" );
strcat ( newargz[1], "/" );
strcat ( newargz[1], shwrapper_name );
EOF
case $host_os in
mingw*)
cat <<"EOF"
{
char* p;
while( (p = strchr(newargz[1], '\\')) != NULL) {
*p = '/';
}
}
EOF
;;
esac
cat <<"EOF"
XFREE( shwrapper_name );
XFREE( actual_cwrapper_path );
/* note: do NOT use "wt" here! -- defer to underlying
* mount type on cygwin
*/
if ( (shwrapper = fopen (newargz[1], "w")) == 0 )
{
lt_fatal("Could not open %s for writing", newargz[1]);
}
fprintf (shwrapper, "%s", script_text);
fclose (shwrapper);
make_executable( newargz[1] );
for (i = 1; i < argc; i++)
newargz[i+1] = xstrdup(argv[i]);
newargz[argc+1] = NULL;
for (i=0; i<argc+1; i++)
{
DEBUG("(main) newargz[%d] : %s\n",i,newargz[i]);
;
LTWRAPPER_DEBUGPRINTF("(main) newargz[%d] : %s\n",i,newargz[i]);
}
EOF
@ -2539,12 +2656,12 @@ EOF
case $host_os in
mingw*)
cat <<EOF
execv("$SHELL",(char const **)newargz);
execv ("$lt_newargv0", (const char * const *) newargz);
EOF
;;
*)
cat <<EOF
execv("$SHELL",newargz);
execv ("$lt_newargv0", newargz);
EOF
;;
esac
@ -2592,7 +2709,7 @@ check_executable(const char * path)
{
struct stat st;
DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!");
LTWRAPPER_DEBUGPRINTF("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!");
if ((!path) || (!*path))
return 0;
@ -2612,8 +2729,37 @@ check_executable(const char * path)
return 0;
}
int
make_executable(const char * path)
{
int rval = 0;
struct stat st;
/* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
int S_XFLAGS =
#if defined (S_IXOTH)
S_IXOTH ||
#endif
#if defined (S_IXGRP)
S_IXGRP ||
#endif
S_IXUSR;
LTWRAPPER_DEBUGPRINTF("(make_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!");
if ((!path) || (!*path))
return 0;
if (stat (path, &st) >= 0)
{
rval = chmod ( path, st.st_mode | S_XFLAGS );
}
return rval;
}
/* Searches for the full path of the wrapper. Returns
newly allocated full path name if found, NULL otherwise */
newly allocated full path name if found, NULL otherwise
Does not chase symlinks, even on platforms that support them.
*/
char *
find_executable (const char* wrapper)
{
@ -2625,7 +2771,7 @@ find_executable (const char* wrapper)
int tmp_len;
char* concat_name;
DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!");
LTWRAPPER_DEBUGPRINTF("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!");
if ((wrapper == NULL) || (*wrapper == '\0'))
return NULL;
@ -2714,6 +2860,62 @@ find_executable (const char* wrapper)
return NULL;
}
char *
chase_symlinks(const char *pathspec)
{
#ifndef S_ISLNK
return xstrdup ( pathspec );
#else
char buf[LT_PATHMAX];
struct stat s;
int rv = 0;
char* tmp_pathspec = xstrdup (pathspec);
char* p;
int has_symlinks = 0;
while (strlen(tmp_pathspec) && !has_symlinks)
{
LTWRAPPER_DEBUGPRINTF("checking path component for symlinks: %s\n", tmp_pathspec);
if (lstat (tmp_pathspec, &s) == 0)
{
if (S_ISLNK(s.st_mode) != 0)
{
has_symlinks = 1;
break;
}
/* search backwards for last DIR_SEPARATOR */
p = tmp_pathspec + strlen(tmp_pathspec) - 1;
while ( (p > tmp_pathspec) && (! IS_DIR_SEPARATOR(*p)) )
p--;
if ( (p == tmp_pathspec) && (! IS_DIR_SEPARATOR(*p)) )
{
/* no more DIR_SEPARATORS left */
break;
}
*p = '\0';
}
else
{
char* errstr = strerror(errno);
lt_fatal("Error accessing file %s (%s)", tmp_pathspec, errstr);
}
}
XFREE(tmp_pathspec);
if (!has_symlinks)
{
return xstrdup ( pathspec );
}
tmp_pathspec = realpath ( pathspec, buf );
if (tmp_pathspec == 0)
{
lt_fatal("Could not follow symlinks for %s", pathspec);
}
return xstrdup ( tmp_pathspec );
#endif
}
char *
strendzap(char *str, const char *pat)
{