Python module error in Mac OS X Lion

Post Reply
shhong
Posts: 9
Joined: Wed Jan 07, 2009 6:52 am

Python module error in Mac OS X Lion

Post by shhong » Tue Aug 16, 2011 12:25 am

In Mac OS 10.7 aka Lion, importing the python module causes an exception as follows: (NEURON version: 536:c4eed98bb84b, Python: 2.7.1, compiler: i686-apple-darwin11-llvm-gcc-4.2)

Code: Select all

In [1]: import neuron
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
/Users/shhong/<ipython-input-1-861d48cbe3e0> in <module>()
----> 1 import neuron

/Library/Python/2.7/site-packages/neuron/__init__.py in <module>()
     79 except:
     80   #Python3.1 extending needs to look into the module explicitly

---> 81   import neuron.hoc
     82 
     83 import nrn

ImportError: dlopen(/Library/Python/2.7/site-packages/neuron/hoc.so, 2): Symbol not found: _environ
  Referenced from: /Applications/NEURON/nrn/x86_64/lib/liboc.0.dylib
  Expected in: flat namespace
 in /Applications/NEURON/nrn/x86_64/lib/liboc.0.dylib
This is because Mac OS X handles environ in a non-POSIX-standard way, and the environ pointer cannot be used in dynamic libraries but should be read via _NSGetEnviron(). Here is the patch:

Code: Select all

diff -r c4eed98bb84b src/ivoc/ivocmain.cpp
--- a/src/ivoc/ivocmain.cpp	Mon Aug 15 10:58:56 2011 -0400
+++ b/src/ivoc/ivocmain.cpp	Tue Aug 16 03:09:24 2011 +0900
@@ -12,17 +12,21 @@ extern "C" {
 	void hoc_main1_init(char*, char**);
 }
 #endif
 
 #include <stdio.h>
 #include <stdlib.h>
 #if HAVE_UNISTD_H
 #include <unistd.h>
+#if !defined (__APPLE__)
 extern char** environ;
+#else
+#include <crt_externs.h>
+#endif
 #endif
 
 #if HAVE_IV
 #ifdef WIN32
 #include <IV-Win/MWlib.h>
 void iv_display_scale(float);
 #endif
 
