Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NF: generate config.pxi file with Cython DEF vars #445

Merged
merged 1 commit into from Oct 11, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -113,7 +113,7 @@ def package_check(*args, **kwargs):
# up pyx and c files.
build_ext = cyproc_exts(EXTS, CYTHON_MIN_VERSION, 'pyx-stamps')
# Add openmp flags if they work
extbuilder = add_flag_checking(build_ext, ['-fopenmp'])
extbuilder = add_flag_checking(build_ext, [('-fopenmp', 'HAVE_OPENMP')])

# Installer that checks for install-time dependencies
class installer(install.install):
Expand Down
45 changes: 37 additions & 8 deletions setup_helpers.py
Expand Up @@ -2,7 +2,7 @@

'''
import os
from os.path import join as pjoin, split as psplit, splitext
from os.path import join as pjoin, split as psplit, splitext, dirname, exists
import tempfile
import shutil

Expand All @@ -27,6 +27,10 @@
call %py_exe% %pyscript% %*
"""

# File to which to write Cython conditional DEF vars
CONFIG_PXI = pjoin('build', 'config.pxi')


class install_scripts_bat(install_scripts):
""" Make scripts executable on Windows

Expand Down Expand Up @@ -81,8 +85,13 @@ def add_flag_checking(build_ext_class, input_flags):
Class implementing ``distutils.command.build_ext.build_ext`` interface,
with a ``build_extensions`` method.
input_flags : sequence
A sequence of compiler flags. We check each to see whether a simple C
source file will compile, and omit flags that cause a compile error
A sequence of elements, where the elements can be ``str`` with
a compiler flag or a tuple containing (<compiler flag>, <defvar>). We
check each compiler flag to see whether a simple C source file will
compile, and omit flags that cause a compile error. If the element is
a tuple, then <defvar> is the name of Cython variable to be defined in
``build/config.pxi`` with True if `input_flags` will compile, False
otherwise. If None, do not write variable.

Returns
-------
Expand Down Expand Up @@ -119,14 +128,34 @@ def can_compile_link(self, flags):

def build_extensions(self):
""" Hook into extension building to check compiler flags """
for flag in self.flags:
if not self.can_compile_link([flag]):
def_vars = []
good_flags = []
config_dir = dirname(CONFIG_PXI)
for element in self.flags:
if isinstance(element, (tuple, list)):
flag, def_var = element
else:
flag, def_var = element, None
flag_good = self.can_compile_link([flag])
if def_var:
def_vars.append('DEF {0} = {1}'.format(def_var, flag_good))
if flag_good:
good_flags.append(flag)
else:
log.warn("Flag {0} omitted because of compile or link "
"error".format(flag))
continue
if def_vars:
if not exists(config_dir):
os.mkdir(config_dir)
with open(CONFIG_PXI, 'wt') as fobj:
fobj.write('# Automatically generated; do not edit\n')
fobj.write('\n'.join(def_vars))
if def_vars or good_flags:
for ext in self.extensions:
ext.extra_compile_args.append(flag)
ext.extra_link_args.append(flag)
ext.extra_compile_args += good_flags
ext.extra_link_args += good_flags
if def_vars:
ext.include_dirs.append(config_dir)
build_ext_class.build_extensions(self)

return Checker