* tests/cwrapper.test: Add new test for -DLT_DEBUGWRAPPER. * doc/libtool.texi [Linking executables]: Mention wrapper executables, in addition to wrapper scripts. Add menu referencing subsection 'Wrapper executables for programs'. [Wrapper executables for programs]: New subsection. Documents cwrapper rationale, command line options, and LT_DEBUGWRAPPER macro. --- OK to push?
doc/libtool.texi | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++- tests/cwrapper.at | 31 +++++++++++++++++ 2 files changed, 125 insertions(+), 2 deletions(-) diff --git a/doc/libtool.texi b/doc/libtool.texi index d304f28..cfae448 100644 --- a/doc/libtool.texi +++ b/doc/libtool.texi @@ -790,8 +790,9 @@ Note that libtool added the necessary run-time path flag, as well as @cindex wrapper scripts for programs @cindex program wrapper scripts Notice that the executable, @code{hell}, was actually created in the -...@file{@value{objdir}} subdirectory. Then, a wrapper script was created -in the current directory. +...@file{@value{objdir}} subdirectory. Then, a wrapper script (or, on +certain platforms, a wrapper executable @pxref{Wrapper executables}) was +created in the current directory. Since libtool created a wrapper script, you should use libtool to install it and debug it too. However, since the program does not depend @@ -845,6 +846,97 @@ price of being dynamic is eight kilobytes, and the payoff is about four kilobytes. So, having a shared @file{libhello} won't be an advantage until we link it against at least a few more programs. +...@menu +* Wrapper executables:: Wrapper executables for certain platforms. +...@end menu + +...@node Wrapper executables +...@subsection Wrapper executables for programs +...@cindex wrapper executables for programs +...@cindex program wrapper executables + +Some platforms, notably those hosted on win32 such as cygwin +and mingw, use a wrapper executable rather than a wrapper script. It +performs the same function, but is necessary so that @code{make} +rules for target executables (whose names end in @code{$(EXEEXT)}) +are satisfied. Recall that the actual target executable is created +in @value{objdir} as @co...@value{objdir}/program_name.exe} on +these platforms. If a wrapper script were used, then the build +directory would contain @code{program_name}, @emph{not} @code{program_name.exe}. +Thus, @code{make} would never believe that the target executable had +been created, leading to continual and useless relinking. (We could +name the wrapper script @code{program_name.exe} on these platforms, but it +is not a good idea to lie to win32 in this way). + +Therefore, these platforms use a wrapper executable to set various +environment values so that the target executable may locate its +shared libraries. The wrapper executable then launches the target +executable using a (possibly $host-dependent) function, such as +exec() or _spawn(). + +Note that the wrapper executable, like the target executable, is a +$host program, not a $build program. Therefore, the path to the +target executable must be expressed in the native format of the +$host, not that of $build. Similarly, the environment variable +values --- and even the name of the specific environment variables +to adjust --- are $host-specific and should be in $host, not $build, +format. For this reason, libtool contains a number of path and +pathlist conversion functions for various $host/$build combinations, +where $host is one of those platforms where a wrapper executable is +needed. + +Obviously, the wrapper executable itself is quite complex (more so +than the wrapper script). If something goes wrong, it is useful to +debug its operation. This can be enabled by recompiling the wrapper +executable itself as follows: + +...@example +burger$ @kbd{$CC $CFLAGS -DLT_DEBUGWRAPPER -o program_name.exe @value{objdir}/lt-program_name.c} +burger$ +...@end example + +When executing the new wrapper, diagnostic information will be printed +to @code{stderr} before the target executable is launched. + +Finally, the wrapper executable supports a number of command line +options. All of these options are in the @code{--lt-} namespace, and +if present they and their arguments will be removed from the argument +list passed on to the target executable. Therefore, the target +executable may not employ command line options in the @code{--lt-} +namespace. (In fact, the wrapper executable will detect any command +line options in the @code{--lt-} namespace and abort with an error +message if the option is recognized). If this presents a problem, +please contact the libtool team at @email{bug-libtool@@gnu.org}. + +These command line options include: + +...@table @option +...@item --lt-dump-script +Causes the wrapper executable to print a copy of the wrapper @emph{script} +to @code{stdout}, and exit. + +...@item --lt-env-set VAR=VAL +Takes one argument of the form VAR=VAL. The wrapper executable will set +the specified environment variable VAR to the value specified by VAL. +That is, given @samp{--lt-env-set foo=bar}, the new value of @cod...@{foo@}} +will be @code{bar}. No additional subsitution is performed. + +...@item --lt-env-prepend VAR=VAL +Takes one argument of the form VAR=VAL. The wrapper executable will +prepend the value specified by VAL to the specified environment +variable VAR. That is, given @samp{--lt-env-prepend foo=bar}, the new +value of @cod...@{foo@}} will be @code{b...@{foo@}}. No additional subsitution +is performed. + +...@item --lt-env-append VAR=VAL +Takes one argument of the form VAR=VAL. The wrapper executable will +append the value specified by VAL to the specified environment +variable VAR. That is, given @samp{--lt-env-append foo=bar}, the new +value of @cod...@{foo@}} will be @cod...@{foo@}bar}. No additional subsitution +is performed. + +...@end table + @node Debugging executables @section Debugging executables diff --git a/tests/cwrapper.at b/tests/cwrapper.at index ce4572e..7f583f0 100644 --- a/tests/cwrapper.at +++ b/tests/cwrapper.at @@ -78,5 +78,36 @@ for restrictive_flags in '-Wall -Werror' '-std=c89 -Wall -Werror' '-std=c99 -Wal LT_AT_EXEC_CHECK([./usea], [0], [ignore], [ignore], []) done +# Make sure wrapper debugging works. +# This is not part of the loop above, because we +# need to check, not ignore, the output. We structure +# this test as a loop, so that we can 'break' out of it +# if necessary -- even though the loop by design executes +# only once. +for debugwrapper_flags in '-DLT_DEBUGWRAPPER'; do + CFLAGS="$orig_CFLAGS $debugwrapper_flags" + sed "s/LTCFLAGS=.*/&' $debugwrapper_flags'/" < "$orig_LIBTOOL" > ./libtool + LIBTOOL=./libtool + + # make sure $debugwrapper_Flags do not cause a failure + # themselves (e.g. because a non-gcc compiler doesn't + # understand them) + $LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c trivial.c || continue + + AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c liba.c], + [], [ignore], [ignore]) + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -version-info=0.0.0 -no-undefined -o liba.la -rpath /foo liba.lo], + [], [ignore], [ignore]) + AT_CHECK([test -f liba.la]) + + AT_CHECK([$CC $CPPFLAGS $CFLAGS -c usea.c], + [], [ignore], [ignore]) + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o usea$EXEEXT usea.$OBJEXT liba.la], + [], [ignore], [ignore]) + LT_AT_EXEC_CHECK([./usea], [0], [ignore], [stderr], []) + LT_AT_UNIFY_NL([stderr]) + AT_CHECK([grep '^(main) argv\[[0\]][[ \t]]*: \./usea' stderr], [0], [ignore], [ignore]) +done + AT_CLEANUP -- 1.6.0.4