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

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

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

File size: 9.5 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 //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);
104 }
105
106#endif
107return;
108}
109
110/* --Methode-Static-- */
111/*! Returns the temporary space path */
112string& PDynLinkMgr::GetTmpDir()
113{
114if (tmpDir == NULL) {
115 tmpDir = new string("");
116 char* varenv;
117 if ( (varenv=getenv("TMPDIR")) != NULL ) {
118 *tmpDir = varenv;
119 if ((*tmpDir)[tmpDir->length()-1] != '/') (*tmpDir) += '/';
120 }
121}
122return(*tmpDir);
123}
124
125/* --Methode-Static-- */
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*/
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
142#ifndef __mac__
143#ifdef SGI_ARCH64
144cmd = "cc -64 -c -o " + fnameobj + " " + fname;
145#else
146cmd = "cc -c -o " + fnameobj + " " + fname;
147#endif
148#else
149cmd = "Il faut compiler !!!" + fnameobj + " " + fname;
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";
167#elif defined(Linux)
168 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
169#elif defined(SunOS)
170 cmd = "ld -G -o " + fnameso + " " + fnameobj + " -lm -lc";
171#elif defined(IRIX64)
172#ifdef SGI_ARCH64
173 cmd = "ld -64 -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
174#else
175 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
176#endif
177#elif defined(AIX)
178 // cmd = "ld -G -bnogc -bexpall -bM:1L -o " + fnameso + " " + fnameobj;
179 cmd = "cc -brtl -qmkshrobj -o " + fnameso + " " + fnameobj + " -lm -lc";;
180#elif defined(HPUX)
181 cmd = "ld -b -o " + fnameso + " " + fnameobj + " -lm -lc";
182#elif defined(Darwin)
183 // cmd = "cc -bundle -flat_namespace -undefined suppress -o " + fnameso + " " + fnameobj + " -lm -lcc_dynamic -lSystem ";
184 cmd = "cc -bundle -o " + fnameso + " " + fnameobj + " -lSystem -lm";
185#else
186 cmd = "ld -o " + fnameso + " " + fnameobj + " -lm -lc";
187#endif
188rc = system(cmd.c_str());
189if (rc != 0) {
190 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
191 return(NULL);
192 }
193PDynLinkMgr* rdyn = new PDynLinkMgr(fnameso, false);
194rdyn->copy = true;
195return(rdyn);
196
197}
198
199/* --Methode-- */
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*/
205PDynLinkMgr::PDynLinkMgr(string& soname, bool cp)
206{
207dylok = false;
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);
223#elif defined(Darwin)
224 sprintf(buff,"pdlmgr%d%s", numSO,sofext_Darwin);
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
240string sdylerr;
241#if defined(HPUX)
242cerr << "PDynLinkMgr::PDynLinkMgr() Not yet available on HP-UX " << endl;
243return;
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;
262 }
263#else
264dlhandle = NULL;
265dlhandle = dlopen(fnameso.c_str(), RTLD_NOW);
266if (dlhandle != NULL) dylok = true;
267else {
268 sdylerr = "Loader Error (dlerror()):";
269 sdylerr += dlerror();
270 }
271#endif
272
273if (!dylok) {
274 cerr << "PDynLinkMgr::PDynLinkMgr(): Error opening SO " << fnameso
275 << " (" << soname << ")" << endl;
276 if (sdylerr.length() > 0) cerr << sdylerr;
277 return;
278 }
279}
280
281/* --Methode-- */
282/*! Destructor. Closes the shared library. Removes the file if it had been
283 copied in the temporary space, or generated by \b BuildFromCFile */
284PDynLinkMgr::~PDynLinkMgr()
285{
286#if defined(HPUX)
287cerr << "PDynLinkMgr::~PDynLinkMgr() Not yet available on HP-UX " << endl;
288// return;
289#elif defined(Darwin)
290if (dylok) {
291 if (nsmod != NULL) NSUnLinkModule(nsmod, NSUNLINKMODULE_OPTION_NONE);
292 NSDestroyObjectFileImage(nsobjfile);
293 }
294#else
295if (dylok) {
296 if (dlhandle) dlclose(dlhandle); dlhandle = NULL;
297 }
298#endif
299if (copy) {
300 string cmd = "rm -f " + soName;
301 system(cmd.c_str());
302 }
303}
304
305/* --Methode-- */
306/*! Returns a handle to the function named \b funcname.
307 Returns the NULL pointer in case of error */
308DlFunction PDynLinkMgr::GetFunction(string const & funcname)
309{
310DlFunction f = NULL;
311if (!dylok) {
312 cerr << "PDynLinkMgr::GetFunction() Error:sharedobjet/dynamic library not open -> f=NULL" << endl;
313 return f;
314}
315#if defined(HPUX)
316cerr << "PDynLinkMgr::GetFunction() Not yet available on HP-UX " << endl;
317return f;
318#endif
319#if defined(Darwin)
320string funame = "_" + funcname;
321NSSymbol nsf = NSLookupSymbolInModule(nsmod, funame.c_str());
322f = (DlFunction)NSAddressOfSymbol(nsf);
323#else
324string const & funame = funcname;
325if (dlhandle != NULL)
326 f = (DlFunction)dlsym(dlhandle, funame.c_str());
327#endif
328
329if (f == NULL) cerr << "PDynLinkMgr::GetFunction(): Error linking " << funcname << endl;
330return(f);
331}
332
333
Note: See TracBrowser for help on using the repository browser.