diff options
author | Aleksey Filippov <alekseyf@google.com> | 2018-09-25 18:07:09 +0100 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2018-11-22 23:38:40 +0200 |
commit | 1c8c888854e2c3ad2fbfeb3229520b8a6d3c1799 (patch) | |
tree | 88c66bd2555170e03bbcdb96af7985ac361cbb09 /mesonbuild/build.py | |
parent | 9f675cc55a04545886e6de4fb1721acc6536f40c (diff) | |
download | meson-1c8c888854e2c3ad2fbfeb3229520b8a6d3c1799.zip meson-1c8c888854e2c3ad2fbfeb3229520b8a6d3c1799.tar.gz meson-1c8c888854e2c3ad2fbfeb3229520b8a6d3c1799.tar.bz2 |
Use first 7 letters of sha256 for subdirectory part of target id
Fixed-size hash makes paths shorter and prevents doubling of path length
because of subdir usage in target id: "subdir/id" would generate
"subdir/{subdir-without-slashes}@@id" target otherwise.
Export construct_id_from_path() to aid tests.
Add a separate unit test for this function to make sure it is not broken unexpectedly.
Closes #4226.
Diffstat (limited to 'mesonbuild/build.py')
-rw-r--r-- | mesonbuild/build.py | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py index c0f4564..e47bd6f 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -15,6 +15,7 @@ import copy, os, re from collections import OrderedDict import itertools, pathlib +import hashlib import pickle from functools import lru_cache @@ -363,19 +364,38 @@ a hard error in the future.''' % name) def get_subdir(self): return self.subdir - def get_id(self): + @staticmethod + def _get_id_hash(target_id): + # We don't really need cryptographic security here. + # Small-digest hash function with unlikely collision is good enough. + h = hashlib.sha256() + h.update(target_id.encode(encoding='utf-8', errors='replace')) + # This ID should be case-insensitive and should work in Visual Studio, + # e.g. it should not start with leading '-'. + return h.hexdigest()[:7] + + @staticmethod + def construct_id_from_path(subdir, name, type_suffix): + """Construct target ID from subdir, name and type suffix. + + This helper function is made public mostly for tests.""" # This ID must also be a valid file name on all OSs. # It should also avoid shell metacharacters for obvious # reasons. '@' is not used as often as '_' in source code names. # In case of collisions consider using checksums. # FIXME replace with assert when slash in names is prohibited - name_part = self.name.replace('/', '@').replace('\\', '@') - assert not has_path_sep(self.type_suffix()) - myid = name_part + self.type_suffix() - if self.subdir: - subdir_part = self.subdir.replace('/', '@').replace('\\', '@') - myid = subdir_part + '@@' + myid - return myid + name_part = name.replace('/', '@').replace('\\', '@') + assert not has_path_sep(type_suffix) + my_id = name_part + type_suffix + if subdir: + subdir_part = Target._get_id_hash(subdir) + # preserve myid for better debuggability + return subdir_part + '@@' + my_id + return my_id + + def get_id(self): + return self.construct_id_from_path( + self.subdir, self.name, self.type_suffix()) def process_kwargs(self, kwargs): if 'build_by_default' in kwargs: |