cmake: fix shared_module dependency (fixes #7715)
This commit is contained in:
parent
4c2d0eb9bc
commit
4cef45af21
|
@ -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…
Reference in New Issue