1 # demo.at -- Dynamic ltdl runtime loading -*- Autotest -*-
3 # Copyright (C) 1998, 2002-2004, 2011-2019, 2021-2024 Free Software
5 # Written by Thomas Tanner, 1998
6 # Written by Greg Eisenhauer, 2002
7 # Rewritten by Gary V. Vaughan, 2003
9 # This file is part of GNU Libtool.
11 # GNU Libtool is free software; you can redistribute it and/or
12 # modify it under the terms of the GNU General Public License as
13 # published by the Free Software Foundation; either version 2 of
14 # the License, or (at your option) any later version.
16 # GNU Libtool is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
21 # You should have received a copy of the GNU General Public License
22 # along with GNU Libtool; see the file COPYING. If not, a copy
23 # can be downloaded from http://www.gnu.org/licenses/gpl.html,
24 # or obtained by writing to the Free Software Foundation, Inc.,
25 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29 AT_BANNER([Dynamic ltdl runtime loading.])
33 m4_define([_LT_SETUP],
34 [dnl We can't use AT_DATA here, because we need an unquoted here-
35 dnl document to splice in the path to the top level libltdl directory,
36 dnl but, we do need to double m4-quote to prevent premature expansion
37 dnl of any active m4 symbols in the here-doc content, and to maintain
38 dnl the square-bracket symbols as is.
39 [cat >configure.ac <<_EOT_
40 AC_INIT([mdemo], ]AT_PACKAGE_VERSION[, ]AT_PACKAGE_BUGREPORT[)
41 AC_CONFIG_AUX_DIR([build-aux])
42 AC_CONFIG_MACRO_DIRS([m4])
43 LT_CONFIG_LTDL_DIR([libltdl])
46 LT_INIT([dlopen win32-dll])
47 LTDL_INIT([nonrecursive convenience])
48 AC_SUBST([LIBTOOL_DEPS])
52 test yes = "$enable_static" && STATIC=-static
55 AC_CONFIG_FILES([Makefile])
56 AC_CONFIG_HEADERS([config.h:config.in.h])
61 [cat >Makefile.am <<_EOT_
62 AUTOMAKE_OPTIONS = no-dependencies subdir-objects foreign
63 ACLOCAL_AMFLAGS = -I m4
64 AM_CPPFLAGS = \$(INCLTDL)
78 lib_LTLIBRARIES = libsub.la foo1.la libfoo2.la libmlib.la
80 foo1_la_SOURCES = foo1.c
81 foo1_la_LIBADD = \$(LIBM) libsub.la
82 foo1_la_LDFLAGS = -no-undefined -module -avoid-version
84 libfoo2_la_SOURCES = foo2.c
85 libfoo2_la_LIBADD = \$(LIBM) libsub.la
86 libfoo2_la_LDFLAGS = -no-undefined -module -export-symbols-regex "libfoo2.*"
88 libsub_la_SOURCES = sub.c
89 libsub_la_LDFLAGS = -no-undefined
91 ## Use -export-symbols-regex here explicitly because libltdl marks
92 ## its exported symbols, and we use libltdl as a convenience archive.
93 ## Thus, on w32, auto-exporting is turned off.
94 libmlib_la_SOURCES = mlib.c
95 libmlib_la_LIBADD = \$(LIBLTDL) "-dlopen" foo1.la "-dlopen" libfoo2.la
96 libmlib_la_LDFLAGS = -no-undefined -export-symbols-regex ".*"
97 libmlib_la_DEPENDENCIES = \$(LIBLTDL) libsub.la foo1.la libfoo2.la
99 noinst_HEADERS = foo.h
101 bin_PROGRAMS = mdemo mdemo_static
103 # Create a version of mdemo that does dlopen.
104 mdemo_SOURCES = main.c
105 mdemo_LDFLAGS = -export-dynamic
106 ## The quotes around -dlopen below fool automake into accepting it
107 mdemo_LDADD = \$(LIBLTDL) libsub.la "-dlopen" self \
108 "-dlopen" foo1.la "-dlopen" libfoo2.la
109 mdemo_DEPENDENCIES = \$(LIBLTDL) libsub.la foo1.la libfoo2.la
111 # Create a statically linked version of mdemo.
112 mdemo_static_SOURCES = \$(mdemo_SOURCES)
113 mdemo_static_LDFLAGS = \$(STATIC) \$(mdemo_LDFLAGS)
114 mdemo_static_LDADD = \$(mdemo_LDADD)
115 mdemo_static_DEPENDENCIES = \$(mdemo_DEPENDENCIES)
117 libtool: \$(LIBTOOL_DEPS)
118 \$(SHELL) ./config.status --recheck
120 include \$(srcdir)/libltdl/ltdl.mk
121 include \$(srcdir)/mdemo.mk
125 [[# Don't abort for lack of mdemo.mk
132 /* Silly constants that the functions return. */
133 #define HELLO_RET 0xe110
134 #define FOO_RET 0xf00
142 [[#include <config.h>
148 #define nothing foo1_LTX_nothing
149 #define foo1 foo1_LTX_foo1
150 #define hello foo1_LTX_hello
152 /* Give a global variable definition. */
153 int nothing = FOO_RET;
155 /* private function */
156 int _foo1_helper (void) {
161 /* export functions */
167 printf ("cos (0.0) = %g\n", (double) cos ((double) 0.0));
168 return _foo1_helper ();
172 printf ("** This is foolib 1 **\n");
182 [[#include <config.h>
188 #define nothing libfoo2_LTX_nothing
189 #define foo2 libfoo2_LTX_foo2
190 #define hello libfoo2_LTX_hello
192 /* Give a global variable definition. */
195 /* private function */
196 int _foo2_helper (void) {
201 /* export functions */
207 printf ("sin (0.0) = %g\n", (double) sin ((double) 0.0));
208 return _foo2_helper ();
212 printf ("** This is foolib 2 **\n");
222 [[#include <config.h>
228 int test_dl (char *filename) {
230 const lt_dlinfo *info;
237 handle = lt_dlopen(filename);
239 fprintf (stderr, "can't open the module %s!\n", filename);
240 fprintf (stderr, "error was: %s\n", lt_dlerror());
244 info = lt_dlgetinfo(handle);
246 fprintf (stderr, "can't get module info: %s\n", lt_dlerror());
250 printf ("module name: %s\n", info->name);
252 printf ("module is not a libtool module\n");
254 printf ("module filename: %s\n", info->filename);
255 printf ("module reference count: %i\n", info->ref_count);
257 phello = (int(*)())lt_dlsym(handle, "hello");
260 int value = (*phello) ();
262 printf ("hello returned: %i\n", value);
263 if (value == HELLO_RET)
264 printf("hello is ok!\n");
268 fprintf (stderr, "did not find the 'hello' function\n");
269 fprintf (stderr, "error was: %s\n", lt_dlerror());
273 pnothing = (int*)lt_dlsym(handle, "nothing");
274 /* Try assigning to the nothing variable. */
279 fprintf (stderr, "did not find the 'nothing' variable\n");
280 fprintf (stderr, "error was: %s\n", lt_dlerror());
284 pfoo1 = (int(*)())lt_dlsym(handle, "foo1");
285 /* Just call the functions and check return values. */
288 if ((*pfoo1) () == FOO_RET)
289 printf("foo1 is ok!\n");
294 pfoo2 = (int(*)())lt_dlsym(handle, "foo2");
297 if ((*pfoo2) () == FOO_RET)
298 printf("foo2 is ok!\n");
303 fprintf (stderr, "did not find any of the 'foo' functions\n");
304 fprintf (stderr, "error was: %s\n", lt_dlerror());
313 mlib_func (int argc, char **argv)
318 * Would be nice if this somehow worked for libraries, not just executables.
319 * LTDL_SET_PRELOADED_SYMBOLS();
321 if (lt_dlinit() != 0) {
322 fprintf (stderr, "error during initialization: %s\n", lt_dlerror());
326 for (i = 1; i < argc; i++)
327 if (test_dl(argv[i]))
336 [[#include <config.h>
338 void sub (void) { printf ("sub() called\n"); }
342 [[#include <config.h>
350 # define EXPORT extern "C"
352 # define EXPORT extern
355 EXPORT int myfunc (void);
358 test_dl (char *filename, int test_ext)
361 const lt_dlinfo *info;
369 handle = lt_dlopenext (filename);
371 handle = lt_dlopen (filename);
374 fprintf (stderr, "can't open the module %s!\n", filename);
375 fprintf (stderr, "error was: %s\n", lt_dlerror());
379 info = lt_dlgetinfo(handle);
381 fprintf (stderr, "can't get module info: %s\n", lt_dlerror());
385 printf ("module name: %s\n", info->name);
387 printf ("module is not a libtool module\n");
389 printf ("module filename: %s\n", info->filename);
390 printf ("module reference count: %i\n", info->ref_count);
392 phello = (int(*)())lt_dlsym(handle, "hello");
395 int value = (*phello) ();
397 printf ("hello returned: %i\n", value);
398 if (value == HELLO_RET)
399 printf("hello is ok!\n");
403 fprintf (stderr, "did not find the 'hello' function\n");
404 fprintf (stderr, "error was: %s\n", lt_dlerror());
408 pnothing = (int*)lt_dlsym(handle, "nothing");
409 /* Try assigning to the nothing variable. */
414 fprintf (stderr, "did not find the 'nothing' variable\n");
415 fprintf (stderr, "error was: %s\n", lt_dlerror());
419 pfoo1 = (int(*)())lt_dlsym(handle, "foo1");
420 /* Just call the functions and check return values. */
423 if ((*pfoo1) () == FOO_RET)
424 printf("foo1 is ok!\n");
429 pfoo2 = (int(*)())lt_dlsym(handle, "foo2");
432 if ((*pfoo2) () == FOO_RET)
433 printf("foo2 is ok!\n");
438 fprintf (stderr, "did not find any of the 'foo' functions\n");
439 fprintf (stderr, "error was: %s\n", lt_dlerror());
459 int (*pmyfunc)() = 0;
463 handle = lt_dlopen(0);
465 fprintf (stderr, "can't dlopen the program!\n");
466 fprintf (stderr, "error was: %s\n", lt_dlerror());
470 pmyfunc = (int(*)())lt_dlsym(handle, "myfunc");
473 int value = (*pmyfunc) ();
475 printf ("myfunc returned: %i\n", value);
476 if (value == HELLO_RET)
477 printf("myfunc is ok!\n");
481 fprintf (stderr, "did not find the 'myfunc' function\n");
482 fprintf (stderr, "error was: %s\n", lt_dlerror());
486 pmyvar = (int*)lt_dlsym(handle, "myvar");
487 /* Try assigning to the variable. */
492 fprintf (stderr, "did not find the 'myvar' variable\n");
493 fprintf (stderr, "error was: %s\n", lt_dlerror());
502 callback (const char *filename, void *data)
504 printf ("%s: %s\n", (char *)data, filename);
509 try_iterate (const char *search_path)
511 char *s = "try_iterate";
512 return lt_dlforeachfile (search_path, callback, s);
515 /* cheap dirname clone. We require a '/' separator, nonempty and large
516 enough input, not ending with '/', and we will overwrite the input. */
518 my_dirname (char *path)
520 char *p = strrchr (path, '/');
532 main (int argc, char **argv)
538 printf ("Welcome to GNU libtool mdemo!\n");
541 fprintf (stderr, "usage: %s module [module...]\n", argv[0]);
544 LTDL_SET_PRELOADED_SYMBOLS();
545 if (lt_dlinit() != 0) {
546 fprintf (stderr, "error during initialization: %s\n", lt_dlerror());
550 for (i = 1; i < argc; i++)
552 if (test_dl(argv[i], 0))
554 p = strrchr(argv[i], '.');
558 if (test_dl(argv[i], 1))
567 for (i = 1; i < argc; i++)
568 if (argv[i][0] != '\0')
570 my_dirname (argv[i]);
571 if (try_iterate (argv[i]))
580 LT_AT_HOST_DATA([expout],
581 [[Welcome to GNU Hell!
583 ** This is not GNU Hello. There is no built-in mail reader. **
592 # Run the listed make rules, and check that the built binaries work.
593 m4_define([_LT_CHECK_EXECUTE],
595 LT_AT_EXEC_CHECK([./mdemo_static], 0, [ignore], [],
596 [./foo1.la ./libfoo2.la | $GREP '^try_iterate: '])
597 LT_AT_EXEC_CHECK([./mdemo], 0, [ignore], [],
598 [./foo1.la ./libfoo2.la | $GREP '^try_iterate: '])
599 LT_AT_EXEC_CHECK([./mdemo_static], 0, [ignore], [],
600 [`pwd`/foo1.la `pwd`/libfoo2.la | $GREP '^try_iterate: '])
601 LT_AT_EXEC_CHECK([./mdemo], 0, [ignore], [],
602 [`pwd`/foo1.la `pwd`/libfoo2.la | $GREP '^try_iterate: '])
607 # Run the make install rule, and check that installed binaries work too.
608 m4_define([_LT_CHECK_INSTALL],
609 [LT_AT_MAKE([install])
611 # Windows hosts search for dlls in the command path.
612 PATH=$prefix/lib:$PATH
614 LT_AT_EXEC_CHECK([$prefix/bin/mdemo_static], 0, [ignore], [],
615 [$prefix/lib/foo1.la $prefix/lib/libfoo2.la | $GREP '^try_iterate: '])
616 LT_AT_EXEC_CHECK([$prefix/bin/mdemo], 0, [ignore], [],
617 [$prefix/lib/foo1.la $prefix/lib/libfoo2.la | $GREP '^try_iterate: '])
625 AT_SETUP([dynamically ltdl preload static modules])
629 LT_AT_CHECK_CONFIG([--with-included-ltdl --disable-shared],
630 [^build_old_libs=yes], [^build_libtool_libs=no])
633 LT_AT_CHECK_UNINSTALL
642 AT_SETUP([dynamically ltdl load a shared module])
646 LT_AT_CHECK_CONFIG([--with-included-ltdl --disable-static],
647 [^build_old_libs=no], [^build_libtool_libs=yes])
650 LT_AT_CHECK_UNINSTALL
659 AT_SETUP([ltdl load shared and static modules])
663 LT_AT_CHECK_CONFIG([--with-included-ltdl],
664 [^build_old_libs=yes], [^build_libtool_libs=yes])
667 LT_AT_CHECK_UNINSTALL
676 AT_SETUP([ltdl dryrun])
680 LT_AT_CHECK_CONFIG([--with-included-ltdl])
681 LT_AT_MAKE([all-local libltdl/libltdlc.la])
683 # create 'before' and 'after' in a directory deep within objdir,
684 # so that their creation and removal does not modify even a timestamp
685 # in the output of 'ls -l . $objdir'
686 $lt_INSTALL -d "$objdir/temp/temp"
687 before=$objdir/temp/temp/before
688 after=$objdir/temp/temp/after
690 # Create a new libtool script that will enter dry run if the environment
691 # variable force_dry_run is set
692 $SED 's|^[[ ]]*opt_dry_run=.*$|opt_dry_run=$force_dry_run|' libtool > ltnew && mv ltnew libtool
695 # main.o is not compiled with libtool, but it depends on it, so make
696 # sure it is up-to-date. libfoo2.la is linked with libsub.la, so make
697 # sure it exists, otherwise libtool will complain.
699 LT_AT_MAKE([main.$objext])
701 # Making object files
702 # ls -l in MSYS sometimes shows year, not time, for really fresh files.
704 ls -l . "$objdir" | $EGREP -v '(^total|testsuite.log$)' > "$before"
706 LT_AT_MAKE([foo1.lo foo2.lo libsub.la])
707 ls -l . "$objdir" | $EGREP -v '(^total|testsuite.log$)' > "$after"
708 AT_CHECK([cmp "$before" "$after"], 0, [ignore])
710 # Now really make them
712 LT_AT_MAKE([foo1.lo foo2.lo libsub.la])
716 ls -l . "$objdir" | $EGREP -v '(^total|testsuite.log$)' > "$before"
718 LT_AT_MAKE([foo1.la libfoo2.la])
719 ls -l . "$objdir" | $EGREP -v '(^total|testsuite.log$)' > "$after"
720 AT_CHECK([cmp "$before" "$after"], 0, [ignore])
722 # Now really make them
724 LT_AT_MAKE([foo1.la libfoo2.la])
728 ls -l . "$objdir" | $EGREP -v '(^total|testsuite.log$)' > "$before"
730 LT_AT_MAKE([mdemo$EXEEXT mdemo_static$EXEEXT])
731 ls -l . "$objdir" | $EGREP -v '(^total|testsuite.log$)' > "$after"
732 AT_CHECK([cmp "$before" "$after"], 0, [ignore])
734 # Running $MAKE install
735 # Libtool does not create these directories
736 $lt_INSTALL -d "$prefix/bin"
737 $lt_INSTALL -d "$prefix/include"
738 $lt_INSTALL -d "$prefix/lib"
741 ls -l . "$objdir" | $EGREP -v '(^total|testsuite.log$)' > "$before"
742 ls -lR "$prefix" | $EGREP -v '(^total|testsuite.log$)' >> "$before"
744 LT_AT_MAKE([install])
746 ls -l . "$objdir" | $EGREP -v '(^total|testsuite.log$)' > "$after"
747 ls -lR "$prefix" | $EGREP -v '(^total|testsuite.log$)' >> "$after"
748 AT_CHECK([cmp "$before" "$after"], 0, [ignore])
752 LT_AT_MAKE([install])
754 # Running $MAKE uninstall
755 # Libtool does not uninstall the programs, remove them first
756 rm -f "$prefix/bin/mdemo$EXEEXT" "$prefix/bin/mdemo_static$EXEEXT"
759 ls -l . "$objdir" | $EGREP -v '(^total|testsuite.log$)' > "$before"
760 ls -lR "$prefix" | $EGREP -v '(^total|testsuite.log$)' >> "$before"
762 LT_AT_MAKE([uninstall])
763 ls -l . "$objdir" | $EGREP -v '(^total|testsuite.log$)' > "$after"
764 ls -lR "$prefix" | $EGREP -v '(^total|testsuite.log$)' >> "$after"
765 AT_CHECK([cmp "$before" "$after"], 0, [ignore])
767 # Now really uninstall
769 LT_AT_CHECK_UNINSTALL
777 AT_SETUP([link with library that loads ltdl modules])
782 [[bin_PROGRAMS += mdemo2 mdemo2_static
784 # Create a version of mdemo2 that links a library that does dlopen.
785 mdemo2_LDFLAGS = -export-dynamic "-dlopen" force
786 mdemo2_LDADD = libmlib.la
788 # Create a statically linked version of mdemo.
789 mdemo2_static_SOURCES = mdemo2.c
790 mdemo2_static_LDFLAGS = $(STATIC) $(mdemo2_LDFLAGS)
791 mdemo2_static_LDADD = $(mdemo2_LDADD)
792 mdemo2_static_DEPENDENCIES = $(mdemo2_DEPENDENCIES)
799 extern int mlib_func (int, char **);
801 int main (int argc, char **argv)
805 printf ("Welcome to GNU libtool mdemo2!\n");
807 fprintf (stderr, "usage: %s module [module...]\n", argv[0]);
810 /* This must be called in the program to get the preloaded symbols */
811 LTDL_SET_PRELOADED_SYMBOLS();
813 ret = mlib_func(argc, argv);
819 # Normalize line endings after $EGREP instead of using LT_AT_HOST_DATA
820 # here, since $EGREP *may* normalize line endings for us.
822 [[Welcome to GNU libtool mdemo2!
824 module reference count: 1
825 ** This is foolib 1 **
826 hello returned: 57616
832 module reference count: 1
833 ** This is foolib 2 **
834 hello returned: 57616
841 LT_AT_CHECK_CONFIG([--with-included-ltdl])
845 LT_AT_EXEC_CHECK([./mdemo2_static], 0, [stdout], [],
846 [./foo1.la ./libfoo2.la | $EGREP -v '^module filename: '])
847 LT_AT_UNIFY_NL([stdout])
848 LT_AT_CHECK([diff expout stdout])
850 LT_AT_EXEC_CHECK([./mdemo2], 0, [stdout], [],
851 [./foo1.la ./libfoo2.la | $EGREP -v '^module filename: '])
852 LT_AT_UNIFY_NL([stdout])
853 LT_AT_CHECK([diff expout stdout])