source: Sophya/trunk/SophyaLib/SysTools/pdlmgr.cc@ 3007

Last change on this file since 3007 was 2867, checked in by ansari, 20 years ago

Portage/compilation sur AIX-XlC (regatta) - Reza 3 Jan 2006

File size: 9.5 KB
RevLine 
[1371]1//
[219]2// Gestionnaire de lien dynamique - R. Ansari 12/98
3// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
[1371]4//
[1783]5#include <machdefs.h>
[219]6
[2615]7#include "sopnamsp.h"
[913]8#include "pdlmgr.h"
[219]9#include <stdio.h>
10#include <stdlib.h>
11
[2322]12#include <iostream>
[219]13
14
15// Extension de noms de fichiers Shared libs
16static const char* sofext = ".so";
17static const char* sofext_HPUX = ".sl";
[1900]18// static const char* sofext_Darwin = ".dylib"; pas necessaire - Reza 02/2002
[219]19
20// Variables et methodes static
21int PDynLinkMgr::numSO = 0;
22string* PDynLinkMgr::tmpDir = NULL;
23
[895]24/*!
25 \class SOPHYA::PDynLinkMgr
[913]26 \ingroup SysTools
[895]27 This classes handles the run-time operations related to using shared
28 libraries. The present version has been adapted for different Unix
[2598]29 flavours (Linux, HP/Compaq/Digital OSF-Tru64, SGI IRIX, IBM AIX, Sun Solaris,
30 MacOS X/Darwin). \n
31 For MacOS X/Darwin, the NSxxx API
32 <tt> (NSLinkModule , NSCreateObjectFileImageFromFile, ...) </tt>
33 is used.
[1275]34 The example here shows the linking of shared library named "mylib.so"
[913]35 containing a function \c double \c myfunction(double x).
36 \code
37 #include "pdlmgr.h"
38 typedef double (* AFunctionOfX) (double x);
39 {
40 // ...
41 string soname = "mylib.so";
42 string funcname = "myfunction";
43 PDynLinkMgr dyl(son);
44 AFunctionOfX f = (AFunctionOfX)dyl.GetFunction(funcname);
45 double x = 3.1425;
46 if (f != NULL)
47 cout << " X= " << x << " myfunction(x)=" << f(x) << endl;
48 // ...
49 }
50 \endcode
[895]51*/
52
[219]53/* --Methode-Static-- */
[895]54/*! Sets the path for a temporary space where shared libraries are copied.
55 The path is appended to \b LD_LIBRARY_PATH
56*/
[219]57void PDynLinkMgr::SetTmpDir(string const & path)
58{
[1275]59if ( (path.length() > 0) && (path[path.length()-1] != '/') ) GetTmpDir() = path + '/';
[219]60else GetTmpDir() = path;
[1275]61#if defined(OSF1) || defined(Linux) || defined(SunOS) || defined(IRIX64)
62 char* varenv=NULL;
63#if !defined(IRIX64)
[480]64 string cmd = "LD_LIBRARY_PATH=";
65 varenv=getenv("LD_LIBRARY_PATH");
[1275]66#else
67#ifdef SGI_ARCH64
[480]68 string cmd = "LD_LIBRARYN32_PATH=";
69 varenv=getenv("LD_LIBRARYN32_PATH");
[1275]70#else
71 string cmd = "LD_LIBRARYN64_PATH=";
72 varenv=getenv("LD_LIBRARYN64_PATH");
73#endif
74#endif
[480]75
76 if (varenv == NULL) {
77 cmd += '.';
78 if (path.length() > 0) cmd += ':' + path;
79 }
80 else {
81 if (varenv[0] != '.') cmd += ".:";
82 if (path.length() > 0) cmd += path + ':';
83 cmd += varenv;
[1294]84 putenv(const_cast<char *>(cmd.c_str()));
[480]85 }
86#elif defined(AIX)
87 string cmd = "LIBPATH=";
88 char* varenv=NULL;
89 varenv=getenv("LIBPATH");
90 if (varenv == NULL) {
91 cmd += '.';
92 if (path.length() > 0) cmd += ':' + path;
93 cmd += ":/usr/lib:/lib";
94 }
95 else {
96 if (varenv[0] != '.') cmd += ".:";
97 if (path.length() > 0) cmd += path + ':';
98 cmd += varenv;
[2867]99 //AIX: l'argument de putenv n'est pas const (Reza Dec 2005)
100 //On fait un new - mais qui fait le delete ?
101 char * pevc = new char [cmd.length()+1];
102 strcpy(pevc, cmd.c_str());
103 putenv(pevc);
[480]104 }
105
106#endif
[219]107return;
108}
109
110/* --Methode-Static-- */
[895]111/*! Returns the temporary space path */
[219]112string& PDynLinkMgr::GetTmpDir()
113{
114if (tmpDir == NULL) {
115 tmpDir = new string("");
116 char* varenv;
[1277]117 if ( (varenv=getenv("TMPDIR")) != NULL ) {
118 *tmpDir = varenv;
119 if ((*tmpDir)[tmpDir->length()-1] != '/') (*tmpDir) += '/';
[219]120 }
[1277]121}
[219]122return(*tmpDir);
123}
124
125/* --Methode-Static-- */
[895]126/*! Compiles the C source file named \b fname and creates the
127 corresponding shared library linking against the standard
128 C library (-lc) and the math library (-lm).
129 Returns a pointer to the created PDynLinkMgr object (by new).
130 Returns the NULL pointer in case of errors.
131*/
[219]132PDynLinkMgr* PDynLinkMgr::BuildFromCFile(string const & fname)
133{
134size_t l = fname.length();
135if (l < 1) return(NULL);
136string fnameobj = GetTmpDir()+"tmp_pdl.o";
137
138string cmd;
139int rc;
140
141// Compilation du fichier
[480]142#ifndef __mac__
[1249]143#ifdef SGI_ARCH64
144cmd = "cc -64 -c -o " + fnameobj + " " + fname;
145#else
[219]146cmd = "cc -c -o " + fnameobj + " " + fname;
[1249]147#endif
[480]148#else
149cmd = "Il faut compiler !!!" + fnameobj + " " + fname;
[219]150#endif
151rc = system(cmd.c_str());
152if (rc != 0) {
153 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
154 return(NULL);
155 }
156
157char buff[32];
158numSO++;
159#ifndef HPUX
160sprintf(buff,"pdlmgr%d%s", numSO,sofext);
161#endif
162string fnameso = GetTmpDir()+buff;
163
164// Creation du shared-lib
165#if defined(OSF1)
166 cmd = "ld -shared -o " + fnameso + " -all " + fnameobj + " -none -lm -lc";
[480]167#elif defined(Linux)
[219]168 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
[480]169#elif defined(SunOS)
170 cmd = "ld -G -o " + fnameso + " " + fnameobj + " -lm -lc";
171#elif defined(IRIX64)
[1249]172#ifdef SGI_ARCH64
173 cmd = "ld -64 -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
174#else
[480]175 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
[1249]176#endif
[480]177#elif defined(AIX)
[2867]178 // cmd = "ld -G -bnogc -bexpall -bM:1L -o " + fnameso + " " + fnameobj;
179 cmd = "cc -brtl -qmkshrobj -o " + fnameso + " " + fnameobj + " -lm -lc";;
[480]180#elif defined(HPUX)
181 cmd = "ld -b -o " + fnameso + " " + fnameobj + " -lm -lc";
[1795]182#elif defined(Darwin)
[2496]183 // cmd = "cc -bundle -flat_namespace -undefined suppress -o " + fnameso + " " + fnameobj + " -lm -lcc_dynamic -lSystem ";
184 cmd = "cc -bundle -o " + fnameso + " " + fnameobj + " -lSystem -lm";
[480]185#else
186 cmd = "ld -o " + fnameso + " " + fnameobj + " -lm -lc";
[219]187#endif
188rc = system(cmd.c_str());
189if (rc != 0) {
190 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
191 return(NULL);
192 }
[296]193PDynLinkMgr* rdyn = new PDynLinkMgr(fnameso, false);
194rdyn->copy = true;
195return(rdyn);
[219]196
197}
198
199/* --Methode-- */
[895]200/*! The constructor.
201 \param soname : Name of the shared library. ".so" is appended
202 to the name if no dot "." is found in the name.
203 \param cp : if true, copies the shared library in the temporary space.
204*/
[219]205PDynLinkMgr::PDynLinkMgr(string& soname, bool cp)
206{
[2496]207dylok = false;
[219]208soName = "";
209
210if (soname.find_last_of(".") > soname.length())
211#ifdef HPUX
212 soname += sofext_HPUX;
213#else
214 soname += sofext;
215#endif
216
217string fnameso;
218if (cp) {
219 numSO++;
220 char buff[32];
221#ifndef HPUX
222 sprintf(buff,"pdlmgr%d%s", numSO,sofext);
[1795]223#elif defined(Darwin)
224 sprintf(buff,"pdlmgr%d%s", numSO,sofext_Darwin);
[219]225#else
226 sprintf(buff,"pdlmgr%d%s", numSO,sofext_HPUX);
227#endif
228 fnameso = GetTmpDir()+buff;
229 string cmd = "cp " + soname + " " + fnameso;
230 int rc = system(cmd.c_str());
231 if (rc != 0) {
232 cerr << "PDynLinkMgr::PDynLinkMgr() Error Rc(" << cmd <<")= "<< rc << endl;
233 return;
234 }
235 }
236else fnameso = soname;
237copy = cp;
238soName = fnameso;
239
[2496]240string sdylerr;
[480]241#if defined(HPUX)
242cerr << "PDynLinkMgr::PDynLinkMgr() Not yet available on HP-UX " << endl;
243return;
[2496]244#elif defined(Darwin)
245NSObjectFileImageReturnCode nsrc = NSCreateObjectFileImageFromFile(fnameso.c_str(), &nsobjfile);
246if (nsrc == NSObjectFileImageSuccess) {
247 nsmod = NSLinkModule(nsobjfile, fnameso.c_str(),
248 NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_PRIVATE |
249 NSLINKMODULE_OPTION_RETURN_ON_ERROR);
250 // The second argument of NSLinkModule is the module name
251 // We might associate later a name for the module in the PDynLinkMgr object
252 if (nsmod != NULL) dylok = true;
253 else cerr << "PDynLinkMgr::PDynLinkMgr()/ Error from NSLinkModule ... " << endl;
254}
255else {
256 cerr << "PDynLinkMgr::PDynLinkMgr()/ Error from NSCreateObjectFileImageFromFile ... " << endl;
257 if (nsrc == NSObjectFileImageFailure) cerr << " ErrCode= NSObjectFileImageFailure " << endl;
258 else if (nsrc == NSObjectFileImageInappropriateFile) cerr << " ErrCode= NSObjectFileImageInappropriateFile" << endl;
259 else if (nsrc == NSObjectFileImageArch ) cerr << " ErrCode= NSObjectFileImageArch" << endl;
260 else if (nsrc == NSObjectFileImageFormat) cerr << " ErrCode= NSObjectFileImageFormat" << endl;
261 else if (nsrc == NSObjectFileImageAccess) cerr << " ErrCode= NSObjectFileImageAccess" << endl;
[2498]262 }
[480]263#else
[2496]264dlhandle = NULL;
[219]265dlhandle = dlopen(fnameso.c_str(), RTLD_NOW);
[2496]266if (dlhandle != NULL) dylok = true;
267else {
268 sdylerr = "Loader Error (dlerror()):";
269 sdylerr += dlerror();
[2498]270 }
[2496]271#endif
272
273if (!dylok) {
[219]274 cerr << "PDynLinkMgr::PDynLinkMgr(): Error opening SO " << fnameso
275 << " (" << soname << ")" << endl;
[2496]276 if (sdylerr.length() > 0) cerr << sdylerr;
[219]277 return;
278 }
279}
280
281/* --Methode-- */
[895]282/*! Destructor. Closes the shared library. Removes the file if it had been
283 copied in the temporary space, or generated by \b BuildFromCFile */
[219]284PDynLinkMgr::~PDynLinkMgr()
285{
[480]286#if defined(HPUX)
287cerr << "PDynLinkMgr::~PDynLinkMgr() Not yet available on HP-UX " << endl;
[2496]288// return;
289#elif defined(Darwin)
290if (dylok) {
291 if (nsmod != NULL) NSUnLinkModule(nsmod, NSUNLINKMODULE_OPTION_NONE);
292 NSDestroyObjectFileImage(nsobjfile);
293 }
[480]294#else
[2496]295if (dylok) {
296 if (dlhandle) dlclose(dlhandle); dlhandle = NULL;
297 }
298#endif
[219]299if (copy) {
[296]300 string cmd = "rm -f " + soName;
[219]301 system(cmd.c_str());
302 }
303}
304
305/* --Methode-- */
[895]306/*! Returns a handle to the function named \b funcname.
307 Returns the NULL pointer in case of error */
[219]308DlFunction PDynLinkMgr::GetFunction(string const & funcname)
309{
310DlFunction f = NULL;
[2496]311if (!dylok) {
312 cerr << "PDynLinkMgr::GetFunction() Error:sharedobjet/dynamic library not open -> f=NULL" << endl;
313 return f;
314}
[480]315#if defined(HPUX)
316cerr << "PDynLinkMgr::GetFunction() Not yet available on HP-UX " << endl;
317return f;
[2496]318#endif
[1900]319#if defined(Darwin)
320string funame = "_" + funcname;
[2496]321NSSymbol nsf = NSLookupSymbolInModule(nsmod, funame.c_str());
322f = (DlFunction)NSAddressOfSymbol(nsf);
[1900]323#else
[1902]324string const & funame = funcname;
[219]325if (dlhandle != NULL)
[1900]326 f = (DlFunction)dlsym(dlhandle, funame.c_str());
[2496]327#endif
328
[480]329if (f == NULL) cerr << "PDynLinkMgr::GetFunction(): Error linking " << funcname << endl;
330return(f);
[219]331}
332
[1795]333
Note: See TracBrowser for help on using the repository browser.