From 5234c4e1118fae1db6934b33cd17683c313ee3f0 Mon Sep 17 00:00:00 2001 From: "Adam C. Emerson" Date: Fri, 4 May 2018 01:31:57 -0400 Subject: [PATCH] build: Allow use of Clang to build Python extensions under Fedora 28 Fedora builds Python with hardening flags that are unsupported by Clang. Python insists on building extensions with all the flags it was given, not just ones relevant to finding Python libraries and includes. Ended up monkey patching customize_compiler to pull out the offending flags when Clang is in use. Signed-off-by: Adam C. Emerson --- src/pybind/cephfs/setup.py | 37 ++++++++++++++++++++++++++-------- src/pybind/rados/setup.py | 37 ++++++++++++++++++++++++++-------- src/pybind/rbd/setup.py | 37 ++++++++++++++++++++++++++-------- src/pybind/rgw/setup.py | 41 +++++++++++++++++++++++++++++--------- 4 files changed, 119 insertions(+), 33 deletions(-) diff --git a/src/pybind/cephfs/setup.py b/src/pybind/cephfs/setup.py index 6533f41ee53..1f95005537c 100755 --- a/src/pybind/cephfs/setup.py +++ b/src/pybind/cephfs/setup.py @@ -9,7 +9,30 @@ import tempfile import textwrap from distutils.ccompiler import new_compiler from distutils.errors import CompileError, LinkError -from distutils.sysconfig import customize_compiler +import distutils.sysconfig + +unwrapped_customize = distutils.sysconfig.customize_compiler + +clang = False + +def filter_unsupported_flags(flags): + if clang: + return [f for f in flags if not (f == '-mcet' or + f.startswith('-fcf-protection'))] + else: + return flags + +def monkey_with_compiler(compiler): + unwrapped_customize(compiler) + if compiler.compiler_type == 'unix': + if compiler.compiler[0].find('clang') != -1: + global clang + clang = True + compiler.compiler = filter_unsupported_flags(compiler.compiler) + compiler.compiler_so = filter_unsupported_flags( + compiler.compiler_so) + +distutils.sysconfig.customize_compiler = monkey_with_compiler if not pkgutil.find_loader('setuptools'): from distutils.core import setup @@ -35,17 +58,15 @@ def get_python_flags(): python_config = python + '-config' - for cflag in subprocess.check_output( - [python_config, "--cflags"] - ).strip().decode('utf-8').split(): + for cflag in filter_unsupported_flags(subprocess.check_output( + [python_config, "--cflags"]).strip().decode('utf-8').split()): if cflag.startswith('-I'): cflags['I'].append(cflag.replace('-I', '')) else: cflags['extras'].append(cflag) - for ldflag in subprocess.check_output( - [python_config, "--ldflags"] - ).strip().decode('utf-8').split(): + for ldflag in filter_unsupported_flags(subprocess.check_output( + [python_config, "--ldflags"]).strip().decode('utf-8').split()): if ldflag.startswith('-l'): ldflags['l'].append(ldflag.replace('-l', '')) if ldflag.startswith('-L'): @@ -86,7 +107,7 @@ def check_sanity(): fp.write(dummy_prog) compiler = new_compiler() - customize_compiler(compiler) + distutils.sysconfig.customize_compiler(compiler) if {'MAKEFLAGS', 'MFLAGS', 'MAKELEVEL'}.issubset(set(os.environ.keys())): # The setup.py has been invoked by a top-level Ceph make. diff --git a/src/pybind/rados/setup.py b/src/pybind/rados/setup.py index ef7c307c737..c708c3e145d 100755 --- a/src/pybind/rados/setup.py +++ b/src/pybind/rados/setup.py @@ -17,7 +17,30 @@ else: from distutils.ccompiler import new_compiler from distutils.errors import CompileError, LinkError -from distutils.sysconfig import customize_compiler +import distutils.sysconfig + +unwrapped_customize = distutils.sysconfig.customize_compiler + +clang = False + +def filter_unsupported_flags(flags): + if clang: + return [f for f in flags if not (f == '-mcet' or + f.startswith('-fcf-protection'))] + else: + return flags + +def monkey_with_compiler(compiler): + unwrapped_customize(compiler) + if compiler.compiler_type == 'unix': + if compiler.compiler[0].find('clang') != -1: + global clang + clang = True + compiler.compiler = filter_unsupported_flags(compiler.compiler) + compiler.compiler_so = filter_unsupported_flags( + compiler.compiler_so) + +distutils.sysconfig.customize_compiler = monkey_with_compiler # PEP 440 versioning of the Rados package on PyPI # Bump this version, after every changeset @@ -35,17 +58,15 @@ def get_python_flags(): python_config = python + '-config' - for cflag in subprocess.check_output( - [python_config, "--cflags"] - ).strip().decode('utf-8').split(): + for cflag in filter_unsupported_flags(subprocess.check_output( + [python_config, "--cflags"]).strip().decode('utf-8').split()): if cflag.startswith('-I'): cflags['I'].append(cflag.replace('-I', '')) else: cflags['extras'].append(cflag) - for ldflag in subprocess.check_output( - [python_config, "--ldflags"] - ).strip().decode('utf-8').split(): + for ldflag in filter_unsupported_flags(subprocess.check_output( + [python_config, "--ldflags"]).strip().decode('utf-8').split()): if ldflag.startswith('-l'): ldflags['l'].append(ldflag.replace('-l', '')) if ldflag.startswith('-L'): @@ -85,7 +106,7 @@ def check_sanity(): fp.write(dummy_prog) compiler = new_compiler() - customize_compiler(compiler) + distutils.sysconfig.customize_compiler(compiler) if {'MAKEFLAGS', 'MFLAGS', 'MAKELEVEL'}.issubset(set(os.environ.keys())): # The setup.py has been invoked by a top-level Ceph make. diff --git a/src/pybind/rbd/setup.py b/src/pybind/rbd/setup.py index bcf96f261cf..8dd5c12a8ec 100755 --- a/src/pybind/rbd/setup.py +++ b/src/pybind/rbd/setup.py @@ -9,7 +9,30 @@ import tempfile import textwrap from distutils.ccompiler import new_compiler from distutils.errors import CompileError, LinkError -from distutils.sysconfig import customize_compiler +import distutils.sysconfig + +unwrapped_customize = distutils.sysconfig.customize_compiler + +clang = False + +def filter_unsupported_flags(flags): + if clang: + return [f for f in flags if not (f == '-mcet' or + f.startswith('-fcf-protection'))] + else: + return flags + +def monkey_with_compiler(compiler): + unwrapped_customize(compiler) + if compiler.compiler_type == 'unix': + if compiler.compiler[0].find('clang') != -1: + global clang + clang = True + compiler.compiler = filter_unsupported_flags(compiler.compiler) + compiler.compiler_so = filter_unsupported_flags( + compiler.compiler_so) + +distutils.sysconfig.customize_compiler = monkey_with_compiler if not pkgutil.find_loader('setuptools'): from distutils.core import setup @@ -35,17 +58,15 @@ def get_python_flags(): python_config = python + '-config' - for cflag in subprocess.check_output( - [python_config, "--cflags"] - ).strip().decode('utf-8').split(): + for cflag in filter_unsupported_flags(subprocess.check_output( + [python_config, "--cflags"]).strip().decode('utf-8').split()): if cflag.startswith('-I'): cflags['I'].append(cflag.replace('-I', '')) else: cflags['extras'].append(cflag) - for ldflag in subprocess.check_output( - [python_config, "--ldflags"] - ).strip().decode('utf-8').split(): + for ldflag in filter_unsupported_flags(subprocess.check_output( + [python_config, "--ldflags"]).strip().decode('utf-8').split()): if ldflag.startswith('-l'): ldflags['l'].append(ldflag.replace('-l', '')) if ldflag.startswith('-L'): @@ -85,7 +106,7 @@ def check_sanity(): fp.write(dummy_prog) compiler = new_compiler() - customize_compiler(compiler) + distutils.sysconfig.customize_compiler(compiler) if {'MAKEFLAGS', 'MFLAGS', 'MAKELEVEL'}.issubset(set(os.environ.keys())): # The setup.py has been invoked by a top-level Ceph make. diff --git a/src/pybind/rgw/setup.py b/src/pybind/rgw/setup.py index f14f30c8966..4ee4f491ba5 100755 --- a/src/pybind/rgw/setup.py +++ b/src/pybind/rgw/setup.py @@ -9,7 +9,33 @@ import tempfile import textwrap from distutils.ccompiler import new_compiler from distutils.errors import CompileError, LinkError -from distutils.sysconfig import customize_compiler +import distutils.sysconfig + +unwrapped_customize = distutils.sysconfig.customize_compiler + +clang = False + +def filter_unsupported_flags(flags): + if clang: + return [f for f in flags if not (f == '-mcet' or + f.startswith('-fcf-protection'))] + return flags + +def monkey_with_compiler(compiler): + unwrapped_customize(compiler) + if compiler.compiler_type == 'unix': + if compiler.compiler[0].find('clang') != -1: + global clang + clang = True + compiler.compiler = filter_unsupported_flags(compiler.compiler) + compiler.compiler_so = filter_unsupported_flags( + compiler.compiler_so) + +# See what you made me do? + +distutils.sysconfig.customize_compiler = monkey_with_compiler + +import distutils.core if not pkgutil.find_loader('setuptools'): from distutils.core import setup @@ -23,7 +49,6 @@ else: __version__ = '2.0.0' - def get_python_flags(): cflags = {'I': [], 'extras': []} ldflags = {'l': [], 'L': [], 'extras': []} @@ -35,17 +60,15 @@ def get_python_flags(): python_config = python + '-config' - for cflag in subprocess.check_output( - [python_config, "--cflags"] - ).strip().decode('utf-8').split(): + for cflag in filter_unsupported_flags(subprocess.check_output( + [python_config, "--cflags"]).strip().decode('utf-8').split()): if cflag.startswith('-I'): cflags['I'].append(cflag.replace('-I', '')) else: cflags['extras'].append(cflag) - for ldflag in subprocess.check_output( - [python_config, "--ldflags"] - ).strip().decode('utf-8').split(): + for ldflag in filter_unsupported_flags(subprocess.check_output( + [python_config, "--ldflags"]).strip().decode('utf-8').split()): if ldflag.startswith('-l'): ldflags['l'].append(ldflag.replace('-l', '')) if ldflag.startswith('-L'): @@ -85,7 +108,7 @@ def check_sanity(): fp.write(dummy_prog) compiler = new_compiler() - customize_compiler(compiler) + distutils.sysconfig.customize_compiler(compiler) if {'MAKEFLAGS', 'MFLAGS', 'MAKELEVEL'}.issubset(set(os.environ.keys())): # The setup.py has been invoked by a top-level Ceph make. -- 2.39.5