diff --git a/setup.py b/setup.py index c0b72c6..035551b 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,10 @@ from distutils.core import setup + +import setuptools from Cython.Build import cythonize from distutils.extension import Extension +from setuptools.command.build_ext import build_ext +import sys import numpy sourcefiles = ['src/sent2vec.pyx', @@ -24,7 +28,73 @@ include_dirs=[numpy.get_include()], libraries=['rt'])] +def has_flag(compiler, flags): + """Return a boolean indicating whether a flag name is supported on + the specified compiler. + """ + import tempfile + with tempfile.NamedTemporaryFile('w', suffix='.cpp') as f: + f.write('int main (int argc, char **argv) { return 0; }') + try: + compiler.compile([f.name], extra_postargs=flags) + except setuptools.distutils.errors.CompileError: + return False + return True + + +def cpp_flag(compiler): + """Return the -std=c++[0x/11/14] compiler flag. + The c++14 is preferred over c++0x/11 (when it is available). + """ + standards = ['-std=c++14', '-std=c++11', '-std=c++0x'] + for standard in standards: + if has_flag(compiler, [standard]): + return standard + raise RuntimeError( + 'Unsupported compiler -- at least C++0x support ' + 'is needed!' + ) + + +class BuildExt(build_ext): + """A custom build extension for adding compiler-specific options.""" + c_opts = { + 'msvc': ['/EHsc'], + 'unix': [], + } + + def build_extensions(self): + if sys.platform == 'darwin': + all_flags = ['-stdlib=libc++', '-mmacosx-version-min=10.7'] + if has_flag(self.compiler, [all_flags[0]]): + self.c_opts['unix'] += [all_flags[0]] + elif has_flag(self.compiler, all_flags): + self.c_opts['unix'] += all_flags + else: + raise RuntimeError( + 'libc++ is needed! Failed to compile with {} and {}.'. + format(" ".join(all_flags), all_flags[0]) + ) + ct = self.compiler.compiler_type + opts = self.c_opts.get(ct, []) + if ct == 'unix': + opts.append('-DVERSION_INFO="%s"' % self.distribution.get_version()) + opts.append(cpp_flag(self.compiler)) + if has_flag(self.compiler, ['-fvisibility=hidden']): + opts.append('-fvisibility=hidden') + elif ct == 'msvc': + opts.append( + '/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version() + ) + for ext in self.extensions: + ext.extra_compile_args = opts + if sys.platform == 'darwin': + ext.libraries.remove('rt') + build_ext.build_extensions(self) + + setup( name='sent2vec', - ext_modules=cythonize(ext) + ext_modules=cythonize(ext), + cmdclass={'build_ext': BuildExt} )