From 48580ac8a322bb760fc00e6d74dde63225f3ee0a Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 13 Jun 2017 01:16:06 -0400 Subject: Add broken test case from #1494. Also, check a file with a subdirectory and extract_objects(). --- test cases/common/160 duplicate source names/dir1/file.c | 1 + test cases/common/160 duplicate source names/dir1/meson.build | 1 + test cases/common/160 duplicate source names/dir2/dir1/file.c | 0 test cases/common/160 duplicate source names/dir2/file.c | 0 test cases/common/160 duplicate source names/dir2/meson.build | 1 + test cases/common/160 duplicate source names/dir3/dir1/file.c | 0 test cases/common/160 duplicate source names/dir3/file.c | 0 test cases/common/160 duplicate source names/dir3/meson.build | 1 + test cases/common/160 duplicate source names/meson.build | 7 +++++++ 9 files changed, 11 insertions(+) create mode 100644 test cases/common/160 duplicate source names/dir1/file.c create mode 100644 test cases/common/160 duplicate source names/dir1/meson.build create mode 100644 test cases/common/160 duplicate source names/dir2/dir1/file.c create mode 100644 test cases/common/160 duplicate source names/dir2/file.c create mode 100644 test cases/common/160 duplicate source names/dir2/meson.build create mode 100644 test cases/common/160 duplicate source names/dir3/dir1/file.c create mode 100644 test cases/common/160 duplicate source names/dir3/file.c create mode 100644 test cases/common/160 duplicate source names/dir3/meson.build create mode 100644 test cases/common/160 duplicate source names/meson.build diff --git a/test cases/common/160 duplicate source names/dir1/file.c b/test cases/common/160 duplicate source names/dir1/file.c new file mode 100644 index 0000000..76e8197 --- /dev/null +++ b/test cases/common/160 duplicate source names/dir1/file.c @@ -0,0 +1 @@ +int main() { return 0; } diff --git a/test cases/common/160 duplicate source names/dir1/meson.build b/test cases/common/160 duplicate source names/dir1/meson.build new file mode 100644 index 0000000..00bc85d --- /dev/null +++ b/test cases/common/160 duplicate source names/dir1/meson.build @@ -0,0 +1 @@ +sources += files('file.c') diff --git a/test cases/common/160 duplicate source names/dir2/dir1/file.c b/test cases/common/160 duplicate source names/dir2/dir1/file.c new file mode 100644 index 0000000..e69de29 diff --git a/test cases/common/160 duplicate source names/dir2/file.c b/test cases/common/160 duplicate source names/dir2/file.c new file mode 100644 index 0000000..e69de29 diff --git a/test cases/common/160 duplicate source names/dir2/meson.build b/test cases/common/160 duplicate source names/dir2/meson.build new file mode 100644 index 0000000..f116a02 --- /dev/null +++ b/test cases/common/160 duplicate source names/dir2/meson.build @@ -0,0 +1 @@ +sources += files('file.c', 'dir1/file.c') diff --git a/test cases/common/160 duplicate source names/dir3/dir1/file.c b/test cases/common/160 duplicate source names/dir3/dir1/file.c new file mode 100644 index 0000000..e69de29 diff --git a/test cases/common/160 duplicate source names/dir3/file.c b/test cases/common/160 duplicate source names/dir3/file.c new file mode 100644 index 0000000..e69de29 diff --git a/test cases/common/160 duplicate source names/dir3/meson.build b/test cases/common/160 duplicate source names/dir3/meson.build new file mode 100644 index 0000000..08a2b9c --- /dev/null +++ b/test cases/common/160 duplicate source names/dir3/meson.build @@ -0,0 +1 @@ +lib = static_library('empty', 'file.c', 'dir1/file.c') diff --git a/test cases/common/160 duplicate source names/meson.build b/test cases/common/160 duplicate source names/meson.build new file mode 100644 index 0000000..30d7ad0 --- /dev/null +++ b/test cases/common/160 duplicate source names/meson.build @@ -0,0 +1,7 @@ +project('proj', 'c') + +sources = [] +subdir('dir1') +subdir('dir2') +subdir('dir3') +executable('a.out', sources : sources, objects : lib.extract_objects()) -- cgit v1.1 From c09586462cbf36477a505dd3cdaa7a80da17dbbd Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 13 Jun 2017 01:53:41 -0400 Subject: Add variables to test to prove linkage is correct. --- .../common/160 duplicate source names/dir1/file.c | 17 ++++++++++++++++- .../common/160 duplicate source names/dir2/dir1/file.c | 1 + .../common/160 duplicate source names/dir2/file.c | 1 + .../common/160 duplicate source names/dir3/dir1/file.c | 1 + .../common/160 duplicate source names/dir3/file.c | 1 + .../common/160 duplicate source names/dir3/meson.build | 2 +- .../common/160 duplicate source names/meson.build | 2 +- 7 files changed, 22 insertions(+), 3 deletions(-) diff --git a/test cases/common/160 duplicate source names/dir1/file.c b/test cases/common/160 duplicate source names/dir1/file.c index 76e8197..094e187 100644 --- a/test cases/common/160 duplicate source names/dir1/file.c +++ b/test cases/common/160 duplicate source names/dir1/file.c @@ -1 +1,16 @@ -int main() { return 0; } +extern int dir2; +extern int dir2_dir1; +extern int dir3; +extern int dir3_dir1; + +int main() { + if (dir2 != 20) + return 1; + if (dir2_dir1 != 21) + return 1; + if (dir3 != 30) + return 1; + if (dir3_dir1 != 31) + return 1; + return 0; +} diff --git a/test cases/common/160 duplicate source names/dir2/dir1/file.c b/test cases/common/160 duplicate source names/dir2/dir1/file.c index e69de29..5aac8e5 100644 --- a/test cases/common/160 duplicate source names/dir2/dir1/file.c +++ b/test cases/common/160 duplicate source names/dir2/dir1/file.c @@ -0,0 +1 @@ +int dir2_dir1 = 21; diff --git a/test cases/common/160 duplicate source names/dir2/file.c b/test cases/common/160 duplicate source names/dir2/file.c index e69de29..6cf8d66 100644 --- a/test cases/common/160 duplicate source names/dir2/file.c +++ b/test cases/common/160 duplicate source names/dir2/file.c @@ -0,0 +1 @@ +int dir2 = 20; diff --git a/test cases/common/160 duplicate source names/dir3/dir1/file.c b/test cases/common/160 duplicate source names/dir3/dir1/file.c index e69de29..04667c2 100644 --- a/test cases/common/160 duplicate source names/dir3/dir1/file.c +++ b/test cases/common/160 duplicate source names/dir3/dir1/file.c @@ -0,0 +1 @@ +int dir3_dir1 = 31; diff --git a/test cases/common/160 duplicate source names/dir3/file.c b/test cases/common/160 duplicate source names/dir3/file.c index e69de29..d16d0a8 100644 --- a/test cases/common/160 duplicate source names/dir3/file.c +++ b/test cases/common/160 duplicate source names/dir3/file.c @@ -0,0 +1 @@ +int dir3 = 30; diff --git a/test cases/common/160 duplicate source names/dir3/meson.build b/test cases/common/160 duplicate source names/dir3/meson.build index 08a2b9c..70ddbf2 100644 --- a/test cases/common/160 duplicate source names/dir3/meson.build +++ b/test cases/common/160 duplicate source names/dir3/meson.build @@ -1 +1 @@ -lib = static_library('empty', 'file.c', 'dir1/file.c') +lib = static_library('lib', 'file.c', 'dir1/file.c') diff --git a/test cases/common/160 duplicate source names/meson.build b/test cases/common/160 duplicate source names/meson.build index 30d7ad0..cac5194 100644 --- a/test cases/common/160 duplicate source names/meson.build +++ b/test cases/common/160 duplicate source names/meson.build @@ -4,4 +4,4 @@ sources = [] subdir('dir1') subdir('dir2') subdir('dir3') -executable('a.out', sources : sources, objects : lib.extract_objects()) +executable('a.out', sources : sources, objects : lib.extract_all_objects()) -- cgit v1.1 From ba6fdb996a56c10ce1517c2b97051619ea083f91 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 13 Jun 2017 03:43:12 -0400 Subject: Simplify path-determination in compile-generation. --- mesonbuild/backend/ninjabackend.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 0587cff..4283896 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2102,24 +2102,23 @@ rule FORTRAN_DEP_HACK self.target_arg_cache[key] = commands commands = CompilerArgs(commands.compiler, commands) - if isinstance(src, mesonlib.File) and src.is_built: - rel_src = os.path.join(src.subdir, src.fname) - if os.path.isabs(rel_src): - assert(rel_src.startswith(self.environment.get_build_dir())) - rel_src = rel_src[len(self.environment.get_build_dir()) + 1:] - abs_src = os.path.join(self.environment.get_build_dir(), rel_src) - elif isinstance(src, mesonlib.File): + if isinstance(src, File): + source_dir = self.environment.get_source_dir() + build_dir = self.environment.get_build_dir() + abs_src = src.absolute_path(source_dir, build_dir) rel_src = src.rel_to_builddir(self.build_to_src) - abs_src = src.absolute_path(self.environment.get_source_dir(), - self.environment.get_build_dir()) + if src.is_built: + assert abs_src.startswith(build_dir) + if os.path.isabs(rel_src): + rel_src = rel_src[len(build_dir) + 1:] + else: + # Source files may not be from the source directory if they originate in source-only libraries, + # so we can't assert that the absolute path is anywhere in particular. + pass elif is_generated: raise AssertionError('BUG: broken generated source file handling for {!r}'.format(src)) else: - if isinstance(src, File): - rel_src = src.rel_to_builddir(self.build_to_src) - else: - raise InvalidArguments('Invalid source type: {!r}'.format(src)) - abs_src = os.path.join(self.environment.get_build_dir(), rel_src) + raise InvalidArguments('Invalid source type: {!r}'.format(src)) if isinstance(src, File): if src.is_built: src_filename = os.path.join(src.subdir, src.fname) -- cgit v1.1 From 879770ccf00f875618960f2063faaeb387377f88 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 13 Jun 2017 05:44:25 -0400 Subject: Only calculate absolute source path when necessary. --- mesonbuild/backend/ninjabackend.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 4283896..e9f5acc 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2102,19 +2102,15 @@ rule FORTRAN_DEP_HACK self.target_arg_cache[key] = commands commands = CompilerArgs(commands.compiler, commands) + build_dir = self.environment.get_build_dir() if isinstance(src, File): - source_dir = self.environment.get_source_dir() - build_dir = self.environment.get_build_dir() - abs_src = src.absolute_path(source_dir, build_dir) rel_src = src.rel_to_builddir(self.build_to_src) - if src.is_built: - assert abs_src.startswith(build_dir) - if os.path.isabs(rel_src): - rel_src = rel_src[len(build_dir) + 1:] - else: + if os.path.isabs(rel_src): # Source files may not be from the source directory if they originate in source-only libraries, # so we can't assert that the absolute path is anywhere in particular. - pass + if src.is_built: + assert rel_src.startswith(build_dir) + rel_src = rel_src[len(build_dir) + 1:] elif is_generated: raise AssertionError('BUG: broken generated source file handling for {!r}'.format(src)) else: @@ -2166,6 +2162,7 @@ rule FORTRAN_DEP_HACK # outdir argument instead. # https://github.com/mesonbuild/meson/issues/1348 if not is_generated: + abs_src = os.path.join(build_dir, rel_src) extra_deps += self.get_fortran_deps(compiler, abs_src, target) # Dependency hack. Remove once multiple outputs in Ninja is fixed: # https://groups.google.com/forum/#!topic/ninja-build/j-2RfBIOd_8 -- cgit v1.1 From b68cb3c713337dda159faf203ece775d30825a1d Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 13 Jun 2017 06:29:57 -0400 Subject: Use object_filename_from_source when creating objects. This will ensure a consistent path between generated object names and names expected of extracted objects. --- mesonbuild/backend/backends.py | 2 +- mesonbuild/backend/ninjabackend.py | 15 +-------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index f967de0..0496b38 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -315,7 +315,7 @@ class Backend: if source.endswith(('.vala', '.gs')): if is_unity: return source[:-5] + '.c.' + self.environment.get_object_suffix() - source = os.path.join(self.get_target_private_dir(target), source[:-5] + '.c') + source = source[:-5] + '.c' return source.replace('/', '_').replace('\\', '_') + '.' + self.environment.get_object_suffix() def determine_ext_objs(self, target, extobj, proj_dir_to_build_root): diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index e9f5acc..68daaac 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2115,21 +2115,8 @@ rule FORTRAN_DEP_HACK raise AssertionError('BUG: broken generated source file handling for {!r}'.format(src)) else: raise InvalidArguments('Invalid source type: {!r}'.format(src)) - if isinstance(src, File): - if src.is_built: - src_filename = os.path.join(src.subdir, src.fname) - if os.path.isabs(src_filename): - assert(src_filename.startswith(self.environment.get_build_dir())) - src_filename = src_filename[len(self.environment.get_build_dir()) + 1:] - else: - src_filename = src.fname - elif os.path.isabs(src): - src_filename = os.path.basename(src) - else: - src_filename = src - obj_basename = src_filename.replace('/', '_').replace('\\', '_') + obj_basename = self.object_filename_from_source(target, src, self.is_unity(target)) rel_obj = os.path.join(self.get_target_private_dir(target), obj_basename) - rel_obj += '.' + self.environment.get_object_suffix() dep_file = compiler.depfile_for_object(rel_obj) # Add MSVC debug file generation compile flags: /Fd /FS -- cgit v1.1 From bf0164ff6e6b82328a438bb5f5ad4988c5c3ff2a Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 14 Jun 2017 04:50:58 -0400 Subject: 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 0496b38..c2264ab 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): -- cgit v1.1 From 320862991a22026b257ffa4b735cdf00a4b74c8c Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 22 Jun 2017 18:39:51 -0400 Subject: Fix object extraction in unity builds. --- mesonbuild/backend/backends.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index c2264ab..6723b26 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -179,8 +179,9 @@ class Backend: # target that the GeneratedList is used in return os.path.join(self.get_target_private_dir(target), src) - def get_unity_source_filename(self, target, suffix): - return target.name + '-unity.' + suffix + def get_unity_source_file(self, target, suffix): + osrc = target.name + '-unity.' + suffix + return mesonlib.File.from_built_file(self.get_target_private_dir(target), osrc) def generate_unity_files(self, target, unity_src): abs_files = [] @@ -188,18 +189,15 @@ class Backend: compsrcs = classify_unity_sources(target.compilers.values(), unity_src) def init_language_file(suffix): - unity_src_name = self.get_unity_source_filename(target, suffix) - unity_src_subdir = self.get_target_private_dir_abs(target) - outfilename = os.path.join(unity_src_subdir, - unity_src_name) - outfileabs = os.path.join(self.environment.get_build_dir(), - outfilename) + unity_src = self.get_unity_source_file(target, suffix) + outfileabs = unity_src.absolute_path(self.environment.get_source_dir(), + self.environment.get_build_dir()) outfileabs_tmp = outfileabs + '.tmp' abs_files.append(outfileabs) outfileabs_tmp_dir = os.path.dirname(outfileabs_tmp) if not os.path.exists(outfileabs_tmp_dir): os.makedirs(outfileabs_tmp_dir) - result.append(mesonlib.File(True, unity_src_subdir, unity_src_name)) + result.append(unity_src) return open(outfileabs_tmp, 'w') # For each language, generate a unity source file and return the list @@ -351,9 +349,8 @@ class Backend: extobj.srclist[0]) # There is a potential conflict here, but it is unlikely that # anyone both enables unity builds and has a file called foo-unity.cpp. - osrc = self.get_unity_source_filename(extobj.target, - comp.get_default_suffix()) - osrc = os.path.join(self.get_target_private_dir(extobj.target), osrc) + osrc = self.get_unity_source_file(extobj.target, + comp.get_default_suffix()) objname = self.object_filename_from_source(extobj.target, osrc, True) objname = objname.replace('/', '_').replace('\\', '_') objpath = os.path.join(proj_dir_to_build_root, targetdir, objname) -- cgit v1.1 From cf1242655f3c6c914582d0de6b5cfb0e67af8401 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Mon, 14 Aug 2017 17:30:13 -0400 Subject: Remove VS implementation of object name resolver. The upstream one should work properly now, one hopes. --- mesonbuild/backend/vs2010backend.py | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 4832f7e..2e38356 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -80,39 +80,10 @@ class Vs2010Backend(backends.Backend): super().__init__(build) self.name = 'vs2010' self.project_file_version = '10.0.30319.1' - self.sources_conflicts = {} self.platform_toolset = None self.vs_version = '2010' self.windows_target_platform_version = None - def object_filename_from_source(self, target, source, is_unity=False): - basename = os.path.basename(source.fname) - filename_without_extension = '.'.join(basename.split('.')[:-1]) - if basename in self.sources_conflicts[target.get_id()]: - # If there are multiple source files with the same basename, we must resolve the conflict - # by giving each a unique object output file. - filename_without_extension = '.'.join(source.fname.split('.')[:-1]).replace('/', '_').replace('\\', '_') - return filename_without_extension + '.' + self.environment.get_object_suffix() - - def resolve_source_conflicts(self): - for name, target in self.build.targets.items(): - if not isinstance(target, BuildTarget): - continue - conflicts = {} - for s in target.get_sources(): - if hasattr(s, 'held_object'): - s = s.held_object - if not isinstance(s, File): - continue - basename = os.path.basename(s.fname) - conflicting_sources = conflicts.get(basename, None) - if conflicting_sources is None: - conflicting_sources = [] - conflicts[basename] = conflicting_sources - conflicting_sources.append(s) - self.sources_conflicts[target.get_id()] = {name: src_conflicts for name, src_conflicts in conflicts.items() - if len(src_conflicts) > 1} - def generate_custom_generator_commands(self, target, parent_node): generator_output_files = [] custom_target_include_dirs = [] @@ -164,7 +135,6 @@ class Vs2010Backend(backends.Backend): return generator_output_files, custom_target_output_files, custom_target_include_dirs def generate(self, interp): - self.resolve_source_conflicts() self.interpreter = interp target_machine = self.interpreter.builtin['target_machine'].cpu_family_method(None, None) if target_machine.endswith('64'): @@ -1003,9 +973,7 @@ class Vs2010Backend(backends.Backend): self.add_additional_options(lang, inc_cl, file_args) self.add_preprocessor_defines(lang, inc_cl, file_defines) self.add_include_dirs(lang, inc_cl, file_inc_dirs) - basename = os.path.basename(s.fname) - if basename in self.sources_conflicts[target.get_id()]: - ET.SubElement(inc_cl, 'ObjectFileName').text = "$(IntDir)" + self.object_filename_from_source(target, s) + ET.SubElement(inc_cl, 'ObjectFileName').text = "$(IntDir)" + self.object_filename_from_source(target, s, False) for s in gen_src: inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=s) lang = Vs2010Backend.lang_from_source_file(s) -- cgit v1.1