from __future__ import print_function #Check for cython >= 0.17 due to the use of STL containers try: import Cython except ImportError: raise ImportError("Cython not found") major,minor = Cython.__version__.split('.')[0:2] #Convert major to integer major = int(major) iEnd = 0 while minor[iEnd].isdigit(): iEnd+=1 if iEnd == len(minor): break minor = int(minor[0:iEnd]) if not(major > 0 or minor >= 17): raise ImportError('Cython version >= 0.17 required due to the use of STL wrappers. Please update your version of cython') if minor >= 20: _profiling_enabled = True else: _profiling_enabled = False try: import psutil for proc in psutil.get_process_list(): cmdline = proc.cmdline if cmdline and ''.join(cmdline).find('pycompletionserver.py') > 0: proc.terminate() print('Python completion server killed') break except ImportError: print('psutil was not found, it is used to kill the python completion server in Eclipse which keeps CoolProp from building sometimes. psutils can be easy_install-ed') from distutils.core import setup, Extension import subprocess, shutil, os, sys, glob from Cython.Build import cythonize from Cython.Distutils import build_ext from Cython.Distutils.extension import Extension as CyExtension from distutils.sysconfig import get_python_inc from distutils.ccompiler import new_compiler from distutils.dep_util import newer_group #This will generate HTML to show where there are still pythonic bits hiding out Cython.Compiler.Options.annotate = True # Two options for the location of the C++ files. Either in the normal ../../CoolProp folder # or they are in the CoolPropSource folder in this folder # For PYPI purposes if 'sdist' in sys.argv: CProot = '.' shutil.copy2(os.path.join('..','..','version.txt'),'version.txt') shutil.copytree(os.path.join('..','..','CoolProp'),'CoolPropSource') else: CProot = os.path.join('..','..') if os.path.exists('CoolPropSource'): CPSourceDir = 'CoolPropSource' CProot = '.' else: CPSourceDir = os.path.join(CProot,'CoolProp') version = open(os.path.join(CProot,'version.txt'),'r').read().strip() if __name__=='__main__': def gitrev_to_file(): """ If a git repo, use git to update the gitrevision """ try: try: subprocess.check_call('git --version', shell=True) print('git was found') except subprocess.CalledProcessError: print('git was not found') return #subprocess.call('git fetch', shell = True) p = subprocess.Popen('git rev-parse HEAD', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = True) stdout, stderr = p.communicate() if p.returncode != 0: print('tried to update git revision, but it failed for some reason (building from zip file?)') return rev = stdout.strip() print('git revision is',rev) gitstring = 'std::string gitrevision = "'+str(rev)+'";' _write = False try: is_hash = rev.find(' ') == -1 # python 2.x except TypeError: is_hash = ' ' not in str(rev) # python 3.x if not os.path.exists(os.path.join(CPSourceDir,'gitrevision.h')): _write = True elif not is_hash: _write = False else: # Check if it is different than the current version f = open(os.path.join(CPSourceDir,'gitrevision.h'),'r') current_git = f.read() f.close() if not current_git.strip() == gitstring.strip(): _write = True else: _write = False if _write: f = open(os.path.join(CPSourceDir,'gitrevision.h'),'w') f.write(gitstring) f.close() except (subprocess.CalledProcessError,OSError): pass gitrev_to_file() def version_to_file(): string_for_file = 'static char version [] ="{v:s}";'.format(v = version) f = open(os.path.join(CPSourceDir,'version.h'),'r') current_version = f.read() f.close() if not current_version.strip() == string_for_file.strip(): f = open(os.path.join(CPSourceDir,'version.h'),'w') f.write(string_for_file) f.close() version_to_file() #This will generate HTML to show where there are still pythonic bits hiding out Cython.Compiler.Options.annotate = True ## If the file is run directly without any parameters, build and install if len(sys.argv)==1: #sys.argv += ['build_ext','--inplace'] # sys.argv += ['build','--compiler=mingw32','--force','install'] sys.argv += ['build','install'] #sys.argv += ['install'] badfiles = [os.path.join('CoolProp','__init__.pyc'), os.path.join('CoolProp','__init__.py')] for file in badfiles: try: os.remove(file) except: pass ######################### ## __init__.py builder ## ######################### #Unpack the __init__.py file template and add some things to the __init__ file lines=open('__init__.py.template','r').readlines() f = open(os.path.join(CPSourceDir,'gitrevision.h'),'r') rev = f.read().strip().split('=')[1].strip('";').strip() f.close() gitstring = '__gitrevision__ ='+rev+'"\n' for i in range(len(lines)-1,-1,-1): if lines[i].strip().startswith('#') or len(lines[i].strip())==0: lines.pop(i) lines=['from __future__ import absolute_import\n']+['__version__=\''+version+'\'\n']+[gitstring]+lines fp=open(os.path.join('CoolProp','__init__.py'),'w') for line in lines: fp.write(line) fp.close() Sources = glob.glob(os.path.join(CPSourceDir,'*.cpp')) ### Include folders for build include_dirs = [os.path.join(CPSourceDir),get_python_inc(False)] def touch(fname): open(fname, 'a').close() os.utime(fname, None) #If library has been updated but the cython sources haven't been, #force cython to build by touching the cython sources cython_sources = [os.path.join('CoolProp','CoolProp.pyx')] if _profiling_enabled: cython_directives = dict(profile = True, embed_signature = True) else: cython_directives = dict(embed_signature = True) common_args = dict(include_dirs = include_dirs, language='c++', cython_c_in_temp = True, cython_directives = cython_directives ) CoolProp_module = CyExtension('CoolProp.CoolProp', [os.path.join('CoolProp','CoolProp.pyx')]+Sources, **common_args) param_constants_module = CyExtension('CoolProp.param_constants', [os.path.join('CoolProp','param_constants.pyx')], **common_args) phase_constants_module = CyExtension('CoolProp.phase_constants', [os.path.join('CoolProp','phase_constants.pyx')], **common_args) unit_systems_constants_module = CyExtension('CoolProp.unit_systems_constants', [os.path.join('CoolProp','unit_systems_constants.pyx')], **common_args) #Collect all the header files in the main folder into an include folder try: os.mkdir(os.path.join('CoolProp','include')) except: pass for folder in [os.path.join(CPSourceDir)]: for header in glob.glob(os.path.join(folder,'*.h')): pth,fName = os.path.split(header) shutil.copy2(header,os.path.join('CoolProp','include',fName)) try: shutil.copytree(os.path.join(CPSourceDir,'rapidjson'),os.path.join('CoolProp','include','rapidjson')) except: pass shutil.copy2(os.path.join(CPSourceDir,'CoolPropBibTeXLibrary.bib'),os.path.join('CoolProp','CoolPropBibTeXLibrary.bib')) setup (name = 'CoolProp', version = version, #look above for the definition of version variable - don't modify it here author = "Ian Bell", author_email='ian.h.bell@gmail.com', url='http://coolprop.sourceforge.net', description = """Open-source thermodynamic and transport properties database""", packages = ['CoolProp','CoolProp.Plots','CoolProp.tests','CoolProp.GUI'], ext_modules = [CoolProp_module,param_constants_module,phase_constants_module,unit_systems_constants_module], package_dir = {'CoolProp':'CoolProp',}, package_data = {'CoolProp':['State.pxd','CoolProp.pxd','param_constants_header.pxd','include/*.h','include/rapidjson/*.h','include/rapidjson/internal/*.h','CoolPropBibTeXLibrary.bib']}, cmdclass={'build_ext': build_ext}, classifiers = [ "Programming Language :: Python", "Development Status :: 4 - Beta", "Environment :: Other Environment", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Topic :: Software Development :: Libraries :: Python Modules" ], ) #Clean up the include folder shutil.rmtree(os.path.join('CoolProp','include'), ignore_errors = True) os.remove(os.path.join('CoolProp','CoolPropBibTeXLibrary.bib')) for file in glob.glob(os.path.join('CoolProp','__init__.*')): try: os.remove(file) except: pass if 'sdist' in sys.argv: shutil.rmtree('CoolPropSource') os.remove('version.txt') touch('setup.py') # try: # import nose # import CoolProp # CoolProp.test() # except ImportError: # print("Could not run tests, nose not installed")