4 // Author: Phil Mesnier
6 // This file contains the implementation of the classes responsible for
7 // generating specialized mpc files for individual libraries, as well as
8 // outputting usage metrics for the various object modules contained in the
11 #include "ace/OS_NS_dirent.h"
12 #include "ace/OS_NS_stdlib.h"
13 #include "ace/OS_NS_string.h"
14 #include "ace/OS_NS_unistd.h"
15 #include "ace/OS_NS_sys_stat.h"
16 #include "ace/OS_NS_ctype.h"
17 #include "ace/Log_Msg.h"
21 MPC_Generator::MPC_Generator (const ACE_CString
& libname
)
26 mpcfilename_
= libname_
+ "_subset.mpc";
29 MPC_Generator::~MPC_Generator ()
34 MPC_Generator::write_file (const ACE_CString
& file
)
36 mpcfile_
<< " " << file
<< ".cpp" << endl
;
40 MPC_Generator::write_prolog (const ACE_CString
& path
)
42 ACE_CString
fname (path
+ "/" + mpcfilename_
);
43 ACE_DEBUG ((LM_DEBUG
, "writing file %s\n",fname
.c_str()));
44 mpcfile_
.open(fname
.c_str());
46 ACE_DEBUG ((LM_DEBUG
,"mpc file open failed\n"));
49 << "// Generated mpc file for producing a subset of the "
50 << libname_
<< " library " << endl
<< endl
51 << "project(" << libname_
<< "_subset)";
53 this->write_baseprojects ();
57 << " sharedname = " << libname_
<< "_subset" << endl
58 << " pch_header = " << endl
59 << " pch_source = " << endl
;
61 this->write_projectinfo ();
64 << " Source_Files {" << endl
;
68 MPC_Generator::write_epilog ()
70 mpcfile_
<< " }" << endl
76 MPC_Generator::write_baseprojects()
78 mpcfile_
<< ": acedefaults, core";
82 MPC_Generator::write_projectinfo()
84 mpcfile_
<< " libout = $(ACE_ROOT)/lib" << endl
85 << " dynamicflags = ACE_BUILD_DLL ACE_OS_BUILD_DLL" << endl
;
88 //-----------------------------------------------------------------------------
89 MPC_ACE_Dep_Lib::MPC_ACE_Dep_Lib (const ACE_CString
& libname
)
90 : MPC_Generator(libname
)
94 MPC_ACE_Dep_Lib::write_baseprojects()
96 mpcfile_
<< ": acedefaults, aceversion";
100 MPC_ACE_Dep_Lib::write_projectinfo()
102 mpcfile_
<< " libout = $(ACE_ROOT)/lib" << endl
103 << " libs += ACE_subset" << endl
104 << " after += ACE_subset" << endl
;
107 //-----------------------------------------------------------------------------
108 MPC_TAO_Lib::MPC_TAO_Lib (const ACE_CString
& libname
)
109 : MPC_ACE_Dep_Lib(libname
)
113 MPC_TAO_Lib::write_baseprojects()
115 MPC_ACE_Dep_Lib::write_baseprojects ();
116 mpcfile_
<< ", core, tao_output, taodefaults";
120 MPC_TAO_Lib::write_projectinfo()
122 MPC_ACE_Dep_Lib::write_projectinfo();
123 mpcfile_
<< " dynamicflags = TAO_BUILD_DLL" << endl
;
126 //-----------------------------------------------------------------------------
127 MPC_TAO_Dep_Lib::MPC_TAO_Dep_Lib (const ACE_CString
& libname
)
128 : MPC_TAO_Lib(libname
)
132 MPC_TAO_Dep_Lib::write_baseprojects()
134 MPC_TAO_Lib::write_baseprojects ();
135 mpcfile_
<< ", taoidldefaults";
139 MPC_TAO_Dep_Lib::write_projectinfo()
141 // Try our best to generate the dynamicflags
143 for(size_t i
= 0; i
< this->libname_
.length (); ++i
) {
144 dflags
+= static_cast<char>(ACE_OS::ace_toupper (this->libname_
[i
]));
146 dflags
+= "_BUILD_DLL";
148 MPC_ACE_Dep_Lib::write_projectinfo();
149 mpcfile_
<< " dynamicflags = " << dflags
.c_str () << endl
150 << " libs += TAO_subset" << endl
151 << " after += TAO_subset" << endl
152 << " includes += $(TAO_ROOT)/orbsvcs" << endl
153 << " idlflags += -I$(TAO_ROOT)/orbsvcs" << endl
;
156 //-----------------------------------------------------------------------------
158 Library::Library (const char *name
)
169 mpcfile_
= new MPC_Generator(name_
);
170 else if (name_
.find ("ACE_") == 0)
171 mpcfile_
= new MPC_ACE_Dep_Lib (name_
);
172 else if (name_
== "TAO")
173 mpcfile_
= new MPC_TAO_Lib (name_
);
175 mpcfile_
= new MPC_TAO_Dep_Lib (name_
);
183 for (i
= 0; i
< num_modules_
; delete modules_
[i
++])
192 Library::set_path (const char *p
)
195 ACE_OS::memset (abspath
,0,1000);
196 ssize_t abspathlen
= ACE_OS::readlink(p
,abspath
,999);
197 ACE_CString
path (p
);
198 if (abspathlen
> 0) {
199 abspath
[abspathlen
] = 0;
203 ACE_CString::size_type pathsep
= path
.rfind('/');
205 if (pathsep
== ACE_CString::npos
) {
208 path_
= path
.substr(0,pathsep
);
213 Library::name () const
219 Library::has_modules () const
221 return num_modules_
> 0;
226 selector (const dirent
*d
)
228 return ACE_OS::strstr (d
->d_name
, ACE_TEXT (".o")) != 0;
232 comparator (const dirent
**d1
, const dirent
**d2
)
234 return ACE_OS::strcmp ((*d1
)->d_name
, (*d2
)->d_name
);
240 Library::load_modules ()
242 ACE_CString subdir
= path_
+ "/.shobj";
244 struct dirent
**dent
;
245 num_modules_
= ACE_OS::scandir(ACE_TEXT_CHAR_TO_TCHAR (subdir
.c_str()),
246 &dent
,selector
,comparator
);
248 if (num_modules_
> 0) {
249 modules_
= new Obj_Module
* [num_modules_
];
250 for (int i
= 0; i
< num_modules_
; i
++) {
251 ACE_CString
ent_name (ACE_TEXT_ALWAYS_CHAR (dent
[i
]->d_name
));
252 modules_
[i
] = new Obj_Module(ent_name
);
253 modules_
[i
]->add_source (ACE_CString(subdir
+ "/" + ent_name
).c_str());
254 ACE_OS::free(dent
[i
]);
258 if (num_modules_
> -1)
263 Library::resolve (Sig_List
&undefs
)
265 if (num_modules_
< 1)
268 for (const Signature
*uname
= undefs
.first();
270 uname
= undefs
.next()) {
271 if (exported_
.index_of(uname
) != -1) {
272 undefs
.remove_current();
275 for (int i
= 0; i
< num_modules_
; i
++)
276 if (modules_
[i
]->extref() == 0 &&
277 modules_
[i
]->exports().index_of(uname
) != -1)
279 undefs
.remove_current();
280 exported_
.add (modules_
[i
]->exports());
281 for (const Signature
*needed
= modules_
[i
]->imports().first();
282 modules_
[i
]->imports().hasmore();
283 needed
= modules_
[i
]->imports().next())
284 if (exported_
.index_of(needed
) == -1)
285 undefs
.add (needed
->name());
286 modules_
[i
]->add_extref();
294 Library::write_export_list (int show_ref_counts
)
296 if (num_modules_
< 1)
299 ACE_CString excludedfilename
= path_
+ "/excluded_modules";
300 ACE_CString rcpath
= path_
+ "/usage_metrics";
302 ofstream
exclusions (excludedfilename
.c_str());
304 ACE_ERROR ((LM_ERROR
, "%p\n", "open exclusions list"));
307 if (show_ref_counts
) {
308 ACE_DEBUG ((LM_DEBUG
, "Making directory %s\n",rcpath
.c_str()));
309 if (ACE_OS::mkdir(ACE_TEXT_CHAR_TO_TCHAR (rcpath
.c_str())) == -1 &&
311 ACE_ERROR ((LM_ERROR
, "%p\n", "mkdir"));
314 ACE_DEBUG ((LM_DEBUG
,"%s: %d out of %d modules required\n",
315 name_
.c_str(), num_extrefs_
, num_modules_
));
317 mpcfile_
->write_prolog(path_
);
319 for (int i
= 0; i
< num_modules_
; i
++)
320 if (modules_
[i
]->extref()) {
321 if (show_ref_counts
) {
322 ACE_CString fname
= rcpath
+ "/" + modules_
[i
]->name();
323 ofstream
countfile (fname
.c_str());
324 countfile
<< "Exported symbols:" << endl
;
325 for (const Signature
*sig
= modules_
[i
]->exports().first();
326 modules_
[i
]->exports().hasmore();
327 sig
= modules_
[i
]->exports().next())
330 countfile
<< sig
->used_count() << " " << sig
->name() << endl
;
332 countfile
<< "\nImported symbols:" << endl
;
333 for (const Signature
*n_sig
= modules_
[i
]->imports().first();
334 modules_
[i
]->imports().hasmore();
335 n_sig
= modules_
[i
]->imports().next())
336 countfile
<< n_sig
->name() << endl
;
338 mpcfile_
->write_file(modules_
[i
]->name().substring(0,modules_
[i
]->name().length()-2));
340 // const char * modname = modules_[i]->name().c_str();
342 << modules_
[i
]->name().substring(0,modules_
[i
]->name().length()-2)
346 mpcfile_
->write_epilog();