setup.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #!/usr/bin/env python3
  2. #
  3. # mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
  4. # Copyright (C)2013-2023 The MMGen Project <mmgen@tuta.io>
  5. # Licensed under the GNU General Public License, Version 3:
  6. # https://www.gnu.org/licenses
  7. # Public project repositories:
  8. # https://github.com/mmgen/mmgen
  9. # https://gitlab.com/mmgen/mmgen
  10. import os
  11. from subprocess import run,PIPE
  12. from setuptools import setup,Extension
  13. from setuptools.command.build_ext import build_ext
  14. cache_path = os.path.join(os.environ['HOME'],'.cache','mmgen')
  15. ext_path = os.path.join(cache_path,'secp256k1')
  16. def build_libsecp256k1():
  17. def fix_broken_libpython_fn():
  18. from pathlib import Path
  19. path = Path(Path().resolve().anchor) / 'msys64/mingw64/lib'
  20. old = path / 'libpython3.10.dll.a'
  21. new = path / 'libpython310.dll.a'
  22. if old.exists() and not new.exists():
  23. import shutil
  24. print(f'Fixing broken library filename: {old.name!r} -> {new.name!r}')
  25. shutil.copy2(old,new)
  26. def fix_broken_aclocal_path():
  27. os.environ['ACLOCAL_PATH'] = '/ucrt64/share/aclocal:/usr/share/aclocal'
  28. import platform
  29. if platform.system() == 'Windows':
  30. fix_broken_libpython_fn()
  31. if os.getenv('MSYSTEM') == 'UCRT64':
  32. fix_broken_aclocal_path()
  33. if not os.path.exists(cache_path):
  34. os.makedirs(cache_path)
  35. if not os.path.exists(ext_path):
  36. print('\nCloning libsecp256k1')
  37. run(['git','clone','https://github.com/bitcoin-core/secp256k1.git'],check=True,cwd=cache_path)
  38. if not os.path.exists(os.path.join(ext_path,'.libs/libsecp256k1.a')):
  39. print('\nBuilding libsecp256k1')
  40. cmds = {
  41. 'Windows': (
  42. ['sh','./autogen.sh'],
  43. ['sh','./configure','CFLAGS=-g -O2 -fPIC','--disable-dependency-tracking'],
  44. ['mingw32-make','MAKE=mingw32-make']
  45. ),
  46. 'Linux': (
  47. ['./autogen.sh'],
  48. ['./configure','CFLAGS=-g -O2 -fPIC'],
  49. ['make'] + ([] if have_arm else ['-j4']),
  50. ),
  51. }[platform.system()]
  52. for cmd in cmds:
  53. print('Executing {}'.format(' '.join(cmd)))
  54. run(cmd,check=True,cwd=ext_path)
  55. uname = {k:run(['uname',f'-{k}'],stdout=PIPE,check=True).stdout.strip().decode() for k in ('m','s')}
  56. have_arm = uname['m'] in ('aarch64','armv7l') # x86_64, aarch64, armv7l
  57. have_msys2 = uname['s'].startswith('MSYS_NT') # Linux, MSYS_NT.*
  58. class my_build_ext(build_ext):
  59. def build_extension(self,ext):
  60. build_libsecp256k1()
  61. build_ext.build_extension(self,ext)
  62. setup(
  63. cmdclass = { 'build_ext': my_build_ext },
  64. ext_modules = [Extension(
  65. name = 'mmgen.proto.secp256k1.secp256k1',
  66. sources = ['extmod/secp256k1mod.c'],
  67. libraries = ([],['gmp'])[have_msys2],
  68. extra_objects = [os.path.join(ext_path,'.libs/libsecp256k1.a')],
  69. include_dirs = [os.path.join(ext_path,'include')],
  70. )]
  71. )