cmake_extension.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # Copyright (c) 2021-2022 Xiaomi Corporation (author: Fangjun Kuang)
  2. # flake8: noqa
  3. import os
  4. import platform
  5. import shutil
  6. import sys
  7. from pathlib import Path
  8. import setuptools
  9. from setuptools.command.build_ext import build_ext
  10. def is_for_pypi():
  11. ans = os.environ.get("SHERPA_NCNN_IS_FOR_PYPI", None)
  12. return ans is not None
  13. def is_macos():
  14. return platform.system() == "Darwin"
  15. def is_windows():
  16. return platform.system() == "Windows"
  17. try:
  18. from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
  19. class bdist_wheel(_bdist_wheel):
  20. def finalize_options(self):
  21. _bdist_wheel.finalize_options(self)
  22. # In this case, the generated wheel has a name in the form
  23. # sherpa-xxx-pyxx-none-any.whl
  24. if is_for_pypi() and not is_macos():
  25. self.root_is_pure = True
  26. else:
  27. # The generated wheel has a name ending with
  28. # -linux_x86_64.whl
  29. self.root_is_pure = False
  30. except ImportError:
  31. bdist_wheel = None
  32. def cmake_extension(name, *args, **kwargs) -> setuptools.Extension:
  33. kwargs["language"] = "c++"
  34. sources = []
  35. return setuptools.Extension(name, sources, *args, **kwargs)
  36. class BuildExtension(build_ext):
  37. def build_extension(self, ext: setuptools.extension.Extension):
  38. # build/temp.linux-x86_64-3.8
  39. os.makedirs(self.build_temp, exist_ok=True)
  40. # build/lib.linux-x86_64-3.8
  41. os.makedirs(self.build_lib, exist_ok=True)
  42. out_bin_dir = Path(self.build_lib).parent / "bin"
  43. install_dir = Path(self.build_lib).resolve()
  44. sherpa_ncnn_dir = Path(__file__).parent.parent.resolve()
  45. cmake_args = os.environ.get("SHERPA_NCNN_CMAKE_ARGS", "")
  46. make_args = os.environ.get("SHERPA_NCNN_MAKE_ARGS", "")
  47. system_make_args = os.environ.get("MAKEFLAGS", "")
  48. if cmake_args == "":
  49. cmake_args = "-DCMAKE_BUILD_TYPE=Release"
  50. extra_cmake_args = f" -DCMAKE_INSTALL_PREFIX={install_dir} "
  51. extra_cmake_args += f" -DBUILD_SHARED_LIBS=ON "
  52. extra_cmake_args += f" -DSHERPA_NCNN_ENABLE_PYTHON=ON "
  53. extra_cmake_args += f" -DSHERPA_NCNN_ENABLE_PORTAUDIO=ON "
  54. if "PYTHON_EXECUTABLE" not in cmake_args:
  55. print(f"Setting PYTHON_EXECUTABLE to {sys.executable}")
  56. cmake_args += f" -DPYTHON_EXECUTABLE={sys.executable}"
  57. cmake_args += extra_cmake_args
  58. if is_windows():
  59. build_cmd = f"""
  60. cmake {cmake_args} -B {self.build_temp} -S {sherpa_ncnn_dir}
  61. cmake --build {self.build_temp} --target install --config Release -- -m
  62. """
  63. print(f"build command is:\n{build_cmd}")
  64. ret = os.system(
  65. f"cmake {cmake_args} -B {self.build_temp} -S {sherpa_ncnn_dir}"
  66. )
  67. if ret != 0:
  68. raise Exception("Failed to configure sherpa")
  69. ret = os.system(
  70. f"cmake --build {self.build_temp} --target install --config Release -- -m" # noqa
  71. )
  72. if ret != 0:
  73. raise Exception("Failed to build and install sherpa")
  74. else:
  75. if make_args == "" and system_make_args == "":
  76. print("for fast compilation, run:")
  77. print('export SHERPA_NCNN_MAKE_ARGS="-j"; python setup.py install')
  78. print('Setting make_args to "-j4"')
  79. make_args = "-j4"
  80. build_cmd = f"""
  81. cd {self.build_temp}
  82. cmake {cmake_args} {sherpa_ncnn_dir}
  83. make {make_args} install/strip
  84. """
  85. print(f"build command is:\n{build_cmd}")
  86. ret = os.system(build_cmd)
  87. if ret != 0:
  88. raise Exception(
  89. "\nBuild sherpa-ncnn failed. Please check the error message.\n"
  90. "You can ask for help by creating an issue on GitHub.\n"
  91. "\nClick:\n\thttps://github.com/k2-fsa/sherpa-ncnn/issues/new\n" # noqa
  92. )
  93. suffix = ".exe" if is_windows() else ""
  94. # Remember to also change setup.py
  95. binaries = ["sherpa-ncnn"]
  96. binaries += ["sherpa-ncnn-microphone"]
  97. for f in binaries:
  98. src_file = install_dir / "bin" / (f + suffix)
  99. print(f"Copying {src_file} to {out_bin_dir}/")
  100. shutil.copy(f"{src_file}", f"{out_bin_dir}/")