cmake_extension.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. install_dir = Path(self.build_lib).resolve() / "sherpa_ncnn"
  43. sherpa_ncnn_dir = Path(__file__).parent.parent.resolve()
  44. cmake_args = os.environ.get("SHERPA_NCNN_CMAKE_ARGS", "")
  45. make_args = os.environ.get("SHERPA_NCNN_MAKE_ARGS", "")
  46. system_make_args = os.environ.get("MAKEFLAGS", "")
  47. if cmake_args == "":
  48. cmake_args = "-DCMAKE_BUILD_TYPE=Release"
  49. extra_cmake_args = f" -DCMAKE_INSTALL_PREFIX={install_dir} "
  50. extra_cmake_args += f" -DBUILD_SHARED_LIBS=ON "
  51. extra_cmake_args += f" -DSHERPA_NCNN_ENABLE_PYTHON=ON "
  52. extra_cmake_args += f" -DSHERPA_NCNN_ENABLE_PORTAUDIO=OFF "
  53. if "PYTHON_EXECUTABLE" not in cmake_args:
  54. print(f"Setting PYTHON_EXECUTABLE to {sys.executable}")
  55. cmake_args += f" -DPYTHON_EXECUTABLE={sys.executable}"
  56. cmake_args += extra_cmake_args
  57. if is_windows():
  58. build_cmd = f"""
  59. cmake {cmake_args} -B {self.build_temp} -S {sherpa_ncnn_dir}
  60. cmake --build {self.build_temp} --target install --config Release -- -m
  61. """
  62. print(f"build command is:\n{build_cmd}")
  63. ret = os.system(
  64. f"cmake {cmake_args} -B {self.build_temp} -S {sherpa_ncnn_dir}"
  65. )
  66. if ret != 0:
  67. raise Exception("Failed to configure sherpa")
  68. ret = os.system(
  69. f"cmake --build {self.build_temp} --target install --config Release -- -m" # noqa
  70. )
  71. if ret != 0:
  72. raise Exception("Failed to build and install sherpa")
  73. else:
  74. if make_args == "" and system_make_args == "":
  75. print("for fast compilation, run:")
  76. print('export SHERPA_NCNN_MAKE_ARGS="-j"; python setup.py install')
  77. print('Setting make_args to "-j4"')
  78. make_args = "-j4"
  79. build_cmd = f"""
  80. cd {self.build_temp}
  81. cmake {cmake_args} {sherpa_ncnn_dir}
  82. make {make_args} install/strip
  83. """
  84. print(f"build command is:\n{build_cmd}")
  85. ret = os.system(build_cmd)
  86. if ret != 0:
  87. raise Exception(
  88. "\nBuild sherpa-ncnn failed. Please check the error message.\n"
  89. "You can ask for help by creating an issue on GitHub.\n"
  90. "\nClick:\n\thttps://github.com/k2-fsa/sherpa-ncnn/issues/new\n" # noqa
  91. )
  92. dirs = [
  93. install_dir / "include",
  94. install_dir / "lib" / "cmake",
  95. install_dir / "lib" / "pkgconfig",
  96. install_dir / "lib64" / "cmake",
  97. install_dir / "lib64" / "pkgconfig",
  98. ]
  99. for d in dirs:
  100. if not d.is_dir():
  101. continue
  102. shutil.rmtree(str(d))