1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
|
# static.at -- test flags for static/dynamic linking -*- Autotest -*-
#
# Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
# Written by Ralf Wildenhues, 2006
#
# This file is part of GNU Libtool.
#
# GNU Libtool is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# GNU Libtool 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Libtool; see the file COPYING. If not, a copy
# can be downloaded from http://www.gnu.org/licenses/gpl.html,
# or obtained by writing to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
####
##### NOTES #####
#
# - How do we test whether a library was linked statically?
# We could
# - try $NM on the program to see whether it includes the symbol definitions.
# disadvantage: for uninstalled programs, we may need to find out the name
# of the _real_ linked-against-uninstalled executable
# (.libs/prog vs .libs/lt-prog etc).
# - simply remove the libraries before execution. If the program still works,
# then the library was linked statically.
# -Does this work on all systems?
# -No, it will fail on AIX with non-rtl-created libraries: plain `-static'
# will only cause the linker not to consider `*.so' libraries, but only
# `*.a'. The latter, however, may still be shared images. :-/
# `-all-static' still works, however.
#
# It will not work with dlpreloading until we fix its related bug.
#
# Let's try the latter until we know better.
# - Test -Bstatic/-Bdynamic. It should work with all of:
# - (un)installed libtool libraries
# - non-libtool libraries
# - direct or pulled-in libraries
# - libraries of which there are only one kind available (TODO)
# (in the static case, should having only the shared one provoke failure?)
# - Check no extraneous run paths have been added.
# - make sure -Bstatic/-Bdynamic cannot be mixed with -all-static (TODO)
# - should -Bstatic/-Bdynamic be mixable with -static or -static-libtool-libs?
# Semantics could be as follows:
# - `-static'/`-static-libtool-libs' set the default which is the initial
# value, then `-Bstatic'/`-Bdynamic' override that
# - `-Bdefault' resets to the default value given by the other switches.
# - TODO: test exposure for dlopened and dlpreopened modules,
# without and with diverse static flag combinations.
# - TODO: test other tags: C++ etc.
# (most likely the Sun compiler suite will be the only problem child).
AT_SETUP([static linking flags for programs])
AT_KEYWORDS([libtool])
LDFLAGS="$LDFLAGS -no-undefined"
prefix=`pwd`/inst
bindir=$prefix/bin
prefix1=`pwd`/inst1
prefix2=`pwd`/inst2
prefix3=`pwd`/inst3
libdir1=$prefix1/lib
libdir2=$prefix2/lib
libdir3=$prefix3/lib
srcdir_broken=`pwd`/broken-src
prefix_broken=`pwd`/broken
libdir_broken=$prefix_broken/lib
bindir_broken=$prefix_broken/bin
have_static=false
have_shared=false
per_deplib=false
$LIBTOOL --features | grep 'enable static libraries' >/dev/null && have_static=:
$LIBTOOL --features | grep 'enable shared libraries' >/dev/null && have_shared=:
eval `$LIBTOOL --config |
$EGREP '^(per_deplib_(static|dynamic)_flag|shlibpath_var|link_static_flag)='`
if test -n "$per_deplib_static_flag" && test -n "$per_deplib_dynamic_flag"; then
per_deplib=:
fi
# On GNU/Linux with --disable-static, m-all-static fails to link.
# What we'd like to state here is: if the user actively passed
# --disable-static (as opposed to: the libtool.m4 macros set
# enable_static=no), then they cannot expect -all-static to work.
# So we punt, knowing that we mangle enable_static on AIX only.
can_link_all_static=-all-static
case $host_os,$have_static,$link_static_flag in
aix*) ;;
*,false,?*) can_link_all_static= ;;
esac
# Create broken libraries. They will later be moved to those
# directories where the respective libraries should be linked
# statically from. This detects both failure to link statically
# and failure to omit extraneous run paths.
mkdir $srcdir_broken $prefix_broken $libdir_broken
(
cd $srcdir_broken
echo 'int this_should_not_be_linked_against() { return 0; }' > a.c
$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c a.c
for i in 1 1dep 2 2dep 3 3dep; do
$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba$i.la a.lo -rpath $libdir_broken
$LIBTOOL --mode=install cp liba$i.la $libdir_broken/liba$i.la
done
)
func_fix_path ()
{
# For w32, hardcoding cannot work, but $libdir/../bin is where binaries
# usually are installed. Since we use several prefixes for testing
# convenience -- it allows us to replace the good libraries easily with
# broken ones and vice versa -- we have to set PATH to find them.
# Since OTOH we put broken libs of all names in the "moved" prefixes,
# we have to ensure that this prefix comes last: otherwise we may link
# against a broken library but the good one would come later in the PATH.
# So we let the caller of this function set the order: the "other" two
# come first.
if test "$shlibpath_var" = PATH; then
save_PATH=$PATH
sep=
test -z "$PATH" || sep=:
PATH=${2}/bin:${3}/bin:${1}/bin$sep$PATH
fi
}
func_restore_path ()
{
if test "$shlibpath_var" = PATH; then
PATH=$save_PATH
fi
}
# func_move_libs srcdir_to_move prefix_to_move other_prefix other_prefix
func_move_libs ()
{
LT_AT_MVDIR(["${1}"], ["${1}-moved"])
LT_AT_MVDIR(["${2}"], ["${2}-moved"])
LT_AT_MVDIR(["$srcdir_broken"], ["${1}"])
LT_AT_MVDIR(["$prefix_broken"], ["${2}"])
func_fix_path ${2} ${3} ${4}
}
# func_restore_libs srcdir_to_restore prefix_to_restore
func_restore_libs ()
{
func_restore_path
LT_AT_MVDIR(["${2}"], ["$prefix_broken"])
LT_AT_MVDIR(["${1}"], ["$srcdir_broken"])
LT_AT_MVDIR(["${2}-moved"], ["${2}"])
LT_AT_MVDIR(["${1}-moved"], ["${1}"])
}
# make sure the program can be run.
func_test_exec ()
{
# On AIX without runtimelinking, this does not make sense.
if $have_static; then
echo "## The following should succeed:"
for st
do
echo "# m$st"
LT_AT_EXEC_CHECK([./m$st])
# For some per-deplib flag combinations there may be no installed program,
# because liba2 is not yet installed.
if test -f "$bindir/m$st"; then
LT_AT_EXEC_CHECK([$bindir/m$st])
fi
done
fi
}
# make sure the program cannot be run.
func_test_exec_fail ()
{
# No point in testing if we're linking statically anyway.
# TODO: Maybe in the `else' case we could test for success?
if $have_shared; then
echo "## The following should fail:"
for st
do
echo "# m$st"
LT_AT_EXEC_CHECK([./m$st || (exit 1)], [1], [], [ignore])
# For some per-deplib flag combinations there may be no installed program,
# because liba2 is not yet installed.
if test -f "$bindir/m$st"; then
LT_AT_EXEC_CHECK([$bindir/m$st || (exit 1)], [1], [], [ignore])
fi
done
fi
}
# Try three independent libraries,
# one installed libtool library,
# one uninstalled libtool library,
# one non-libtool library,
# the libtool libraries each having a dependency, or not.
# Try both an uninstalled and the corresponding installed program.
for withdep in no yes; do
echo
echo "### libraries with dependencies: $withdep"
rm -rf src $prefix $prefix1 $prefix2 $prefix3
mkdir src $prefix $bindir $prefix1 $prefix2 $prefix3
cd src
### build the libraries.
for i in 1 2 3; do
eval ldir=\$libdir$i
mkdir a$i $ldir
cd a$i
case $withdep,$i in
no,* | yes,3)
echo "int a$i() { return 0; }" > a$i.c
$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c a$i.c
$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba$i.la a$i.lo -rpath $ldir
;;
*)
echo "int a${i}dep() { return 0; }" > a${i}dep.c
$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c a${i}dep.c
$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba${i}dep.la a${i}dep.lo -rpath $ldir
echo "extern int a${i}dep(); int a$i() { return a${i}dep(); }" > a$i.c
$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c a$i.c
$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba$i.la a$i.lo -rpath $ldir ./liba${i}dep.la
;;
esac
cd ..
done
### install the libraries.
test "$withdep" = yes && $LIBTOOL --mode=install cp a1/liba1dep.la $libdir1/liba1dep.la
$LIBTOOL --mode=install cp a1/liba1.la $libdir1/liba1.la
$LIBTOOL --mode=install cp a3/liba3.la $libdir3/liba3.la
$LIBTOOL --mode=clean rm -f a1/liba1.la a3/liba3.la
test "$withdep" = yes && $LIBTOOL --mode=clean rm -f a1/liba1dep.la
# simulate a non-libtool lib:
rm -f $libdir3/liba3.la
### build the programs.
echo 'extern int a1(), a2(), a3();
int main() { return a1() + a2() + a3(); }' > m.c
$CC $CPPFLAGS $CFLAGS -c m.c
# global static flags.
for st in -static -static-libtool-libs $can_link_all_static; do
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS $st -o m$st m.$OBJEXT \
-L$libdir1 -la1 a2/liba2.la -L$libdir3 -R$libdir3 -la3],
[0], [ignore], [ignore])
done
# per-deplib static/shared flags.
# also try a bit redundant flags, and shuffled order (for run paths check).
if $per_deplib; then
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m1 m.$OBJEXT \
-L$libdir1 -Bstatic -la1 -Bdynamic a2/liba2.la -L$libdir3 -R$libdir3 -la3],
[0], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m2 m.$OBJEXT \
-L$libdir1 -la1 -Bstatic a2/liba2.la -Bdynamic -L$libdir3 -R$libdir3 -la3],
[0], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m3 m.$OBJEXT \
-L$libdir1 -la1 a2/liba2.la -L$libdir3 -Bstatic -la3 -Bdynamic],
[0], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m12 m.$OBJEXT \
-L$libdir1 -Bstatic -la1 a2/liba2.la -Bdynamic -L$libdir3 -R$libdir3 -la3],
[0], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m13 m.$OBJEXT \
-L$libdir1 -Bstatic -la1 -Bdynamic a2/liba2.la \
-L$libdir3 -Bstatic -la3 -Bdynamic],
[0], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m31 m.$OBJEXT \
-L$libdir3 -Bstatic -la3 -Bdynamic a2/liba2.la \
-L$libdir1 -Bstatic -la1 -Bdynamic],
[0], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m23 m.$OBJEXT \
-L$libdir1 -la1 -Bstatic a2/liba2.la -Bdynamic \
-L$libdir3 -Bstatic -la3 -Bdynamic],
[0], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m123 m.$OBJEXT \
-L$libdir1 -Bstatic -la1 a2/liba2.la -L$libdir3 -la3 -Bdynamic],
[0], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m123a m.$OBJEXT \
-L$libdir1 -Bstatic -la1 -Bdynamic -Bstatic a2/liba2.la -Bdynamic \
-Bstatic -L$libdir3 -la3 -Bdynamic],
[0], [ignore], [ignore])
dnl # This usually fails. So don't do it.
dnl AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m123b m.$OBJEXT \
dnl -L$libdir1 -Bstatic -la1 a2/liba2.la -L$libdir3 -la3],
dnl [0], [ignore], [ignore])
fi
### install the programs.
# We can't install any program that links dynamically against liba2.
for st in -static -static-libtool-libs $can_link_all_static `$per_deplib && echo 2 12 23 123 123a`; do
echo "# m$st"
AT_CHECK([$LIBTOOL --mode=install cp m$st $bindir/m$st], [0], [ignore], [stderr])
if $have_static; then
AT_CHECK([$EGREP 'relinking|has not been installed' stderr], [1], [], [])
fi
done
dnl AT_CHECK([$LIBTOOL --mode=install cp m123b $bindir/m123b], [0], [ignore], [ignore])
### Run each program once so that relinking has happened.
func_fix_path $prefix1 $prefix2 $prefix3
func_test_exec -static -static-libtool-libs -all-static `$per_deplib && echo 1 2 3 12 13 23 31 123 123a`
func_restore_path
# For each library:
# - remove the library images to catch failure to link statically/dynamically,
# - add false other deplibs in the paths to catch (some) wrongly added run paths.
# if -all-static does not work, do not exercise it any more.
all_static=-all-static
test -z "$link_static_flag" && all_static=
echo "### test whether installed libtool library liba2 was linked statically"
func_move_libs a2 $prefix2 $prefix3 $prefix1
func_test_exec -static -static-libtool-libs $all_static `$per_deplib && echo 2 12 23 123 123a`
$per_deplib && func_test_exec_fail 1 3 13 31
func_restore_libs a2 $prefix2
echo "### test whether uninstalled libtool library liba1 was linked statically"
func_move_libs a1 $prefix1 $prefix2 $prefix3
func_test_exec -static-libtool-libs $all_static `$per_deplib && echo 1 12 13 31 123 123a`
$per_deplib && func_test_exec_fail -static 2 3 23
func_restore_libs a1 $prefix1
echo "### test whether non-libtool library liba3 was linked statically"
func_move_libs a3 $prefix3 $prefix1 $prefix2
func_test_exec $all_static `$per_deplib && echo 3 13 23 31 123 123a`
func_test_exec_fail -static -static-libtool-libs `$per_deplib && echo 1 2 12`
func_restore_libs a3 $prefix3
cd ..
done
AT_CLEANUP
AT_SETUP([ccache -all-static])
AT_DATA([ccache],
[[#! /bin/sh
# poor man's ccache clone
case $1 in
-*) echo "bogus argument: $1" >&2; exit 1 ;;
esac
exec "$@"
]])
chmod +x ./ccache
AT_DATA([a.c],
[[int main(void) { return 0; }
]])
AT_CHECK([$CC $CPPFLAGS $CFLAGS -c a.c], [], [ignore])
AT_CHECK([$LIBTOOL --mode=link --tag=CC ./ccache $CC $CFLAGS $LDFLAGS -all-static a.$OBJEXT -o a],
[], [ignore], [ignore])
AT_CLEANUP
|