setup.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. from os import getenv, path
  2. from subprocess import Popen, PIPE
  3. from re import sub
  4. import shlex
  5. cc = getenv("CC")
  6. assert cc, "Environment variable CC not set"
  7. # Check if CC has options, as is the case in yocto, where it uses CC="cc --sysroot..."
  8. cc_tokens = cc.split()
  9. if len(cc_tokens) > 1:
  10. cc = cc_tokens[0]
  11. cc_options = " ".join([str(e) for e in cc_tokens[1:]]) + " "
  12. else:
  13. cc_options = ""
  14. # ignore optional stderr could be None as it is set to PIPE to avoid that.
  15. # mypy: disable-error-code="union-attr"
  16. cc_is_clang = b"clang version" in Popen([cc, "-v"], stderr=PIPE).stderr.readline()
  17. srctree = getenv('srctree')
  18. assert srctree, "Environment variable srctree, for the Linux sources, not set"
  19. src_feature_tests = f'{srctree}/tools/build/feature'
  20. def clang_has_option(option):
  21. error_substrings = (
  22. b"unknown argument",
  23. b"is not supported",
  24. b"unknown warning option"
  25. )
  26. cmd = shlex.split(f"{cc} {cc_options} {option}") + [
  27. "-o", "/dev/null",
  28. path.join(src_feature_tests, "test-hello.c")
  29. ]
  30. cc_output = Popen(cmd, stderr=PIPE).stderr.readlines()
  31. return not any(any(error in line for error in error_substrings) for line in cc_output)
  32. if cc_is_clang:
  33. from sysconfig import get_config_vars
  34. vars = get_config_vars()
  35. for var in ('CFLAGS', 'OPT'):
  36. vars[var] = sub("-specs=[^ ]+", "", vars[var])
  37. if not clang_has_option("-mcet"):
  38. vars[var] = sub("-mcet", "", vars[var])
  39. if not clang_has_option("-fcf-protection"):
  40. vars[var] = sub("-fcf-protection", "", vars[var])
  41. if not clang_has_option("-fstack-clash-protection"):
  42. vars[var] = sub("-fstack-clash-protection", "", vars[var])
  43. if not clang_has_option("-fstack-protector-strong"):
  44. vars[var] = sub("-fstack-protector-strong", "", vars[var])
  45. if not clang_has_option("-fno-semantic-interposition"):
  46. vars[var] = sub("-fno-semantic-interposition", "", vars[var])
  47. if not clang_has_option("-ffat-lto-objects"):
  48. vars[var] = sub("-ffat-lto-objects", "", vars[var])
  49. if not clang_has_option("-ftree-loop-distribute-patterns"):
  50. vars[var] = sub("-ftree-loop-distribute-patterns", "", vars[var])
  51. if not clang_has_option("-gno-variable-location-views"):
  52. vars[var] = sub("-gno-variable-location-views", "", vars[var])
  53. from setuptools import setup, Extension
  54. from setuptools.command.build_ext import build_ext as _build_ext
  55. from setuptools.command.install_lib import install_lib as _install_lib
  56. class build_ext(_build_ext):
  57. def finalize_options(self):
  58. _build_ext.finalize_options(self)
  59. self.build_lib = build_lib
  60. self.build_temp = build_tmp
  61. class install_lib(_install_lib):
  62. def finalize_options(self):
  63. _install_lib.finalize_options(self)
  64. self.build_dir = build_lib
  65. cflags = getenv('CFLAGS', '').split()
  66. # switch off several checks (need to be at the end of cflags list)
  67. cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter', '-Wno-redundant-decls' ]
  68. if cc_is_clang:
  69. cflags += ["-Wno-unused-command-line-argument" ]
  70. if clang_has_option("-Wno-cast-function-type-mismatch"):
  71. cflags += ["-Wno-cast-function-type-mismatch" ]
  72. else:
  73. cflags += ['-Wno-cast-function-type' ]
  74. # The python headers have mixed code with declarations (decls after asserts, for instance)
  75. cflags += [ "-Wno-declaration-after-statement" ]
  76. src_perf = f'{srctree}/tools/perf'
  77. build_lib = getenv('PYTHON_EXTBUILD_LIB')
  78. build_tmp = getenv('PYTHON_EXTBUILD_TMP')
  79. perf = Extension('perf',
  80. sources = [ src_perf + '/util/python.c' ],
  81. include_dirs = ['util/include'],
  82. extra_compile_args = cflags,
  83. )
  84. setup(name='perf',
  85. version='0.1',
  86. description='Interface with the Linux profiling infrastructure',
  87. author='Arnaldo Carvalho de Melo',
  88. author_email='acme@redhat.com',
  89. license='GPLv2',
  90. url='http://perf.wiki.kernel.org',
  91. ext_modules=[perf],
  92. cmdclass={'build_ext': build_ext, 'install_lib': install_lib})