unixccompiler.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. """
  2. unixccompiler - can handle very long argument lists for ar.
  3. """
  4. from __future__ import division, absolute_import, print_function
  5. import os
  6. from distutils.errors import DistutilsExecError, CompileError
  7. from distutils.unixccompiler import *
  8. from numpy.distutils.ccompiler import replace_method
  9. from numpy.distutils.compat import get_exception
  10. if sys.version_info[0] < 3:
  11. from . import log
  12. else:
  13. from numpy.distutils import log
  14. # Note that UnixCCompiler._compile appeared in Python 2.3
  15. def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
  16. """Compile a single source files with a Unix-style compiler."""
  17. # HP ad-hoc fix, see ticket 1383
  18. ccomp = self.compiler_so
  19. if ccomp[0] == 'aCC':
  20. # remove flags that will trigger ANSI-C mode for aCC
  21. if '-Ae' in ccomp:
  22. ccomp.remove('-Ae')
  23. if '-Aa' in ccomp:
  24. ccomp.remove('-Aa')
  25. # add flags for (almost) sane C++ handling
  26. ccomp += ['-AA']
  27. self.compiler_so = ccomp
  28. # ensure OPT environment variable is read
  29. if 'OPT' in os.environ:
  30. from distutils.sysconfig import get_config_vars
  31. opt = " ".join(os.environ['OPT'].split())
  32. gcv_opt = " ".join(get_config_vars('OPT')[0].split())
  33. ccomp_s = " ".join(self.compiler_so)
  34. if opt not in ccomp_s:
  35. ccomp_s = ccomp_s.replace(gcv_opt, opt)
  36. self.compiler_so = ccomp_s.split()
  37. llink_s = " ".join(self.linker_so)
  38. if opt not in llink_s:
  39. self.linker_so = llink_s.split() + opt.split()
  40. display = '%s: %s' % (os.path.basename(self.compiler_so[0]), src)
  41. try:
  42. self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
  43. extra_postargs, display = display)
  44. except DistutilsExecError:
  45. msg = str(get_exception())
  46. raise CompileError(msg)
  47. replace_method(UnixCCompiler, '_compile', UnixCCompiler__compile)
  48. def UnixCCompiler_create_static_lib(self, objects, output_libname,
  49. output_dir=None, debug=0, target_lang=None):
  50. """
  51. Build a static library in a separate sub-process.
  52. Parameters
  53. ----------
  54. objects : list or tuple of str
  55. List of paths to object files used to build the static library.
  56. output_libname : str
  57. The library name as an absolute or relative (if `output_dir` is used)
  58. path.
  59. output_dir : str, optional
  60. The path to the output directory. Default is None, in which case
  61. the ``output_dir`` attribute of the UnixCCompiler instance.
  62. debug : bool, optional
  63. This parameter is not used.
  64. target_lang : str, optional
  65. This parameter is not used.
  66. Returns
  67. -------
  68. None
  69. """
  70. objects, output_dir = self._fix_object_args(objects, output_dir)
  71. output_filename = \
  72. self.library_filename(output_libname, output_dir=output_dir)
  73. if self._need_link(objects, output_filename):
  74. try:
  75. # previous .a may be screwed up; best to remove it first
  76. # and recreate.
  77. # Also, ar on OS X doesn't handle updating universal archives
  78. os.unlink(output_filename)
  79. except (IOError, OSError):
  80. pass
  81. self.mkpath(os.path.dirname(output_filename))
  82. tmp_objects = objects + self.objects
  83. while tmp_objects:
  84. objects = tmp_objects[:50]
  85. tmp_objects = tmp_objects[50:]
  86. display = '%s: adding %d object files to %s' % (
  87. os.path.basename(self.archiver[0]),
  88. len(objects), output_filename)
  89. self.spawn(self.archiver + [output_filename] + objects,
  90. display = display)
  91. # Not many Unices required ranlib anymore -- SunOS 4.x is, I
  92. # think the only major Unix that does. Maybe we need some
  93. # platform intelligence here to skip ranlib if it's not
  94. # needed -- or maybe Python's configure script took care of
  95. # it for us, hence the check for leading colon.
  96. if self.ranlib:
  97. display = '%s:@ %s' % (os.path.basename(self.ranlib[0]),
  98. output_filename)
  99. try:
  100. self.spawn(self.ranlib + [output_filename],
  101. display = display)
  102. except DistutilsExecError:
  103. msg = str(get_exception())
  104. raise LibError(msg)
  105. else:
  106. log.debug("skipping %s (up-to-date)", output_filename)
  107. return
  108. replace_method(UnixCCompiler, 'create_static_lib',
  109. UnixCCompiler_create_static_lib)