@@ -466,19 +470,22 @@ int ivocmain (int argc, char** argv, cha
 		setenv("NEURONHOME", NEURON_DATA_DIR, 1);
 		neuron_home = NEURON_DATA_DIR;
 #else
 #error "I don't know how to set environment variables."
 // Maybe in this case the user will have to set it by hand.
 #endif
 		// putenv and setenv may invalidate env but we no longer
 		// use it so following should not be needed
-#if HAVE_UNISTD_H
+#if HAVE_UNISTD_H && !defined(__APPLE__)
 		env = environ;
 #endif
+#if defined (__APPLE__)
+    env = (*_NSGetEnviron());
+#endif
 	}
 
 #else // Not unix:
 	neuron_home = getenv("NEURONHOME");
 	if (!neuron_home) {
 		setneuronhome((argc > 0)?argv[0]:0);
 	}
 	if (!neuron_home) {
diff -r c4eed98bb84b src/oc/parallel.c
--- a/src/oc/parallel.c	Mon Aug 15 10:58:56 2011 -0400
+++ b/src/oc/parallel.c	Tue Aug 16 03:09:24 2011 +0900
@@ -5,16 +5,20 @@
 	#define WIN32 1
 #endif
 
 #if !OCSMALL
 #include <stdlib.h>
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#if defined(__APPLE__)
+#include <crt_externs.h>
+#endif
+
 #include "hoc.h"
 #include "parse.h" /* OBJECTVAR */
 
 static int parallel_seen;
 
 static double *pval; /* pointer to loop counter value */
 static double end_val; /* value to assign loop counter upon completion of loop */
 
@@ -240,20 +244,25 @@ save_parallel_argv(argc, argv)
     }
     *pnt = '\0'; /* place extra '\0' at end */
 #endif
 #endif
 }
 
 save_parallel_envp() { 
 #if LINDA
+#if !defined(__APPLE__)
 	extern char** environ;
+	char** envp = environ;
+#endif
+#if defined(__APPLE__)
+  char** envp = (*_NSGetEnviron());
+#endif
 	 char *pnt;
     int j;
-	char** envp = environ;
 
     /* count how long the block of memory should be */
     for (j = 0; envp[j]; j++) {
 	pnt = envp[j];
 	while (*pnt++) { senvp++; }
 	senvp++; /* add room for '\0' */
     }
 
diff -r c4eed98bb84b src/oc/plot.c
--- a/src/oc/plot.c	Mon Aug 15 10:58:56 2011 -0400
+++ b/src/oc/plot.c	Tue Aug 16 03:09:24 2011 +0900
@@ -1,9 +1,10 @@
 #include <../../nrnconf.h>
+  
 /* /local/src/master/nrn/src/oc/plot.c,v 1.7 1999/06/22 12:51:55 hines Exp */
 /*
 plot.c,v
  * Revision 1.7  1999/06/22  12:51:55  hines
  * a work around for LINUX installation problem with old style x graph
  * using plot (just not compile it)
  *
  * Revision 1.6  1999/05/11  13:56:03  hines
@@ -203,18 +204,23 @@ plot.c,v
 #include <stdio.h>
 #include <string.h>
 
 #if defined(__MINGW32__)
 extern char** _environ;
 #else //!defined(__MINGW32__)
 #if HAVE_UNISTD_H
 #include <unistd.h>
+#if !defined(__APPLE__)
 extern char** environ;
 #endif
+#if defined(__APPLE__)
+#include <crt_externs.h>
+#endif
+#endif
 #endif //defined(__MINGW32__)
 
 #if DOS
 #include <graphics.h>
 #include <dos.h>
 #endif
 #if defined(GRX)
 #define DOS 1
@@ -503,16 +509,19 @@ hoc_outtext(s) char* s; {
 #endif
 
 initplot()
 {
 	int i;
 #if defined(__MINGW32__)
 	char** environ=_environ;
 #endif
+#if defined (__APPLE__)
+  char** environ=(*_NSGetEnviron());
+#endif
 #if defined(__TURBOC__)
 	graphdev = 0;
 #else
 #if NeXTstep
 	graphdev = NX;
 #else
 	graphdev = SSUN;
 	for (i = 0; environ[i] != NULL; i++)
diff -r c4eed98bb84b src/oc/system.c
--- a/src/oc/system.c	Mon Aug 15 10:58:56 2011 -0400
+++ b/src/oc/system.c	Tue Aug 16 03:09:24 2011 +0900
@@ -55,16 +55,20 @@ Supporting OS subroutines required: <<_e
 
 #include <errno.h>
 #include <stddef.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <_syslist.h>
 #include <reent.h>
 
+#if defined (__APPLE__)
+#include <crt_externs.h>
+#endif
+
 #if defined (unix) || defined (__CYGWIN__)
 static int do_system ();
 #endif
 
 int
 _system_r (ptr, s)
      struct _reent *ptr;
      _CONST char *s;
@@ -103,24 +107,29 @@ _system_r (ptr, s)
 int
 system (s)
      _CONST char *s;
 {
   return _system_r (_REENT, s);
 }
 
 #endif
-
+
 #if defined (unix) && !defined (__CYGWIN__) && !defined(__rtems__)
+#if !defined(__APPLE__)
 extern char **environ;
 
 /* Only deal with a pointer to environ, to work around subtle bugs with shared
    libraries and/or small data systems where the user declares his own
    'environ'.  */
 static char ***p_environ = &environ;
+#endif
+#if defined(__APPLE__)
+static char ***p_environ = _NSGetEnviron();
+#endif
 
 static int
 do_system (ptr, s)
      struct _reent *ptr;
      _CONST char *s;
 {
   char *argv[4];
   int pid, status;

khosra
Posts: 1
Joined: Wed Oct 05, 2011 5:57 am

Re: Python module error in Mac OS X Lion

Post by khosra » Wed Oct 05, 2011 6:04 am

Thanks for your post. I am having this issue with Lion whereas others seem not to.

How do you apply this patch? I am not sure if it's my unfamiliarity with patch or another issue that is causing the patch not to be applied.

Code: Select all

% cd $HOME/neuron/nrn
% patch --dry-run -p1 < environ_patch

patching file src/ivoc/ivocmain.cpp
patch: **** malformed patch at line 6: }

pbmanis
Posts: 3
Joined: Thu Jun 14, 2007 9:02 pm
Location: UNC Chapel Hill
Contact:

Re: Python module error in Mac OS X Lion

Post by pbmanis » Sat Oct 15, 2011 9:38 am

I received the same error with the patch. However, I was able to manually edit the files (ivocmain.cpp, plot.c, parallel.c ,and system.c) to make the changes indicated in the patch - add the lines with "+" in front of them where indicated, and remove any lines with "-" in front of them. There were only 2 or 3 places to edit in each file, so it wasn't hard.

Everything then compiled perfectly, and is working great with Python 2.7.2.5 from Active State (Community edition).

--Paul

ted
Site Admin
Posts: 5592
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Python module error in Mac OS X Lion

Post by ted » Sat Oct 15, 2011 1:57 pm

Thanks, Paul, that's a useful suggestion.

selfdestructo
Posts: 32
Joined: Wed Oct 14, 2009 11:12 am

Re: Python module error in Mac OS X Lion

Post by selfdestructo » Mon Dec 05, 2011 8:52 am

Hi,
Will sshong's patch make it into the alpha-repository?
I'm experiencing the same problem here and had to roll back to my previous install;
NEURON -- VERSION 7.2 (504:f8e1ebea86e4) f8e1ebea86e4

Then, it loads just fine

Best,
Espen

hines
Site Admin
Posts: 1577
Joined: Wed May 18, 2005 3:32 pm

Re: Python module error in Mac OS X Lion

Post by hines » Mon Dec 05, 2011 9:19 am

I'll be pushing this to the repository sometime this week. Hopefully tonight.

hines
Site Admin
Posts: 1577
Joined: Wed May 18, 2005 3:32 pm

Re: Python module error in Mac OS X Lion

Post by hines » Tue Dec 06, 2011 3:01 pm

I've learned that one cannot easily copy/paste code fragments from the forum
into a file and then use it as a patch. If someone will send me an email with an
attachment with the proper patch contents that would be very helpful.
Otherwise, I'll wait til next week when I get back to my mac so I can do it manually.
(send to michael dot hines at yale dot edu)

selfdestructo
Posts: 32
Joined: Wed Oct 14, 2009 11:12 am

Re: Python module error in Mac OS X Lion

Post by selfdestructo » Mon Dec 12, 2011 5:51 am

I'm not sure if it helps or not, but I was able to use the patch as copied and paste with the --ignore-whitespace flag to rev 536, i.e;

Code: Select all

hg update -r 536:c4eed98bb84b
patch -Np1 --ignore-whitespace < environ_patch
This will build correctly for me using

Code: Select all

sh build.sh
./configure --prefix=/Applications/NEURON-7.2/nrn --with-iv=/Applications/NEURON-7.2/iv \
    --with-x --x-includes=/usr/X11/include/ --x-libraries=/usr/X11/lib/ \
    --with-nrnpython=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python \
    --host=x86_64-apple-darwin10.7.0 --build=x86_64-apple-darwin10.7.0
make
sudo make install
sudo make after_install
cd src/nrnpython
sudo python setup.py install
Updating to the latest revision would fail to build though during make.

hines
Site Admin
Posts: 1577
Joined: Wed May 18, 2005 3:32 pm

Re: Python module error in Mac OS X Lion

Post by hines » Mon Dec 12, 2011 7:18 am

I couldn't get the patch to apply so manually added the changes. Same issues with line 6 as mentioned by others. Anyway, see
http://www.neuron.yale.edu/hg/neuron/nr ... 8a73adcc53
Many thanks to shhong.
Of course, let me know if some typo has crept in.

selfdestructo
Posts: 32
Joined: Wed Oct 14, 2009 11:12 am

Re: Python module error in Mac OS X Lion

Post by selfdestructo » Tue Dec 13, 2011 5:12 am

Works for me!
Espen.

Post Reply