cmake: fix shared_module dependency (fixes #7715)

pull/7021/head
Daniel Mensinger 4 years ago committed by Nirbheek Chauhan
parent 4c2d0eb9bc
commit 4cef45af21
  1. 4
      mesonbuild/cmake/interpreter.py
  2. 13
      test cases/cmake/21 shared module/meson.build
  3. 108
      test cases/cmake/21 shared module/prog.c
  4. 19
      test cases/cmake/21 shared module/runtime.c
  5. 7
      test cases/cmake/21 shared module/subprojects/cmMod/CMakeLists.txt
  6. 96
      test cases/cmake/21 shared module/subprojects/cmMod/module/module.c
  7. 3
      test cases/cmake/21 shared module/subprojects/cmMod/module/module.h

@ -1235,6 +1235,10 @@ class CMakeInterpreter:
if tgt_func in ['static_library', 'shared_library']:
dep_node = assign(dep_var, function('declare_dependency', kwargs=dep_kwargs))
node_list += [dep_node]
elif tgt_func in ['shared_module']:
del dep_kwargs['link_with']
dep_node = assign(dep_var, function('declare_dependency', kwargs=dep_kwargs))
node_list += [dep_node]
else:
dep_var = None

@ -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)

@ -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

@ -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;
}

@ -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")

@ -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

@ -0,0 +1,3 @@
#pragma once
#define SPECIAL_MAGIC_DEFINE 42
Loading…
Cancel
Save