Actual source code: pythonsys.c
1: #define PETSC_DLL
3: #include petscsys.h
5: /* ---------------------------------------------------------------- */
7: #if !defined(PETSC_PYTHON_EXE)
8: #define PETSC_PYTHON_EXE "python"
9: #endif
13: static PetscErrorCode PetscPythonFindExecutable(char pythonexe[PETSC_MAX_PATH_LEN])
14: {
15: PetscTruth flag;
18: /* get the path for the Python interpreter executable */
19: PetscStrncpy(pythonexe,PETSC_PYTHON_EXE,PETSC_MAX_PATH_LEN);
20: PetscOptionsGetString(PETSC_NULL,"-python",pythonexe,PETSC_MAX_PATH_LEN,&flag);
21: if (!flag || pythonexe[0]==0) {
22: PetscStrncpy(pythonexe,PETSC_PYTHON_EXE,PETSC_MAX_PATH_LEN);
23: }
24: return(0);
25: }
29: static PetscErrorCode PetscPythonFindLibrary(char pythonexe[PETSC_MAX_PATH_LEN],
30: char pythonlib[PETSC_MAX_PATH_LEN])
31: {
32: const char cmdline[] = "-c 'import sys; print(sys.exec_prefix); print(sys.version[:3])'";
33: char command[PETSC_MAX_PATH_LEN+1+sizeof(cmdline)+1];
34: char prefix[PETSC_MAX_PATH_LEN],version[8],sep[2]={PETSC_DIR_SEPARATOR, 0},*eol;
35: FILE* fp = NULL;
36: char path[PETSC_MAX_PATH_LEN+1];
37: PetscTruth found = PETSC_FALSE;
41: #if defined(PETSC_PYTHON_LIB)
42: PetscStrcpy(pythonlib,PETSC_PYTHON_LIB);
43: return(0);
44: #endif
45:
46: /* call Python to find out the name of the Python dynamic library */
47: PetscStrncpy(command,pythonexe,PETSC_MAX_PATH_LEN);
48: PetscStrcat(command," ");
49: PetscStrcat(command,cmdline);
50: #if defined(PETSC_HAVE_POPEN)
51: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,command,"r",&fp);
52: if (!fgets(prefix,sizeof(prefix),fp))
53: { SETERRQ1(PETSC_ERR_PLIB,"Python: bad output from executable: %s",pythonexe); }
54: if (!fgets(version,sizeof(version),fp))
55: { SETERRQ1(PETSC_ERR_PLIB,"Python: bad output from executable: %s",pythonexe); }
56: PetscPClose(PETSC_COMM_SELF,fp);
57: #else
58: SETERRQ(1,"Python: Aborted due to missing popen()");
59: #endif
60: /* remove newlines */
61: PetscStrchr(prefix,'\n',&eol);
62: if (eol) eol[0] = 0;
63: PetscStrchr(version,'\n',&eol);
64: if (eol) eol[0] = 0;
66: /* test for $prefix/lib64/libpythonX.X[.so]*/
67: PetscStrcpy(pythonlib,prefix);
68: PetscStrcat(pythonlib,sep);
69: PetscStrcat(pythonlib,"lib64");
70: PetscTestDirectory(pythonlib,'r',&found);
71: if (found) {
72: PetscStrcat(pythonlib,sep);
73: PetscStrcat(pythonlib,"libpython");
74: PetscStrcat(pythonlib,version);
75: PetscDLLibraryRetrieve(PETSC_COMM_SELF,pythonlib,path,PETSC_MAX_PATH_LEN,&found);
76: if (found) return(0);
77: }
79: /* test for $prefix/lib/libpythonX.X[.so]*/
80: PetscStrcpy(pythonlib,prefix);
81: PetscStrcat(pythonlib,sep);
82: PetscStrcat(pythonlib,"lib");
83: PetscTestDirectory(pythonlib,'r',&found);
84: if (found) {
85: PetscStrcat(pythonlib,sep);
86: PetscStrcat(pythonlib,"libpython");
87: PetscStrcat(pythonlib,version);
88: PetscDLLibraryRetrieve(PETSC_COMM_SELF,pythonlib,path,PETSC_MAX_PATH_LEN,&found);
89: if (found) return(0);
90: }
92: /* nothing good found */
93: PetscMemzero(pythonlib,PETSC_MAX_PATH_LEN);
94: PetscInfo(0,"Python dynamic library not found\n");
96: return(0);
97: }
99: /* ---------------------------------------------------------------- */
101: typedef struct _Py_object_t PyObject; /* fake definition */
103: static int (*Py_IsInitialized)(void);
104: static void (*Py_InitializeEx)(int);
105: static void (*Py_Finalize)(void);
107: static void (*PySys_SetArgv)(int, char **);
108: static PyObject* (*PyImport_ImportModule)(const char *);
110: static void (*Py_IncRef)(PyObject *);
111: static void (*Py_DecRef)(PyObject *);
113: static void (*PyErr_Clear)(void);
114: static PyObject* (*PyErr_Occurred)(void);
117: #define PetscDLPyLibOpen(libname) \
118: PetscDLLibraryAppend(PETSC_COMM_SELF,&DLLibrariesLoaded,libname)
119: #define PetscDLPyLibSym(symbol, value) \
120: PetscDLLibrarySym(PETSC_COMM_SELF,&DLLibrariesLoaded,PETSC_NULL,symbol,(void**)value)
121: #define PetscDLPyLibClose(comm) \
122: do { } while(0)
126: static PetscErrorCode PetscPythonLoadLibrary(const char pythonlib[])
127: {
131: /* open the Python dynamic library */
132: PetscDLPyLibOpen(pythonlib);
133: PetscInfo1(0,"Python: loaded dynamic library %s\n", pythonlib);
134: /* look required symbols from the Python C-API */
135: PetscDLPyLibSym("Py_IsInitialized" , &Py_IsInitialized );
136: PetscDLPyLibSym("Py_InitializeEx" , &Py_InitializeEx );
137: PetscDLPyLibSym("Py_Finalize" , &Py_Finalize );
138: PetscDLPyLibSym("PySys_SetArgv" , &PySys_SetArgv );
139: PetscDLPyLibSym("PyImport_ImportModule" , &PyImport_ImportModule );
140: PetscDLPyLibSym("Py_IncRef" , &Py_IncRef );
141: PetscDLPyLibSym("Py_DecRef" , &Py_DecRef );
142: PetscDLPyLibSym("PyErr_Clear" , &PyErr_Clear );
143: PetscDLPyLibSym("PyErr_Occurred" , &PyErr_Occurred );
144: /* XXX TODO: check that ALL symbols were there !!! */
145: if (!Py_IsInitialized) {SETERRQ(1,"Python: failed to load symbols from dynamic library");}
146: if (!Py_InitializeEx) {SETERRQ(1,"Python: failed to load symbols from dynamic library");}
147: if (!Py_Finalize) {SETERRQ(1,"Python: failed to load symbols from dynamic library");}
148: PetscInfo(0,"Python: all required symbols loaded from Python dynamic library\n");
150: return(0);
151: }
153: /* ---------------------------------------------------------------- */
155: static char PetscPythonExe[PETSC_MAX_PATH_LEN] = { 0 };
156: static char PetscPythonLib[PETSC_MAX_PATH_LEN] = { 0 };
157: static PetscTruth PetscBeganPython = PETSC_FALSE;
161: /*@C
162: PetscPythonFinalize - Finalize Python.
163:
164: Level: intermediate
166: .keywords: Python
167: @*/
168: PetscErrorCode PetscPythonFinalize(void)
169: {
171: if (PetscBeganPython) { if (Py_IsInitialized()) Py_Finalize(); }
172: PetscBeganPython = PETSC_FALSE;
173: return(0);
174: }
178: /*@C
179: PetscPythonInitialize - Initialize Python and import petsc4py.
181: Input Parameter:
182: + pyexe - path to the Python interpreter executable, or PETSC_NULL.
183: - pylib - full path to the Python dynamic library, or PETSC_NULL.
185: Level: intermediate
187: .keywords: Python
188:
189: @*/
190: PetscErrorCode PetscPythonInitialize(const char pyexe[],const char pylib[])
191: {
192: int argc = 0;
193: char **argv = 0;
194: PyObject *module = 0;
195: static PetscTruth registered = PETSC_FALSE;
196: PetscErrorCode ierr;
198: if (PetscBeganPython) return(0);
199: /* Python executable */
200: if (pyexe && pyexe[0] != 0) {
201: PetscStrncpy(PetscPythonExe,pyexe,sizeof(PetscPythonExe));
202: } else {
203: PetscPythonFindExecutable(PetscPythonExe);
204: }
205: /* Python dynamic library */
206: if (pylib && pylib[0] != 0) {
207: PetscStrncpy(PetscPythonLib,pylib,sizeof(PetscPythonLib));
208: } else {
209: PetscPythonFindLibrary(PetscPythonExe,PetscPythonLib);
210: }
211: /* dynamically load Python library */
212: PetscPythonLoadLibrary(PetscPythonLib);
213: /* initialize Python */
214: PetscBeganPython = PETSC_FALSE;
215: if (!Py_IsInitialized()) {
216: /* call below does not install signal handlers */
217: Py_InitializeEx(0);
218: /* call below required to build 'sys.argv' list */
219: PetscGetArgs(&argc,&argv);
220: if (argc && argv && argv[0]) PySys_SetArgv(argc,argv);
221: /* register finalizer */
222: if (!registered) {
223: PetscRegisterFinalize(PetscPythonFinalize);
224: registered = PETSC_TRUE;
225: }
226: PetscBeganPython = PETSC_TRUE;
227: }
228: /* import 'petsc4py.PETSc' module */
229: module = PyImport_ImportModule("petsc4py.PETSc");
230: if (module) {
231: PetscInfo(0,"Python: successfully imported module 'petsc4py.PETSc'\n");
232: Py_DecRef(module); module = 0;
233: } else {
234: SETERRQ(PETSC_ERR_PLIB,"Python: could not import module 'petsc4py.PETSc', perhaps your PYTHONPATH does not contain it\n");
235: }
236: return(0);
237: }
239: /* ---------------------------------------------------------------- */