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

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

Classe CxxCompilerLinker, compilation C++ et fabrication de shared lib au vol - Reza 2/11/2000

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