1e5c89e4eSSatish Balay #define PETSC_DLL 2e5c89e4eSSatish Balay /* 3e5c89e4eSSatish Balay Routines for opening dynamic link libraries (DLLs), keeping a searchable 4e5c89e4eSSatish Balay path of DLLs, obtaining remote DLLs via a URL and opening them locally. 5e5c89e4eSSatish Balay */ 6e5c89e4eSSatish Balay 7e5c89e4eSSatish Balay #include "petsc.h" 8e5c89e4eSSatish Balay #include "petscsys.h" 9e5c89e4eSSatish Balay #include "petscfix.h" 10e5c89e4eSSatish Balay 11e5c89e4eSSatish Balay #if defined(PETSC_HAVE_PWD_H) 12e5c89e4eSSatish Balay #include <pwd.h> 13e5c89e4eSSatish Balay #endif 14e5c89e4eSSatish Balay #include <ctype.h> 15e5c89e4eSSatish Balay #include <sys/types.h> 16e5c89e4eSSatish Balay #include <sys/stat.h> 17e5c89e4eSSatish Balay #if defined(PETSC_HAVE_UNISTD_H) 18e5c89e4eSSatish Balay #include <unistd.h> 19e5c89e4eSSatish Balay #endif 20e5c89e4eSSatish Balay #if defined(PETSC_HAVE_STDLIB_H) 21e5c89e4eSSatish Balay #include <stdlib.h> 22e5c89e4eSSatish Balay #endif 23e5c89e4eSSatish Balay #if defined(PETSC_HAVE_SYS_UTSNAME_H) 24e5c89e4eSSatish Balay #include <sys/utsname.h> 25e5c89e4eSSatish Balay #endif 26e5c89e4eSSatish Balay #include <fcntl.h> 27e5c89e4eSSatish Balay #include <time.h> 28e5c89e4eSSatish Balay #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H) 29e5c89e4eSSatish Balay #include <sys/systeminfo.h> 30e5c89e4eSSatish Balay #endif 31e5c89e4eSSatish Balay 32e5c89e4eSSatish Balay 33e5c89e4eSSatish Balay /* 34e5c89e4eSSatish Balay Contains the list of registered CCA components 35e5c89e4eSSatish Balay */ 36e5c89e4eSSatish Balay PetscFList CCAList = 0; 37e5c89e4eSSatish Balay 38e5c89e4eSSatish Balay 39e5c89e4eSSatish Balay /* ------------------------------------------------------------------------------*/ 40e5c89e4eSSatish Balay /* 41e5c89e4eSSatish Balay Code to maintain a list of opened dynamic libraries and load symbols 42e5c89e4eSSatish Balay */ 43e5bd5246SBarry Smith struct _n_PetscDLLibrary { 44e5bd5246SBarry Smith PetscDLLibrary next; 45*ebd79076SLisandro Dalcin PetscDLHandle handle; 46e5c89e4eSSatish Balay char libname[PETSC_MAX_PATH_LEN]; 47e5c89e4eSSatish Balay }; 48e5c89e4eSSatish Balay 49e5c89e4eSSatish Balay EXTERN_C_BEGIN 50e5c89e4eSSatish Balay EXTERN PetscErrorCode Petsc_DelTag(MPI_Comm,int,void*,void*); 51e5c89e4eSSatish Balay EXTERN_C_END 52e5c89e4eSSatish Balay 53e5c89e4eSSatish Balay #undef __FUNCT__ 54e5c89e4eSSatish Balay #define __FUNCT__ "PetscDLLibraryPrintPath" 55e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryPrintPath(void) 56e5c89e4eSSatish Balay { 57e5bd5246SBarry Smith PetscDLLibrary libs; 58e5c89e4eSSatish Balay 59e5c89e4eSSatish Balay PetscFunctionBegin; 60e5c89e4eSSatish Balay libs = DLLibrariesLoaded; 61e5c89e4eSSatish Balay while (libs) { 62e5c89e4eSSatish Balay PetscErrorPrintf(" %s\n",libs->libname); 63e5c89e4eSSatish Balay libs = libs->next; 64e5c89e4eSSatish Balay } 65e5c89e4eSSatish Balay PetscFunctionReturn(0); 66e5c89e4eSSatish Balay } 67e5c89e4eSSatish Balay 68e5c89e4eSSatish Balay #undef __FUNCT__ 69e5c89e4eSSatish Balay #define __FUNCT__ "PetscDLLibraryRetrieve" 70e5c89e4eSSatish Balay /*@C 71e5c89e4eSSatish Balay PetscDLLibraryRetrieve - Copies a PETSc dynamic library from a remote location 72e5c89e4eSSatish Balay (if it is remote), indicates if it exits and its local name. 73e5c89e4eSSatish Balay 74e5c89e4eSSatish Balay Collective on MPI_Comm 75e5c89e4eSSatish Balay 76e5c89e4eSSatish Balay Input Parameters: 77e5c89e4eSSatish Balay + comm - processors that are opening the library 78e5c89e4eSSatish Balay - libname - name of the library, can be relative or absolute 79e5c89e4eSSatish Balay 80e5c89e4eSSatish Balay Output Parameter: 81e5c89e4eSSatish Balay . handle - library handle 82e5c89e4eSSatish Balay 83e5c89e4eSSatish Balay Level: developer 84e5c89e4eSSatish Balay 85e5c89e4eSSatish Balay Notes: 86e5c89e4eSSatish Balay [[<http,ftp>://hostname]/directoryname/]filename[.so.1.0] 87e5c89e4eSSatish Balay 88e5c89e4eSSatish Balay ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, or ${any environmental variable} 89e5c89e4eSSatish Balay occuring in directoryname and filename will be replaced with appropriate values. 90e5c89e4eSSatish Balay @*/ 91300a7f5bSBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryRetrieve(MPI_Comm comm,const char libname[],char *lname,size_t llen,PetscTruth *found) 92e5c89e4eSSatish Balay { 93e5c89e4eSSatish Balay char *par2,buff[10],*en,*gz; 94e5c89e4eSSatish Balay PetscErrorCode ierr; 95e5c89e4eSSatish Balay size_t len1,len2,len; 96e5c89e4eSSatish Balay PetscTruth tflg,flg; 97e5c89e4eSSatish Balay 98e5c89e4eSSatish Balay PetscFunctionBegin; 99e5c89e4eSSatish Balay /* 100a523d312SBarry Smith make copy of library name and replace $PETSC_ARCH etc 101e5c89e4eSSatish Balay so we can add to the end of it to look for something like .so.1.0 etc. 102e5c89e4eSSatish Balay */ 103e5c89e4eSSatish Balay ierr = PetscStrlen(libname,&len);CHKERRQ(ierr); 104e5c89e4eSSatish Balay len = PetscMax(4*len,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 105e5c89e4eSSatish Balay ierr = PetscMalloc(len*sizeof(char),&par2);CHKERRQ(ierr); 106e5c89e4eSSatish Balay ierr = PetscStrreplace(comm,libname,par2,len);CHKERRQ(ierr); 107e5c89e4eSSatish Balay 108e5c89e4eSSatish Balay /* 109e5c89e4eSSatish Balay Remove any file: header 110e5c89e4eSSatish Balay */ 111e5c89e4eSSatish Balay ierr = PetscStrncmp(par2,"file:",5,&tflg);CHKERRQ(ierr); 112e5c89e4eSSatish Balay if (tflg) { 113e5c89e4eSSatish Balay ierr = PetscStrcpy(par2,par2+5);CHKERRQ(ierr); 114e5c89e4eSSatish Balay } 115e5c89e4eSSatish Balay 116e5c89e4eSSatish Balay /* strip out .a from it if user put it in by mistake */ 117e5c89e4eSSatish Balay ierr = PetscStrlen(par2,&len);CHKERRQ(ierr); 118e5c89e4eSSatish Balay if (par2[len-1] == 'a' && par2[len-2] == '.') par2[len-2] = 0; 119e5c89e4eSSatish Balay 120e5c89e4eSSatish Balay /* remove .gz if it ends library name */ 121e5c89e4eSSatish Balay ierr = PetscStrstr(par2,".gz",&gz);CHKERRQ(ierr); 122e5c89e4eSSatish Balay if (gz) { 123e5c89e4eSSatish Balay ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 124e5c89e4eSSatish Balay if (len == 3) { 125e5c89e4eSSatish Balay *gz = 0; 126e5c89e4eSSatish Balay } 127e5c89e4eSSatish Balay } 128e5c89e4eSSatish Balay 129e5c89e4eSSatish Balay /* see if library name does already not have suffix attached */ 130e5c89e4eSSatish Balay ierr = PetscStrcpy(buff,".");CHKERRQ(ierr); 131e5c89e4eSSatish Balay ierr = PetscStrcat(buff,PETSC_SLSUFFIX);CHKERRQ(ierr); 132e5c89e4eSSatish Balay ierr = PetscStrstr(par2,buff,&en);CHKERRQ(ierr); 133e5c89e4eSSatish Balay if (en) { 134e5c89e4eSSatish Balay ierr = PetscStrlen(en,&len1);CHKERRQ(ierr); 135e5c89e4eSSatish Balay ierr = PetscStrlen(PETSC_SLSUFFIX,&len2);CHKERRQ(ierr); 136e5c89e4eSSatish Balay flg = (PetscTruth) (len1 != 1 + len2); 137e5c89e4eSSatish Balay } else { 138e5c89e4eSSatish Balay flg = PETSC_TRUE; 139e5c89e4eSSatish Balay } 140e5c89e4eSSatish Balay if (flg) { 141e5c89e4eSSatish Balay ierr = PetscStrcat(par2,".");CHKERRQ(ierr); 142e5c89e4eSSatish Balay ierr = PetscStrcat(par2,PETSC_SLSUFFIX);CHKERRQ(ierr); 143e5c89e4eSSatish Balay } 144e5c89e4eSSatish Balay 145e5c89e4eSSatish Balay /* put the .gz back on if it was there */ 146e5c89e4eSSatish Balay if (gz) { 147e5c89e4eSSatish Balay ierr = PetscStrcat(par2,".gz");CHKERRQ(ierr); 148e5c89e4eSSatish Balay } 149e5c89e4eSSatish Balay 150e5c89e4eSSatish Balay ierr = PetscFileRetrieve(comm,par2,lname,llen,found);CHKERRQ(ierr); 151e5c89e4eSSatish Balay ierr = PetscFree(par2);CHKERRQ(ierr); 152e5c89e4eSSatish Balay PetscFunctionReturn(0); 153e5c89e4eSSatish Balay } 154e5c89e4eSSatish Balay 155e5c89e4eSSatish Balay 156e5c89e4eSSatish Balay #undef __FUNCT__ 157e5c89e4eSSatish Balay #define __FUNCT__ "PetscDLLibraryOpen" 158e5c89e4eSSatish Balay /*@C 159*ebd79076SLisandro Dalcin PetscDLLibraryOpen - Opens a PETSc dynamic link library 160e5c89e4eSSatish Balay 161e5c89e4eSSatish Balay Collective on MPI_Comm 162e5c89e4eSSatish Balay 163e5c89e4eSSatish Balay Input Parameters: 164e5c89e4eSSatish Balay + comm - processors that are opening the library 165e5c89e4eSSatish Balay - libname - name of the library, can be relative or absolute 166e5c89e4eSSatish Balay 167e5c89e4eSSatish Balay Output Parameter: 168e5c89e4eSSatish Balay . handle - library handle 169e5c89e4eSSatish Balay 170e5c89e4eSSatish Balay Level: developer 171e5c89e4eSSatish Balay 172e5c89e4eSSatish Balay Notes: 173e5c89e4eSSatish Balay [[<http,ftp>://hostname]/directoryname/]filename[.so.1.0] 174e5c89e4eSSatish Balay 175e5c89e4eSSatish Balay ${PETSC_ARCH} occuring in directoryname and filename 176e5c89e4eSSatish Balay will be replaced with the appropriate value. 177e5c89e4eSSatish Balay @*/ 178*ebd79076SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryOpen(MPI_Comm comm,const char libname[],PetscDLHandle *handle) 179e5c89e4eSSatish Balay { 180e5c89e4eSSatish Balay PetscErrorCode ierr; 181e5c89e4eSSatish Balay char *par2,registername[128],*ptr,*ptrp; 182e5c89e4eSSatish Balay PetscTruth foundlibrary; 183e5c89e4eSSatish Balay PetscErrorCode (*func)(const char*) = NULL; 184e5c89e4eSSatish Balay size_t len; 185e5c89e4eSSatish Balay 186e5c89e4eSSatish Balay PetscFunctionBegin; 187*ebd79076SLisandro Dalcin PetscValidPointer(handle, 3); 188*ebd79076SLisandro Dalcin 189*ebd79076SLisandro Dalcin *handle = PETSC_NULL; 190e5c89e4eSSatish Balay ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&par2);CHKERRQ(ierr); 191e5c89e4eSSatish Balay ierr = PetscDLLibraryRetrieve(comm,libname,par2,PETSC_MAX_PATH_LEN,&foundlibrary);CHKERRQ(ierr); 192a523d312SBarry Smith if (!foundlibrary) SETERRQ1(PETSC_ERR_FILE_OPEN,"Unable to locate dynamic library:\n %s\n",libname); 193e5c89e4eSSatish Balay 194e5c89e4eSSatish Balay /* Eventually config/configure.py should determine if the system needs an executable dynamic library */ 195e5c89e4eSSatish Balay #define PETSC_USE_NONEXECUTABLE_SO 196e5c89e4eSSatish Balay #if !defined(PETSC_USE_NONEXECUTABLE_SO) 197e5c89e4eSSatish Balay ierr = PetscTestFile(par2,'x',&foundlibrary);CHKERRQ(ierr); 198a523d312SBarry Smith if (!foundlibrary) SETERRQ2(PETSC_ERR_FILE_OPEN,"Dynamic library is not executable:\n %s\n %s\n",libname,par2); 199e5c89e4eSSatish Balay #endif 200e5c89e4eSSatish Balay 201ae15b995SBarry Smith ierr = PetscInfo1(0,"Opening %s\n",libname);CHKERRQ(ierr); 202*ebd79076SLisandro Dalcin ierr = PetscDLOpen(par2, PETSC_DL_GLOBAL, handle);CHKERRQ(ierr); 203e5c89e4eSSatish Balay /* build name of symbol to look for based on libname */ 204e5c89e4eSSatish Balay ierr = PetscStrcpy(registername,"PetscDLLibraryRegister_");CHKERRQ(ierr); 205e5c89e4eSSatish Balay /* look for libXXXXX.YYY and extract out the XXXXXX */ 206e5c89e4eSSatish Balay ierr = PetscStrrstr(libname,"lib",&ptr);CHKERRQ(ierr); 207e5c89e4eSSatish Balay if (!ptr) SETERRQ1(PETSC_ERR_ARG_WRONG,"Dynamic library name must have lib prefix:%s",libname); 208e5c89e4eSSatish Balay ierr = PetscStrchr(ptr+3,'.',&ptrp);CHKERRQ(ierr); 209e5c89e4eSSatish Balay if (ptrp) { 21019bdad02SBarry Smith len = ptrp - ptr - 3; 211e5c89e4eSSatish Balay } else { 212e5c89e4eSSatish Balay ierr = PetscStrlen(ptr+3,&len);CHKERRQ(ierr); 213e5c89e4eSSatish Balay } 214e5c89e4eSSatish Balay ierr = PetscStrncat(registername,ptr+3,len);CHKERRQ(ierr); 215*ebd79076SLisandro Dalcin ierr = PetscDLSym(*handle,registername, (void**)&func);CHKERRQ(ierr); 216e5c89e4eSSatish Balay if (func) { 217e5c89e4eSSatish Balay ierr = (*func)(libname);CHKERRQ(ierr); 218ae15b995SBarry Smith ierr = PetscInfo1(0,"Loading registered routines from %s\n",libname);CHKERRQ(ierr); 219e5c89e4eSSatish Balay } else { 220e5c89e4eSSatish Balay SETERRQ2(PETSC_ERR_FILE_UNEXPECTED,"Able to locate dynamic library %s, but cannot load symbol %s\n",libname,registername); 221e5c89e4eSSatish Balay } 222e5c89e4eSSatish Balay ierr = PetscFree(par2);CHKERRQ(ierr); 223e5c89e4eSSatish Balay PetscFunctionReturn(0); 224e5c89e4eSSatish Balay } 225e5c89e4eSSatish Balay 226e5c89e4eSSatish Balay #undef __FUNCT__ 227e5c89e4eSSatish Balay #define __FUNCT__ "PetscDLLibrarySym" 228e5c89e4eSSatish Balay /*@C 229e5c89e4eSSatish Balay PetscDLLibrarySym - Load a symbol from the dynamic link libraries. 230e5c89e4eSSatish Balay 231e5c89e4eSSatish Balay Collective on MPI_Comm 232e5c89e4eSSatish Balay 233e5c89e4eSSatish Balay Input Parameter: 234e5bd5246SBarry Smith + comm - communicator that will open the library 235e5bd5246SBarry Smith . inlist - list of already open libraries that may contain symbol (checks here before path) 236e5bd5246SBarry Smith . path - optional complete library name 237e5c89e4eSSatish Balay - insymbol - name of symbol 238e5c89e4eSSatish Balay 239e5c89e4eSSatish Balay Output Parameter: 240e5c89e4eSSatish Balay . value 241e5c89e4eSSatish Balay 242e5c89e4eSSatish Balay Level: developer 243e5c89e4eSSatish Balay 244e5c89e4eSSatish Balay Notes: Symbol can be of the form 245e5c89e4eSSatish Balay [/path/libname[.so.1.0]:]functionname[()] where items in [] denote optional 246e5c89e4eSSatish Balay 247e5c89e4eSSatish Balay Will attempt to (retrieve and) open the library if it is not yet been opened. 248e5c89e4eSSatish Balay 249e5c89e4eSSatish Balay @*/ 250e5bd5246SBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscDLLibrarySym(MPI_Comm comm,PetscDLLibrary *inlist,const char path[],const char insymbol[],void **value) 251e5c89e4eSSatish Balay { 252e5c89e4eSSatish Balay char *par1,*symbol; 253e5c89e4eSSatish Balay PetscErrorCode ierr; 254e5c89e4eSSatish Balay size_t len; 255e5bd5246SBarry Smith PetscDLLibrary nlist,prev,list; 256e5c89e4eSSatish Balay 257e5c89e4eSSatish Balay PetscFunctionBegin; 258e5c89e4eSSatish Balay if (inlist) list = *inlist; else list = PETSC_NULL; 259e5c89e4eSSatish Balay *value = 0; 260e5c89e4eSSatish Balay 261e5c89e4eSSatish Balay /* make copy of symbol so we can edit it in place */ 262e5c89e4eSSatish Balay ierr = PetscStrlen(insymbol,&len);CHKERRQ(ierr); 263e5c89e4eSSatish Balay ierr = PetscMalloc((len+1)*sizeof(char),&symbol);CHKERRQ(ierr); 264e5c89e4eSSatish Balay ierr = PetscStrcpy(symbol,insymbol);CHKERRQ(ierr); 265e5c89e4eSSatish Balay 266e5c89e4eSSatish Balay /* 267e5c89e4eSSatish Balay If symbol contains () then replace with a NULL, to support functionname() 268e5c89e4eSSatish Balay */ 269e5c89e4eSSatish Balay ierr = PetscStrchr(symbol,'(',&par1);CHKERRQ(ierr); 270e5c89e4eSSatish Balay if (par1) *par1 = 0; 271e5c89e4eSSatish Balay 272e5c89e4eSSatish Balay 273e5c89e4eSSatish Balay /* 274e5c89e4eSSatish Balay Function name does include library 275e5c89e4eSSatish Balay ------------------------------------- 276e5c89e4eSSatish Balay */ 277e5c89e4eSSatish Balay if (path && path[0] != '\0') { 278*ebd79076SLisandro Dalcin PetscDLHandle handle; 279e5c89e4eSSatish Balay 280e5c89e4eSSatish Balay /* 281e5c89e4eSSatish Balay Look if library is already opened and in path 282e5c89e4eSSatish Balay */ 283e5c89e4eSSatish Balay nlist = list; 284e5c89e4eSSatish Balay prev = 0; 285e5c89e4eSSatish Balay while (nlist) { 286e5c89e4eSSatish Balay PetscTruth match; 287e5c89e4eSSatish Balay 288e5c89e4eSSatish Balay ierr = PetscStrcmp(nlist->libname,path,&match);CHKERRQ(ierr); 289e5c89e4eSSatish Balay if (match) { 290e5c89e4eSSatish Balay handle = nlist->handle; 291e5c89e4eSSatish Balay goto done; 292e5c89e4eSSatish Balay } 293e5c89e4eSSatish Balay prev = nlist; 294e5c89e4eSSatish Balay nlist = nlist->next; 295e5c89e4eSSatish Balay } 296e5c89e4eSSatish Balay ierr = PetscDLLibraryOpen(comm,path,&handle);CHKERRQ(ierr); 297e5c89e4eSSatish Balay 298e5bd5246SBarry Smith ierr = PetscNew(struct _n_PetscDLLibrary,&nlist);CHKERRQ(ierr); 299e5c89e4eSSatish Balay nlist->next = 0; 300e5c89e4eSSatish Balay nlist->handle = handle; 301e5c89e4eSSatish Balay ierr = PetscStrcpy(nlist->libname,path);CHKERRQ(ierr); 302e5c89e4eSSatish Balay 303e5c89e4eSSatish Balay if (prev) { 304e5c89e4eSSatish Balay prev->next = nlist; 305e5c89e4eSSatish Balay } else { 306e5c89e4eSSatish Balay if (inlist) *inlist = nlist; 307e5c89e4eSSatish Balay else {ierr = PetscDLLibraryClose(nlist);CHKERRQ(ierr);} 308e5c89e4eSSatish Balay } 309ae15b995SBarry Smith ierr = PetscInfo1(0,"Appending %s to dynamic library search path\n",path);CHKERRQ(ierr); 310e5c89e4eSSatish Balay 311e5c89e4eSSatish Balay done:; 312*ebd79076SLisandro Dalcin ierr = PetscDLSym(handle,symbol,value);CHKERRQ(ierr); 313e5c89e4eSSatish Balay if (!*value) { 314e5c89e4eSSatish Balay SETERRQ2(PETSC_ERR_PLIB,"Unable to locate function %s in dynamic library %s",insymbol,path); 315e5c89e4eSSatish Balay } 316ae15b995SBarry Smith ierr = PetscInfo2(0,"Loading function %s from dynamic library %s\n",insymbol,path);CHKERRQ(ierr); 317e5c89e4eSSatish Balay 318e5c89e4eSSatish Balay /* 319e5c89e4eSSatish Balay Function name does not include library so search path 320e5c89e4eSSatish Balay ----------------------------------------------------- 321e5c89e4eSSatish Balay */ 322e5c89e4eSSatish Balay } else { 323e5c89e4eSSatish Balay while (list) { 324*ebd79076SLisandro Dalcin ierr = PetscDLSym(list->handle,symbol,value);CHKERRQ(ierr); 325e5c89e4eSSatish Balay if (*value) { 326ae15b995SBarry Smith ierr = PetscInfo2(0,"Loading function %s from dynamic library %s\n",symbol,list->libname);CHKERRQ(ierr); 327e5c89e4eSSatish Balay break; 328e5c89e4eSSatish Balay } 329e5c89e4eSSatish Balay list = list->next; 330e5c89e4eSSatish Balay } 331e5c89e4eSSatish Balay if (!*value) { 332*ebd79076SLisandro Dalcin ierr = PetscDLSym(PETSC_NULL,symbol,value);CHKERRQ(ierr); 333e5c89e4eSSatish Balay if (*value) { 334ae15b995SBarry Smith ierr = PetscInfo1(0,"Loading function %s from object code\n",symbol);CHKERRQ(ierr); 335e5c89e4eSSatish Balay } 336e5c89e4eSSatish Balay } 337e5c89e4eSSatish Balay } 338e5c89e4eSSatish Balay 339e5c89e4eSSatish Balay ierr = PetscFree(symbol);CHKERRQ(ierr); 340e5c89e4eSSatish Balay PetscFunctionReturn(0); 341e5c89e4eSSatish Balay } 342e5c89e4eSSatish Balay 343e5c89e4eSSatish Balay #undef __FUNCT__ 344e5c89e4eSSatish Balay #define __FUNCT__ "PetscDLLibraryAppend" 345e5c89e4eSSatish Balay /*@C 346e5c89e4eSSatish Balay PetscDLLibraryAppend - Appends another dynamic link library to the seach list, to the end 347e5c89e4eSSatish Balay of the search path. 348e5c89e4eSSatish Balay 349e5c89e4eSSatish Balay Collective on MPI_Comm 350e5c89e4eSSatish Balay 351e5c89e4eSSatish Balay Input Parameters: 352e5c89e4eSSatish Balay + comm - MPI communicator 353e5c89e4eSSatish Balay - libname - name of the library 354e5c89e4eSSatish Balay 355e5c89e4eSSatish Balay Output Parameter: 356e5c89e4eSSatish Balay . outlist - list of libraries 357e5c89e4eSSatish Balay 358e5c89e4eSSatish Balay Level: developer 359e5c89e4eSSatish Balay 360e5c89e4eSSatish Balay Notes: if library is already in path will not add it. 361e5c89e4eSSatish Balay @*/ 362e5bd5246SBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryAppend(MPI_Comm comm,PetscDLLibrary *outlist,const char libname[]) 363e5c89e4eSSatish Balay { 364e5bd5246SBarry Smith PetscDLLibrary list,prev; 365e5c89e4eSSatish Balay void* handle; 366e5c89e4eSSatish Balay PetscErrorCode ierr; 367e5c89e4eSSatish Balay size_t len; 368e5c89e4eSSatish Balay PetscTruth match,dir; 369e5c89e4eSSatish Balay char program[PETSC_MAX_PATH_LEN],buf[8*PETSC_MAX_PATH_LEN],*found,*libname1,suffix[16],*s; 3709c9d3cfdSBarry Smith PetscToken token; 371e5c89e4eSSatish Balay 372e5c89e4eSSatish Balay PetscFunctionBegin; 373e5c89e4eSSatish Balay 374e5c89e4eSSatish Balay /* is libname a directory? */ 375e5c89e4eSSatish Balay ierr = PetscTestDirectory(libname,'r',&dir);CHKERRQ(ierr); 376e5c89e4eSSatish Balay if (dir) { 377ae15b995SBarry Smith ierr = PetscInfo1(0,"Checking directory %s for dynamic libraries\n",libname);CHKERRQ(ierr); 378e5c89e4eSSatish Balay ierr = PetscStrcpy(program,libname);CHKERRQ(ierr); 379e5c89e4eSSatish Balay ierr = PetscStrlen(program,&len);CHKERRQ(ierr); 380e5c89e4eSSatish Balay if (program[len-1] == '/') { 381e5c89e4eSSatish Balay ierr = PetscStrcat(program,"*.");CHKERRQ(ierr); 382e5c89e4eSSatish Balay } else { 383e5c89e4eSSatish Balay ierr = PetscStrcat(program,"/*.");CHKERRQ(ierr); 384e5c89e4eSSatish Balay } 385e5c89e4eSSatish Balay ierr = PetscStrcat(program,PETSC_SLSUFFIX);CHKERRQ(ierr); 386e5c89e4eSSatish Balay 387e5c89e4eSSatish Balay ierr = PetscLs(comm,program,buf,8*PETSC_MAX_PATH_LEN,&dir);CHKERRQ(ierr); 388e5c89e4eSSatish Balay if (!dir) PetscFunctionReturn(0); 389e5c89e4eSSatish Balay found = buf; 390e5c89e4eSSatish Balay } else { 391e5c89e4eSSatish Balay found = (char*)libname; 392e5c89e4eSSatish Balay } 393e5c89e4eSSatish Balay ierr = PetscStrcpy(suffix,".");CHKERRQ(ierr); 394e5c89e4eSSatish Balay ierr = PetscStrcat(suffix,PETSC_SLSUFFIX);CHKERRQ(ierr); 395e5c89e4eSSatish Balay 396e5c89e4eSSatish Balay ierr = PetscTokenCreate(found,'\n',&token);CHKERRQ(ierr); 397e5c89e4eSSatish Balay ierr = PetscTokenFind(token,&libname1);CHKERRQ(ierr); 398e5c89e4eSSatish Balay ierr = PetscStrstr(libname1,suffix,&s);CHKERRQ(ierr); 399e5c89e4eSSatish Balay if (s) s[0] = 0; 400e5c89e4eSSatish Balay while (libname1) { 401e5c89e4eSSatish Balay 402e5c89e4eSSatish Balay /* see if library was already open then we are done */ 403e5c89e4eSSatish Balay list = prev = *outlist; 404e5c89e4eSSatish Balay match = PETSC_FALSE; 405e5c89e4eSSatish Balay while (list) { 406e5c89e4eSSatish Balay 407e5c89e4eSSatish Balay ierr = PetscStrcmp(list->libname,libname1,&match);CHKERRQ(ierr); 408e5c89e4eSSatish Balay if (match) break; 409e5c89e4eSSatish Balay prev = list; 410e5c89e4eSSatish Balay list = list->next; 411e5c89e4eSSatish Balay } 412e5c89e4eSSatish Balay if (!match) { 413e5c89e4eSSatish Balay 414e5c89e4eSSatish Balay ierr = PetscDLLibraryOpen(comm,libname1,&handle);CHKERRQ(ierr); 415e5c89e4eSSatish Balay 416e5bd5246SBarry Smith ierr = PetscNew(struct _n_PetscDLLibrary,&list);CHKERRQ(ierr); 417e5c89e4eSSatish Balay list->next = 0; 418e5c89e4eSSatish Balay list->handle = handle; 419e5c89e4eSSatish Balay ierr = PetscStrcpy(list->libname,libname1);CHKERRQ(ierr); 420e5c89e4eSSatish Balay 421e5c89e4eSSatish Balay if (!*outlist) { 422e5c89e4eSSatish Balay *outlist = list; 423e5c89e4eSSatish Balay } else { 424e5c89e4eSSatish Balay prev->next = list; 425e5c89e4eSSatish Balay } 426ae15b995SBarry Smith ierr = PetscInfo1(0,"Appending %s to dynamic library search path\n",libname1);CHKERRQ(ierr); 427e5c89e4eSSatish Balay } 428e5c89e4eSSatish Balay ierr = PetscTokenFind(token,&libname1);CHKERRQ(ierr); 429e5c89e4eSSatish Balay if (libname1) { 430e5c89e4eSSatish Balay ierr = PetscStrstr(libname1,suffix,&s);CHKERRQ(ierr); 431e5c89e4eSSatish Balay if (s) s[0] = 0; 432e5c89e4eSSatish Balay } 433e5c89e4eSSatish Balay } 434e5c89e4eSSatish Balay ierr = PetscTokenDestroy(token);CHKERRQ(ierr); 435e5c89e4eSSatish Balay PetscFunctionReturn(0); 436e5c89e4eSSatish Balay } 437e5c89e4eSSatish Balay 438e5c89e4eSSatish Balay #undef __FUNCT__ 439e5c89e4eSSatish Balay #define __FUNCT__ "PetscDLLibraryPrepend" 440e5c89e4eSSatish Balay /*@C 441e5c89e4eSSatish Balay PetscDLLibraryPrepend - Add another dynamic library to search for symbols to the beginning of 442e5c89e4eSSatish Balay the search path. 443e5c89e4eSSatish Balay 444e5c89e4eSSatish Balay Collective on MPI_Comm 445e5c89e4eSSatish Balay 446e5c89e4eSSatish Balay Input Parameters: 447e5c89e4eSSatish Balay + comm - MPI communicator 448e5c89e4eSSatish Balay - libname - name of the library 449e5c89e4eSSatish Balay 450e5c89e4eSSatish Balay Output Parameter: 451e5c89e4eSSatish Balay . outlist - list of libraries 452e5c89e4eSSatish Balay 453e5c89e4eSSatish Balay Level: developer 454e5c89e4eSSatish Balay 455e5c89e4eSSatish Balay Notes: If library is already in path will remove old reference. 456e5c89e4eSSatish Balay 457e5c89e4eSSatish Balay @*/ 458e5bd5246SBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryPrepend(MPI_Comm comm,PetscDLLibrary *outlist,const char libname[]) 459e5c89e4eSSatish Balay { 460e5bd5246SBarry Smith PetscDLLibrary list,prev; 461e5c89e4eSSatish Balay void* handle; 462e5c89e4eSSatish Balay PetscErrorCode ierr; 463e5c89e4eSSatish Balay size_t len; 464e5c89e4eSSatish Balay PetscTruth match,dir; 465e5c89e4eSSatish Balay char program[PETSC_MAX_PATH_LEN],buf[8*PETSC_MAX_PATH_LEN],*found,*libname1,suffix[16],*s; 4665b096c79SMatthew Knepley PetscToken token; 467e5c89e4eSSatish Balay 468e5c89e4eSSatish Balay PetscFunctionBegin; 469e5c89e4eSSatish Balay 470e5c89e4eSSatish Balay /* is libname a directory? */ 471e5c89e4eSSatish Balay ierr = PetscTestDirectory(libname,'r',&dir);CHKERRQ(ierr); 472e5c89e4eSSatish Balay if (dir) { 473ae15b995SBarry Smith ierr = PetscInfo1(0,"Checking directory %s for dynamic libraries\n",libname);CHKERRQ(ierr); 474e5c89e4eSSatish Balay ierr = PetscStrcpy(program,libname);CHKERRQ(ierr); 475e5c89e4eSSatish Balay ierr = PetscStrlen(program,&len);CHKERRQ(ierr); 476e5c89e4eSSatish Balay if (program[len-1] == '/') { 477e5c89e4eSSatish Balay ierr = PetscStrcat(program,"*.");CHKERRQ(ierr); 478e5c89e4eSSatish Balay } else { 479e5c89e4eSSatish Balay ierr = PetscStrcat(program,"/*.");CHKERRQ(ierr); 480e5c89e4eSSatish Balay } 481e5c89e4eSSatish Balay ierr = PetscStrcat(program,PETSC_SLSUFFIX);CHKERRQ(ierr); 482e5c89e4eSSatish Balay 483e5c89e4eSSatish Balay ierr = PetscLs(comm,program,buf,8*PETSC_MAX_PATH_LEN,&dir);CHKERRQ(ierr); 484e5c89e4eSSatish Balay if (!dir) PetscFunctionReturn(0); 485e5c89e4eSSatish Balay found = buf; 486e5c89e4eSSatish Balay } else { 487e5c89e4eSSatish Balay found = (char*)libname; 488e5c89e4eSSatish Balay } 489e5c89e4eSSatish Balay 490e5c89e4eSSatish Balay ierr = PetscStrcpy(suffix,".");CHKERRQ(ierr); 491e5c89e4eSSatish Balay ierr = PetscStrcat(suffix,PETSC_SLSUFFIX);CHKERRQ(ierr); 492e5c89e4eSSatish Balay 493e5c89e4eSSatish Balay ierr = PetscTokenCreate(found,'\n',&token);CHKERRQ(ierr); 494e5c89e4eSSatish Balay ierr = PetscTokenFind(token,&libname1);CHKERRQ(ierr); 495e5c89e4eSSatish Balay ierr = PetscStrstr(libname1,suffix,&s);CHKERRQ(ierr); 496e5c89e4eSSatish Balay if (s) s[0] = 0; 497e5c89e4eSSatish Balay while (libname1) { 498e5c89e4eSSatish Balay /* see if library was already open and move it to the front */ 499e5c89e4eSSatish Balay list = *outlist; 500e5c89e4eSSatish Balay prev = 0; 501e5c89e4eSSatish Balay match = PETSC_FALSE; 502e5c89e4eSSatish Balay while (list) { 503e5c89e4eSSatish Balay 504e5c89e4eSSatish Balay ierr = PetscStrcmp(list->libname,libname1,&match);CHKERRQ(ierr); 505e5c89e4eSSatish Balay if (match) { 506e5c89e4eSSatish Balay if (prev) prev->next = list->next; 507e5c89e4eSSatish Balay list->next = *outlist; 508e5c89e4eSSatish Balay *outlist = list; 509e5c89e4eSSatish Balay break; 510e5c89e4eSSatish Balay } 511e5c89e4eSSatish Balay prev = list; 512e5c89e4eSSatish Balay list = list->next; 513e5c89e4eSSatish Balay } 514e5c89e4eSSatish Balay if (!match) { 515e5c89e4eSSatish Balay /* open the library and add to front of list */ 516e5c89e4eSSatish Balay ierr = PetscDLLibraryOpen(comm,libname1,&handle);CHKERRQ(ierr); 517e5c89e4eSSatish Balay 518e5bd5246SBarry Smith ierr = PetscNew(struct _n_PetscDLLibrary,&list);CHKERRQ(ierr); 519*ebd79076SLisandro Dalcin list->next = 0; 520e5c89e4eSSatish Balay list->handle = handle; 521e5c89e4eSSatish Balay ierr = PetscStrcpy(list->libname,libname1);CHKERRQ(ierr); 522*ebd79076SLisandro Dalcin 523*ebd79076SLisandro Dalcin ierr = PetscInfo1(0,"Prepending %s to dynamic library search path\n",libname1);CHKERRQ(ierr); 524*ebd79076SLisandro Dalcin list->next = *outlist; 525e5c89e4eSSatish Balay *outlist = list; 526*ebd79076SLisandro Dalcin 527*ebd79076SLisandro Dalcin 528e5c89e4eSSatish Balay } 529e5c89e4eSSatish Balay ierr = PetscTokenFind(token,&libname1);CHKERRQ(ierr); 530e5c89e4eSSatish Balay if (libname1) { 531e5c89e4eSSatish Balay ierr = PetscStrstr(libname1,suffix,&s);CHKERRQ(ierr); 532e5c89e4eSSatish Balay if (s) s[0] = 0; 533e5c89e4eSSatish Balay } 534e5c89e4eSSatish Balay } 535e5c89e4eSSatish Balay ierr = PetscTokenDestroy(token);CHKERRQ(ierr); 536e5c89e4eSSatish Balay PetscFunctionReturn(0); 537e5c89e4eSSatish Balay } 538e5c89e4eSSatish Balay 539e5c89e4eSSatish Balay #undef __FUNCT__ 540e5c89e4eSSatish Balay #define __FUNCT__ "PetscDLLibraryClose" 541e5c89e4eSSatish Balay /*@C 542e5c89e4eSSatish Balay PetscDLLibraryClose - Destroys the search path of dynamic libraries and closes the libraries. 543e5c89e4eSSatish Balay 544e5c89e4eSSatish Balay Collective on PetscDLLibrary 545e5c89e4eSSatish Balay 546e5c89e4eSSatish Balay Input Parameter: 547e5c89e4eSSatish Balay . next - library list 548e5c89e4eSSatish Balay 549e5c89e4eSSatish Balay Level: developer 550e5c89e4eSSatish Balay 551e5c89e4eSSatish Balay @*/ 552e5bd5246SBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryClose(PetscDLLibrary next) 553e5c89e4eSSatish Balay { 554e5bd5246SBarry Smith PetscDLLibrary prev; 555e5c89e4eSSatish Balay PetscErrorCode ierr; 556e5c89e4eSSatish Balay 557e5c89e4eSSatish Balay PetscFunctionBegin; 558e5c89e4eSSatish Balay while (next) { 559e5c89e4eSSatish Balay prev = next; 560e5c89e4eSSatish Balay next = next->next; 561*ebd79076SLisandro Dalcin /* close the dynamic library */ 562*ebd79076SLisandro Dalcin ierr = PetscDLClose(&prev->handle);CHKERRQ(ierr); 563e5c89e4eSSatish Balay /* free the space in the prev data-structure */ 564e5c89e4eSSatish Balay ierr = PetscFree(prev);CHKERRQ(ierr); 565e5c89e4eSSatish Balay } 566e5c89e4eSSatish Balay PetscFunctionReturn(0); 567e5c89e4eSSatish Balay } 568e5c89e4eSSatish Balay 569e5c89e4eSSatish Balay #undef __FUNCT__ 570e5c89e4eSSatish Balay #define __FUNCT__ "PetscDLLibraryCCAAppend" 571e5c89e4eSSatish Balay /*@C 572e5c89e4eSSatish Balay PetscDLLibraryCCAAppend - Appends another CCA dynamic link library to the seach list, to the end 573e5c89e4eSSatish Balay of the search path. 574e5c89e4eSSatish Balay 575e5c89e4eSSatish Balay Collective on MPI_Comm 576e5c89e4eSSatish Balay 577e5c89e4eSSatish Balay Input Parameters: 578e5c89e4eSSatish Balay + comm - MPI communicator 579e5c89e4eSSatish Balay - libname - name of directory to check 580e5c89e4eSSatish Balay 581e5c89e4eSSatish Balay Output Parameter: 582e5c89e4eSSatish Balay . outlist - list of libraries 583e5c89e4eSSatish Balay 584e5c89e4eSSatish Balay Level: developer 585e5c89e4eSSatish Balay 586e5c89e4eSSatish Balay Notes: if library is already in path will not add it. 587e5c89e4eSSatish Balay @*/ 588e5bd5246SBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscDLLibraryCCAAppend(MPI_Comm comm,PetscDLLibrary *outlist,const char dirname[]) 589e5c89e4eSSatish Balay { 590e5c89e4eSSatish Balay PetscErrorCode ierr; 591e5c89e4eSSatish Balay size_t l; 592e5c89e4eSSatish Balay PetscTruth dir; 593e5c89e4eSSatish Balay char program[PETSC_MAX_PATH_LEN],buf[8*PETSC_MAX_PATH_LEN],*libname1,fbuf[PETSC_MAX_PATH_LEN],*found,suffix[16],*f2; 594e5c89e4eSSatish Balay char *func,*funcname,libname[PETSC_MAX_PATH_LEN],*lib; 595e5c89e4eSSatish Balay FILE *fp; 5965b096c79SMatthew Knepley PetscToken token1, token2; 597ed9cf6e9SBarry Smith int err; 598e5c89e4eSSatish Balay 599e5c89e4eSSatish Balay PetscFunctionBegin; 600e5c89e4eSSatish Balay /* is dirname a directory? */ 601e5c89e4eSSatish Balay ierr = PetscTestDirectory(dirname,'r',&dir);CHKERRQ(ierr); 602e5c89e4eSSatish Balay if (!dir) PetscFunctionReturn(0); 603e5c89e4eSSatish Balay 604ae15b995SBarry Smith ierr = PetscInfo1(0,"Checking directory %s for CCA components\n",dirname);CHKERRQ(ierr); 605e5c89e4eSSatish Balay ierr = PetscStrcpy(program,dirname);CHKERRQ(ierr); 606e5c89e4eSSatish Balay ierr = PetscStrcat(program,"/*.cca");CHKERRQ(ierr); 607e5c89e4eSSatish Balay 608e5c89e4eSSatish Balay ierr = PetscLs(comm,program,buf,8*PETSC_MAX_PATH_LEN,&dir);CHKERRQ(ierr); 609e5c89e4eSSatish Balay if (!dir) PetscFunctionReturn(0); 610e5c89e4eSSatish Balay 611e5c89e4eSSatish Balay ierr = PetscStrcpy(suffix,".");CHKERRQ(ierr); 612e5c89e4eSSatish Balay ierr = PetscStrcat(suffix,PETSC_SLSUFFIX);CHKERRQ(ierr); 613e5c89e4eSSatish Balay ierr = PetscTokenCreate(buf,'\n',&token1);CHKERRQ(ierr); 614e5c89e4eSSatish Balay ierr = PetscTokenFind(token1,&libname1);CHKERRQ(ierr); 615e5c89e4eSSatish Balay while (libname1) { 616e5c89e4eSSatish Balay fp = fopen(libname1,"r"); if (!fp) continue; 617e5c89e4eSSatish Balay while ((found = fgets(fbuf,PETSC_MAX_PATH_LEN,fp))) { 618e5c89e4eSSatish Balay if (found[0] == '!') continue; 619e5c89e4eSSatish Balay ierr = PetscStrstr(found,suffix,&f2);CHKERRQ(ierr); 620e5c89e4eSSatish Balay if (f2) { /* found library name */ 621e5c89e4eSSatish Balay if (found[0] == '/') { 622e5c89e4eSSatish Balay lib = found; 623e5c89e4eSSatish Balay } else { 624e5c89e4eSSatish Balay ierr = PetscStrcpy(libname,dirname);CHKERRQ(ierr); 625e5c89e4eSSatish Balay ierr = PetscStrlen(libname,&l);CHKERRQ(ierr); 626e5c89e4eSSatish Balay if (libname[l-1] != '/') {ierr = PetscStrcat(libname,"/");CHKERRQ(ierr);} 627e5c89e4eSSatish Balay ierr = PetscStrcat(libname,found);CHKERRQ(ierr); 628e5c89e4eSSatish Balay lib = libname; 629e5c89e4eSSatish Balay } 630e5c89e4eSSatish Balay ierr = PetscDLLibraryAppend(comm,outlist,lib);CHKERRQ(ierr); 631e5c89e4eSSatish Balay } else { 632ae15b995SBarry Smith ierr = PetscInfo2(0,"CCA Component function and name: %s from %s\n",found,libname1);CHKERRQ(ierr); 633e5c89e4eSSatish Balay ierr = PetscTokenCreate(found,' ',&token2);CHKERRQ(ierr); 634e5c89e4eSSatish Balay ierr = PetscTokenFind(token2,&func);CHKERRQ(ierr); 635e5c89e4eSSatish Balay ierr = PetscTokenFind(token2,&funcname);CHKERRQ(ierr); 636e5c89e4eSSatish Balay ierr = PetscFListAdd(&CCAList,funcname,func,PETSC_NULL);CHKERRQ(ierr); 637e5c89e4eSSatish Balay ierr = PetscTokenDestroy(token2);CHKERRQ(ierr); 638e5c89e4eSSatish Balay } 639e5c89e4eSSatish Balay } 640ed9cf6e9SBarry Smith err = fclose(fp); 641ed9cf6e9SBarry Smith if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file"); 642e5c89e4eSSatish Balay ierr = PetscTokenFind(token1,&libname1);CHKERRQ(ierr); 643e5c89e4eSSatish Balay } 644e5c89e4eSSatish Balay ierr = PetscTokenDestroy(token1);CHKERRQ(ierr); 645e5c89e4eSSatish Balay PetscFunctionReturn(0); 646e5c89e4eSSatish Balay } 647