[Bf-committers] 2nd Try OS X Plugins Fix
Ton Roosendaal
bf-committers@blender.org
Tue, 2 Dec 2003 22:09:42 +0100
Hi,
I received a .c file per mail, and at OSX 10.2.6 it compiled & runs
smoothly now with plugins. The binary 2.31a is at
download.blender.org/release/ now, and the c file itself will be
committed tomorrow.
-Ton-
On Tuesday, Dec 2, 2003, at 18:54 Europe/Amsterdam, Douglas Bischoff
wrote:
> Hello all:
>
> Okay, second try at fixing OS X plugins involves rewriting the
> dlopen() series of functions in native OS X operations using the code
> from the dlcompat library as a starting point.
>
> I have contacted the author of dlcompat to ensure that his rights with
> regards to his code are respected.
>
> Here are 2 diff files that enable the revised method to work.
>
> -Bischofftep
>
> Index: bmake
> ===================================================================
> RCS file: /cvsroot/bf-blender/blender/release/plugins/bmake,v
> retrieving revision 1.5
> diff -u -u -r1.5 bmake
> --- bmake 25 Nov 2003 20:10:06 -0000 1.5
> +++ bmake 2 Dec 2003 17:53:05 -0000
> @@ -74,7 +74,7 @@
> CC="cc";
> CFLAGS="-fPIC -funsigned-char -O2 -fno-common";
> LD="cc";
> - LDFLAGS="-flat_namespace -bundle -bundle_loader
> ../../blender.app/Contents/MacOS/blender -ldl -lm";
> + LDFLAGS="-flat_namespace -bundle -bundle_loader
> ../../blender.app/Contents/MacOS/blender -lm";
> EXT="so";
> fi
>
> Index: dynlib.c
> ===================================================================
> RCS file:
> /cvsroot/bf-blender/blender/source/blender/blenlib/intern/dynlib.c,v
> retrieving revision 1.7
> diff -u -u -r1.7 dynlib.c
> --- dynlib.c 25 Nov 2003 20:10:06 -0000 1.7
> +++ dynlib.c 2 Dec 2003 17:49:21 -0000
> @@ -102,7 +102,203 @@
> free(lib);
> }
>
> -#else /* Unix & MacOS X */
> +#else
> +#ifdef __APPLE__ /* MacOS X */
> +
> +#include <mach-o/dyld.h>
> +#include <dlfcn.h>
> +#include <stdarg.h>
> +
> +#define ERR_STR_LEN 256
> +
> +struct PILdynlib {
> + void *handle;
> +};
> +
> +char *osxerror(int setget, const char *str, ...)
> +{
> + static char errstr[ERR_STR_LEN];
> + static int err_filled = 0;
> + char *retval;
> + NSLinkEditErrors ler;
> + int lerno;
> + const char *dylderrstr;
> + const char *file;
> + va_list arg;
> + if (setget <= 0)
> + {
> + va_start(arg, str);
> + strncpy(errstr, "dlsimple: ", ERR_STR_LEN);
> + vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg);
> + va_end(arg);
> + /* We prefer to use the dyld error string if setget is 0 */
> + if (setget == 0) {
> + NSLinkEditError(&ler, &lerno, &file, &dylderrstr);
> + printf("dyld: %s\n",dylderrstr);
> + if (dylderrstr && strlen(dylderrstr))
> + strncpy(errstr,dylderrstr,ERR_STR_LEN);
> + }
> + err_filled = 1;
> + retval = NULL;
> + }
> + else
> + {
> + if (!err_filled)
> + retval = NULL;
> + else
> + retval = errstr;
> + err_filled = 0;
> + }
> + return retval;
> +}
> +
> +void *osxdlopen(const char *path, int mode)
> +{
> + void *module = 0;
> + NSObjectFileImage ofi = 0;
> + NSObjectFileImageReturnCode ofirc;
> + static int (*make_private_module_public) (NSModule module) = 0;
> + unsigned int flags = NSLINKMODULE_OPTION_RETURN_ON_ERROR |
> NSLINKMODULE_OPTION_PRIVATE;
> +
> + /* If we got no path, the app wants the global namespace, use -1 as
> the marker
> + in this case */
> + if (!path)
> + return (void *)-1;
> +
> + /* Create the object file image, works for things linked with the
> -bundle arg to ld */
> + ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
> + switch (ofirc)
> + {
> + case NSObjectFileImageSuccess:
> + /* It was okay, so use NSLinkModule to link in the image */
> + if (!(mode & RTLD_LAZY)) flags += NSLINKMODULE_OPTION_BINDNOW;
> + module = NSLinkModule(ofi, path,flags);
> + /* Don't forget to destroy the object file image, unless you like
> leaks */
> + NSDestroyObjectFileImage(ofi);
> + /* If the mode was global, then change the module, this avoids
> + multiply defined symbol errors to first load private then make
> + global. Silly, isn't it. */
> + if ((mode & RTLD_GLOBAL))
> + {
> + if (!make_private_module_public)
> + {
> + _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",
> + (unsigned long *)&make_private_module_public);
> + }
> + make_private_module_public(module);
> + }
> + break;
> + case NSObjectFileImageInappropriateFile:
> + /* It may have been a dynamic library rather than a bundle, try to
> load it */
> + module = (void *)NSAddImage(path,
> NSADDIMAGE_OPTION_RETURN_ON_ERROR);
> + break;
> + case NSObjectFileImageFailure:
> + osxerror(0,"Object file setup failure : \"%s\"", path);
> + return 0;
> + case NSObjectFileImageArch:
> + osxerror(0,"No object for this architecture : \"%s\"", path);
> + return 0;
> + case NSObjectFileImageFormat:
> + osxerror(0,"Bad object file format : \"%s\"", path);
> + return 0;
> + case NSObjectFileImageAccess:
> + osxerror(0,"Can't read object file : \"%s\"", path);
> + return 0;
> + }
> + if (!module)
> + osxerror(0, "Can not open \"%s\"", path);
> + return module;
> +}
> +
> +PILdynlib *PIL_dynlib_open(char *name) {
> + void *handle= osxdlopen(name, RTLD_LAZY);
> +
> + if (handle) {
> + PILdynlib *lib= malloc(sizeof(*lib));
> + lib->handle= handle;
> +
> + return lib;
> + } else {
> + return NULL;
> + }
> +}
> +
> +void *PIL_dynlib_find_symbol(PILdynlib* lib, char *symname)
> +{
> + int sym_len = strlen(symname);
> + void *value = NULL;
> + char *malloc_sym = NULL;
> + NSSymbol *nssym = 0;
> + malloc_sym = malloc(sym_len + 2);
> + if (malloc_sym)
> + {
> + sprintf(malloc_sym, "_%s", symname);
> + /* If the lib->handle is -1, if is the app global context */
> + if (lib->handle == (void *)-1)
> + {
> + /* Global context, use NSLookupAndBindSymbol */
> + if (NSIsSymbolNameDefined(malloc_sym))
> + {
> + nssym = NSLookupAndBindSymbol(malloc_sym);
> + }
> + }
> + /* Now see if the lib->handle is a struch mach_header* or not, use
> NSLookupSymbol in image
> + for libraries, and NSLookupSymbolInModule for bundles */
> + else
> + {
> + /* Check for both possible magic numbers depending on x86/ppc byte
> order */
> + if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) ||
> + (((struct mach_header *)lib->handle)->magic == MH_CIGAM))
> + {
> + if (NSIsSymbolNameDefinedInImage((struct mach_header
> *)lib->handle, malloc_sym))
> + {
> + nssym = NSLookupSymbolInImage((struct mach_header *)lib->handle,
> + malloc_sym,
> + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
> + | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
> + }
> +
> + }
> + else
> + {
> + nssym = NSLookupSymbolInModule(lib->handle, malloc_sym);
> + }
> + }
> + if (!nssym)
> + {
> + osxerror(0, "symname \"%s\" Not found", symname);
> + }
> + value = NSAddressOfSymbol(nssym);
> + free(malloc_sym);
> + }
> + else
> + {
> + osxerror(-1, "Unable to allocate memory");
> + }
> + return value;
> +}
> +
> +char *PIL_dynlib_get_error_as_string(PILdynlib* lib)
> +{
> + return osxerror(1, (char *)NULL);
> +}
> +
> +void PIL_dynlib_close(PILdynlib *lib)
> +{
> + if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) ||
> + (((struct mach_header *)lib->handle)->magic == MH_CIGAM))
> + {
> + osxerror(-1, "Can't remove dynamic libraries on darwin");
> + }
> + if (!NSUnLinkModule(lib->handle, 0))
> + {
> + osxerror(0, "unable to unlink module %s",
> NSNameOfModule(lib->handle));
> + }
> +
> + free(lib);
> +}
> +
> +#else /* Unix */
>
> #include <dlfcn.h>
>
> @@ -137,4 +333,5 @@
> free(lib);
> }
>
> +#endif
> #endif
>
> _______________________________________________
> Bf-committers mailing list
> Bf-committers@blender.org
> http://www.blender.org/mailman/listinfo/bf-committers
>
>
------------------------------------------------------------------------
--
Ton Roosendaal Blender Foundation ton@blender.org
http://www.blender.org