aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2016-02-15 09:05:10 +0530
committerNirbheek Chauhan <nirbheek.chauhan@gmail.com>2016-03-30 16:24:35 +0530
commit1713fa02970ca2a045b1635186fef718620bf1b3 (patch)
tree6e0395fd46efec1338dab2db8f5b984e7115c1de
parent8945c85f968e851010b101ac2654aa3758470589 (diff)
downloadmeson-1713fa02970ca2a045b1635186fef718620bf1b3.zip
meson-1713fa02970ca2a045b1635186fef718620bf1b3.tar.gz
meson-1713fa02970ca2a045b1635186fef718620bf1b3.tar.bz2
Add shared_library argument for a Visual Studio module definitions file
On MSVC, shared libraries only export symbols that have been explicitly exported either as part of the symbol prototype or via a module definitions file. On compilers other than MSVC, all symbols are exported in the shared library by default and the format for the list of symbols to export is different, so this is only used with the VisualStudio compiler. The module defs file path can either be relative to the current source directory or an absolute path using meson.source_root() + '/some/path'
-rw-r--r--mesonbuild/backend/ninjabackend.py2
-rw-r--r--mesonbuild/build.py9
-rw-r--r--mesonbuild/compilers.py7
-rw-r--r--test cases/failing/28 no vs module defs/meson.build9
-rw-r--r--test cases/failing/28 no vs module defs/prog.c5
-rw-r--r--test cases/failing/28 no vs module defs/subdir/meson.build1
-rw-r--r--test cases/failing/28 no vs module defs/subdir/somedll.c7
-rw-r--r--test cases/windows/6 vs module defs/meson.build7
-rw-r--r--test cases/windows/6 vs module defs/prog.c5
-rw-r--r--test cases/windows/6 vs module defs/subdir/meson.build1
-rw-r--r--test cases/windows/6 vs module defs/subdir/somedll.c5
-rw-r--r--test cases/windows/6 vs module defs/subdir/somedll.def3
12 files changed, 60 insertions, 1 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 8e8fa42..29ce8cd 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -1657,6 +1657,8 @@ rule FORTRAN_DEP_HACK
else:
soversion = None
commands += linker.get_soname_args(target.name, abspath, soversion)
+ if target.vs_module_defs and hasattr(linker, 'gen_vs_module_defs_args'):
+ commands += linker.gen_vs_module_defs_args(target.vs_module_defs.rel_to_builddir(self.build_to_src))
elif isinstance(target, build.StaticLibrary):
commands += linker.get_std_link_args()
else:
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index ab9d0d5..8732987 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -47,7 +47,7 @@ known_shlib_kwargs.update({'version' : True,
'soversion' : True,
'name_prefix' : True,
'name_suffix' : True,
- })
+ 'vs_module_defs' : True})
backslash_explanation = \
'''Compiler arguments have a backslash "\\" character. This is unfortunately not
@@ -703,6 +703,7 @@ class SharedLibrary(BuildTarget):
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
self.version = None
self.soversion = None
+ self.vs_module_defs = None
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs);
if len(self.sources) > 0 and self.sources[0].endswith('.cs'):
prefix = 'lib'
@@ -726,6 +727,12 @@ class SharedLibrary(BuildTarget):
self.set_version(kwargs['version'])
if 'soversion' in kwargs:
self.set_soversion(kwargs['soversion'])
+ 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)
+ else:
+ self.vs_module_defs = File.from_source_file(environment.source_dir, self.subdir, path)
def check_unknown_kwargs(self, kwargs):
self.check_unknown_kwargs_int(kwargs, known_shlib_kwargs)
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index f1868dd..ff2df56 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -1252,6 +1252,13 @@ class VisualStudioCCompiler(CCompiler):
def get_std_shared_lib_link_args(self):
return ['/DLL']
+ def gen_vs_module_defs_args(self, defsfile):
+ if not isinstance(defsfile, str):
+ raise RuntimeError('Module definitions file should be str')
+ # With MSVC, DLLs only export symbols that are explicitly exported,
+ # so if a module defs file is specified, we use that to export symbols
+ return ['/DEF:' + defsfile]
+
def gen_pch_args(self, header, source, pchname):
objname = os.path.splitext(pchname)[0] + '.obj'
return (objname, ['/Yc' + header, '/Fp' + pchname, '/Fo' + objname ])
diff --git a/test cases/failing/28 no vs module defs/meson.build b/test cases/failing/28 no vs module defs/meson.build
new file mode 100644
index 0000000..7864daa
--- /dev/null
+++ b/test cases/failing/28 no vs module defs/meson.build
@@ -0,0 +1,9 @@
+project('dll_no_module_def', 'c')
+
+if meson.get_compiler('c').get_id() != 'msvc'
+ error('Need to use the Visual Studio compiler')
+endif
+
+subdir('subdir')
+exe = executable('prog', 'prog.c', link_with : shlib)
+test('runtest', exe)
diff --git a/test cases/failing/28 no vs module defs/prog.c b/test cases/failing/28 no vs module defs/prog.c
new file mode 100644
index 0000000..f35f4a0
--- /dev/null
+++ b/test cases/failing/28 no vs module defs/prog.c
@@ -0,0 +1,5 @@
+int somedllfunc();
+
+int main(int argc, char **argv) {
+ return somedllfunc() == 42 ? 0 : 1;
+}
diff --git a/test cases/failing/28 no vs module defs/subdir/meson.build b/test cases/failing/28 no vs module defs/subdir/meson.build
new file mode 100644
index 0000000..8395d59
--- /dev/null
+++ b/test cases/failing/28 no vs module defs/subdir/meson.build
@@ -0,0 +1 @@
+shlib = shared_library('somedll', 'somedll.c')
diff --git a/test cases/failing/28 no vs module defs/subdir/somedll.c b/test cases/failing/28 no vs module defs/subdir/somedll.c
new file mode 100644
index 0000000..5c469b1
--- /dev/null
+++ b/test cases/failing/28 no vs module defs/subdir/somedll.c
@@ -0,0 +1,7 @@
+/* With MSVC, the DLL created from this will not export any symbols
+ * without a module definitions file specified while linking */
+#ifdef _MSC_VER
+int somedllfunc() {
+ return 42;
+}
+#endif
diff --git a/test cases/windows/6 vs module defs/meson.build b/test cases/windows/6 vs module defs/meson.build
new file mode 100644
index 0000000..4b9e735
--- /dev/null
+++ b/test cases/windows/6 vs module defs/meson.build
@@ -0,0 +1,7 @@
+project('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/6 vs module defs/prog.c b/test cases/windows/6 vs module defs/prog.c
new file mode 100644
index 0000000..f35f4a0
--- /dev/null
+++ b/test cases/windows/6 vs module defs/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/6 vs module defs/subdir/meson.build b/test cases/windows/6 vs module defs/subdir/meson.build
new file mode 100644
index 0000000..60633c3
--- /dev/null
+++ b/test cases/windows/6 vs module defs/subdir/meson.build
@@ -0,0 +1 @@
+shlib = shared_library('somedll', 'somedll.c', vs_module_defs : 'somedll.def')
diff --git a/test cases/windows/6 vs module defs/subdir/somedll.c b/test cases/windows/6 vs module defs/subdir/somedll.c
new file mode 100644
index 0000000..df255e3
--- /dev/null
+++ b/test cases/windows/6 vs module defs/subdir/somedll.c
@@ -0,0 +1,5 @@
+#ifdef _MSC_VER
+int somedllfunc() {
+ return 42;
+}
+#endif
diff --git a/test cases/windows/6 vs module defs/subdir/somedll.def b/test cases/windows/6 vs module defs/subdir/somedll.def
new file mode 100644
index 0000000..217801b
--- /dev/null
+++ b/test cases/windows/6 vs module defs/subdir/somedll.def
@@ -0,0 +1,3 @@
+EXPORTS
+ somedllfunc
+