aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Reference-manual.md16
-rw-r--r--mesonbuild/backend/ninjabackend.py3
-rw-r--r--mesonbuild/build.py25
-rw-r--r--mesonbuild/compilers/c.py8
-rw-r--r--mesonbuild/interpreter.py2
-rw-r--r--test cases/common/125 shared module/meson.build4
-rw-r--r--test cases/common/156 shared module resolving symbol in executable/meson.build8
7 files changed, 46 insertions, 20 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index e30b79c..a231ed4 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -403,7 +403,7 @@ be passed to [shared and static libraries](#library).
flags here for all platforms.
- `link_depends` strings, files, or custom targets the link step
depends on such as a symbol visibility map. The purpose is to
- automaticallytrigger a re-link (but not a re-compile) of the target
+ automatically trigger a re-link (but not a re-compile) of the target
when this file changes.
- `link_whole` links all contents of the given static libraries
whether they are used by not, equivalent to the
@@ -412,13 +412,18 @@ be passed to [shared and static libraries](#library).
- `link_with`, one or more shared or static libraries (built by this
project) that this target should be linked with, If passed a list
this list will be flattened as of 0.41.0.
+- `export_dynamic` when set to true causes the target's symbols to be
+ dynamically exported, allowing modules built using the
+ [`shared_module`](#shared_module) function to refer to functions,
+ variables and other symbols defined in the executable itself. Implies
+ the `implib` argument. Since 0.44.0
- `implib` when set to true, an import library is generated for the
executable (the name of the import library is based on *exe_name*).
Alternatively, when set to a string, that gives the base name for
the import library. The import library is used when the returned
build target object appears in `link_with:` elsewhere. Only has any
- effect on platforms where that is meaningful (e.g. Windows). Since
- 0.42.0
+ effect on platforms where that is meaningful (e.g. Windows). Implies
+ the `export_dynamic` argument. Since 0.42.0
- `implicit_include_directories` is a boolean telling whether Meson
adds the current source and build directories to the include path,
defaults to `true`, since 0.42.0
@@ -1010,6 +1015,11 @@ This is useful for building modules that will be `dlopen()`ed and
hence may contain undefined symbols that will be provided by the
library that is loading it.
+If you want the shared module to be able to refer to functions and
+variables defined in the [`executable`](#executable) it is loaded by,
+you will need to set the `export_dynamic` argument of the executable to
+`true`.
+
*Added 0.37.0*
### static_library()
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 2429fba..2945d6a 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -2341,6 +2341,9 @@ rule FORTRAN_DEP_HACK
# If gui_app, and that's significant on this platform
if target.gui_app and hasattr(linker, 'get_gui_app_args'):
commands += linker.get_gui_app_args()
+ # If export_dynamic, add the appropriate linker arguments
+ if target.export_dynamic:
+ commands += linker.gen_export_dynamic_link_args(self.environment)
# If implib, and that's significant on this platform (i.e. Windows using either GCC or Visual Studio)
if target.import_filename:
commands += linker.gen_import_library_args(os.path.join(self.get_target_dir(target), target.import_filename))
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 8a2e716..16a18a9 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -82,6 +82,7 @@ known_lib_kwargs.update({'version': True, # Only for shared libs
known_exe_kwargs = known_basic_kwargs.copy()
known_exe_kwargs.update({'implib': True,
+ 'export_dynamic': True
})
class InvalidArguments(MesonException):
@@ -1160,23 +1161,33 @@ class Executable(BuildTarget):
# The import library that GCC would generate (and prefer)
self.gcc_import_filename = None
- # if implib appears, this target is linkwith:-able, but that only means
- # something on Windows platforms.
- self.is_linkwithable = False
- if 'implib' in kwargs and kwargs['implib']:
+ # Check for export_dynamic
+ self.export_dynamic = False
+ if kwargs.get('export_dynamic'):
+ if not isinstance(kwargs['export_dynamic'], bool):
+ raise InvalidArguments('"export_dynamic" keyword argument must be a boolean')
+ self.export_dynamic = True
+ if kwargs.get('implib'):
+ self.export_dynamic = True
+ if self.export_dynamic and kwargs.get('implib') is False:
+ raise InvalidArguments('"implib" keyword argument must not be false for if "export_dynamic" is true')
+
+ # If using export_dynamic, set the import library name
+ if self.export_dynamic:
implib_basename = self.name + '.exe'
- if not isinstance(kwargs['implib'], bool):
+ if not isinstance(kwargs.get('implib', False), bool):
implib_basename = kwargs['implib']
- self.is_linkwithable = True
if for_windows(is_cross, environment) or for_cygwin(is_cross, environment):
self.vs_import_filename = '{0}.lib'.format(implib_basename)
self.gcc_import_filename = 'lib{0}.a'.format(implib_basename)
-
if self.get_using_msvc():
self.import_filename = self.vs_import_filename
else:
self.import_filename = self.gcc_import_filename
+ # Only linkwithable if using export_dynamic
+ self.is_linkwithable = self.export_dynamic
+
def type_suffix(self):
return "@exe"
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 233fc84..4c6e3a2 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -183,6 +183,14 @@ class CCompiler(Compiler):
def get_default_include_dirs(self):
return []
+ def gen_export_dynamic_link_args(self, env):
+ if for_windows(env.is_cross_build(), env):
+ return ['-Wl,--export-all-symbols']
+ elif for_darwin(env.is_cross_build(), env):
+ return []
+ else:
+ return ['-Wl,-export-dynamic']
+
def gen_import_library_args(self, implibname):
"""
The name of the outputted import library
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 48b8d82..488c2a3 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1347,7 +1347,7 @@ build_target_common_kwargs = (
rust_kwargs |
cs_kwargs)
-exe_kwargs = (build_target_common_kwargs) | {'implib'}
+exe_kwargs = (build_target_common_kwargs) | {'implib', 'export_dynamic'}
shlib_kwargs = (build_target_common_kwargs) | {'version', 'soversion'}
shmod_kwargs = shlib_kwargs
stlib_kwargs = shlib_kwargs
diff --git a/test cases/common/125 shared module/meson.build b/test cases/common/125 shared module/meson.build
index 29277e9..08a284d 100644
--- a/test cases/common/125 shared module/meson.build
+++ b/test cases/common/125 shared module/meson.build
@@ -8,6 +8,6 @@ l = shared_library('runtime', 'runtime.c')
# at runtime. This requires extra help on Windows, so
# should be avoided unless really necessary.
m = shared_module('mymodule', 'module.c')
-e = executable('prog', 'prog.c', link_with : l, dependencies : dl)
+e = executable('prog', 'prog.c',
+ link_with : l, export_dynamic : true, dependencies : dl)
test('import test', e, args : m)
-
diff --git a/test cases/common/156 shared module resolving symbol in executable/meson.build b/test cases/common/156 shared module resolving symbol in executable/meson.build
index 34a75f1..282a4d2 100644
--- a/test cases/common/156 shared module resolving symbol in executable/meson.build
+++ b/test cases/common/156 shared module resolving symbol in executable/meson.build
@@ -9,13 +9,7 @@ project('shared module resolving symbol in executable', 'c')
# 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']
-endif
-
dl = meson.get_compiler('c').find_library('dl', required: false)
-e = executable('prog', 'prog.c', dependencies: dl, implib: true, link_args: link_flags)
+e = executable('prog', 'prog.c', dependencies: dl, export_dynamic: true)
m = shared_module('module', 'module.c', link_with: e)
test('test', e, args: m.full_path())