/* * This program checks to see if a Tcl extension shared lib * stub enabled, which means the extension uses functions * from the stub table and does not reference any global * Tcl variables. This is important since we want to * be able to load Tcl and its extensions into another * process space without having to link the extension to * a specific version of Tcl or use RTLD_GLOBAL when * opening the Tcl shared library. Note that this checker * could return a false positive if the extension * is linked to a specific Tcl shared library. * * Example: * % ./tcl_stub_checker /build/tcl/libtcl8.3g.so \ * /build/thread/libthread2.4g.so * /build/thread/libthread2.4g.so: dlopen: * `/build/thread/libthread2.4g.so: undefined symbol: tclEmptyStringRep' * * The above result indicates that the extension is not * fully stub enabled since it makes use of the global * symbol "tclEmptyStringRep" defined in the Tcl shared library. */ #include #include #include #include #include main (int argc, char **argv) { void *handle; char *tcllib, *extlib; int mode = RTLD_NOW; if (argc != 3) { fprintf (stderr, "usage: %s tcllib extlib\n", argv[0]); } tcllib = argv[1]; extlib = argv[2]; handle = dlopen (tcllib, mode); if (handle == NULL) { fprintf (stderr, "%s: dlopen: `%s'\n", tcllib, dlerror ()); exit (1); } handle = dlopen (extlib, mode); if (handle == NULL) { fprintf (stderr, "%s: dlopen: `%s'\n", extlib, dlerror ()); exit (1); } dlclose (handle); printf("Extension lib %s is ok\n", extlib); return 0; }