[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