1 # lt_dladvise.at -- test libltdl functionality -*- Autotest -*-
3 # Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
4 # Written by Gary V. Vaughan, 2007
6 # This file is part of GNU Libtool.
8 # GNU Libtool is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License as
10 # published by the Free Software Foundation; either version 2 of
11 # the License, or (at your option) any later version.
13 # GNU Libtool is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with GNU Libtool; see the file COPYING. If not, a copy
20 # can be downloaded from http://www.gnu.org/licenses/gpl.html,
21 # or obtained by writing to the Free Software Foundation, Inc.,
22 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 # Try to keep the new interfaces of HEAD separate from those of
26 # branch-1-5 to facilitate testing of older releases.
28 AT_SETUP([lt_dlopenadvise library loading])
29 AT_KEYWORDS([libltdl])
35 typedef int funcp (int);
37 static int errors = 0;
40 complain (const char *msg)
42 const char *errmsg = lt_dlerror ();
43 fprintf (stderr, "%s", msg);
45 fprintf (stderr, ": %s\n", errmsg);
47 fprintf (stderr, ".\n");
52 moduleopen (const char *filename, lt_dladvise advise)
56 handle = lt_dlopenadvise (filename, advise);
59 fprintf (stderr, "can't open the module %s!\n", filename);
60 complain ("error was");
67 moduletest (lt_dlhandle handle, const char *fname, const char *vname)
69 funcp *f = (funcp *) lt_dlsym (handle, fname);
70 int *v = (int *) lt_dlsym (handle, vname);
74 fprintf (stderr, "function `%s' not found\n", fname);
80 fprintf (stderr, "variable `%s' not found\n", vname);
93 if (lt_dladvise_init (&advise) || lt_dladvise_ext (&advise))
94 complain ("error setting advise ext");
96 handle = moduleopen ("libdepend", advise);
99 printf ("depend: %d\n", moduletest (handle, "g", "j"));
101 lt_dladvise_destroy (&advise);
107 const lt_dlinfo *info;
111 if (lt_dladvise_init (&advise) || lt_dladvise_resident (&advise))
112 complain ("error setting advise resident");
114 handle = moduleopen ("libresident.la", advise);
118 info = lt_dlgetinfo (handle);
119 if (!info->is_resident)
120 complain ("error taking advise resident");
122 /* cannot close resident modules */
123 if (lt_dlclose (handle) == 0)
124 complain ("successfully unloaded resident module");
126 printf ("resident: %d\n", moduletest (handle, "func", "numb"));
129 lt_dladvise_destroy (&advise);
135 const lt_dlinfo *info;
139 if (lt_dladvise_init (&advise) || lt_dladvise_local (&advise))
140 complain ("error setting advise local");
142 handle = moduleopen ("liblocal.la", advise);
146 info = lt_dlgetinfo (handle);
147 printf ("local: %d\n", moduletest (handle, "f", "i"));
149 /* If the symlocal hint was taken, don't unload this module
150 and test that our local symbolnames won't clash with modglobal. */
151 if (!info->is_symlocal && lt_dlclose (handle))
152 complain ("error unloading modlocal");
155 lt_dladvise_destroy (&advise);
161 const lt_dlinfo *info;
165 if (lt_dladvise_init (&advise) || lt_dladvise_global (&advise))
166 complain ("error setting advise global");
168 handle = moduleopen ("libglobal.la", advise);
172 info = lt_dlgetinfo (handle);
173 printf ("global: %d\n", moduletest (handle, "f", "i"));
175 /* Don't attempt to load moddepend unless modglobal was successfully
176 loaded and the symglobal hint was taken, and the system allows to
177 to have undefined symbols. */
178 if (info && info->is_symglobal && HAVE_UNDEFINED_SYMBOLS)
184 /* Fake the output so the test won't fail when using a dlloader
185 unable to take symglobal hints. */
186 printf ("depend: 5\n");
190 lt_dladvise_destroy (&advise);
199 if (lt_dladvise_init (&advise) || lt_dladvise_preload (&advise))
200 complain ("error setting advise preload");
202 handle = moduleopen ("libpreload.la", advise);
206 printf("preload: %d\n", moduletest (handle, "h", "k"));
209 lt_dladvise_destroy (&advise);
216 LTDL_SET_PRELOADED_SYMBOLS();
218 if (lt_dlinit() != 0)
220 fprintf (stderr, "error during initialization: %s\n", lt_dlerror());
229 /* This ugly hack is because we have symbols with the same name in both the
230 global module and the local one, we can't lt_dlopen the local module
231 locally and then later load the global module globally because of this.
232 Instead of skipping the test entirely, we test what we can and
234 printf ("global: 4\n");
235 printf ("depend: 5\n");
239 if (lt_dlexit () != 0)
240 complain ("error during exit");
242 return (errors != 0);
246 AT_DATA([modresident.c],
250 int func (int x) { return x / 3; }
257 AT_DATA([modlocal.c],
261 int f (int x) { return (x * x) / 10; }
268 AT_DATA([modglobal.c],
272 int f (int x) { return x - 1; }
279 AT_DATA([moddepend.c],
283 extern int f (int), i;
284 int g (int x) { return f (i) + x - 3; }
291 AT_DATA([modpreload.c],
295 int h (int x) { return 2 * x; }
302 LT_AT_HOST_DATA([expout],
310 : ${LTDLINCL="-I$abs_top_srcdir/libltdl"}
311 : ${LIBLTDL="$abs_builddir/../libltdl/libltdlc.la"}
313 # Skip this test when called from:
314 # make distcheck DISTCHECK_CONFIGURE_FLAGS=--disable-ltdl-install
315 AT_CHECK([case $LIBLTDL in #(
316 */_inst/lib/*) test -f $LIBLTDL || (exit 77) ;;
319 CPPFLAGS="$LTDLINCL $CPPFLAGS"
321 dlopenable='resident local global'
322 dlpreloadable='preload'
324 # ------------------------------------------------------------------------- #
325 # The depend test makes no sense unless compiled without -no-undefined. By #
326 # not building the depend module in that case, when this test passes we can #
327 # be sure that hint_global() above, is being correctly informed those hosts #
328 # are reporting not able to accept the global hint to lt_dlopenadvise(). #
329 # ------------------------------------------------------------------------- #
332 $LIBTOOL --features | grep 'enable shared libraries' >/dev/null && have_shared=:
334 case $host_os,$have_shared in
335 cygwin* | mingw* | cegcc* | *,false)
336 # These hosts do not support linking without -no-undefined
337 CPPFLAGS="$CPPFLAGS -DHAVE_UNDEFINED_SYMBOLS=0"
340 CPPFLAGS="$CPPFLAGS -DHAVE_UNDEFINED_SYMBOLS=1"
341 dlopenable="$dlopen depend"
342 $LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c moddepend.c
343 AT_CHECK([$LIBTOOL --mode=link $CC -module $CFLAGS $LDFLAGS -o libdepend.la ]dnl
344 [moddepend.lo -rpath /foo -avoid-version], [], [ignore], [ignore])
348 $have_shared && CPPFLAGS="$CPPFLAGS -DHAVE_SHARED"
350 # ------------------------------------------------------------------------- #
351 # Other modules can be tested correctly even when built with -no-undefined. #
352 # ------------------------------------------------------------------------- #
354 LDFLAGS="$LDFLAGS -no-undefined"
356 $CC $CPPFLAGS $CFLAGS -c main.c
357 for name in resident local global preload; do
358 # FIXME: adding -static to libpreload shouldn't be necessary.
359 # Fix this properly in ltmain, then remove this workaround.
360 if test $name = preload; then
365 $LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c mod$name.c
366 AT_CHECK([$LIBTOOL --mode=link $CC -module $CFLAGS $LDFLAGS -o lib$name.la ]dnl
367 [mod$name.lo $st -rpath /foo -avoid-version], [], [ignore], [ignore])
371 for module in $dlpreloadable; do
372 preloaded="${preloaded+$preloaded }-dlpreopen lib$module.la"
376 for module in $dlopenable; do
377 modules="${modules+$modules }-dlopen lib$module.la"
380 AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o main$EXEEXT main.$OBJEXT $preloaded $modules $LIBLTDL],
381 [], [ignore], [ignore])
383 # Remove loadable libpreload module, so we know it is the preloaded module
384 # that is being executed by a successful test invocation:
385 AT_CHECK([$LIBTOOL --mode=clean rm -f libpreload.la], [], [ignore], [ignore])
387 LT_AT_NOINST_EXEC_CHECK([./main], [$modules], [], [expout], [])