from setuptools import setup from setuptools.command.build_py import build_py import glob import os import pathlib import shutil import subprocess import sys if os.name != 'nt': raise EnvironmentError(f"This is only supported on Windows... not for: {os.name}") THIS_FOLDER = os.path.abspath(os.path.dirname(__file__)) def getVersion() -> str: with open(os.path.join(THIS_FOLDER, 'pydeskband', '__init__.py'), 'r') as f: text = f.read() for line in text.splitlines(): if line.startswith('__version__'): version = line.split('=', 1)[1].replace('\'', '').replace('"', '') return version.strip() raise EnvironmentError("Unable to find __version__!") def get_msbuild() -> str: ''' globs to find VS 2019's instance of MSBuild.exe ''' matches = glob.glob(r'C:\Program Files*\Microsoft Visual Studio\2019\*\MSBuild\*\Bin\MSBuild.exe') if matches: print(f"MSBuild: {matches[0]}") return pathlib.Path(matches[0]) raise EnvironmentError("Could not find MSBuild for VS 2019!") def get_sln() -> pathlib.Path: sln = pathlib.Path(THIS_FOLDER) / "dll/PyDeskband/PyDeskband.sln" if not sln.is_file(): raise FileNotFoundError(f"Could not find sln file: {sln}") return sln def run_msbuild(configuration, platform) -> pathlib.Path: ''' Runs MSBuild for the given configuration/platform. Returns the path to the built dll ''' if configuration not in ('Debug', 'Release'): raise ValueError("configuration should be Debug or Release") if platform not in ('x64', 'x86'): raise ValueError("platform should be x64 or x86") if subprocess.check_call([ get_msbuild(), get_sln(), f'/p:Configuration={configuration}', f'/p:Platform={platform}', ]) == 0: arch_folder = 'x64' if platform == 'x64' else '' output = pathlib.Path(THIS_FOLDER) / f"dll/PyDeskband/{arch_folder}/{configuration}/PyDeskband.dll" if not output.is_file(): raise FileNotFoundError("MSBuild was successful, though we couldn't find the output dll.") return output class BuildPyCommand(build_py): """Custom build command. That will build dlls using MSBuild""" def build_and_copy_dlls(self): ''' Build x64 and x86 versions of the dll. Then copies them to pydeskband/dlls within the Python package ''' x64_dll = run_msbuild('Release', 'x64') x86_dll = run_msbuild('Release', 'x86') dll_dir = pathlib.Path(THIS_FOLDER) / "pydeskband/dlls" if not dll_dir.is_dir(): dll_dir.mkdir() # copy dlls to dll dir shutil.copy(x64_dll, dll_dir / "PyDeskband_x64.dll") shutil.copy(x86_dll, dll_dir / "PyDeskband_x86.dll") print("DLLs have been copied!") def run(self): ''' Called to perform the build_py step ''' self.build_and_copy_dlls() build_py.run(self) setup( name='pydeskband', author='csm10495', author_email='csm10495@gmail.com', url='http://github.com/csm10495/pydeskband', version=getVersion(), packages=['pydeskband'], license='MIT License', python_requires='>=3.7', long_description=open(os.path.join(os.path.dirname(__file__), 'README.md')).read(), long_description_content_type="text/markdown", classifiers=[ 'Intended Audience :: Developers', 'Natural Language :: English', 'Operating System :: Microsoft :: Windows', 'Programming Language :: Python', 'Programming Language :: Python :: 3', ], package_data={ "pydeskband": ["dlls/*.dll"], }, cmdclass={ 'build_py': BuildPyCommand }, install_requires=[], )