From c2c4c493cc109a40284af90962b58989aae2ae8c Mon Sep 17 00:00:00 2001 From: Chen Feng Date: Wed, 25 Sep 2019 02:45:02 -0400 Subject: [PATCH] improved setup.py to make it more easy to install from source for both Linux/Mac/Windows. --- python/pyAprilTag/__init__.py | 1 + python/pyAprilTag/demo_calib.py | 2 +- python/pyAprilTag/demo_calib_by_photo.py | 4 +- setup.py | 107 +++++++++++++---------- 4 files changed, 66 insertions(+), 48 deletions(-) diff --git a/python/pyAprilTag/__init__.py b/python/pyAprilTag/__init__.py index b2f0938..ca2360c 100644 --- a/python/pyAprilTag/__init__.py +++ b/python/pyAprilTag/__init__.py @@ -1,5 +1,6 @@ import os from pyAprilTag._apriltag import * + calib_pattern_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data", "calib_pattern_Tag36h11.png") calib_example_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data", "calib") diff --git a/python/pyAprilTag/demo_calib.py b/python/pyAprilTag/demo_calib.py index 6ba3f15..64f0859 100644 --- a/python/pyAprilTag/demo_calib.py +++ b/python/pyAprilTag/demo_calib.py @@ -17,7 +17,7 @@ print('no calibration log available!') exit(-1) -last_log = os.path.relpath(os.path.join(LOG_DIR, logs[-1])).replace('\\','.')[:-3] +last_log = os.path.relpath(os.path.join(LOG_DIR, logs[-1])).replace(os.path.sep,'.')[:-3] calib = importlib.import_module(last_log) print('last log: '+last_log) print('camera intrinsic matrix:') diff --git a/python/pyAprilTag/demo_calib_by_photo.py b/python/pyAprilTag/demo_calib_by_photo.py index 838c115..31a2d1c 100644 --- a/python/pyAprilTag/demo_calib_by_photo.py +++ b/python/pyAprilTag/demo_calib_by_photo.py @@ -8,7 +8,7 @@ if not os.path.exists(LOG_DIR): os.makedirs(LOG_DIR) pyAprilTag.calib(pyAprilTag.calib_pattern_path, - 'photo://{}\*.png'.format(pyAprilTag.calib_example_dir), + 'photo://{}'.format(os.path.join(pyAprilTag.calib_example_dir, '*.png')), log_dir=LOG_DIR, nDistCoeffs=4) import importlib @@ -17,7 +17,7 @@ print('no calibration log available!') exit(-1) -last_log = os.path.relpath(os.path.join(LOG_DIR, logs[-1])).replace('\\','.')[:-3] +last_log = os.path.relpath(os.path.join(LOG_DIR, logs[-1])).replace(os.path.sep,'.')[:-3] calib = importlib.import_module(last_log) print('last log: '+last_log) print('camera intrinsic matrix:') diff --git a/setup.py b/setup.py index 6ab1767..b36d52b 100644 --- a/setup.py +++ b/setup.py @@ -1,9 +1,9 @@ import os +import sys import glob import platform import numpy as np -# from distutils.core import setup, Extension -from setuptools import setup, Extension, find_packages +from setuptools import setup, Extension from Cython.Build import cythonize from Cython.Distutils import build_ext @@ -14,54 +14,71 @@ ``` """ +# Avoid a gcc warning below: +# cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid +# for C/ObjC but not for C++ +class BuildExt(build_ext): + def build_extensions(self): + if '-Wstrict-prototypes' in self.compiler.compiler_so: + self.compiler.compiler_so.remove('-Wstrict-prototypes') + super().build_extensions() + # Determine current directory of this setup file to find our module CUR_DIR = os.path.dirname(__file__) -sys_name = platform.system() -if sys_name == 'Linux': - opencv_libs = glob.glob('/usr/local/lib/libopencv*.so') - opencv_incs = ['/usr/local/include/'] +self_incs = [os.path.join(CUR_DIR, 'src'), + os.path.join(CUR_DIR, 'src/cv2cg/include'), + os.path.join(CUR_DIR, 'src/cv2cg/3rdparty/lch/include')] -elif sys_name=='Windows': - opencv_libs_str = 'C:/lib/build/vs2017_x64/opencv347_minimal/install/x64/vc15/lib/opencv_world347.lib' - opencv_incs_str = 'C:/lib/build/vs2017_x64/opencv347_minimal/install/include' - # Parse into usable format for Extension call - opencv_libs = [str(lib) for lib in opencv_libs_str.strip().split()] - opencv_incs = [str(inc) for inc in opencv_incs_str.strip().split()] +required_opencv_modules = ['opencv_'+it for it in + 'calib3d core features2d highgui imgcodecs imgproc videoio world'.split(' ')] - #copy *.dll to local - bin_dir = os.path.join(os.path.dirname(opencv_libs_str), '..', 'bin') - opencv_bins = [os.path.join(bin_dir, f) for f in os.listdir(bin_dir) if f.endswith('.dll')] - bin_dest = os.path.join(CUR_DIR, 'python', 'pyAprilTag') - [os.system('copy "{}" {}'.format(f, bin_dest)) for f in opencv_bins] +def get_conda_opencv_info(sys_name): + try: + import cv2 + except ImportError as e: + print(str(e)) + print('Please install opencv for python in your current Anaconda environment via the following:\n' + 'conda install -c conda-forge opencv') + exit(-1) -elif sys_name=='Darwin': #Mac - raise NotImplementedError( - "Mac users: you need to set the opencv_libs and opencv_incs accordingly!" - ) + if sys_name == 'Linux': + opencv_lib_dir = os.path.abspath(os.path.join(os.path.dirname(cv2.__file__), *(['..'] * 2))) + available_opencv_libs = glob.glob(os.path.join(opencv_lib_dir, 'libopencv*.so')) + elif sys_name == 'Darwin': + opencv_lib_dir = os.path.abspath(os.path.join(os.path.dirname(cv2.__file__), *(['..'] * 2))) + available_opencv_libs = glob.glob(os.path.join(opencv_lib_dir, 'libopencv*.dylib')) + else: #sys_name=='Windows' + opencv_lib_dir = os.path.abspath(os.path.join(os.path.dirname(cv2.__file__), *['..'] * 2, 'Library', 'lib')) + available_opencv_libs = glob.glob(os.path.join(opencv_lib_dir, 'opencv*.lib')) -for it in opencv_incs+opencv_libs: - assert(os.path.exists(it)) + opencv_inc_dir = os.path.abspath(os.path.join(opencv_lib_dir, '..', 'include')) + assert(os.path.exists(opencv_lib_dir)) + assert(os.path.exists(opencv_inc_dir)) + assert(os.path.exists(os.path.join(opencv_inc_dir, 'opencv2'))) -self_incs = [os.path.join(CUR_DIR, 'src'), - os.path.join(CUR_DIR, 'src/cv2cg/include'), - os.path.join(CUR_DIR, 'src/cv2cg/3rdparty/lch/include')] + assert(any(available_opencv_libs)) + available_opencv_libs = [os.path.splitext(os.path.basename(it))[0].lstrip('lib') + for it in available_opencv_libs] + + opencv_libs = [lib for lib in required_opencv_modules if lib in available_opencv_libs] + return opencv_lib_dir, opencv_inc_dir, opencv_libs + +sys_name = platform.system() +opencv_lib_dir, opencv_inc_dir, opencv_libs = get_conda_opencv_info(sys_name) +# print(opencv_lib_dir) +# print(opencv_inc_dir) +# print(opencv_libs) -if sys_name == 'Linux' or sys_name == 'Darwin': - extensions = [ - Extension('pyAprilTag._apriltag', - sources=[os.path.join(CUR_DIR, '_cy_apriltag.pyx')], - language='c++', - include_dirs=[np.get_include()] + opencv_incs + self_incs, - extra_compile_args=['-O3', '-w'], - extra_link_args=opencv_libs)] -elif sys_name == 'Windows': - extensions = [ - Extension('pyAprilTag._apriltag', - sources=[os.path.join(CUR_DIR, '_cy_apriltag.pyx')], - language='c++', - include_dirs=[np.get_include()] + opencv_incs + self_incs, - extra_compile_args=['/O2'], - extra_link_args=opencv_libs)] +extensions = [ +Extension('pyAprilTag._apriltag', + sources=[os.path.join(CUR_DIR, '_cy_apriltag.pyx')], + language='c++', + include_dirs=[np.get_include(), opencv_inc_dir] + self_incs, + libraries=opencv_libs, + library_dirs=[opencv_lib_dir,], + extra_compile_args=['/O2'] if sys_name=='Windows' else ['-O3', '-w'], + # extra_link_args=None if sys_name=='Windows' else ['-Wl,-R$ORIGIN/.'] +)] setup( name="pyAprilTag", @@ -72,9 +89,9 @@ url="https://github.com/ai4ce/pyAprilTag", packages=['pyAprilTag'], package_dir={'': 'python'}, - package_data={'pyAprilTag': ['*.png', 'data/**/*', '*.dll', '*.so', '*.dylib']}, + package_data={'pyAprilTag': ['data/*.png', 'data/**/*']}, include_package_data=True, license="BSD", - cmdclass={'build_ext': build_ext}, - ext_modules=cythonize(extensions) + cmdclass={'build_ext': BuildExt}, + ext_modules=cythonize(extensions, compiler_directives={'language_level' : sys.version_info[0]}) ) \ No newline at end of file