162306a36Sopenharmony_cifrom os import getenv, path
262306a36Sopenharmony_cifrom subprocess import Popen, PIPE
362306a36Sopenharmony_cifrom re import sub
462306a36Sopenharmony_ci
562306a36Sopenharmony_cicc = getenv("CC")
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci# Check if CC has options, as is the case in yocto, where it uses CC="cc --sysroot..."
862306a36Sopenharmony_cicc_tokens = cc.split()
962306a36Sopenharmony_ciif len(cc_tokens) > 1:
1062306a36Sopenharmony_ci    cc = cc_tokens[0]
1162306a36Sopenharmony_ci    cc_options = " ".join([str(e) for e in cc_tokens[1:]]) + " "
1262306a36Sopenharmony_cielse:
1362306a36Sopenharmony_ci    cc_options = ""
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cicc_is_clang = b"clang version" in Popen([cc, "-v"], stderr=PIPE).stderr.readline()
1662306a36Sopenharmony_cisrc_feature_tests  = getenv('srctree') + '/tools/build/feature'
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cidef clang_has_option(option):
1962306a36Sopenharmony_ci    cc_output = Popen([cc, cc_options + option, path.join(src_feature_tests, "test-hello.c") ], stderr=PIPE).stderr.readlines()
2062306a36Sopenharmony_ci    return [o for o in cc_output if ((b"unknown argument" in o) or (b"is not supported" in o))] == [ ]
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ciif cc_is_clang:
2362306a36Sopenharmony_ci    from sysconfig import get_config_vars
2462306a36Sopenharmony_ci    vars = get_config_vars()
2562306a36Sopenharmony_ci    for var in ('CFLAGS', 'OPT'):
2662306a36Sopenharmony_ci        vars[var] = sub("-specs=[^ ]+", "", vars[var])
2762306a36Sopenharmony_ci        if not clang_has_option("-mcet"):
2862306a36Sopenharmony_ci            vars[var] = sub("-mcet", "", vars[var])
2962306a36Sopenharmony_ci        if not clang_has_option("-fcf-protection"):
3062306a36Sopenharmony_ci            vars[var] = sub("-fcf-protection", "", vars[var])
3162306a36Sopenharmony_ci        if not clang_has_option("-fstack-clash-protection"):
3262306a36Sopenharmony_ci            vars[var] = sub("-fstack-clash-protection", "", vars[var])
3362306a36Sopenharmony_ci        if not clang_has_option("-fstack-protector-strong"):
3462306a36Sopenharmony_ci            vars[var] = sub("-fstack-protector-strong", "", vars[var])
3562306a36Sopenharmony_ci        if not clang_has_option("-fno-semantic-interposition"):
3662306a36Sopenharmony_ci            vars[var] = sub("-fno-semantic-interposition", "", vars[var])
3762306a36Sopenharmony_ci        if not clang_has_option("-ffat-lto-objects"):
3862306a36Sopenharmony_ci            vars[var] = sub("-ffat-lto-objects", "", vars[var])
3962306a36Sopenharmony_ci        if not clang_has_option("-ftree-loop-distribute-patterns"):
4062306a36Sopenharmony_ci            vars[var] = sub("-ftree-loop-distribute-patterns", "", vars[var])
4162306a36Sopenharmony_ci        if not clang_has_option("-gno-variable-location-views"):
4262306a36Sopenharmony_ci            vars[var] = sub("-gno-variable-location-views", "", vars[var])
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cifrom setuptools import setup, Extension
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cifrom setuptools.command.build_ext   import build_ext   as _build_ext
4762306a36Sopenharmony_cifrom setuptools.command.install_lib import install_lib as _install_lib
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ciclass build_ext(_build_ext):
5062306a36Sopenharmony_ci    def finalize_options(self):
5162306a36Sopenharmony_ci        _build_ext.finalize_options(self)
5262306a36Sopenharmony_ci        self.build_lib  = build_lib
5362306a36Sopenharmony_ci        self.build_temp = build_tmp
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ciclass install_lib(_install_lib):
5662306a36Sopenharmony_ci    def finalize_options(self):
5762306a36Sopenharmony_ci        _install_lib.finalize_options(self)
5862306a36Sopenharmony_ci        self.build_dir = build_lib
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cicflags = getenv('CFLAGS', '').split()
6262306a36Sopenharmony_ci# switch off several checks (need to be at the end of cflags list)
6362306a36Sopenharmony_cicflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter', '-Wno-redundant-decls', '-DPYTHON_PERF' ]
6462306a36Sopenharmony_ciif cc_is_clang:
6562306a36Sopenharmony_ci    cflags += ["-Wno-unused-command-line-argument" ]
6662306a36Sopenharmony_cielse:
6762306a36Sopenharmony_ci    cflags += ['-Wno-cast-function-type' ]
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci# The python headers have mixed code with declarations (decls after asserts, for instance)
7062306a36Sopenharmony_cicflags += [ "-Wno-declaration-after-statement" ]
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_cisrc_perf  = getenv('srctree') + '/tools/perf'
7362306a36Sopenharmony_cibuild_lib = getenv('PYTHON_EXTBUILD_LIB')
7462306a36Sopenharmony_cibuild_tmp = getenv('PYTHON_EXTBUILD_TMP')
7562306a36Sopenharmony_cilibtraceevent = getenv('LIBTRACEEVENT')
7662306a36Sopenharmony_cilibapikfs = getenv('LIBAPI')
7762306a36Sopenharmony_cilibperf = getenv('LIBPERF')
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ciext_sources = [f.strip() for f in open('util/python-ext-sources')
8062306a36Sopenharmony_ci				if len(f.strip()) > 0 and f[0] != '#']
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ciextra_libraries = []
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ciif '-DHAVE_LIBTRACEEVENT' in cflags:
8562306a36Sopenharmony_ci    extra_libraries += [ 'traceevent' ]
8662306a36Sopenharmony_cielse:
8762306a36Sopenharmony_ci    ext_sources.remove('util/trace-event.c')
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci# use full paths with source files
9062306a36Sopenharmony_ciext_sources = list(map(lambda x: '%s/%s' % (src_perf, x) , ext_sources))
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ciif '-DHAVE_LIBNUMA_SUPPORT' in cflags:
9362306a36Sopenharmony_ci    extra_libraries += [ 'numa' ]
9462306a36Sopenharmony_ciif '-DHAVE_LIBCAP_SUPPORT' in cflags:
9562306a36Sopenharmony_ci    extra_libraries += [ 'cap' ]
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ciperf = Extension('perf',
9862306a36Sopenharmony_ci		  sources = ext_sources,
9962306a36Sopenharmony_ci		  include_dirs = ['util/include'],
10062306a36Sopenharmony_ci		  libraries = extra_libraries,
10162306a36Sopenharmony_ci		  extra_compile_args = cflags,
10262306a36Sopenharmony_ci		  extra_objects = [ x for x in [libtraceevent, libapikfs, libperf]
10362306a36Sopenharmony_ci                                    if x is not None],
10462306a36Sopenharmony_ci                 )
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cisetup(name='perf',
10762306a36Sopenharmony_ci      version='0.1',
10862306a36Sopenharmony_ci      description='Interface with the Linux profiling infrastructure',
10962306a36Sopenharmony_ci      author='Arnaldo Carvalho de Melo',
11062306a36Sopenharmony_ci      author_email='acme@redhat.com',
11162306a36Sopenharmony_ci      license='GPLv2',
11262306a36Sopenharmony_ci      url='http://perf.wiki.kernel.org',
11362306a36Sopenharmony_ci      ext_modules=[perf],
11462306a36Sopenharmony_ci      cmdclass={'build_ext': build_ext, 'install_lib': install_lib})
115