From bf0164ff6e6b82328a438bb5f5ad4988c5c3ff2a Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 14 Jun 2017 04:50:58 -0400 Subject: [PATCH] Use full relative paths to generate object names. This prevents files with the same name from different directories from producing object files with the same name and breaking ninja. Fixes #1494. --- mesonbuild/backend/backends.py | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 0496b386e..c2264ab41 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -309,13 +309,35 @@ class Backend: return result def object_filename_from_source(self, target, source, is_unity): - if isinstance(source, mesonlib.File): - source = source.fname + assert isinstance(source, mesonlib.File) + build_dir = self.environment.get_build_dir() + rel_src = source.rel_to_builddir(self.build_to_src) # foo.vala files compile down to foo.c and then foo.c.o, not foo.vala.o - if source.endswith(('.vala', '.gs')): + if rel_src.endswith(('.vala', '.gs')): + # See description in generate_vala_compile for this logic. + if source.is_built: + if os.path.isabs(rel_src): + rel_src = rel_src[len(build_dir) + 1:] + rel_src = os.path.relpath(rel_src, self.get_target_private_dir(target)) + else: + rel_src = os.path.basename(rel_src) if is_unity: - return source[:-5] + '.c.' + self.environment.get_object_suffix() - source = source[:-5] + '.c' + return 'meson-generated_' + rel_src[:-5] + '.c.' + self.environment.get_object_suffix() + # A meson- prefixed directory is reserved; hopefully no-one creates a file name with such a weird prefix. + source = 'meson-generated_' + rel_src[:-5] + '.c' + elif source.is_built: + if os.path.isabs(rel_src): + rel_src = rel_src[len(build_dir) + 1:] + targetdir = self.get_target_private_dir(target) + # A meson- prefixed directory is reserved; hopefully no-one creates a file name with such a weird prefix. + source = 'meson-generated_' + os.path.relpath(rel_src, targetdir) + else: + if os.path.isabs(rel_src): + # Not from the source directory; hopefully this doesn't conflict with user's source files. + source = os.path.basename(rel_src) + else: + source = os.path.relpath(os.path.join(build_dir, rel_src), + os.path.join(self.environment.get_source_dir(), target.get_subdir())) return source.replace('/', '_').replace('\\', '_') + '.' + self.environment.get_object_suffix() def determine_ext_objs(self, target, extobj, proj_dir_to_build_root):