From 75e87457da55482ae069a305a19e08e46d4c14e8 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 24 Jul 2020 16:39:43 -0400 Subject: [PATCH 1/5] Add '-stdlib=libc++' so the code can compile on macOS with Anaconda. --- setup.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c308fc1..ad0468b 100755 --- a/setup.py +++ b/setup.py @@ -1,8 +1,15 @@ import os from setuptools import Extension, setup +# '-std=c++11' was added to `extra_compile_args` so the code can compile with clang++. +# '-stdlib=libc++' was added to `extra_compile_args` and `extra_link_args` so the code +# can compile on macOS with Anaconda. extension = Extension( - 'kmeans1d._core', ["kmeans1d/_core.cpp"], extra_compile_args=['-std=c++11']) + 'kmeans1d._core', + ['kmeans1d/_core.cpp'], + extra_compile_args=['-std=c++11', '-stdlib=libc++'], + extra_link_args=['-stdlib=libc++'] +) version_txt = os.path.join(os.path.dirname(__file__), 'kmeans1d', 'version.txt') with open(version_txt, 'r') as f: From ea17674e9871981a26b086d43ba7d132b7c3de42 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 24 Jul 2020 19:06:49 -0400 Subject: [PATCH 2/5] Use custom build extension. To append clang-specific compiler flags. --- setup.py | 57 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/setup.py b/setup.py index ad0468b..24305b8 100755 --- a/setup.py +++ b/setup.py @@ -1,15 +1,29 @@ import os from setuptools import Extension, setup +from setuptools.command.build_ext import build_ext -# '-std=c++11' was added to `extra_compile_args` so the code can compile with clang++. -# '-stdlib=libc++' was added to `extra_compile_args` and `extra_link_args` so the code -# can compile on macOS with Anaconda. -extension = Extension( - 'kmeans1d._core', - ['kmeans1d/_core.cpp'], - extra_compile_args=['-std=c++11', '-stdlib=libc++'], - extra_link_args=['-stdlib=libc++'] -) + +class BuildExt(build_ext): + """A custom build extension for adding -std and -stdlib arguments for clang++.""" + def is_using_clang(self): + cxx = self.compiler.compiler_cxx[0] + if 'clang' in cxx: + return True + # TODO: check if 'cxx' points to clang++. + return False + + def build_extensions(self): + if self.is_using_clang(): + for extension in self.extensions: + # '-std=c++11' is added to `extra_compile_args` so the code can compile + # with clang++. '-stdlib=libc++' is added to `extra_compile_args` and + # `extra_link_args` so the code can compile on macOS with Anaconda. + extension.extra_compile_args.extend(('-std=c++11', '-stdlib=libc++')) + extension.extra_link_args.append('-stdlib=libc++') + build_ext.build_extensions(self) + + +extension = Extension('kmeans1d._core', ['kmeans1d/_core.cpp']) version_txt = os.path.join(os.path.dirname(__file__), 'kmeans1d', 'version.txt') with open(version_txt, 'r') as f: @@ -19,19 +33,20 @@ author='Daniel Steinberg', author_email='ds@dannyadam.com', classifiers=[ - 'Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'Intended Audience :: Science/Research', - 'Topic :: Scientific/Engineering', - 'Topic :: Scientific/Engineering :: Artificial Intelligence', - 'Topic :: Scientific/Engineering :: Information Analysis', - 'License :: OSI Approved :: MIT License', - 'Operating System :: Unix', - 'Operating System :: POSIX :: Linux', - 'Operating System :: MacOS', - 'Operating System :: Microsoft :: Windows', - 'Programming Language :: Python :: 3', + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'Intended Audience :: Science/Research', + 'Topic :: Scientific/Engineering', + 'Topic :: Scientific/Engineering :: Artificial Intelligence', + 'Topic :: Scientific/Engineering :: Information Analysis', + 'License :: OSI Approved :: MIT License', + 'Operating System :: Unix', + 'Operating System :: POSIX :: Linux', + 'Operating System :: MacOS', + 'Operating System :: Microsoft :: Windows', + 'Programming Language :: Python :: 3', ], + cmdclass={'build_ext': BuildExt}, description='A Python package for optimal 1D k-means clustering', ext_modules=[extension], keywords=['k-means', 'machine learning', 'optimization'], From d1ed10235bf46991522a9053fbf600683a398bd0 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 25 Jul 2020 16:33:31 -0400 Subject: [PATCH 3/5] Add extra compile/link args if build fails. --- setup.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/setup.py b/setup.py index 24305b8..062a86d 100755 --- a/setup.py +++ b/setup.py @@ -1,26 +1,27 @@ import os +import setuptools from setuptools import Extension, setup from setuptools.command.build_ext import build_ext class BuildExt(build_ext): - """A custom build extension for adding -std and -stdlib arguments for clang++.""" - def is_using_clang(self): - cxx = self.compiler.compiler_cxx[0] - if 'clang' in cxx: - return True - # TODO: check if 'cxx' points to clang++. - return False + """A custom build extension for adding -stdlib arguments for clang++.""" def build_extensions(self): - if self.is_using_clang(): + # '-std=c++11' is added to `extra_compile_args` so the code can compile + # with clang++. This works across compilers (ignored by MSVC). + for extension in self.extensions: + extension.extra_compile_args.append('-std=c++11') + + try: + build_ext.build_extensions(self) + except setuptools.distutils.errors.CompileError: + # '-stdlib=libc++' is added to `extra_compile_args` and `extra_link_args` + # so the code can compile on macOS with Anaconda. for extension in self.extensions: - # '-std=c++11' is added to `extra_compile_args` so the code can compile - # with clang++. '-stdlib=libc++' is added to `extra_compile_args` and - # `extra_link_args` so the code can compile on macOS with Anaconda. - extension.extra_compile_args.extend(('-std=c++11', '-stdlib=libc++')) + extension.extra_compile_args.append('-stdlib=libc++') extension.extra_link_args.append('-stdlib=libc++') - build_ext.build_extensions(self) + build_ext.build_extensions(self) extension = Extension('kmeans1d._core', ['kmeans1d/_core.cpp']) From 6f5f69a7949b77d4102ac0275e3a86fccb648eb2 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 25 Jul 2020 16:37:00 -0400 Subject: [PATCH 4/5] Add Issue number to comment. --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 062a86d..ad9be5b 100755 --- a/setup.py +++ b/setup.py @@ -16,6 +16,7 @@ def build_extensions(self): try: build_ext.build_extensions(self) except setuptools.distutils.errors.CompileError: + # Workaround Issue #2. # '-stdlib=libc++' is added to `extra_compile_args` and `extra_link_args` # so the code can compile on macOS with Anaconda. for extension in self.extensions: From 20941e9fa24356d839583079cb872498efa84237 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 25 Jul 2020 16:39:49 -0400 Subject: [PATCH 5/5] Increase version. --- kmeans1d/version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmeans1d/version.txt b/kmeans1d/version.txt index 0ea3a94..0d91a54 100644 --- a/kmeans1d/version.txt +++ b/kmeans1d/version.txt @@ -1 +1 @@ -0.2.0 +0.3.0