aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/yaml/functions/shared_library.yaml7
-rw-r--r--docs/yaml/functions/shared_module.yaml9
-rw-r--r--mesonbuild/backend/ninjabackend.py2
-rw-r--r--mesonbuild/build.py16
-rw-r--r--test cases/failing/75 link with shared module on osx/test.json2
-rw-r--r--test cases/unit/1 soname/main.c5
-rw-r--r--test cases/unit/1 soname/meson.build13
-rw-r--r--unittests/allplatformstests.py6
-rw-r--r--unittests/linuxliketests.py18
9 files changed, 63 insertions, 15 deletions
diff --git a/docs/yaml/functions/shared_library.yaml b/docs/yaml/functions/shared_library.yaml
index 46e5a1c..15ac782 100644
--- a/docs/yaml/functions/shared_library.yaml
+++ b/docs/yaml/functions/shared_library.yaml
@@ -2,13 +2,6 @@ name: shared_library
returns: lib
description: Builds a shared library with the given sources.
-notes:
- - |
- Linking to a shared module is not supported on some
- platforms, notably OSX. Consider using a
- [[shared_library]] instead, if you need to both
- `dlopen()` and link with a library.
-
posargs_inherit: _build_target_base
varargs_inherit: _build_target_base
kwargs_inherit: _build_target_base
diff --git a/docs/yaml/functions/shared_module.yaml b/docs/yaml/functions/shared_module.yaml
index 8909c2f..ff374e7 100644
--- a/docs/yaml/functions/shared_module.yaml
+++ b/docs/yaml/functions/shared_module.yaml
@@ -13,6 +13,15 @@ description: |
you will need to set the `export_dynamic` argument of the executable to
`true`.
+notes:
+ - |
+ *Linking to a shared module is deprecated, and will be an error in the future*.
+ It used to be allowed because it was the only way to have a shared-library-like target that
+ contained references to undefined symbols. However, since 0.40.0, the `override_options:`
+ [[build_target]] keyword argument can be used to create such a [[shared_library]], and shared
+ modules have other characteristics that make them incompatible with linking, such as a lack of
+ SONAME. Linking to shared modules also does not work on some platforms, such as on macOS / iOS.
+
posargs_inherit: _build_target_base
varargs_inherit: _build_target_base
kwargs_inherit: _build_target_base
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index a1d3e50..b6621c9 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -2785,7 +2785,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
commands += linker.get_std_shared_lib_link_args()
# All shared libraries are PIC
commands += linker.get_pic_args()
- if not isinstance(target, build.SharedModule):
+ if not isinstance(target, build.SharedModule) or target.backwards_compat_want_soname:
# Add -Wl,-soname arguments on Linux, -install_name on OS X
commands += linker.get_soname_args(
self.environment, target.prefix, target.name, target.suffix,
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 6036735..ad18a7f 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1591,11 +1591,16 @@ You probably should put it in link_with instead.''')
if isinstance(link_target, SharedModule):
if self.environment.machines[self.for_machine].is_darwin():
raise MesonException(
- 'target links against shared modules. This is not permitted on OSX')
+ f'target {self.name} links against shared module {link_target.name}. This is not permitted on OSX')
else:
- mlog.warning('target links against shared modules. This '
- 'is not recommended as it is not supported on some '
- 'platforms')
+ mlog.deprecation(f'target {self.name} links against shared module {link_target.name}, which is incorrect.'
+ '\n '
+ f'This will be an error in the future, so please use shared_library() for {link_target.name} instead.'
+ '\n '
+ f'If shared_module() was used for {link_target.name} because it has references to undefined symbols,'
+ '\n '
+ 'use shared_libary() with `override_options: [\'b_lundef=false\']` instead.')
+ link_target.backwards_compat_want_soname = True
return
class Generator(HoldableObject):
@@ -2259,6 +2264,9 @@ class SharedModule(SharedLibrary):
raise MesonException('Shared modules must not specify the soversion kwarg.')
super().__init__(name, subdir, subproject, for_machine, sources, objects, environment, kwargs)
self.typename = 'shared module'
+ # We need to set the soname in cases where build files link the module
+ # to build targets, see: https://github.com/mesonbuild/meson/issues/9492
+ self.backwards_compat_want_soname = False
def get_default_install_dir(self, environment) -> T.Tuple[str, str]:
return environment.get_shared_module_dir(), '{moduledir_shared}'
diff --git a/test cases/failing/75 link with shared module on osx/test.json b/test cases/failing/75 link with shared module on osx/test.json
index 7db17d8..81ee2ac 100644
--- a/test cases/failing/75 link with shared module on osx/test.json
+++ b/test cases/failing/75 link with shared module on osx/test.json
@@ -1,7 +1,7 @@
{
"stdout": [
{
- "line": "test cases/failing/75 link with shared module on osx/meson.build:8:0: ERROR: target links against shared modules. This is not permitted on OSX"
+ "line": "test cases/failing/75 link with shared module on osx/meson.build:8:0: ERROR: target prog links against shared module mymodule. This is not permitted on OSX"
}
]
}
diff --git a/test cases/unit/1 soname/main.c b/test cases/unit/1 soname/main.c
new file mode 100644
index 0000000..f5ccbb9
--- /dev/null
+++ b/test cases/unit/1 soname/main.c
@@ -0,0 +1,5 @@
+int versioned_func (void);
+
+int main (void) {
+ return versioned_func();
+}
diff --git a/test cases/unit/1 soname/meson.build b/test cases/unit/1 soname/meson.build
index 950dadc..44b003a 100644
--- a/test cases/unit/1 soname/meson.build
+++ b/test cases/unit/1 soname/meson.build
@@ -20,3 +20,16 @@ shared_library('settosame', 'versioned.c',
install : true,
soversion : '7.8.9',
version : '7.8.9')
+
+shared_module('some_module', 'versioned.c',
+ install: true)
+
+module1 = shared_module('linked_module1', 'versioned.c',
+ install: true)
+
+module2 = shared_module('linked_module2', 'versioned.c',
+ install: true)
+module2_dep = declare_dependency(link_with: module2)
+
+executable('main1', 'main.c', link_with: module1)
+executable('main2', 'main.c', dependencies: module2_dep)
diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py
index 03992bd..30c0572 100644
--- a/unittests/allplatformstests.py
+++ b/unittests/allplatformstests.py
@@ -1946,8 +1946,10 @@ class AllPlatformTests(BasePlatformTests):
"""
tdir = os.path.join(self.unit_test_dir, '30 shared_mod linking')
out = self.init(tdir)
- msg = ('WARNING: target links against shared modules. This is not '
- 'recommended as it is not supported on some platforms')
+ msg = ('''DEPRECATION: target prog links against shared module mymod, which is incorrect.
+ This will be an error in the future, so please use shared_library() for mymod instead.
+ If shared_module() was used for mymod because it has references to undefined symbols,
+ use shared_libary() with `override_options: ['b_lundef=false']` instead.''')
self.assertIn(msg, out)
def test_mixed_language_linker_check(self):
diff --git a/unittests/linuxliketests.py b/unittests/linuxliketests.py
index 0f99f01..8ff0f8e 100644
--- a/unittests/linuxliketests.py
+++ b/unittests/linuxliketests.py
@@ -438,6 +438,24 @@ class LinuxlikeTests(BasePlatformTests):
self.assertEqual(get_soname(bothset), 'libbothset.so.1.2.3')
self.assertEqual(len(self.glob_sofiles_without_privdir(bothset[:-3] + '*')), 3)
+ # A shared_module that is not linked to anything
+ module = os.path.join(libpath, 'libsome_module.so')
+ self.assertPathExists(module)
+ self.assertFalse(os.path.islink(module))
+ self.assertEqual(get_soname(module), None)
+
+ # A shared_module that is not linked to an executable with link_with:
+ module = os.path.join(libpath, 'liblinked_module1.so')
+ self.assertPathExists(module)
+ self.assertFalse(os.path.islink(module))
+ self.assertEqual(get_soname(module), 'liblinked_module1.so')
+
+ # A shared_module that is not linked to an executable with dependencies:
+ module = os.path.join(libpath, 'liblinked_module2.so')
+ self.assertPathExists(module)
+ self.assertFalse(os.path.islink(module))
+ self.assertEqual(get_soname(module), 'liblinked_module2.so')
+
def test_soname(self):
self._test_soname_impl(self.builddir, False)