Merge pull request #1943 from QuLogic/duplicate-names

Fix creation of objects with duplicate names
pull/2315/head
Jussi Pakkanen 8 years ago committed by GitHub
commit 75208604da
  1. 53
      mesonbuild/backend/backends.py
  2. 39
      mesonbuild/backend/ninjabackend.py
  3. 34
      mesonbuild/backend/vs2010backend.py
  4. 16
      test cases/common/160 duplicate source names/dir1/file.c
  5. 1
      test cases/common/160 duplicate source names/dir1/meson.build
  6. 1
      test cases/common/160 duplicate source names/dir2/dir1/file.c
  7. 1
      test cases/common/160 duplicate source names/dir2/file.c
  8. 1
      test cases/common/160 duplicate source names/dir2/meson.build
  9. 1
      test cases/common/160 duplicate source names/dir3/dir1/file.c
  10. 1
      test cases/common/160 duplicate source names/dir3/file.c
  11. 1
      test cases/common/160 duplicate source names/dir3/meson.build
  12. 7
      test cases/common/160 duplicate source names/meson.build

@ -180,8 +180,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 = []
@ -189,18 +190,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
@ -310,13 +308,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 = os.path.join(self.get_target_private_dir(target), 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):
@ -330,9 +350,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)

@ -2116,39 +2116,21 @@ 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):
build_dir = self.environment.get_build_dir()
if isinstance(src, File):
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 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.
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:
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)
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('\\', '_')
raise InvalidArguments('Invalid source type: {!r}'.format(src))
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
@ -2181,6 +2163,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

@ -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'):
@ -1004,9 +974,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)

@ -0,0 +1,16 @@
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;
}

@ -0,0 +1 @@
sources += files('file.c', 'dir1/file.c')

@ -0,0 +1 @@
lib = static_library('lib', 'file.c', 'dir1/file.c')

@ -0,0 +1,7 @@
project('proj', 'c')
sources = []
subdir('dir1')
subdir('dir2')
subdir('dir3')
executable('a.out', sources : sources, objects : lib.extract_all_objects())
Loading…
Cancel
Save