|
5 | 5 | import distutils
|
6 | 6 | import distutils.ccompiler
|
7 | 7 | import fnmatch
|
| 8 | +import glob |
| 9 | +import hashlib |
8 | 10 | import json
|
9 | 11 | import os
|
10 | 12 | import platform
|
|
16 | 18 |
|
17 | 19 | MOVEFILE_DELAY_UNTIL_REBOOT = 4
|
18 | 20 |
|
| 21 | +if platform.system() == "Windows": |
| 22 | + interpreter_prefix = sysconfig.get_config_var("srcdir") |
| 23 | +else: |
| 24 | + interpreter_prefix = sysconfig.get_config_var("prefix") |
19 | 25 |
|
20 | 26 | def find_files(directory, pattern):
|
21 | 27 | for root, dirs, files in os.walk(directory):
|
@@ -57,7 +63,48 @@ def getPythonInitFunctions(compiler, filename):
|
57 | 63 | return initFunctions
|
58 | 64 |
|
59 | 65 |
|
| 66 | +def get_lib_hash(): |
| 67 | + hash_string = "" |
| 68 | + read_files = set() |
| 69 | + |
| 70 | + extra_scan_dirs = [] |
| 71 | + if platform.system() == "Windows": |
| 72 | + extra_scan_dirs.append(os.path.join(sysconfig.get_config_var('srcdir'), 'libs')) |
| 73 | + else: |
| 74 | + extra_scan_dirs.append(interpreter_prefix) |
| 75 | + |
| 76 | + # Scan sys.path for any more lingering static libs. |
| 77 | + for path in list(reversed(sys.path)) + extra_scan_dirs: |
| 78 | + # Ignore the working directory so we don't grab duplicate stuff. Also ignore the pip temp path that is |
| 79 | + # injected during a pip install. |
| 80 | + if path == os.getcwd() or "pip-install-" in path: |
| 81 | + continue |
| 82 | + |
| 83 | + for lib_file in list(glob.glob(os.path.join("**", "*.a"), root_dir=path, recursive=True)) + list(glob.glob(os.path.join("**", "*.lib"), root_dir=path, recursive=True)): |
| 84 | + if os.path.basename(lib_file) in read_files: |
| 85 | + continue |
| 86 | + |
| 87 | + with open(os.path.join(path, lib_file), 'rb') as f: |
| 88 | + hash_string += hashlib.file_digest(f, "sha512").hexdigest() |
| 89 | + read_files.add(os.path.basename(lib_file)) |
| 90 | + |
| 91 | + return hashlib.sha256(hash_string.encode('ascii')).hexdigest() |
| 92 | + |
60 | 93 | def run_rebuild():
|
| 94 | + try: |
| 95 | + with open(os.path.join(interpreter_prefix, "link.json"), 'r') as f: |
| 96 | + old_link_data = json.load(f) |
| 97 | + except FileNotFoundError: |
| 98 | + old_link_data = {} |
| 99 | + |
| 100 | + old_hash = old_link_data.get("lib_hash") |
| 101 | + new_hash = get_lib_hash() |
| 102 | + |
| 103 | + # Try to avoid building if nothing has changed. |
| 104 | + if old_hash == new_hash: |
| 105 | + print("No native library changes detected. Not rebuilding interpreter.") |
| 106 | + return |
| 107 | + |
61 | 108 | installDir = os.path.dirname(sys.executable)
|
62 | 109 |
|
63 | 110 | has_compiler_vars = sysconfig.get_config_var("CC") and sysconfig.get_config_var("CXX")
|
@@ -130,12 +177,12 @@ def run_rebuild():
|
130 | 177 | dirpath, filename = os.path.split(relativePath)
|
131 | 178 | if platform.system() != "Windows" and filename.startswith("lib"):
|
132 | 179 | filename = filename[3:]
|
| 180 | + if ext_suffix and filename.endswith(ext_suffix): |
| 181 | + filename = filename[: len(ext_suffix) * -1] |
133 | 182 | if filename.endswith(".a"):
|
134 | 183 | filename = filename[:-2]
|
135 | 184 | if filename.endswith(".lib"):
|
136 | 185 | filename = filename[:-4]
|
137 |
| - if ext_suffix and filename.endswith(ext_suffix): |
138 |
| - filename = filename[: len(ext_suffix) * -1] |
139 | 186 | relative_path = filename
|
140 | 187 | if dirpath:
|
141 | 188 | relative_path = dirpath.replace("\\", ".").replace("/", ".") + "." + relative_path
|
@@ -306,11 +353,6 @@ def run_rebuild():
|
306 | 353 |
|
307 | 354 | print("Compiling new interpreter...")
|
308 | 355 |
|
309 |
| - if platform.system() == "Windows": |
310 |
| - interpreter_prefix = sysconfig.get_config_var("srcdir") |
311 |
| - else: |
312 |
| - interpreter_prefix = sysconfig.get_config_var("prefix") |
313 |
| - |
314 | 356 | build_dir = os.path.join(interpreter_prefix, "interpreter_build")
|
315 | 357 |
|
316 | 358 | if os.path.isdir(build_dir):
|
@@ -537,7 +579,8 @@ def run_rebuild():
|
537 | 579 | "libraries": link_libs,
|
538 | 580 | "library_dirs": library_dirs,
|
539 | 581 | "link_flags": link_flags,
|
540 |
| - "compile_flags": compile_flags |
| 582 | + "compile_flags": compile_flags, |
| 583 | + "lib_hash": new_hash |
541 | 584 | },
|
542 | 585 | f,
|
543 | 586 | )
|
|
0 commit comments