process_libraries.py.in 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. # Copyright (c) 2024 PaddlePaddle Authors. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import os
  15. import sys
  16. import shutil
  17. import subprocess
  18. import platform
  19. user_specified_dirs = ['@OPENCV_DIRECTORY@', '@ORT_DIRECTORY@', ]
  20. PACKAGE_NAME = os.getenv("PACKAGE_NAME", "ultra_infer")
  21. PY_PACKAGE_NAME = PACKAGE_NAME + "_main"
  22. def process_on_linux(current_dir):
  23. rpaths = ["$ORIGIN:$ORIGIN/libs"]
  24. fd_libs = list()
  25. libs_path = os.path.join(current_dir, PACKAGE_NAME, "libs")
  26. for f in os.listdir(libs_path):
  27. filename = os.path.join(libs_path, f)
  28. if not os.path.isfile(filename):
  29. continue
  30. if f.count(PACKAGE_NAME) and f.count(".so") > 0:
  31. fd_libs.append(filename)
  32. cmake_build_dir = os.path.join(current_dir, ".setuptools-cmake-build")
  33. patchelf_bin_path = os.path.join(cmake_build_dir, "third_libs/patchelf/bin/patchelf")
  34. if not os.path.exists(patchelf_bin_path):
  35. patchelf_bin_path = "patchelf"
  36. third_libs_path = os.path.join(libs_path, "third_libs")
  37. # remove some useless opencv file in python wheels to decrease package size
  38. if os.path.exists(os.path.join(third_libs_path, "opencv")):
  39. for root, dirs, files in os.walk(os.path.join(third_libs_path, "opencv")):
  40. for f in files:
  41. items = f.strip().split('.')
  42. if len(items) != 4:
  43. os.remove(os.path.join(root, f))
  44. continue
  45. if items[0].strip() not in ["libopencv_highgui", "libopencv_video", "libopencv_videoio", "libopencv_imgcodecs", "libopencv_imgproc", "libopencv_core", "libopencv_calib3d", "libopencv_features2d", "libopencv_flann"]:
  46. os.remove(os.path.join(root, f))
  47. all_libs_paths = [third_libs_path] + user_specified_dirs
  48. for path in all_libs_paths:
  49. for root, dirs, files in os.walk(path):
  50. for d in dirs:
  51. if d not in ["lib", "lib64"]:
  52. continue
  53. rel_path = os.path.relpath(os.path.join(root, d), libs_path)
  54. if path in user_specified_dirs:
  55. # Note(zhoushunjie): Use the absolute path for user_specified_dirs
  56. rpath = os.path.join(root, d)
  57. else:
  58. rpath = "$ORIGIN/" + rel_path
  59. rpaths.append(rpath)
  60. for lib in fd_libs:
  61. command = "{} --set-rpath '{}' {}".format(patchelf_bin_path, ":".join(rpaths), lib)
  62. if platform.machine() != 'sw_64' and platform.machine() != 'mips64':
  63. assert subprocess.Popen(
  64. command,
  65. shell=True) != 0, "patchelf {} failed, the command: {}".format(
  66. command, lib)
  67. def process_on_mac(current_dir):
  68. fd_libs = list()
  69. libs_path = os.path.join(current_dir, PACKAGE_NAME, "libs")
  70. cmake_build_dir = os.path.join(current_dir, ".setuptools-cmake-build")
  71. for f in os.listdir(libs_path):
  72. filename = os.path.join(libs_path, f)
  73. if not os.path.isfile(filename):
  74. continue
  75. if f.count(PACKAGE_NAME) > 0 and (f.count(".dylib") > 0 or
  76. f.count(".so") > 0):
  77. fd_libs.append(filename)
  78. commands = list()
  79. pre_commands = list()
  80. for lib in fd_libs:
  81. if lib.count(PY_PACKAGE_NAME) > 0:
  82. pre_commands.append(
  83. "install_name_tool -delete_rpath {} ".format(cmake_build_dir) + lib)
  84. commands.append("install_name_tool -id @loader_path " + lib)
  85. commands.append("install_name_tool -add_rpath @loader_path " + lib)
  86. third_libs_path = os.path.join(libs_path, "third_libs")
  87. cmake_third_libs_path = os.path.join(cmake_build_dir, "third_libs", "install")
  88. all_libs_paths = [cmake_third_libs_path] + user_specified_dirs
  89. for path in all_libs_paths:
  90. for root, dirs, files in os.walk(path):
  91. for d in dirs:
  92. if d not in ["lib", "lib64"]:
  93. continue
  94. rel_path = os.path.relpath(os.path.join(root, d), cmake_third_libs_path)
  95. if path in user_specified_dirs:
  96. # Note(zhoushunjie): Use the absolute path for user_specified_dirs
  97. need_delete_rpath = os.path.join(root, d)
  98. need_add_rpath = os.path.join(root, d)
  99. else:
  100. need_delete_rpath = os.path.join(root, d)
  101. need_add_rpath = "@loader_path/third_libs/" + rel_path
  102. for lib in fd_libs:
  103. if lib.count(PY_PACKAGE_NAME) > 0:
  104. pre_commands.append(
  105. "install_name_tool -delete_rpath {} {}".format(need_delete_rpath, lib))
  106. commands.append(
  107. "install_name_tool -add_rpath {} {}".format(need_add_rpath, lib))
  108. for command in pre_commands:
  109. try:
  110. os.system(command)
  111. except:
  112. print("Skip execute command: " + command)
  113. for command in commands:
  114. assert os.system(
  115. command) == 0, "command execute failed! command: {}".format(
  116. command)
  117. def process_on_windows(current_dir):
  118. libs_path = os.path.join(current_dir, PACKAGE_NAME, "libs")
  119. third_libs_path = os.path.join(libs_path, "third_libs")
  120. for root, dirs, files in os.walk(third_libs_path):
  121. for f in files:
  122. file_path = os.path.join(root, f)
  123. if f.count('onnxruntime') > 0 and f.endswith('.dll'):
  124. shutil.copy(file_path, libs_path)
  125. def get_all_files(dirname):
  126. files = list()
  127. for root, dirs, filenames in os.walk(dirname):
  128. for f in filenames:
  129. fullname = os.path.join(root, f)
  130. files.append(fullname)
  131. return files
  132. def process_libraries(current_dir):
  133. if platform.system().lower() == "linux":
  134. process_on_linux(current_dir)
  135. elif platform.system().lower() == "darwin":
  136. process_on_mac(current_dir)
  137. elif platform.system().lower() == "windows":
  138. process_on_windows(current_dir)
  139. all_files = get_all_files(os.path.join(current_dir, PACKAGE_NAME, "libs"))
  140. package_data = list()
  141. if platform.system().lower() == "windows":
  142. def check_windows_legal_file(f):
  143. # Note(zhoushunjie): Special case for some library
  144. # File 'plugins.xml' is special case of openvino.
  145. for special_file in ['plugins.xml']:
  146. if special_file in f:
  147. return True
  148. return False
  149. for f in all_files:
  150. if f.endswith(".pyd") or f.endswith("lib") or f.endswith(
  151. "dll") or check_windows_legal_file(f):
  152. package_data.append(
  153. os.path.relpath(f, os.path.join(current_dir,
  154. PACKAGE_NAME)))
  155. return package_data
  156. filters = [".vcxproj", ".png", ".java", ".h", ".cc", ".cpp", ".hpp"]
  157. for f in all_files:
  158. remain = True
  159. for flt in filters:
  160. if f.count(flt) > 0:
  161. remain = False
  162. filename = os.path.split(f)[-1]
  163. # Note(zhoushunjie): To add the trt libs below will increase the size of whl package by 450M.
  164. if filename in [
  165. "libnvinfer_plugin.so",
  166. "libnvinfer.so", "libnvonnxparser.so",
  167. "libnvparsers.so", "libnvcaffe_parser.so"
  168. ]:
  169. continue
  170. for lib_prefix in ["libnvinfer_plugin.so.8.",
  171. "libnvinfer.so.8.", "libnvonnxparser.so.8.",
  172. "libnvparsers.so.8.", "libnvcaffe_parser.so.8."]:
  173. if filename.startswith(lib_prefix):
  174. remain = False
  175. break
  176. if remain:
  177. package_data.append(
  178. os.path.relpath(f, os.path.join(current_dir, PACKAGE_NAME)))
  179. return package_data