diff options
author | Daniel Mensinger <daniel@mensinger-ka.de> | 2020-09-09 22:00:19 +0200 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek.chauhan@gmail.com> | 2020-09-10 06:41:24 +0000 |
commit | 4cef45af21465f4c860dbd467796b1c768f556f4 (patch) | |
tree | 37441f17511e0f0f314d146c142def7c7db7d1e9 /test cases/cmake | |
parent | 4c2d0eb9bcedefa3ef06a237a0502afbc581268b (diff) | |
download | meson-4cef45af21465f4c860dbd467796b1c768f556f4.zip meson-4cef45af21465f4c860dbd467796b1c768f556f4.tar.gz meson-4cef45af21465f4c860dbd467796b1c768f556f4.tar.bz2 |
cmake: fix shared_module dependency (fixes #7715)
Diffstat (limited to 'test cases/cmake')
6 files changed, 246 insertions, 0 deletions
diff --git a/test cases/cmake/21 shared module/meson.build b/test cases/cmake/21 shared module/meson.build new file mode 100644 index 0000000..c6ff957 --- /dev/null +++ b/test cases/cmake/21 shared module/meson.build @@ -0,0 +1,13 @@ +project('cmakeSharedModule', ['c', 'cpp']) + +cm = import('cmake') + +sub_pro = cm.subproject('cmMod') +sub_dep = sub_pro.dependency('myMod') + +dl = meson.get_compiler('c').find_library('dl', required: false) + +l = shared_library('runtime', 'runtime.c') +e = executable('prog', ['prog.c'], link_with: l, dependencies: [sub_dep, dl]) +m = sub_pro.target('myMod') +test('test1', e, args : m) diff --git a/test cases/cmake/21 shared module/prog.c b/test cases/cmake/21 shared module/prog.c new file mode 100644 index 0000000..228a976 --- /dev/null +++ b/test cases/cmake/21 shared module/prog.c @@ -0,0 +1,108 @@ + +#include <stdio.h> +#include "module.h" + +#if SPECIAL_MAGIC_DEFINE != 42 +#error "SPECIAL_MAGIC_DEFINE is not defined" +#endif + +int func_from_language_runtime(void); +typedef int (*fptr) (void); + +#ifdef _WIN32 + +#include <windows.h> + +static wchar_t* +win32_get_last_error (void) +{ + wchar_t *msg = NULL; + + FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_IGNORE_INSERTS + | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, GetLastError (), 0, + (LPWSTR) &msg, 0, NULL); + return msg; +} + +int main(int argc, char **argv) +{ + HINSTANCE handle; + fptr importedfunc; + int expected, actual; + int ret = 1; + if(argc==0) {}; + + handle = LoadLibraryA (argv[1]); + if (!handle) { + wchar_t *msg = win32_get_last_error (); + printf ("Could not open %s: %S\n", argv[1], msg); + goto nohandle; + } + + importedfunc = (fptr) GetProcAddress (handle, "func"); + if (importedfunc == NULL) { + wchar_t *msg = win32_get_last_error (); + printf ("Could not find 'func': %S\n", msg); + goto out; + } + + actual = importedfunc (); + expected = func_from_language_runtime (); + if (actual != expected) { + printf ("Got %i instead of %i\n", actual, expected); + goto out; + } + + ret = 0; +out: + FreeLibrary (handle); +nohandle: + return ret; +} + +#else + +#include<dlfcn.h> +#include<assert.h> + +int main(int argc, char **argv) { + void *dl; + fptr importedfunc; + int expected, actual; + char *error; + int ret = 1; + if(argc==0) {}; + + dlerror(); + dl = dlopen(argv[1], RTLD_LAZY); + error = dlerror(); + if(error) { + printf("Could not open %s: %s\n", argv[1], error); + goto nodl; + } + + importedfunc = (fptr) dlsym(dl, "func"); + if (importedfunc == NULL) { + printf ("Could not find 'func'\n"); + goto out; + } + + assert(importedfunc != func_from_language_runtime); + + actual = (*importedfunc)(); + expected = func_from_language_runtime (); + if (actual != expected) { + printf ("Got %i instead of %i\n", actual, expected); + goto out; + } + + ret = 0; +out: + dlclose(dl); +nodl: + return ret; +} + +#endif diff --git a/test cases/cmake/21 shared module/runtime.c b/test cases/cmake/21 shared module/runtime.c new file mode 100644 index 0000000..03bde86 --- /dev/null +++ b/test cases/cmake/21 shared module/runtime.c @@ -0,0 +1,19 @@ +#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 + +/* + * This file pretends to be a language runtime that supports extension + * modules. + */ + +int DLL_PUBLIC func_from_language_runtime(void) { + return 86; +} diff --git a/test cases/cmake/21 shared module/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/21 shared module/subprojects/cmMod/CMakeLists.txt new file mode 100644 index 0000000..d2fcfe3 --- /dev/null +++ b/test cases/cmake/21 shared module/subprojects/cmMod/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.5) + +project(cmModule) + +include_directories("${CMAKE_CURRENT_SOURCE_DIR}/module") + +add_library(myMod MODULE "${CMAKE_CURRENT_SOURCE_DIR}/module/module.c") diff --git a/test cases/cmake/21 shared module/subprojects/cmMod/module/module.c b/test cases/cmake/21 shared module/subprojects/cmMod/module/module.c new file mode 100644 index 0000000..5dd26d7 --- /dev/null +++ b/test cases/cmake/21 shared module/subprojects/cmMod/module/module.c @@ -0,0 +1,96 @@ +#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 + +#if defined(_WIN32) || defined(__CYGWIN__) + +#include <stdio.h> + +typedef int (*fptr) (void); + +#ifdef __CYGWIN__ + +#include <dlfcn.h> + +fptr find_any_f (const char *name) { + return (fptr) dlsym(RTLD_DEFAULT, name); +} +#else /* _WIN32 */ + +#include <windows.h> +#include <tlhelp32.h> + +static wchar_t* +win32_get_last_error (void) +{ + wchar_t *msg = NULL; + + FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_IGNORE_INSERTS + | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, GetLastError (), 0, + (LPWSTR) &msg, 0, NULL); + return msg; +} + +/* Unlike Linux and OS X, when a library is loaded, all the symbols aren't + * loaded into a single namespace. You must fetch the symbol by iterating over + * all loaded modules. Code for finding the function from any of the loaded + * modules is taken from gmodule.c in glib */ +fptr find_any_f (const char *name) { + fptr f; + HANDLE snapshot; + MODULEENTRY32 me32; + + snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); + if (snapshot == (HANDLE) -1) { + wchar_t *msg = win32_get_last_error(); + printf("Could not get snapshot: %S\n", msg); + return 0; + } + + me32.dwSize = sizeof (me32); + + f = NULL; + if (Module32First (snapshot, &me32)) { + do { + if ((f = (fptr) GetProcAddress (me32.hModule, name)) != NULL) + break; + } while (Module32Next (snapshot, &me32)); + } + + CloseHandle (snapshot); + return f; +} +#endif + +int DLL_PUBLIC func(void) { + fptr f; + + f = find_any_f ("func_from_language_runtime"); + if (f != NULL) + return f(); + printf ("Could not find function\n"); + return 1; +} + +#else +/* + * Shared modules often have references to symbols that are not defined + * at link time, but which will be provided from deps of the executable that + * dlopens it. We need to make sure that this works, i.e. that we do + * not pass -Wl,--no-undefined when linking modules. + */ +int func_from_language_runtime(void); + +int DLL_PUBLIC func(void) { + return func_from_language_runtime(); +} +#endif diff --git a/test cases/cmake/21 shared module/subprojects/cmMod/module/module.h b/test cases/cmake/21 shared module/subprojects/cmMod/module/module.h new file mode 100644 index 0000000..e1d9c13 --- /dev/null +++ b/test cases/cmake/21 shared module/subprojects/cmMod/module/module.h @@ -0,0 +1,3 @@ +#pragma once + +#define SPECIAL_MAGIC_DEFINE 42 |