Repository: mesonbuild/meson

Issue:
[Vala] can't compile files that have the same name but are on different directories
When a project has two files with the same name in multiple directories, meson claims that it has `Multiple producers for Ninja target`
Here is a branch that adds the required test case https://github.com/tintou/meson/commit/960bf0e921d59d301b29e19596d1b398628d4324
I believe that the issue is located in [`./mesonbuild/backend/ninjabackend.py` line 1136](https://github.com/mesonbuild/meson/blob/master/mesonbuild/backend/ninjabackend.py#L1136) but I have no idea how can I fix this.

Thanks in advance


Discussion:

Resolving patch:
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -1131,9 +1131,13 @@ def generate_vala_compile(self, target, outfile):
             # file is outside the build directory, the path components will be
             # stripped and just the basename will be used.
             if isinstance(gensrc, (build.CustomTarget, build.GeneratedList)) or gensrc.is_built:
-                vala_c_file = os.path.splitext(vala_file)[0] + '.c'
-            else:
                 vala_c_file = os.path.splitext(os.path.basename(vala_file))[0] + '.c'
+            else:
+                path_to_target = os.path.join(self.build_to_src, target.get_subdir())
+                if vala_file.startswith(path_to_target):
+                    vala_c_file = os.path.splitext(os.path.relpath(vala_file, path_to_target))[0] + '.c'
+                else:
+                    vala_c_file = os.path.splitext(os.path.basename(vala_file))[0] + '.c'
             # All this will be placed inside the c_out_dir
             vala_c_file = os.path.join(c_out_dir, vala_c_file)
             vala_c_src.append(vala_c_file)
@@ -1144,13 +1148,14 @@ def generate_vala_compile(self, target, outfile):
         # Tell Valac to output everything in our private directory. Sadly this
         # means it will also preserve the directory components of Vala sources
         # found inside the build tree (generated sources).
-        args += ['-d', c_out_dir]
+        args += ['--directory', c_out_dir]
+        args += ['--basedir', os.path.join(self.build_to_src, target.get_subdir())]
         if not isinstance(target, build.Executable):
             # Library name
-            args += ['--library=' + target.name]
+            args += ['--library', target.name]
             # Outputted header
             hname = os.path.join(self.get_target_dir(target), target.vala_header)
-            args += ['-H', hname]
+            args += ['--header', hname]
             if self.is_unity(target):
                 # Without this the declarations will get duplicated in the .c
                 # files and cause a build failure when all of them are


Test patch:
diff --git a/test cases/vala/22 same target in directories/Subdir/Subdir2/Test.vala b/test cases/vala/22 same target in directories/Subdir/Subdir2/Test.vala
new file mode 100644
--- /dev/null
+++ b/test cases/vala/22 same target in directories/Subdir/Subdir2/Test.vala	
@@ -0,0 +1,5 @@
+public class Subdir.Subdir2.Test : GLib.Object {
+    construct {
+        stdout.printf("Test from Subdir/Subdir2/\n");
+    }
+}
diff --git a/test cases/vala/22 same target in directories/Subdir/Test.vala b/test cases/vala/22 same target in directories/Subdir/Test.vala
new file mode 100644
--- /dev/null
+++ b/test cases/vala/22 same target in directories/Subdir/Test.vala	
@@ -0,0 +1,5 @@
+public class Subdir.Test : GLib.Object {
+    construct {
+        stdout.printf("Test from Subdir/\n");
+    }
+}
diff --git a/test cases/vala/22 same target in directories/Subdir2/Test.vala b/test cases/vala/22 same target in directories/Subdir2/Test.vala
new file mode 100644
--- /dev/null
+++ b/test cases/vala/22 same target in directories/Subdir2/Test.vala	
@@ -0,0 +1,5 @@
+public class Subdir2.Test : GLib.Object {
+    construct {
+        stdout.printf("Test from Subdir2/\n");
+    }
+}
diff --git a/test cases/vala/22 same target in directories/Test.vala b/test cases/vala/22 same target in directories/Test.vala
new file mode 100644
--- /dev/null
+++ b/test cases/vala/22 same target in directories/Test.vala	
@@ -0,0 +1,5 @@
+public class Test : GLib.Object {
+    construct {
+        stdout.printf("Test from main directory\n");
+    }
+}
diff --git a/test cases/vala/22 same target in directories/meson.build b/test cases/vala/22 same target in directories/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/vala/22 same target in directories/meson.build	
@@ -0,0 +1,13 @@
+project('valatest', 'vala', 'c')
+
+valadeps = [dependency('glib-2.0'), dependency('gobject-2.0')]
+valafiles = files(
+    'prog.vala',
+    'Test.vala',
+    'Subdir/Test.vala',
+    'Subdir/Subdir2/Test.vala',
+    'Subdir2/Test.vala',
+)
+
+e = executable('multidir_prog', valafiles, dependencies : valadeps)
+test('valatest', e)
diff --git a/test cases/vala/22 same target in directories/prog.vala b/test cases/vala/22 same target in directories/prog.vala
new file mode 100644
--- /dev/null
+++ b/test cases/vala/22 same target in directories/prog.vala	
@@ -0,0 +1,8 @@
+int main() {
+    var test1 = new Test ();
+    var test2 = new Subdir.Test ();
+    var test3 = new Subdir2.Test ();
+    var test4 = new Subdir.Subdir2.Test ();
+    stdout.printf("Vala is working.\n");
+    return 0;
+}