aboutsummaryrefslogtreecommitdiff
path: root/test cases
diff options
context:
space:
mode:
authorJon Turney <jon.turney@dronecode.org.uk>2017-04-14 13:58:21 +0100
committerJon Turney <jon.turney@dronecode.org.uk>2017-07-20 21:11:56 +0100
commit3fa3922cea27026d44aef1cdf3ca92d82adc7ced (patch)
tree512b4bed85b53dfd95add859b0724a1ed84d9754 /test cases
parentb43f4841ba5de2e8bc956eb9fd1f578f90d7ae15 (diff)
downloadmeson-3fa3922cea27026d44aef1cdf3ca92d82adc7ced.zip
meson-3fa3922cea27026d44aef1cdf3ca92d82adc7ced.tar.gz
meson-3fa3922cea27026d44aef1cdf3ca92d82adc7ced.tar.bz2
Support implibs for executables on Windows
Add a boolean 'implib' kwarg to executable(). If true, it is permitted to use the returned build target object in link_with: On platforms where this makes sense (e.g. Windows), an implib is generated for the executable and used when linking. Otherwise, it has no effect. (Rather than checking if it is a StaticLibrary or SharedLibary, BuildTarget subclasses gain the is_linkable_target method to test if they can appear in link_with:) Also install any executable implib in a similar way to a shared library implib, i.e. placing the implib in the appropriate place Add tests of: - a shared_module containing a reference to a symbol which is known (at link time) to be provided by the executable - trying to link with non-implib executables (should fail) - installing the implib (This last one needs a little enhancement of the installed file checking as this is the first install test we have which needs to work with either MSVC-style or GCC-style implib filenames)
Diffstat (limited to 'test cases')
-rw-r--r--test cases/common/154 shared module resolving symbol in executable/meson.build24
-rw-r--r--test cases/common/154 shared module resolving symbol in executable/module.c16
-rw-r--r--test cases/common/154 shared module resolving symbol in executable/prog.c60
-rw-r--r--test cases/failing/57 link with executable/meson.build4
-rw-r--r--test cases/failing/57 link with executable/module.c4
-rw-r--r--test cases/failing/57 link with executable/prog.c5
-rw-r--r--test cases/windows/12 exe implib/installed_files.txt4
-rw-r--r--test cases/windows/12 exe implib/meson.build7
-rw-r--r--test cases/windows/12 exe implib/prog.c6
9 files changed, 130 insertions, 0 deletions
diff --git a/test cases/common/154 shared module resolving symbol in executable/meson.build b/test cases/common/154 shared module resolving symbol in executable/meson.build
new file mode 100644
index 0000000..06c9902
--- /dev/null
+++ b/test cases/common/154 shared module resolving symbol in executable/meson.build
@@ -0,0 +1,24 @@
+project('shared module resolving symbol in executable', 'c')
+
+# The shared module contains a reference to the symbol 'func_from_executable',
+# which is always provided by the executable which loads it. This symbol can be
+# resolved at run-time by an ELF loader. But when building PE/COFF objects, all
+# symbols must be resolved at link-time, so an implib is generated for the
+# executable, and the shared module linked with it.
+#
+# See testcase 125 for an example of the more complex portability gymnastics
+# required if we do not know (at link-time) what provides the symbol.
+
+link_flags = []
+if host_machine.system() != 'windows'
+ # Needed to export dynamic symbols from the executable
+ link_flags += ['-rdynamic']
+ # Need to add this manually because Meson won't add it automatically because
+ # it doesn't know that we are loading a module from the build directory.
+ link_flags += ['-Wl,-rpath,' + meson.current_build_dir()]
+endif
+
+dl = meson.get_compiler('c').find_library('dl', required: false)
+e = executable('prog', 'prog.c', dependencies: dl, implib: true, link_args: link_flags)
+m = shared_module('module', 'module.c', link_with: e)
+test('test', e, args: m)
diff --git a/test cases/common/154 shared module resolving symbol in executable/module.c b/test cases/common/154 shared module resolving symbol in executable/module.c
new file mode 100644
index 0000000..64374d5
--- /dev/null
+++ b/test cases/common/154 shared module resolving symbol in executable/module.c
@@ -0,0 +1,16 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+extern int func_from_executable(void);
+
+int DLL_PUBLIC func(void) {
+ return func_from_executable();
+}
diff --git a/test cases/common/154 shared module resolving symbol in executable/prog.c b/test cases/common/154 shared module resolving symbol in executable/prog.c
new file mode 100644
index 0000000..746c192
--- /dev/null
+++ b/test cases/common/154 shared module resolving symbol in executable/prog.c
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <assert.h>
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <dlfcn.h>
+#endif
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+typedef int (*fptr) (void);
+
+int DLL_PUBLIC
+func_from_executable(void)
+{
+ return 42;
+}
+
+int
+main (int argc, char **argv)
+{
+ int expected, actual;
+ fptr importedfunc;
+
+#ifdef _WIN32
+ HMODULE h = LoadLibraryA(argv[1]);
+#else
+ void *h = dlopen(argv[1], RTLD_NOW);
+#endif
+ assert(h != NULL);
+
+#ifdef _WIN32
+ importedfunc = (fptr) GetProcAddress (h, "func");
+#else
+ importedfunc = (fptr) dlsym(h, "func");
+#endif
+ assert(importedfunc != NULL);
+ assert(importedfunc != func_from_executable);
+
+ actual = (*importedfunc)();
+ expected = func_from_executable();
+ assert(actual == expected);
+
+#ifdef _WIN32
+ FreeLibrary(h);
+#else
+ dlclose(h);
+#endif
+
+ return 0;
+}
diff --git a/test cases/failing/57 link with executable/meson.build b/test cases/failing/57 link with executable/meson.build
new file mode 100644
index 0000000..186b3e5
--- /dev/null
+++ b/test cases/failing/57 link with executable/meson.build
@@ -0,0 +1,4 @@
+project('link with exe', 'c')
+
+e = executable('prog', 'prog.c')
+m = shared_module('module', 'module.c', link_with: e)
diff --git a/test cases/failing/57 link with executable/module.c b/test cases/failing/57 link with executable/module.c
new file mode 100644
index 0000000..dc0124a
--- /dev/null
+++ b/test cases/failing/57 link with executable/module.c
@@ -0,0 +1,4 @@
+
+int func(void) {
+ return 42;
+}
diff --git a/test cases/failing/57 link with executable/prog.c b/test cases/failing/57 link with executable/prog.c
new file mode 100644
index 0000000..f3836d7
--- /dev/null
+++ b/test cases/failing/57 link with executable/prog.c
@@ -0,0 +1,5 @@
+int
+main (int argc, char **argv)
+{
+ return 0;
+}
diff --git a/test cases/windows/12 exe implib/installed_files.txt b/test cases/windows/12 exe implib/installed_files.txt
new file mode 100644
index 0000000..d0ea8f6
--- /dev/null
+++ b/test cases/windows/12 exe implib/installed_files.txt
@@ -0,0 +1,4 @@
+usr/bin/prog.exe
+usr/bin/prog.pdb
+?gcc:usr/lib/libprog.exe.a
+?msvc:usr/lib/prog.lib
diff --git a/test cases/windows/12 exe implib/meson.build b/test cases/windows/12 exe implib/meson.build
new file mode 100644
index 0000000..2393e79
--- /dev/null
+++ b/test cases/windows/12 exe implib/meson.build
@@ -0,0 +1,7 @@
+project('wintest', 'c')
+
+# Test that we can produce an implib for an executable on Windows, and that it
+# is installed along with the executable
+
+prog = executable('prog', 'prog.c', install: true, implib: true)
+test('wintest', prog)
diff --git a/test cases/windows/12 exe implib/prog.c b/test cases/windows/12 exe implib/prog.c
new file mode 100644
index 0000000..6d5a9f5
--- /dev/null
+++ b/test cases/windows/12 exe implib/prog.c
@@ -0,0 +1,6 @@
+#include <windows.h>
+
+int __declspec(dllexport)
+main(int argc, char **argv) {
+ return 0;
+}