Repository: mesonbuild/meson

Issue:
shared_library vs_modules_defs parameter dies when passed anything but string
I'm not sure whether the bug here is that passing a list (particularly an empty one) is not acceptable, or whether generating a giant stacktrace instead of a nice error message is the bug. But either a more helpful error message or accepting the empty list would be good.

meson psuedo code:
```meson
if cc.get_id() == 'msvc'
  def = 'foo.def'
else
  def = []
endif

libfoo = shared_library(
  'libfoo',
  'foo.c',
  vs_modules_def: def,
)
```


Discussion:
Actually, it's even worse. I can't use a generated file as input either.

Resolving patch:
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1191,12 +1191,22 @@ def process_kwargs(self, kwargs, environment):
         # Visual Studio module-definitions file
         if 'vs_module_defs' in kwargs:
             path = kwargs['vs_module_defs']
-            if os.path.isabs(path):
-                self.vs_module_defs = File.from_absolute_file(path)
+            if isinstance(path, str):
+                if os.path.isabs(path):
+                    self.vs_module_defs = File.from_absolute_file(path)
+                else:
+                    self.vs_module_defs = File.from_source_file(environment.source_dir, self.subdir, path)
+                # link_depends can be an absolute path or relative to self.subdir
+                self.link_depends.append(path)
+            elif isinstance(path, File):
+                # When passing a generated file.
+                self.vs_module_defs = path
+                # link_depends can be an absolute path or relative to self.subdir
+                self.link_depends.append(path.absolute_path(environment.source_dir, environment.build_dir))
             else:
-                self.vs_module_defs = File.from_source_file(environment.source_dir, self.subdir, path)
-            # link_depends can be an absolute path or relative to self.subdir
-            self.link_depends.append(path)
+                raise InvalidArguments(
+                    'Shared library vs_module_defs must be either a string, '
+                    'or a file object')
 
     def check_unknown_kwargs(self, kwargs):
         self.check_unknown_kwargs_int(kwargs, known_lib_kwargs)


Test patch:
diff --git a/test cases/windows/10 vs module defs generated/meson.build b/test cases/windows/10 vs module defs generated/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/windows/10 vs module defs generated/meson.build	
@@ -0,0 +1,7 @@
+project('generated_dll_module_defs', 'c')
+
+if meson.get_compiler('c').get_id() == 'msvc'
+  subdir('subdir')
+  exe = executable('prog', 'prog.c', link_with : shlib)
+  test('runtest', exe)
+endif
diff --git a/test cases/windows/10 vs module defs generated/prog.c b/test cases/windows/10 vs module defs generated/prog.c
new file mode 100644
--- /dev/null
+++ b/test cases/windows/10 vs module defs generated/prog.c	
@@ -0,0 +1,5 @@
+int somedllfunc();
+
+int main(int argc, char **argv) {
+    return somedllfunc() == 42 ? 0 : 1;
+}
diff --git a/test cases/windows/10 vs module defs generated/subdir/meson.build b/test cases/windows/10 vs module defs generated/subdir/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/windows/10 vs module defs generated/subdir/meson.build	
@@ -0,0 +1,9 @@
+conf = configuration_data()
+conf.set('func', 'somedllfunc')
+def_file = configure_file(
+  input: 'somedll.def.in',
+  output: 'somedll.def',
+  configuration : conf,
+)
+
+shlib = shared_library('somedll', 'somedll.c', vs_module_defs : def_file)
diff --git a/test cases/windows/10 vs module defs generated/subdir/somedll.c b/test cases/windows/10 vs module defs generated/subdir/somedll.c
new file mode 100644
--- /dev/null
+++ b/test cases/windows/10 vs module defs generated/subdir/somedll.c	
@@ -0,0 +1,5 @@
+#ifdef _MSC_VER
+int somedllfunc() {
+    return 42;
+}
+#endif
diff --git a/test cases/windows/10 vs module defs generated/subdir/somedll.def.in b/test cases/windows/10 vs module defs generated/subdir/somedll.def.in
new file mode 100644
--- /dev/null
+++ b/test cases/windows/10 vs module defs generated/subdir/somedll.def.in	
@@ -0,0 +1,2 @@
+EXPORTS
+    @func@