]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/distutils/command/config.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / distutils / command / config.py
CommitLineData
4710c53d 1"""distutils.command.config\r
2\r
3Implements the Distutils 'config' command, a (mostly) empty command class\r
4that exists mainly to be sub-classed by specific module distributions and\r
5applications. The idea is that while every "config" command is different,\r
6at least they're all named the same, and users always see "config" in the\r
7list of standard commands. Also, this is a good place to put common\r
8configure-like tasks: "try to compile this C code", or "figure out where\r
9this header file lives".\r
10"""\r
11\r
12__revision__ = "$Id$"\r
13\r
14import os\r
15import re\r
16\r
17from distutils.core import Command\r
18from distutils.errors import DistutilsExecError\r
19from distutils.ccompiler import customize_compiler\r
20from distutils import log\r
21\r
22LANG_EXT = {'c': '.c', 'c++': '.cxx'}\r
23\r
24class config(Command):\r
25\r
26 description = "prepare to build"\r
27\r
28 user_options = [\r
29 ('compiler=', None,\r
30 "specify the compiler type"),\r
31 ('cc=', None,\r
32 "specify the compiler executable"),\r
33 ('include-dirs=', 'I',\r
34 "list of directories to search for header files"),\r
35 ('define=', 'D',\r
36 "C preprocessor macros to define"),\r
37 ('undef=', 'U',\r
38 "C preprocessor macros to undefine"),\r
39 ('libraries=', 'l',\r
40 "external C libraries to link with"),\r
41 ('library-dirs=', 'L',\r
42 "directories to search for external C libraries"),\r
43\r
44 ('noisy', None,\r
45 "show every action (compile, link, run, ...) taken"),\r
46 ('dump-source', None,\r
47 "dump generated source files before attempting to compile them"),\r
48 ]\r
49\r
50\r
51 # The three standard command methods: since the "config" command\r
52 # does nothing by default, these are empty.\r
53\r
54 def initialize_options(self):\r
55 self.compiler = None\r
56 self.cc = None\r
57 self.include_dirs = None\r
58 self.libraries = None\r
59 self.library_dirs = None\r
60\r
61 # maximal output for now\r
62 self.noisy = 1\r
63 self.dump_source = 1\r
64\r
65 # list of temporary files generated along-the-way that we have\r
66 # to clean at some point\r
67 self.temp_files = []\r
68\r
69 def finalize_options(self):\r
70 if self.include_dirs is None:\r
71 self.include_dirs = self.distribution.include_dirs or []\r
72 elif isinstance(self.include_dirs, str):\r
73 self.include_dirs = self.include_dirs.split(os.pathsep)\r
74\r
75 if self.libraries is None:\r
76 self.libraries = []\r
77 elif isinstance(self.libraries, str):\r
78 self.libraries = [self.libraries]\r
79\r
80 if self.library_dirs is None:\r
81 self.library_dirs = []\r
82 elif isinstance(self.library_dirs, str):\r
83 self.library_dirs = self.library_dirs.split(os.pathsep)\r
84\r
85 def run(self):\r
86 pass\r
87\r
88\r
89 # Utility methods for actual "config" commands. The interfaces are\r
90 # loosely based on Autoconf macros of similar names. Sub-classes\r
91 # may use these freely.\r
92\r
93 def _check_compiler(self):\r
94 """Check that 'self.compiler' really is a CCompiler object;\r
95 if not, make it one.\r
96 """\r
97 # We do this late, and only on-demand, because this is an expensive\r
98 # import.\r
99 from distutils.ccompiler import CCompiler, new_compiler\r
100 if not isinstance(self.compiler, CCompiler):\r
101 self.compiler = new_compiler(compiler=self.compiler,\r
102 dry_run=self.dry_run, force=1)\r
103 customize_compiler(self.compiler)\r
104 if self.include_dirs:\r
105 self.compiler.set_include_dirs(self.include_dirs)\r
106 if self.libraries:\r
107 self.compiler.set_libraries(self.libraries)\r
108 if self.library_dirs:\r
109 self.compiler.set_library_dirs(self.library_dirs)\r
110\r
111\r
112 def _gen_temp_sourcefile(self, body, headers, lang):\r
113 filename = "_configtest" + LANG_EXT[lang]\r
114 file = open(filename, "w")\r
115 if headers:\r
116 for header in headers:\r
117 file.write("#include <%s>\n" % header)\r
118 file.write("\n")\r
119 file.write(body)\r
120 if body[-1] != "\n":\r
121 file.write("\n")\r
122 file.close()\r
123 return filename\r
124\r
125 def _preprocess(self, body, headers, include_dirs, lang):\r
126 src = self._gen_temp_sourcefile(body, headers, lang)\r
127 out = "_configtest.i"\r
128 self.temp_files.extend([src, out])\r
129 self.compiler.preprocess(src, out, include_dirs=include_dirs)\r
130 return (src, out)\r
131\r
132 def _compile(self, body, headers, include_dirs, lang):\r
133 src = self._gen_temp_sourcefile(body, headers, lang)\r
134 if self.dump_source:\r
135 dump_file(src, "compiling '%s':" % src)\r
136 (obj,) = self.compiler.object_filenames([src])\r
137 self.temp_files.extend([src, obj])\r
138 self.compiler.compile([src], include_dirs=include_dirs)\r
139 return (src, obj)\r
140\r
141 def _link(self, body, headers, include_dirs, libraries, library_dirs,\r
142 lang):\r
143 (src, obj) = self._compile(body, headers, include_dirs, lang)\r
144 prog = os.path.splitext(os.path.basename(src))[0]\r
145 self.compiler.link_executable([obj], prog,\r
146 libraries=libraries,\r
147 library_dirs=library_dirs,\r
148 target_lang=lang)\r
149\r
150 if self.compiler.exe_extension is not None:\r
151 prog = prog + self.compiler.exe_extension\r
152 self.temp_files.append(prog)\r
153\r
154 return (src, obj, prog)\r
155\r
156 def _clean(self, *filenames):\r
157 if not filenames:\r
158 filenames = self.temp_files\r
159 self.temp_files = []\r
160 log.info("removing: %s", ' '.join(filenames))\r
161 for filename in filenames:\r
162 try:\r
163 os.remove(filename)\r
164 except OSError:\r
165 pass\r
166\r
167\r
168 # XXX these ignore the dry-run flag: what to do, what to do? even if\r
169 # you want a dry-run build, you still need some sort of configuration\r
170 # info. My inclination is to make it up to the real config command to\r
171 # consult 'dry_run', and assume a default (minimal) configuration if\r
172 # true. The problem with trying to do it here is that you'd have to\r
173 # return either true or false from all the 'try' methods, neither of\r
174 # which is correct.\r
175\r
176 # XXX need access to the header search path and maybe default macros.\r
177\r
178 def try_cpp(self, body=None, headers=None, include_dirs=None, lang="c"):\r
179 """Construct a source file from 'body' (a string containing lines\r
180 of C/C++ code) and 'headers' (a list of header files to include)\r
181 and run it through the preprocessor. Return true if the\r
182 preprocessor succeeded, false if there were any errors.\r
183 ('body' probably isn't of much use, but what the heck.)\r
184 """\r
185 from distutils.ccompiler import CompileError\r
186 self._check_compiler()\r
187 ok = 1\r
188 try:\r
189 self._preprocess(body, headers, include_dirs, lang)\r
190 except CompileError:\r
191 ok = 0\r
192\r
193 self._clean()\r
194 return ok\r
195\r
196 def search_cpp(self, pattern, body=None, headers=None, include_dirs=None,\r
197 lang="c"):\r
198 """Construct a source file (just like 'try_cpp()'), run it through\r
199 the preprocessor, and return true if any line of the output matches\r
200 'pattern'. 'pattern' should either be a compiled regex object or a\r
201 string containing a regex. If both 'body' and 'headers' are None,\r
202 preprocesses an empty file -- which can be useful to determine the\r
203 symbols the preprocessor and compiler set by default.\r
204 """\r
205 self._check_compiler()\r
206 src, out = self._preprocess(body, headers, include_dirs, lang)\r
207\r
208 if isinstance(pattern, str):\r
209 pattern = re.compile(pattern)\r
210\r
211 file = open(out)\r
212 match = 0\r
213 while 1:\r
214 line = file.readline()\r
215 if line == '':\r
216 break\r
217 if pattern.search(line):\r
218 match = 1\r
219 break\r
220\r
221 file.close()\r
222 self._clean()\r
223 return match\r
224\r
225 def try_compile(self, body, headers=None, include_dirs=None, lang="c"):\r
226 """Try to compile a source file built from 'body' and 'headers'.\r
227 Return true on success, false otherwise.\r
228 """\r
229 from distutils.ccompiler import CompileError\r
230 self._check_compiler()\r
231 try:\r
232 self._compile(body, headers, include_dirs, lang)\r
233 ok = 1\r
234 except CompileError:\r
235 ok = 0\r
236\r
237 log.info(ok and "success!" or "failure.")\r
238 self._clean()\r
239 return ok\r
240\r
241 def try_link(self, body, headers=None, include_dirs=None, libraries=None,\r
242 library_dirs=None, lang="c"):\r
243 """Try to compile and link a source file, built from 'body' and\r
244 'headers', to executable form. Return true on success, false\r
245 otherwise.\r
246 """\r
247 from distutils.ccompiler import CompileError, LinkError\r
248 self._check_compiler()\r
249 try:\r
250 self._link(body, headers, include_dirs,\r
251 libraries, library_dirs, lang)\r
252 ok = 1\r
253 except (CompileError, LinkError):\r
254 ok = 0\r
255\r
256 log.info(ok and "success!" or "failure.")\r
257 self._clean()\r
258 return ok\r
259\r
260 def try_run(self, body, headers=None, include_dirs=None, libraries=None,\r
261 library_dirs=None, lang="c"):\r
262 """Try to compile, link to an executable, and run a program\r
263 built from 'body' and 'headers'. Return true on success, false\r
264 otherwise.\r
265 """\r
266 from distutils.ccompiler import CompileError, LinkError\r
267 self._check_compiler()\r
268 try:\r
269 src, obj, exe = self._link(body, headers, include_dirs,\r
270 libraries, library_dirs, lang)\r
271 self.spawn([exe])\r
272 ok = 1\r
273 except (CompileError, LinkError, DistutilsExecError):\r
274 ok = 0\r
275\r
276 log.info(ok and "success!" or "failure.")\r
277 self._clean()\r
278 return ok\r
279\r
280\r
281 # -- High-level methods --------------------------------------------\r
282 # (these are the ones that are actually likely to be useful\r
283 # when implementing a real-world config command!)\r
284\r
285 def check_func(self, func, headers=None, include_dirs=None,\r
286 libraries=None, library_dirs=None, decl=0, call=0):\r
287\r
288 """Determine if function 'func' is available by constructing a\r
289 source file that refers to 'func', and compiles and links it.\r
290 If everything succeeds, returns true; otherwise returns false.\r
291\r
292 The constructed source file starts out by including the header\r
293 files listed in 'headers'. If 'decl' is true, it then declares\r
294 'func' (as "int func()"); you probably shouldn't supply 'headers'\r
295 and set 'decl' true in the same call, or you might get errors about\r
296 a conflicting declarations for 'func'. Finally, the constructed\r
297 'main()' function either references 'func' or (if 'call' is true)\r
298 calls it. 'libraries' and 'library_dirs' are used when\r
299 linking.\r
300 """\r
301\r
302 self._check_compiler()\r
303 body = []\r
304 if decl:\r
305 body.append("int %s ();" % func)\r
306 body.append("int main () {")\r
307 if call:\r
308 body.append(" %s();" % func)\r
309 else:\r
310 body.append(" %s;" % func)\r
311 body.append("}")\r
312 body = "\n".join(body) + "\n"\r
313\r
314 return self.try_link(body, headers, include_dirs,\r
315 libraries, library_dirs)\r
316\r
317 # check_func ()\r
318\r
319 def check_lib(self, library, library_dirs=None, headers=None,\r
320 include_dirs=None, other_libraries=[]):\r
321 """Determine if 'library' is available to be linked against,\r
322 without actually checking that any particular symbols are provided\r
323 by it. 'headers' will be used in constructing the source file to\r
324 be compiled, but the only effect of this is to check if all the\r
325 header files listed are available. Any libraries listed in\r
326 'other_libraries' will be included in the link, in case 'library'\r
327 has symbols that depend on other libraries.\r
328 """\r
329 self._check_compiler()\r
330 return self.try_link("int main (void) { }",\r
331 headers, include_dirs,\r
332 [library]+other_libraries, library_dirs)\r
333\r
334 def check_header(self, header, include_dirs=None, library_dirs=None,\r
335 lang="c"):\r
336 """Determine if the system header file named by 'header_file'\r
337 exists and can be found by the preprocessor; return true if so,\r
338 false otherwise.\r
339 """\r
340 return self.try_cpp(body="/* No body */", headers=[header],\r
341 include_dirs=include_dirs)\r
342\r
343\r
344def dump_file(filename, head=None):\r
345 """Dumps a file content into log.info.\r
346\r
347 If head is not None, will be dumped before the file content.\r
348 """\r
349 if head is None:\r
350 log.info('%s' % filename)\r
351 else:\r
352 log.info(head)\r
353 file = open(filename)\r
354 try:\r
355 log.info(file.read())\r
356 finally:\r
357 file.close()\r