aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2017-09-12 20:37:43 +0300
committerGitHub <noreply@github.com>2017-09-12 20:37:43 +0300
commit75208604da780e81a4204332cf31e3a7054c80e8 (patch)
treeb1ac699e2801429ae3585e0527e8f4c3ee014492
parentb63710863b277c19ab38eef8f47ff9df5f173822 (diff)
parentcf1242655f3c6c914582d0de6b5cfb0e67af8401 (diff)
downloadmeson-75208604da780e81a4204332cf31e3a7054c80e8.zip
meson-75208604da780e81a4204332cf31e3a7054c80e8.tar.gz
meson-75208604da780e81a4204332cf31e3a7054c80e8.tar.bz2
Merge pull request #1943 from QuLogic/duplicate-names
Fix creation of objects with duplicate names
-rw-r--r--mesonbuild/backend/backends.py53
-rw-r--r--mesonbuild/backend/ninjabackend.py39
-rw-r--r--mesonbuild/backend/vs2010backend.py34
-rw-r--r--test cases/common/160 duplicate source names/dir1/file.c16
-rw-r--r--test cases/common/160 duplicate source names/dir1/meson.build1
-rw-r--r--test cases/common/160 duplicate source names/dir2/dir1/file.c1
-rw-r--r--test cases/common/160 duplicate source names/dir2/file.c1
-rw-r--r--test cases/common/160 duplicate source names/dir2/meson.build1
-rw-r--r--test cases/common/160 duplicate source names/dir3/dir1/file.c1
-rw-r--r--test cases/common/160 duplicate source names/dir3/file.c1
-rw-r--r--test cases/common/160 duplicate source names/dir3/meson.build1
-rw-r--r--test cases/common/160 duplicate source names/meson.build7
12 files changed, 78 insertions, 78 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 3cdf705..97959b6 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -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)
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index bff173a..bac984b 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -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
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index ec5ad7d..0bbc17c 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'):
@@ -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)
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..094e187
--- /dev/null
+++ b/test cases/common/160 duplicate source names/dir1/file.c
@@ -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;
+}
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..5aac8e5
--- /dev/null
+++ 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
new file mode 100644
index 0000000..6cf8d66
--- /dev/null
+++ 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/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..04667c2
--- /dev/null
+++ 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
new file mode 100644
index 0000000..d16d0a8
--- /dev/null
+++ 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
new file mode 100644
index 0000000..70ddbf2
--- /dev/null
+++ b/test cases/common/160 duplicate source names/dir3/meson.build
@@ -0,0 +1 @@
+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
new file mode 100644
index 0000000..cac5194
--- /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_all_objects())