aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/backend/backends.py
diff options
context:
space:
mode:
authorEli Schwartz <eschwartz@archlinux.org>2022-09-07 15:36:52 -0400
committerEli Schwartz <eschwartz@archlinux.org>2022-09-11 14:51:03 -0400
commit7eb5709bd9105c3ab9eec935b4b2b14d2ca7940b (patch)
tree49c2ee09f25e08eea3b27ea123e65ec8c5b4c153 /mesonbuild/backend/backends.py
parent37663da83ee578da2383bdd06402e91bdec97094 (diff)
downloadmeson-7eb5709bd9105c3ab9eec935b4b2b14d2ca7940b.zip
meson-7eb5709bd9105c3ab9eec935b4b2b14d2ca7940b.tar.gz
meson-7eb5709bd9105c3ab9eec935b4b2b14d2ca7940b.tar.bz2
backends: limit maximum path of generated filenames
When calculating the output filename for a compiled object, we sanitize the whole input path, more or less. In cases where the input path is very long, this can overflow the max length of an individual filename component. At the same time, we do want unique names so people can recognize what these outputs actually are. Compromise: - for filepaths with >5 components (which are a lot more likely to cause problems, and simultanously less likely to have crucial information that far back in the filepath) - if an sha1 hash of the full path, replacing all *but* those last 5 components, produces a path that is *shorter* than the original path ... then use that modified path canonicalization via a hash. Due to the use of hashes, it's unique enough to guarantee correct builds. Because we keep the last 5 components intact, it's easy to tell what the output file is compiled from. Fixes building in ecosystems such as spack, where the build environment is a very long path containing repetitions of `__spack_path_placeholder__/` for... reasons of making the path long.
Diffstat (limited to 'mesonbuild/backend/backends.py')
-rw-r--r--mesonbuild/backend/backends.py10
1 files changed, 9 insertions, 1 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 304bea3..64c8fa1 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -781,9 +781,17 @@ class Backend:
@staticmethod
def canonicalize_filename(fname: str) -> str:
+ parts = Path(fname).parts
+ hashed = ''
+ if len(parts) > 5:
+ temp = '/'.join(parts[-5:])
+ # is it shorter to hash the beginning of the path?
+ if len(fname) > len(temp) + 41:
+ hashed = hashlib.sha1(fname.encode('utf-8')).hexdigest() + '_'
+ fname = temp
for ch in ('/', '\\', ':'):
fname = fname.replace(ch, '_')
- return fname
+ return hashed + fname
def object_filename_from_source(self, target: build.BuildTarget, source: 'FileOrString') -> str:
assert isinstance(source, mesonlib.File)