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

Last change on this file since 2680 was 2615, checked in by cmv, 21 years ago

using namespace sophya enleve de machdefs.h, nouveau sopnamsp.h cmv 10/09/2004

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