Skip to content

Commit 2a623df

Browse files
committed
Avoid rebuilding if no native libs were changed.
1 parent b866717 commit 2a623df

File tree

1 file changed

+51
-8
lines changed

1 file changed

+51
-8
lines changed

Lib/rebuildpython.py

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import distutils
66
import distutils.ccompiler
77
import fnmatch
8+
import glob
9+
import hashlib
810
import json
911
import os
1012
import platform
@@ -16,6 +18,10 @@
1618

1719
MOVEFILE_DELAY_UNTIL_REBOOT = 4
1820

21+
if platform.system() == "Windows":
22+
interpreter_prefix = sysconfig.get_config_var("srcdir")
23+
else:
24+
interpreter_prefix = sysconfig.get_config_var("prefix")
1925

2026
def find_files(directory, pattern):
2127
for root, dirs, files in os.walk(directory):
@@ -57,7 +63,48 @@ def getPythonInitFunctions(compiler, filename):
5763
return initFunctions
5864

5965

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+
6093
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+
61108
installDir = os.path.dirname(sys.executable)
62109

63110
has_compiler_vars = sysconfig.get_config_var("CC") and sysconfig.get_config_var("CXX")
@@ -130,12 +177,12 @@ def run_rebuild():
130177
dirpath, filename = os.path.split(relativePath)
131178
if platform.system() != "Windows" and filename.startswith("lib"):
132179
filename = filename[3:]
180+
if ext_suffix and filename.endswith(ext_suffix):
181+
filename = filename[: len(ext_suffix) * -1]
133182
if filename.endswith(".a"):
134183
filename = filename[:-2]
135184
if filename.endswith(".lib"):
136185
filename = filename[:-4]
137-
if ext_suffix and filename.endswith(ext_suffix):
138-
filename = filename[: len(ext_suffix) * -1]
139186
relative_path = filename
140187
if dirpath:
141188
relative_path = dirpath.replace("\\", ".").replace("/", ".") + "." + relative_path
@@ -306,11 +353,6 @@ def run_rebuild():
306353

307354
print("Compiling new interpreter...")
308355

309-
if platform.system() == "Windows":
310-
interpreter_prefix = sysconfig.get_config_var("srcdir")
311-
else:
312-
interpreter_prefix = sysconfig.get_config_var("prefix")
313-
314356
build_dir = os.path.join(interpreter_prefix, "interpreter_build")
315357

316358
if os.path.isdir(build_dir):
@@ -537,7 +579,8 @@ def run_rebuild():
537579
"libraries": link_libs,
538580
"library_dirs": library_dirs,
539581
"link_flags": link_flags,
540-
"compile_flags": compile_flags
582+
"compile_flags": compile_flags,
583+
"lib_hash": new_hash
541584
},
542585
f,
543586
)

0 commit comments

Comments
 (0)