summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/compilers/mixins/clike.py25
-rw-r--r--test cases/common/285 atomic/a.c3
-rw-r--r--test cases/common/285 atomic/meson.build23
-rw-r--r--unittests/internaltests.py23
4 files changed, 59 insertions, 15 deletions
diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py
index 454f5fba8..d31332a68 100644
--- a/mesonbuild/compilers/mixins/clike.py
+++ b/mesonbuild/compilers/mixins/clike.py
@@ -1090,10 +1090,8 @@ class CLikeCompiler(Compiler):
@staticmethod
def _get_file_from_list(env: Environment, paths: T.List[str]) -> T.Optional[Path]:
'''
- We just check whether the library exists. We can't do a link check
- because the library might have unresolved symbols that require other
- libraries. On macOS we check if the library matches our target
- architecture.
+ Check whether the library exists by filename. On macOS, we also
+ check if the library matches our target architecture.
'''
for p in paths:
if os.path.isfile(p):
@@ -1147,17 +1145,28 @@ class CLikeCompiler(Compiler):
except (mesonlib.MesonException, KeyError): # TODO evaluate if catching KeyError is wanted here
elf_class = 0
# Search in the specified dirs, and then in the system libraries
+ largs = self.get_linker_always_args() + self.get_allow_undefined_link_args()
+ lcargs = self.linker_to_compiler_args(largs)
for d in itertools.chain(extra_dirs, [] if ignore_system_dirs else self.get_library_dirs(env, elf_class)):
for p in patterns:
trials = self._get_trials_from_pattern(p, d, libname)
if not trials:
continue
- trial = self._get_file_from_list(env, trials)
- if not trial:
+
+ trial_result = ""
+ for trial in trials:
+ if not os.path.isfile(trial):
+ continue
+ extra_args = [trial] + lcargs
+ if self.links(code, env, extra_args=extra_args, disable_cache=True)[0]:
+ trial_result = trial
+ break
+
+ if not trial_result:
continue
- if libname.startswith('lib') and trial.name.startswith(libname) and lib_prefix_warning:
+ if libname.startswith('lib') and trial_result.startswith(libname) and lib_prefix_warning:
mlog.warning(f'find_library({libname!r}) starting in "lib" only works by accident and is not portable')
- return [trial.as_posix()]
+ return [Path(trial_result).as_posix()]
return None
def _find_library_impl(self, libname: str, env: 'Environment', extra_dirs: T.List[str],
diff --git a/test cases/common/285 atomic/a.c b/test cases/common/285 atomic/a.c
new file mode 100644
index 000000000..03b2213bb
--- /dev/null
+++ b/test cases/common/285 atomic/a.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/285 atomic/meson.build b/test cases/common/285 atomic/meson.build
new file mode 100644
index 000000000..323b9ccb6
--- /dev/null
+++ b/test cases/common/285 atomic/meson.build
@@ -0,0 +1,23 @@
+project('meson system dependency', 'c', meson_version: '>=1.7.0')
+
+cc = meson.get_compiler('c')
+
+# We could check if dependency('atomic') actually finds something when
+# we 'know' it exists (MESON_SKIP_TEST) but that's likely to be brittle,
+# so don't bother (for now, at least).
+atomic = dependency('atomic', required : false)
+
+# If the dependency provider says it found something, make sure it can
+# be linked against (https://github.com/mesonbuild/meson/issues/14946).
+dependencies = [
+ atomic
+]
+
+exe = executable(
+ 'a',
+ 'a.c',
+ dependencies : dependencies,
+ install : false,
+)
+
+test('basic', exe)
diff --git a/unittests/internaltests.py b/unittests/internaltests.py
index 71e32ba3f..8bc9c00c5 100644
--- a/unittests/internaltests.py
+++ b/unittests/internaltests.py
@@ -551,10 +551,14 @@ class InternalTests(unittest.TestCase):
for i in ['libfoo.so.6.0', 'libfoo.so.5.0', 'libfoo.so.54.0', 'libfoo.so.66a.0b', 'libfoo.so.70.0.so.1',
'libbar.so.7.10', 'libbar.so.7.9', 'libbar.so.7.9.3']:
libpath = Path(tmpdir) / i
- libpath.write_text('', encoding='utf-8')
- found = cc._find_library_real('foo', env, [tmpdir], '', LibType.PREFER_SHARED, lib_prefix_warning=True, ignore_system_dirs=False)
+ src = libpath.with_suffix('.c')
+ with src.open('w', encoding='utf-8') as f:
+ f.write('int meson_foobar (void) { return 0; }')
+ subprocess.check_call(['gcc', str(src), '-o', str(libpath), '-shared'])
+
+ found = cc._find_library_real('foo', env, [tmpdir], 'int main(void) { return 0; }', LibType.PREFER_SHARED, lib_prefix_warning=True, ignore_system_dirs=False)
self.assertEqual(os.path.basename(found[0]), 'libfoo.so.54.0')
- found = cc._find_library_real('bar', env, [tmpdir], '', LibType.PREFER_SHARED, lib_prefix_warning=True, ignore_system_dirs=False)
+ found = cc._find_library_real('bar', env, [tmpdir], 'int main(void) { return 0; }', LibType.PREFER_SHARED, lib_prefix_warning=True, ignore_system_dirs=False)
self.assertEqual(os.path.basename(found[0]), 'libbar.so.7.10')
def test_find_library_patterns(self):
@@ -610,17 +614,22 @@ class InternalTests(unittest.TestCase):
https://github.com/mesonbuild/meson/issues/3951
'''
def create_static_lib(name):
- if not is_osx():
- name.open('w', encoding='utf-8').close()
- return
src = name.with_suffix('.c')
out = name.with_suffix('.o')
with src.open('w', encoding='utf-8') as f:
f.write('int meson_foobar (void) { return 0; }')
# use of x86_64 is hardcoded in run_tests.py:get_fake_env()
- subprocess.check_call(['clang', '-c', str(src), '-o', str(out), '-arch', 'x86_64'])
+ if is_osx():
+ subprocess.check_call(['clang', '-c', str(src), '-o', str(out), '-arch', 'x86_64'])
+ else:
+ subprocess.check_call(['gcc', '-c', str(src), '-o', str(out)])
subprocess.check_call(['ar', 'csr', str(name), str(out)])
+ # The test relies on some open-coded toolchain invocations for
+ # library creation in create_static_lib.
+ if is_windows() or is_cygwin():
+ return
+
with tempfile.TemporaryDirectory() as tmpdir:
pkgbin = ExternalProgram('pkg-config', command=['pkg-config'], silent=True)
env = get_fake_env()