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

Last change on this file since 1371 was 1371, checked in by ansari, 25 years ago

MAJ documentation, Makefile, ... - Reza 5/1/2001

File size: 6.9 KB
Line 
1//
2// Gestionnaire de lien dynamique - R. Ansari 12/98
3// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
4//
5
6#include "pdlmgr.h"
7#include <stdio.h>
8#include <stdlib.h>
9
10#include <iostream.h>
11
12
13// Extension de noms de fichiers Shared libs
14static const char* sofext = ".so";
15static const char* sofext_HPUX = ".sl";
16
17// Variables et methodes static
18int PDynLinkMgr::numSO = 0;
19string* PDynLinkMgr::tmpDir = NULL;
20
21/*!
22 \class SOPHYA::PDynLinkMgr
23 \ingroup SysTools
24 This classes handles the run-time operations related to using shared
25 libraries. The present version has been adapted for different Unix
26 flavours (Linux, Compaq/Digital Unix, SGI IRIX, IBM AIX, Sun Solaris).
27 The example here shows the linking of shared library named "mylib.so"
28 containing a function \c double \c myfunction(double x).
29 \code
30 #include "pdlmgr.h"
31 typedef double (* AFunctionOfX) (double x);
32 {
33 // ...
34 string soname = "mylib.so";
35 string funcname = "myfunction";
36 PDynLinkMgr dyl(son);
37 AFunctionOfX f = (AFunctionOfX)dyl.GetFunction(funcname);
38 double x = 3.1425;
39 if (f != NULL)
40 cout << " X= " << x << " myfunction(x)=" << f(x) << endl;
41 // ...
42 }
43 \endcode
44*/
45
46/* --Methode-Static-- */
47/*! Sets the path for a temporary space where shared libraries are copied.
48 The path is appended to \b LD_LIBRARY_PATH
49*/
50void PDynLinkMgr::SetTmpDir(string const & path)
51{
52if ( (path.length() > 0) && (path[path.length()-1] != '/') ) GetTmpDir() = path + '/';
53else GetTmpDir() = path;
54#if defined(OSF1) || defined(Linux) || defined(SunOS) || defined(IRIX64)
55 char* varenv=NULL;
56#if !defined(IRIX64)
57 string cmd = "LD_LIBRARY_PATH=";
58 varenv=getenv("LD_LIBRARY_PATH");
59#else
60#ifdef SGI_ARCH64
61 string cmd = "LD_LIBRARYN32_PATH=";
62 varenv=getenv("LD_LIBRARYN32_PATH");
63#else
64 string cmd = "LD_LIBRARYN64_PATH=";
65 varenv=getenv("LD_LIBRARYN64_PATH");
66#endif
67#endif
68
69 if (varenv == NULL) {
70 cmd += '.';
71 if (path.length() > 0) cmd += ':' + path;
72 }
73 else {
74 if (varenv[0] != '.') cmd += ".:";
75 if (path.length() > 0) cmd += path + ':';
76 cmd += varenv;
77 putenv(const_cast<char *>(cmd.c_str()));
78 }
79#elif defined(AIX)
80 string cmd = "LIBPATH=";
81 char* varenv=NULL;
82 varenv=getenv("LIBPATH");
83 if (varenv == NULL) {
84 cmd += '.';
85 if (path.length() > 0) cmd += ':' + path;
86 cmd += ":/usr/lib:/lib";
87 }
88 else {
89 if (varenv[0] != '.') cmd += ".:";
90 if (path.length() > 0) cmd += path + ':';
91 cmd += varenv;
92 putenv(const_cast<char *>(cmd.c_str()));
93 }
94
95#endif
96return;
97}
98
99/* --Methode-Static-- */
100/*! Returns the temporary space path */
101string& PDynLinkMgr::GetTmpDir()
102{
103if (tmpDir == NULL) {
104 tmpDir = new string("");
105 char* varenv;
106 if ( (varenv=getenv("TMPDIR")) != NULL ) {
107 *tmpDir = varenv;
108 if ((*tmpDir)[tmpDir->length()-1] != '/') (*tmpDir) += '/';
109 }
110}
111return(*tmpDir);
112}
113
114/* --Methode-Static-- */
115/*! Compiles the C source file named \b fname and creates the
116 corresponding shared library linking against the standard
117 C library (-lc) and the math library (-lm).
118 Returns a pointer to the created PDynLinkMgr object (by new).
119 Returns the NULL pointer in case of errors.
120*/
121PDynLinkMgr* PDynLinkMgr::BuildFromCFile(string const & fname)
122{
123size_t l = fname.length();
124if (l < 1) return(NULL);
125string fnameobj = GetTmpDir()+"tmp_pdl.o";
126
127string cmd;
128int rc;
129
130// Compilation du fichier
131#ifndef __mac__
132#ifdef SGI_ARCH64
133cmd = "cc -64 -c -o " + fnameobj + " " + fname;
134#else
135cmd = "cc -c -o " + fnameobj + " " + fname;
136#endif
137#else
138cmd = "Il faut compiler !!!" + fnameobj + " " + fname;
139#endif
140rc = system(cmd.c_str());
141if (rc != 0) {
142 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
143 return(NULL);
144 }
145
146char buff[32];
147numSO++;
148#ifndef HPUX
149sprintf(buff,"pdlmgr%d%s", numSO,sofext);
150#endif
151string fnameso = GetTmpDir()+buff;
152
153// Creation du shared-lib
154#if defined(OSF1)
155 cmd = "ld -shared -o " + fnameso + " -all " + fnameobj + " -none -lm -lc";
156#elif defined(Linux)
157 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
158#elif defined(SunOS)
159 cmd = "ld -G -o " + fnameso + " " + fnameobj + " -lm -lc";
160#elif defined(IRIX64)
161#ifdef SGI_ARCH64
162 cmd = "ld -64 -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
163#else
164 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
165#endif
166#elif defined(AIX)
167 cmd = "ld -G -bnogc -bexpall -bM:1L -o " + fnameso + " " + fnameobj;
168#elif defined(HPUX)
169 cmd = "ld -b -o " + fnameso + " " + fnameobj + " -lm -lc";
170#else
171 cmd = "ld -o " + fnameso + " " + fnameobj + " -lm -lc";
172#endif
173rc = system(cmd.c_str());
174if (rc != 0) {
175 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
176 return(NULL);
177 }
178PDynLinkMgr* rdyn = new PDynLinkMgr(fnameso, false);
179rdyn->copy = true;
180return(rdyn);
181
182}
183
184/* --Methode-- */
185/*! The constructor.
186 \param soname : Name of the shared library. ".so" is appended
187 to the name if no dot "." is found in the name.
188 \param cp : if true, copies the shared library in the temporary space.
189*/
190PDynLinkMgr::PDynLinkMgr(string& soname, bool cp)
191{
192dlhandle = NULL;
193soName = "";
194
195if (soname.find_last_of(".") > soname.length())
196#ifdef HPUX
197 soname += sofext_HPUX;
198#else
199 soname += sofext;
200#endif
201
202string fnameso;
203if (cp) {
204 numSO++;
205 char buff[32];
206#ifndef HPUX
207 sprintf(buff,"pdlmgr%d%s", numSO,sofext);
208#else
209 sprintf(buff,"pdlmgr%d%s", numSO,sofext_HPUX);
210#endif
211 fnameso = GetTmpDir()+buff;
212 string cmd = "cp " + soname + " " + fnameso;
213 int rc = system(cmd.c_str());
214 if (rc != 0) {
215 cerr << "PDynLinkMgr::PDynLinkMgr() Error Rc(" << cmd <<")= "<< rc << endl;
216 return;
217 }
218 }
219else fnameso = soname;
220copy = cp;
221soName = fnameso;
222
223#if defined(HPUX)
224dlhandle = NULL;
225cerr << "PDynLinkMgr::PDynLinkMgr() Not yet available on HP-UX " << endl;
226return;
227#else
228dlhandle = dlopen(fnameso.c_str(), RTLD_NOW);
229if (dlhandle == NULL) {
230 cerr << "PDynLinkMgr::PDynLinkMgr(): Error opening SO " << fnameso
231 << " (" << soname << ")" << endl;
232 string sn = dlerror();
233 cerr << "Loader Error (dlerror()) :" << sn << endl;
234 return;
235 }
236#endif
237}
238
239/* --Methode-- */
240/*! Destructor. Closes the shared library. Removes the file if it had been
241 copied in the temporary space, or generated by \b BuildFromCFile */
242PDynLinkMgr::~PDynLinkMgr()
243{
244#if defined(HPUX)
245cerr << "PDynLinkMgr::~PDynLinkMgr() Not yet available on HP-UX " << endl;
246return;
247#else
248if (dlhandle) dlclose(dlhandle); dlhandle = NULL;
249if (copy) {
250 string cmd = "rm -f " + soName;
251 system(cmd.c_str());
252 }
253#endif
254}
255
256/* --Methode-- */
257/*! Returns a handle to the function named \b funcname.
258 Returns the NULL pointer in case of error */
259DlFunction PDynLinkMgr::GetFunction(string const & funcname)
260{
261DlFunction f = NULL;
262#if defined(HPUX)
263cerr << "PDynLinkMgr::GetFunction() Not yet available on HP-UX " << endl;
264return f;
265#else
266if (dlhandle != NULL)
267 f = (DlFunction)dlsym(dlhandle, funcname.c_str());
268if (f == NULL) cerr << "PDynLinkMgr::GetFunction(): Error linking " << funcname << endl;
269return(f);
270#endif
271}
272
Note: See TracBrowser for help on using the repository browser.