summaryrefslogtreecommitdiffstats
path: root/test cases/common/148 shared module resolving symbol in executable
diff options
context:
space:
mode:
Diffstat (limited to 'test cases/common/148 shared module resolving symbol in executable')
-rw-r--r--test cases/common/148 shared module resolving symbol in executable/meson.build25
-rw-r--r--test cases/common/148 shared module resolving symbol in executable/module.c16
-rw-r--r--test cases/common/148 shared module resolving symbol in executable/prog.c61
3 files changed, 102 insertions, 0 deletions
diff --git a/test cases/common/148 shared module resolving symbol in executable/meson.build b/test cases/common/148 shared module resolving symbol in executable/meson.build
new file mode 100644
index 0000000..bbc7453
--- /dev/null
+++ b/test cases/common/148 shared module resolving symbol in executable/meson.build
@@ -0,0 +1,25 @@
+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.
+
+cc = meson.get_compiler('c')
+if cc.get_id() == 'pgi'
+ error('MESON_SKIP_TEST PGI has its own unique set of macros that would need to be handled')
+endif
+
+dl = meson.get_compiler('c').find_library('dl', required: false)
+e = executable('prog', 'prog.c', dependencies: dl, export_dynamic: true)
+e_dep = declare_dependency(link_with: e)
+
+m = shared_module('module', 'module.c', link_with: e)
+m2 = shared_module('module2', 'module.c', dependencies: e_dep)
+
+test('test', e, args: m.full_path())
+test('test2', e, args: m2.full_path())
diff --git a/test cases/common/148 shared module resolving symbol in executable/module.c b/test cases/common/148 shared module resolving symbol in executable/module.c
new file mode 100644
index 0000000..64374d5
--- /dev/null
+++ b/test cases/common/148 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/148 shared module resolving symbol in executable/prog.c b/test cases/common/148 shared module resolving symbol in executable/prog.c
new file mode 100644
index 0000000..b2abcdb
--- /dev/null
+++ b/test cases/common/148 shared module resolving symbol in executable/prog.c
@@ -0,0 +1,61 @@
+#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;
+
+ if (argc=0) {}; // noop
+
+#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;
+}