1e5c89e4eSSatish Balay /* 2e5c89e4eSSatish Balay Routines for opening dynamic link libraries (DLLs), keeping a searchable 3e5c89e4eSSatish Balay path of DLLs, obtaining remote DLLs via a URL and opening them locally. 4e5c89e4eSSatish Balay */ 5e5c89e4eSSatish Balay 6af0996ceSBarry Smith #include <petsc/private/petscimpl.h> 7e5c89e4eSSatish Balay 8e5c89e4eSSatish Balay /* ------------------------------------------------------------------------------*/ 9e5c89e4eSSatish Balay /* 10e5c89e4eSSatish Balay Code to maintain a list of opened dynamic libraries and load symbols 11e5c89e4eSSatish Balay */ 12e5bd5246SBarry Smith struct _n_PetscDLLibrary { 13e5bd5246SBarry Smith PetscDLLibrary next; 14ebd79076SLisandro Dalcin PetscDLHandle handle; 15e5c89e4eSSatish Balay char libname[PETSC_MAX_PATH_LEN]; 16e5c89e4eSSatish Balay }; 17e5c89e4eSSatish Balay 187087cfbeSBarry Smith PetscErrorCode PetscDLLibraryPrintPath(PetscDLLibrary libs) 19e5c89e4eSSatish Balay { 20e5c89e4eSSatish Balay PetscFunctionBegin; 21e5c89e4eSSatish Balay while (libs) { 22e5c89e4eSSatish Balay PetscErrorPrintf(" %s\n",libs->libname); 23e5c89e4eSSatish Balay libs = libs->next; 24e5c89e4eSSatish Balay } 25e5c89e4eSSatish Balay PetscFunctionReturn(0); 26e5c89e4eSSatish Balay } 27e5c89e4eSSatish Balay 28e5c89e4eSSatish Balay /*@C 29e5c89e4eSSatish Balay PetscDLLibraryRetrieve - Copies a PETSc dynamic library from a remote location 30e5c89e4eSSatish Balay (if it is remote), indicates if it exits and its local name. 31e5c89e4eSSatish Balay 32d083f849SBarry Smith Collective 33e5c89e4eSSatish Balay 34e5c89e4eSSatish Balay Input Parameters: 35e5c89e4eSSatish Balay + comm - processors that are opening the library 36e5c89e4eSSatish Balay - libname - name of the library, can be relative or absolute 37e5c89e4eSSatish Balay 38*d8d19677SJose E. Roman Output Parameters: 392d53ad75SBarry Smith + name - actual name of file on local filesystem if found 402d53ad75SBarry Smith . llen - length of the name buffer 412d53ad75SBarry Smith - found - true if the file exists 42e5c89e4eSSatish Balay 43e5c89e4eSSatish Balay Level: developer 44e5c89e4eSSatish Balay 45e5c89e4eSSatish Balay Notes: 46e5c89e4eSSatish Balay [[<http,ftp>://hostname]/directoryname/]filename[.so.1.0] 47e5c89e4eSSatish Balay 48e5c89e4eSSatish Balay ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, or ${any environmental variable} 49a5b23f4aSJose E. Roman occurring in directoryname and filename will be replaced with appropriate values. 50e5c89e4eSSatish Balay @*/ 517087cfbeSBarry Smith PetscErrorCode PetscDLLibraryRetrieve(MPI_Comm comm,const char libname[],char *lname,size_t llen,PetscBool *found) 52e5c89e4eSSatish Balay { 53d46cf212SLisandro Dalcin char *buf,*par2,suffix[16],*gz,*so; 54d46cf212SLisandro Dalcin size_t len; 55e5c89e4eSSatish Balay PetscErrorCode ierr; 56e5c89e4eSSatish Balay 57e5c89e4eSSatish Balay PetscFunctionBegin; 58e5c89e4eSSatish Balay /* 59a523d312SBarry Smith make copy of library name and replace $PETSC_ARCH etc 60e5c89e4eSSatish Balay so we can add to the end of it to look for something like .so.1.0 etc. 61e5c89e4eSSatish Balay */ 62e5c89e4eSSatish Balay ierr = PetscStrlen(libname,&len);CHKERRQ(ierr); 63e5c89e4eSSatish Balay len = PetscMax(4*len,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 64785e854fSJed Brown ierr = PetscMalloc1(len,&buf);CHKERRQ(ierr); 65d46cf212SLisandro Dalcin par2 = buf; 66e5c89e4eSSatish Balay ierr = PetscStrreplace(comm,libname,par2,len);CHKERRQ(ierr); 67e5c89e4eSSatish Balay 68d46cf212SLisandro Dalcin /* temporarily remove .gz if it ends library name */ 69d46cf212SLisandro Dalcin ierr = PetscStrrstr(par2,".gz",&gz);CHKERRQ(ierr); 70e5c89e4eSSatish Balay if (gz) { 71e5c89e4eSSatish Balay ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 7202c9f0b5SLisandro Dalcin if (len != 3) gz = NULL; /* do not end (exactly) with .gz */ 73d46cf212SLisandro Dalcin else *gz = 0; /* ends with .gz, so remove it */ 74e5c89e4eSSatish Balay } 753fa76a5bSLisandro Dalcin /* strip out .a from it if user put it in by mistake */ 763fa76a5bSLisandro Dalcin ierr = PetscStrlen(par2,&len);CHKERRQ(ierr); 773fa76a5bSLisandro Dalcin if (par2[len-1] == 'a' && par2[len-2] == '.') par2[len-2] = 0; 783fa76a5bSLisandro Dalcin 792d53ad75SBarry Smith ierr = PetscFileRetrieve(comm,par2,lname,llen,found);CHKERRQ(ierr); 808ce0dc28SMatthew G Knepley if (!(*found)) { 81e5c89e4eSSatish Balay /* see if library name does already not have suffix attached */ 82a126751eSBarry Smith ierr = PetscStrncpy(suffix,".",sizeof(suffix));CHKERRQ(ierr); 83a126751eSBarry Smith ierr = PetscStrlcat(suffix,PETSC_SLSUFFIX,sizeof(suffix));CHKERRQ(ierr); 84b3bb0f5eSLisandro Dalcin ierr = PetscStrrstr(par2,suffix,&so);CHKERRQ(ierr); 85d46cf212SLisandro Dalcin /* and attach the suffix if it is not there */ 86d46cf212SLisandro Dalcin if (!so) { ierr = PetscStrcat(par2,suffix);CHKERRQ(ierr); } 87e5c89e4eSSatish Balay 88d46cf212SLisandro Dalcin /* restore the .gz suffix if it was there */ 89d46cf212SLisandro Dalcin if (gz) { ierr = PetscStrcat(par2,".gz");CHKERRQ(ierr); } 90d46cf212SLisandro Dalcin 91d46cf212SLisandro Dalcin /* and finally retrieve the file */ 92e5c89e4eSSatish Balay ierr = PetscFileRetrieve(comm,par2,lname,llen,found);CHKERRQ(ierr); 932d53ad75SBarry Smith } 94d46cf212SLisandro Dalcin 95d46cf212SLisandro Dalcin ierr = PetscFree(buf);CHKERRQ(ierr); 96e5c89e4eSSatish Balay PetscFunctionReturn(0); 97e5c89e4eSSatish Balay } 98e5c89e4eSSatish Balay 99e5c89e4eSSatish Balay /*@C 100ebd79076SLisandro Dalcin PetscDLLibraryOpen - Opens a PETSc dynamic link library 101e5c89e4eSSatish Balay 102d083f849SBarry Smith Collective 103e5c89e4eSSatish Balay 104e5c89e4eSSatish Balay Input Parameters: 105e5c89e4eSSatish Balay + comm - processors that are opening the library 1060f31fb7fSLisandro Dalcin - path - name of the library, can be relative or absolute 107e5c89e4eSSatish Balay 108e5c89e4eSSatish Balay Output Parameter: 1090f31fb7fSLisandro Dalcin . entry - a PETSc dynamic link library entry 110e5c89e4eSSatish Balay 111e5c89e4eSSatish Balay Level: developer 112e5c89e4eSSatish Balay 113e5c89e4eSSatish Balay Notes: 114bb84e0fdSBarry Smith [[<http,ftp>://hostname]/directoryname/]libbasename[.so.1.0] 115bb84e0fdSBarry Smith 116bb84e0fdSBarry Smith If the library has the symbol PetscDLLibraryRegister_basename() in it then that function is automatically run 117bb84e0fdSBarry Smith when the library is opened. 118e5c89e4eSSatish Balay 119a5b23f4aSJose E. Roman ${PETSC_ARCH} occurring in directoryname and filename 120e5c89e4eSSatish Balay will be replaced with the appropriate value. 121bb84e0fdSBarry Smith 122bb84e0fdSBarry Smith .seealso: PetscLoadDynamicLibrary(), PetscDLLibraryAppend() 123e5c89e4eSSatish Balay @*/ 1247087cfbeSBarry Smith PetscErrorCode PetscDLLibraryOpen(MPI_Comm comm,const char path[],PetscDLLibrary *entry) 125e5c89e4eSSatish Balay { 126e5c89e4eSSatish Balay PetscErrorCode ierr; 127ace3abfcSBarry Smith PetscBool foundlibrary,match; 128b3bb0f5eSLisandro Dalcin char libname[PETSC_MAX_PATH_LEN],par2[PETSC_MAX_PATH_LEN],suffix[16],*s; 129b3bb0f5eSLisandro Dalcin char *basename,registername[128]; 1305673baf8SLisandro Dalcin PetscDLHandle handle; 131607a6623SBarry Smith PetscErrorCode (*func)(void) = NULL; 132e5c89e4eSSatish Balay 133e5c89e4eSSatish Balay PetscFunctionBegin; 13482a51d08SSatish Balay PetscValidCharPointer(path,2); 1355673baf8SLisandro Dalcin PetscValidPointer(entry,3); 136ebd79076SLisandro Dalcin 1370298fd71SBarry Smith *entry = NULL; 138e5c89e4eSSatish Balay 139b3bb0f5eSLisandro Dalcin /* retrieve the library */ 14002c9f0b5SLisandro Dalcin ierr = PetscInfo1(NULL,"Retrieving %s\n",path);CHKERRQ(ierr); 141b3bb0f5eSLisandro Dalcin ierr = PetscDLLibraryRetrieve(comm,path,par2,PETSC_MAX_PATH_LEN,&foundlibrary);CHKERRQ(ierr); 142e32f2f54SBarry Smith if (!foundlibrary) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate dynamic library:\n %s\n",path); 143e2e64c6bSBarry Smith /* Eventually ./configure should determine if the system needs an executable dynamic library */ 144e5c89e4eSSatish Balay #define PETSC_USE_NONEXECUTABLE_SO 145e5c89e4eSSatish Balay #if !defined(PETSC_USE_NONEXECUTABLE_SO) 146e5c89e4eSSatish Balay ierr = PetscTestFile(par2,'x',&foundlibrary);CHKERRQ(ierr); 147e32f2f54SBarry Smith if (!foundlibrary) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Dynamic library is not executable:\n %s\n %s\n",path,par2); 148e5c89e4eSSatish Balay #endif 149e5c89e4eSSatish Balay 1503fa76a5bSLisandro Dalcin /* copy path and setup shared library suffix */ 151b3bb0f5eSLisandro Dalcin ierr = PetscStrncpy(libname,path,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 152a126751eSBarry Smith ierr = PetscStrncpy(suffix,".",sizeof(suffix));CHKERRQ(ierr); 153a126751eSBarry Smith ierr = PetscStrlcat(suffix,PETSC_SLSUFFIX,sizeof(suffix));CHKERRQ(ierr); 1543fa76a5bSLisandro Dalcin /* remove wrong suffixes from libname */ 1553fa76a5bSLisandro Dalcin ierr = PetscStrrstr(libname,".gz",&s);CHKERRQ(ierr); 1563fa76a5bSLisandro Dalcin if (s && s[3] == 0) s[0] = 0; 1573fa76a5bSLisandro Dalcin ierr = PetscStrrstr(libname,".a",&s);CHKERRQ(ierr); 1583fa76a5bSLisandro Dalcin if (s && s[2] == 0) s[0] = 0; 1593fa76a5bSLisandro Dalcin /* remove shared suffix from libname */ 160b3bb0f5eSLisandro Dalcin ierr = PetscStrrstr(libname,suffix,&s);CHKERRQ(ierr); 161b3bb0f5eSLisandro Dalcin if (s) s[0] = 0; 162b3bb0f5eSLisandro Dalcin 1635673baf8SLisandro Dalcin /* open the dynamic library */ 16402c9f0b5SLisandro Dalcin ierr = PetscInfo1(NULL,"Opening dynamic library %s\n",libname);CHKERRQ(ierr); 165b3bb0f5eSLisandro Dalcin ierr = PetscDLOpen(par2,PETSC_DL_DECIDE,&handle);CHKERRQ(ierr); 166b3bb0f5eSLisandro Dalcin 167b3bb0f5eSLisandro Dalcin /* look for [path/]libXXXXX.YYY and extract out the XXXXXX */ 168b3bb0f5eSLisandro Dalcin ierr = PetscStrrchr(libname,'/',&basename);CHKERRQ(ierr); /* XXX Windows ??? */ 169b3bb0f5eSLisandro Dalcin if (!basename) basename = libname; 170b3bb0f5eSLisandro Dalcin ierr = PetscStrncmp(basename,"lib",3,&match);CHKERRQ(ierr); 171a297a907SKarl Rupp if (match) basename = basename + 3; 172a297a907SKarl Rupp else { 17302c9f0b5SLisandro Dalcin ierr = PetscInfo1(NULL,"Dynamic library %s does not have lib prefix\n",libname);CHKERRQ(ierr); 174e5c89e4eSSatish Balay } 175cf4b33a9SJed Brown for (s=basename; *s; s++) if (*s == '-') *s = '_'; 176153a8027SBarry Smith ierr = PetscStrncpy(registername,"PetscDLLibraryRegister_",sizeof(registername));CHKERRQ(ierr); 177a126751eSBarry Smith ierr = PetscStrlcat(registername,basename,sizeof(registername));CHKERRQ(ierr); 178b3bb0f5eSLisandro Dalcin ierr = PetscDLSym(handle,registername,(void**)&func);CHKERRQ(ierr); 179b3bb0f5eSLisandro Dalcin if (func) { 18002c9f0b5SLisandro Dalcin ierr = PetscInfo1(NULL,"Loading registered routines from %s\n",libname);CHKERRQ(ierr); 181607a6623SBarry Smith ierr = (*func)();CHKERRQ(ierr); 182b3bb0f5eSLisandro Dalcin } else { 18302c9f0b5SLisandro Dalcin ierr = PetscInfo2(NULL,"Dynamic library %s does not have symbol %s\n",libname,registername);CHKERRQ(ierr); 184b3bb0f5eSLisandro Dalcin } 1855673baf8SLisandro Dalcin 186b00a9115SJed Brown ierr = PetscNew(entry);CHKERRQ(ierr); 18702c9f0b5SLisandro Dalcin (*entry)->next = NULL; 188b3bb0f5eSLisandro Dalcin (*entry)->handle = handle; 189b3bb0f5eSLisandro Dalcin ierr = PetscStrcpy((*entry)->libname,libname);CHKERRQ(ierr); 190e5c89e4eSSatish Balay PetscFunctionReturn(0); 191e5c89e4eSSatish Balay } 192e5c89e4eSSatish Balay 193e5c89e4eSSatish Balay /*@C 194e5c89e4eSSatish Balay PetscDLLibrarySym - Load a symbol from the dynamic link libraries. 195e5c89e4eSSatish Balay 196d083f849SBarry Smith Collective 197e5c89e4eSSatish Balay 198*d8d19677SJose E. Roman Input Parameters: 199e5bd5246SBarry Smith + comm - communicator that will open the library 2000298fd71SBarry Smith . outlist - list of already open libraries that may contain symbol (can be NULL and only the executable is searched for the function) 20130a1dd1fSBarry Smith . path - optional complete library name (if provided checks here before checking outlist) 202e5c89e4eSSatish Balay - insymbol - name of symbol 203e5c89e4eSSatish Balay 204e5c89e4eSSatish Balay Output Parameter: 2050298fd71SBarry Smith . value - if symbol not found then this value is set to NULL 206e5c89e4eSSatish Balay 207e5c89e4eSSatish Balay Level: developer 208e5c89e4eSSatish Balay 20995452b02SPatrick Sanan Notes: 21095452b02SPatrick Sanan Symbol can be of the form 211e5c89e4eSSatish Balay [/path/libname[.so.1.0]:]functionname[()] where items in [] denote optional 212e5c89e4eSSatish Balay 213e5c89e4eSSatish Balay Will attempt to (retrieve and) open the library if it is not yet been opened. 214e5c89e4eSSatish Balay 215e5c89e4eSSatish Balay @*/ 2167087cfbeSBarry Smith PetscErrorCode PetscDLLibrarySym(MPI_Comm comm,PetscDLLibrary *outlist,const char path[],const char insymbol[],void **value) 217e5c89e4eSSatish Balay { 218b3bb0f5eSLisandro Dalcin char libname[PETSC_MAX_PATH_LEN],suffix[16],*symbol,*s; 2190298fd71SBarry Smith PetscDLLibrary nlist,prev,list = NULL; 220b3bb0f5eSLisandro Dalcin PetscErrorCode ierr; 221e5c89e4eSSatish Balay 222e5c89e4eSSatish Balay PetscFunctionBegin; 223340b11eeSBarry Smith if (outlist) PetscValidPointer(outlist,2); 2245673baf8SLisandro Dalcin if (path) PetscValidCharPointer(path,3); 2255673baf8SLisandro Dalcin PetscValidCharPointer(insymbol,4); 2265673baf8SLisandro Dalcin PetscValidPointer(value,5); 2275673baf8SLisandro Dalcin 228340b11eeSBarry Smith if (outlist) list = *outlist; 22902c9f0b5SLisandro Dalcin *value = NULL; 230e5c89e4eSSatish Balay 2312d53ad75SBarry Smith ierr = PetscStrchr(insymbol,'(',&s);CHKERRQ(ierr); 2322d53ad75SBarry Smith if (s) { 233e5c89e4eSSatish Balay /* make copy of symbol so we can edit it in place */ 2342d53ad75SBarry Smith ierr = PetscStrallocpy(insymbol,&symbol);CHKERRQ(ierr); 235b3bb0f5eSLisandro Dalcin /* If symbol contains () then replace with a NULL, to support functionname() */ 236b3bb0f5eSLisandro Dalcin ierr = PetscStrchr(symbol,'(',&s);CHKERRQ(ierr); 2372d53ad75SBarry Smith s[0] = 0; 238a297a907SKarl Rupp } else symbol = (char*)insymbol; 239e5c89e4eSSatish Balay 240e5c89e4eSSatish Balay /* 241e5c89e4eSSatish Balay Function name does include library 242e5c89e4eSSatish Balay ------------------------------------- 243e5c89e4eSSatish Balay */ 244e5c89e4eSSatish Balay if (path && path[0] != '\0') { 245b3bb0f5eSLisandro Dalcin /* copy path and remove suffix from libname */ 246b3bb0f5eSLisandro Dalcin ierr = PetscStrncpy(libname,path,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 247a126751eSBarry Smith ierr = PetscStrncpy(suffix,".",sizeof(suffix));CHKERRQ(ierr); 248a126751eSBarry Smith ierr = PetscStrlcat(suffix,PETSC_SLSUFFIX,sizeof(suffix));CHKERRQ(ierr); 249b3bb0f5eSLisandro Dalcin ierr = PetscStrrstr(libname,suffix,&s);CHKERRQ(ierr); 250b3bb0f5eSLisandro Dalcin if (s) s[0] = 0; 2515673baf8SLisandro Dalcin /* Look if library is already opened and in path */ 25202c9f0b5SLisandro Dalcin prev = NULL; 253b3bb0f5eSLisandro Dalcin nlist = list; 254e5c89e4eSSatish Balay while (nlist) { 255ace3abfcSBarry Smith PetscBool match; 256b3bb0f5eSLisandro Dalcin ierr = PetscStrcmp(nlist->libname,libname,&match);CHKERRQ(ierr); 2575673baf8SLisandro Dalcin if (match) goto done; 258e5c89e4eSSatish Balay prev = nlist; 259e5c89e4eSSatish Balay nlist = nlist->next; 260e5c89e4eSSatish Balay } 261b3bb0f5eSLisandro Dalcin /* open the library and append it to path */ 2625673baf8SLisandro Dalcin ierr = PetscDLLibraryOpen(comm,path,&nlist);CHKERRQ(ierr); 26302c9f0b5SLisandro Dalcin ierr = PetscInfo1(NULL,"Appending %s to dynamic library search path\n",path);CHKERRQ(ierr); 264a297a907SKarl Rupp if (prev) prev->next = nlist; 265ca43db0aSBarry Smith else {if (outlist) *outlist = nlist;} 266e5c89e4eSSatish Balay 267e5c89e4eSSatish Balay done:; 2685673baf8SLisandro Dalcin ierr = PetscDLSym(nlist->handle,symbol,value);CHKERRQ(ierr); 26930a1dd1fSBarry Smith if (*value) { 27002c9f0b5SLisandro Dalcin ierr = PetscInfo2(NULL,"Loading function %s from dynamic library %s\n",insymbol,path);CHKERRQ(ierr); 27130a1dd1fSBarry Smith } 272e5c89e4eSSatish Balay 273e5c89e4eSSatish Balay /* 274e5c89e4eSSatish Balay Function name does not include library so search path 275e5c89e4eSSatish Balay ----------------------------------------------------- 276e5c89e4eSSatish Balay */ 277e5c89e4eSSatish Balay } else { 278e5c89e4eSSatish Balay while (list) { 279ebd79076SLisandro Dalcin ierr = PetscDLSym(list->handle,symbol,value);CHKERRQ(ierr); 280e5c89e4eSSatish Balay if (*value) { 28102c9f0b5SLisandro Dalcin ierr = PetscInfo2(NULL,"Loading symbol %s from dynamic library %s\n",symbol,list->libname);CHKERRQ(ierr); 282e5c89e4eSSatish Balay break; 283e5c89e4eSSatish Balay } 284e5c89e4eSSatish Balay list = list->next; 285e5c89e4eSSatish Balay } 286e5c89e4eSSatish Balay if (!*value) { 2870298fd71SBarry Smith ierr = PetscDLSym(NULL,symbol,value);CHKERRQ(ierr); 288e5c89e4eSSatish Balay if (*value) { 28902c9f0b5SLisandro Dalcin ierr = PetscInfo1(NULL,"Loading symbol %s from object code\n",symbol);CHKERRQ(ierr); 290e5c89e4eSSatish Balay } 291e5c89e4eSSatish Balay } 292e5c89e4eSSatish Balay } 293e5c89e4eSSatish Balay 2942d53ad75SBarry Smith if (symbol != insymbol) { 295e5c89e4eSSatish Balay ierr = PetscFree(symbol);CHKERRQ(ierr); 2962d53ad75SBarry Smith } 297e5c89e4eSSatish Balay PetscFunctionReturn(0); 298e5c89e4eSSatish Balay } 299e5c89e4eSSatish Balay 300e5c89e4eSSatish Balay /*@C 301e5c89e4eSSatish Balay PetscDLLibraryAppend - Appends another dynamic link library to the seach list, to the end 302e5c89e4eSSatish Balay of the search path. 303e5c89e4eSSatish Balay 304d083f849SBarry Smith Collective 305e5c89e4eSSatish Balay 306e5c89e4eSSatish Balay Input Parameters: 307e5c89e4eSSatish Balay + comm - MPI communicator 3080f31fb7fSLisandro Dalcin - path - name of the library 309e5c89e4eSSatish Balay 310e5c89e4eSSatish Balay Output Parameter: 311e5c89e4eSSatish Balay . outlist - list of libraries 312e5c89e4eSSatish Balay 313e5c89e4eSSatish Balay Level: developer 314e5c89e4eSSatish Balay 31595452b02SPatrick Sanan Notes: 31695452b02SPatrick Sanan if library is already in path will not add it. 317bb84e0fdSBarry Smith 318bb84e0fdSBarry Smith If the library has the symbol PetscDLLibraryRegister_basename() in it then that function is automatically run 319bb84e0fdSBarry Smith when the library is opened. 320bb84e0fdSBarry Smith 321bb84e0fdSBarry Smith .seealso: PetscDLLibraryOpen() 322e5c89e4eSSatish Balay @*/ 3237087cfbeSBarry Smith PetscErrorCode PetscDLLibraryAppend(MPI_Comm comm,PetscDLLibrary *outlist,const char path[]) 324e5c89e4eSSatish Balay { 325e5bd5246SBarry Smith PetscDLLibrary list,prev; 326e5c89e4eSSatish Balay PetscErrorCode ierr; 327e5c89e4eSSatish Balay size_t len; 328ace3abfcSBarry Smith PetscBool match,dir; 329b3bb0f5eSLisandro Dalcin char program[PETSC_MAX_PATH_LEN],found[8*PETSC_MAX_PATH_LEN]; 330b3bb0f5eSLisandro Dalcin char *libname,suffix[16],*s; 3319c9d3cfdSBarry Smith PetscToken token; 332e5c89e4eSSatish Balay 333e5c89e4eSSatish Balay PetscFunctionBegin; 334b3bb0f5eSLisandro Dalcin PetscValidPointer(outlist,2); 335e5c89e4eSSatish Balay 336b3bb0f5eSLisandro Dalcin /* is path a directory? */ 337b3bb0f5eSLisandro Dalcin ierr = PetscTestDirectory(path,'r',&dir);CHKERRQ(ierr); 338e5c89e4eSSatish Balay if (dir) { 33902c9f0b5SLisandro Dalcin ierr = PetscInfo1(NULL,"Checking directory %s for dynamic libraries\n",path);CHKERRQ(ierr); 340a126751eSBarry Smith ierr = PetscStrncpy(program,path,sizeof(program));CHKERRQ(ierr); 341e5c89e4eSSatish Balay ierr = PetscStrlen(program,&len);CHKERRQ(ierr); 342e5c89e4eSSatish Balay if (program[len-1] == '/') { 343a126751eSBarry Smith ierr = PetscStrlcat(program,"*.",sizeof(program));CHKERRQ(ierr); 344e5c89e4eSSatish Balay } else { 345a126751eSBarry Smith ierr = PetscStrlcat(program,"/*.",sizeof(program));CHKERRQ(ierr); 346e5c89e4eSSatish Balay } 347a126751eSBarry Smith ierr = PetscStrlcat(program,PETSC_SLSUFFIX,sizeof(program));CHKERRQ(ierr); 348e5c89e4eSSatish Balay 349b3bb0f5eSLisandro Dalcin ierr = PetscLs(comm,program,found,8*PETSC_MAX_PATH_LEN,&dir);CHKERRQ(ierr); 350e5c89e4eSSatish Balay if (!dir) PetscFunctionReturn(0); 351e5c89e4eSSatish Balay } else { 352b3bb0f5eSLisandro Dalcin ierr = PetscStrncpy(found,path,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 353e5c89e4eSSatish Balay } 354a126751eSBarry Smith ierr = PetscStrncpy(suffix,".",sizeof(suffix));CHKERRQ(ierr); 355a126751eSBarry Smith ierr = PetscStrlcat(suffix,PETSC_SLSUFFIX,sizeof(suffix));CHKERRQ(ierr); 356e5c89e4eSSatish Balay 357e5c89e4eSSatish Balay ierr = PetscTokenCreate(found,'\n',&token);CHKERRQ(ierr); 358b3bb0f5eSLisandro Dalcin ierr = PetscTokenFind(token,&libname);CHKERRQ(ierr); 359b3bb0f5eSLisandro Dalcin while (libname) { 360b3bb0f5eSLisandro Dalcin /* remove suffix from libname */ 361b3bb0f5eSLisandro Dalcin ierr = PetscStrrstr(libname,suffix,&s);CHKERRQ(ierr); 362e5c89e4eSSatish Balay if (s) s[0] = 0; 363e5c89e4eSSatish Balay /* see if library was already open then we are done */ 364e5c89e4eSSatish Balay list = prev = *outlist; 365e5c89e4eSSatish Balay match = PETSC_FALSE; 366e5c89e4eSSatish Balay while (list) { 367b3bb0f5eSLisandro Dalcin ierr = PetscStrcmp(list->libname,libname,&match);CHKERRQ(ierr); 368e5c89e4eSSatish Balay if (match) break; 369e5c89e4eSSatish Balay prev = list; 370e5c89e4eSSatish Balay list = list->next; 371e5c89e4eSSatish Balay } 372b3bb0f5eSLisandro Dalcin /* restore suffix from libname */ 373b3bb0f5eSLisandro Dalcin if (s) s[0] = '.'; 374e5c89e4eSSatish Balay if (!match) { 3755673baf8SLisandro Dalcin /* open the library and add to end of list */ 376b3bb0f5eSLisandro Dalcin ierr = PetscDLLibraryOpen(comm,libname,&list);CHKERRQ(ierr); 37702c9f0b5SLisandro Dalcin ierr = PetscInfo1(NULL,"Appending %s to dynamic library search path\n",libname);CHKERRQ(ierr); 378a297a907SKarl Rupp if (!*outlist) *outlist = list; 379a297a907SKarl Rupp else prev->next = list; 380e5c89e4eSSatish Balay } 381b3bb0f5eSLisandro Dalcin ierr = PetscTokenFind(token,&libname);CHKERRQ(ierr); 382e5c89e4eSSatish Balay } 3838c74ee41SBarry Smith ierr = PetscTokenDestroy(&token);CHKERRQ(ierr); 384e5c89e4eSSatish Balay PetscFunctionReturn(0); 385e5c89e4eSSatish Balay } 386e5c89e4eSSatish Balay 387e5c89e4eSSatish Balay /*@C 388e5c89e4eSSatish Balay PetscDLLibraryPrepend - Add another dynamic library to search for symbols to the beginning of 389e5c89e4eSSatish Balay the search path. 390e5c89e4eSSatish Balay 391d083f849SBarry Smith Collective 392e5c89e4eSSatish Balay 393e5c89e4eSSatish Balay Input Parameters: 394e5c89e4eSSatish Balay + comm - MPI communicator 3950f31fb7fSLisandro Dalcin - path - name of the library 396e5c89e4eSSatish Balay 397e5c89e4eSSatish Balay Output Parameter: 398e5c89e4eSSatish Balay . outlist - list of libraries 399e5c89e4eSSatish Balay 400e5c89e4eSSatish Balay Level: developer 401e5c89e4eSSatish Balay 40295452b02SPatrick Sanan Notes: 40395452b02SPatrick Sanan If library is already in path will remove old reference. 404e5c89e4eSSatish Balay 405e5c89e4eSSatish Balay @*/ 4067087cfbeSBarry Smith PetscErrorCode PetscDLLibraryPrepend(MPI_Comm comm,PetscDLLibrary *outlist,const char path[]) 407e5c89e4eSSatish Balay { 408e5bd5246SBarry Smith PetscDLLibrary list,prev; 409e5c89e4eSSatish Balay PetscErrorCode ierr; 410e5c89e4eSSatish Balay size_t len; 411ace3abfcSBarry Smith PetscBool match,dir; 412b3bb0f5eSLisandro Dalcin char program[PETSC_MAX_PATH_LEN],found[8*PETSC_MAX_PATH_LEN]; 413b3bb0f5eSLisandro Dalcin char *libname,suffix[16],*s; 4145b096c79SMatthew Knepley PetscToken token; 415e5c89e4eSSatish Balay 416e5c89e4eSSatish Balay PetscFunctionBegin; 417b3bb0f5eSLisandro Dalcin PetscValidPointer(outlist,2); 418e5c89e4eSSatish Balay 419b3bb0f5eSLisandro Dalcin /* is path a directory? */ 420b3bb0f5eSLisandro Dalcin ierr = PetscTestDirectory(path,'r',&dir);CHKERRQ(ierr); 421e5c89e4eSSatish Balay if (dir) { 42202c9f0b5SLisandro Dalcin ierr = PetscInfo1(NULL,"Checking directory %s for dynamic libraries\n",path);CHKERRQ(ierr); 423a126751eSBarry Smith ierr = PetscStrncpy(program,path,sizeof(program));CHKERRQ(ierr); 424e5c89e4eSSatish Balay ierr = PetscStrlen(program,&len);CHKERRQ(ierr); 425e5c89e4eSSatish Balay if (program[len-1] == '/') { 426a126751eSBarry Smith ierr = PetscStrlcat(program,"*.",sizeof(program));CHKERRQ(ierr); 427e5c89e4eSSatish Balay } else { 428a126751eSBarry Smith ierr = PetscStrlcat(program,"/*.",sizeof(program));CHKERRQ(ierr); 429e5c89e4eSSatish Balay } 430a126751eSBarry Smith ierr = PetscStrlcat(program,PETSC_SLSUFFIX,sizeof(program));CHKERRQ(ierr); 431e5c89e4eSSatish Balay 432b3bb0f5eSLisandro Dalcin ierr = PetscLs(comm,program,found,8*PETSC_MAX_PATH_LEN,&dir);CHKERRQ(ierr); 433e5c89e4eSSatish Balay if (!dir) PetscFunctionReturn(0); 434e5c89e4eSSatish Balay } else { 435b3bb0f5eSLisandro Dalcin ierr = PetscStrncpy(found,path,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 436e5c89e4eSSatish Balay } 437e5c89e4eSSatish Balay 438a126751eSBarry Smith ierr = PetscStrncpy(suffix,".",sizeof(suffix));CHKERRQ(ierr); 439a126751eSBarry Smith ierr = PetscStrlcat(suffix,PETSC_SLSUFFIX,sizeof(suffix));CHKERRQ(ierr); 440e5c89e4eSSatish Balay 441e5c89e4eSSatish Balay ierr = PetscTokenCreate(found,'\n',&token);CHKERRQ(ierr); 442b3bb0f5eSLisandro Dalcin ierr = PetscTokenFind(token,&libname);CHKERRQ(ierr); 443b3bb0f5eSLisandro Dalcin while (libname) { 444b3bb0f5eSLisandro Dalcin /* remove suffix from libname */ 445b3bb0f5eSLisandro Dalcin ierr = PetscStrstr(libname,suffix,&s);CHKERRQ(ierr); 446e5c89e4eSSatish Balay if (s) s[0] = 0; 447e5c89e4eSSatish Balay /* see if library was already open and move it to the front */ 44802c9f0b5SLisandro Dalcin prev = NULL; 449b3bb0f5eSLisandro Dalcin list = *outlist; 450e5c89e4eSSatish Balay match = PETSC_FALSE; 451e5c89e4eSSatish Balay while (list) { 452b3bb0f5eSLisandro Dalcin ierr = PetscStrcmp(list->libname,libname,&match);CHKERRQ(ierr); 453e5c89e4eSSatish Balay if (match) { 45402c9f0b5SLisandro Dalcin ierr = PetscInfo1(NULL,"Moving %s to begin of dynamic library search path\n",libname);CHKERRQ(ierr); 455e5c89e4eSSatish Balay if (prev) prev->next = list->next; 456b3bb0f5eSLisandro Dalcin if (prev) list->next = *outlist; 457e5c89e4eSSatish Balay *outlist = list; 458e5c89e4eSSatish Balay break; 459e5c89e4eSSatish Balay } 460e5c89e4eSSatish Balay prev = list; 461e5c89e4eSSatish Balay list = list->next; 462e5c89e4eSSatish Balay } 463b3bb0f5eSLisandro Dalcin /* restore suffix from libname */ 464b3bb0f5eSLisandro Dalcin if (s) s[0] = '.'; 465e5c89e4eSSatish Balay if (!match) { 4665673baf8SLisandro Dalcin /* open the library and add to front of list */ 467b3bb0f5eSLisandro Dalcin ierr = PetscDLLibraryOpen(comm,libname,&list);CHKERRQ(ierr); 46802c9f0b5SLisandro Dalcin ierr = PetscInfo1(NULL,"Prepending %s to dynamic library search path\n",libname);CHKERRQ(ierr); 469ebd79076SLisandro Dalcin list->next = *outlist; 470e5c89e4eSSatish Balay *outlist = list; 471e5c89e4eSSatish Balay } 472b3bb0f5eSLisandro Dalcin ierr = PetscTokenFind(token,&libname);CHKERRQ(ierr); 473e5c89e4eSSatish Balay } 4748c74ee41SBarry Smith ierr = PetscTokenDestroy(&token);CHKERRQ(ierr); 475e5c89e4eSSatish Balay PetscFunctionReturn(0); 476e5c89e4eSSatish Balay } 477e5c89e4eSSatish Balay 478e5c89e4eSSatish Balay /*@C 479e5c89e4eSSatish Balay PetscDLLibraryClose - Destroys the search path of dynamic libraries and closes the libraries. 480e5c89e4eSSatish Balay 481e5c89e4eSSatish Balay Collective on PetscDLLibrary 482e5c89e4eSSatish Balay 483e5c89e4eSSatish Balay Input Parameter: 4843fa76a5bSLisandro Dalcin . head - library list 485e5c89e4eSSatish Balay 486e5c89e4eSSatish Balay Level: developer 487e5c89e4eSSatish Balay 488e5c89e4eSSatish Balay @*/ 4897087cfbeSBarry Smith PetscErrorCode PetscDLLibraryClose(PetscDLLibrary list) 490e5c89e4eSSatish Balay { 491ace3abfcSBarry Smith PetscBool done = PETSC_FALSE; 4920f31fb7fSLisandro Dalcin PetscDLLibrary prev,tail; 493e5c89e4eSSatish Balay PetscErrorCode ierr; 494e5c89e4eSSatish Balay 495e5c89e4eSSatish Balay PetscFunctionBegin; 4960f31fb7fSLisandro Dalcin if (!list) PetscFunctionReturn(0); 4973fa76a5bSLisandro Dalcin /* traverse the list in reverse order */ 4983fa76a5bSLisandro Dalcin while (!done) { 4990f31fb7fSLisandro Dalcin if (!list->next) done = PETSC_TRUE; 5000f31fb7fSLisandro Dalcin prev = tail = list; 5013fa76a5bSLisandro Dalcin while (tail->next) { 5023fa76a5bSLisandro Dalcin prev = tail; 5033fa76a5bSLisandro Dalcin tail = tail->next; 504e5c89e4eSSatish Balay } 50502c9f0b5SLisandro Dalcin prev->next = NULL; 5063fa76a5bSLisandro Dalcin /* close the dynamic library and free the space in entry data-structure*/ 50702c9f0b5SLisandro Dalcin ierr = PetscInfo1(NULL,"Closing dynamic library %s\n",tail->libname);CHKERRQ(ierr); 5083fa76a5bSLisandro Dalcin ierr = PetscDLClose(&tail->handle);CHKERRQ(ierr); 5093fa76a5bSLisandro Dalcin ierr = PetscFree(tail);CHKERRQ(ierr); 510a297a907SKarl Rupp } 511e5c89e4eSSatish Balay PetscFunctionReturn(0); 512e5c89e4eSSatish Balay } 513e5c89e4eSSatish Balay 514