aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlilinzhe <slayercat.subscription@gmail.com>2021-07-19 15:24:44 +0800
committerNirbheek Chauhan <nirbheek@centricular.com>2021-08-10 16:06:45 +0530
commit596b24ac5b608fac61d29e7d71813838c0b55029 (patch)
treedbeecddc141880e291c438d0c35a8a92262065a8
parentaf280058b01d7970da9bb8fbad2966f9c72cf6a0 (diff)
downloadmeson-596b24ac5b608fac61d29e7d71813838c0b55029.zip
meson-596b24ac5b608fac61d29e7d71813838c0b55029.tar.gz
meson-596b24ac5b608fac61d29e7d71813838c0b55029.tar.bz2
pkg-config: support for `-l:libfoo.a`
fixs: #9000 Meson not correctly process with -l:xxx.a link arguments in pkgconfig .pc file. see also:https://stackoverflow.com/questions/48532868/gcc-library-option-with-a-colon-llibevent-a with unit test, unit test will be partially skiped if pkg-config version < 0.28 . see: https://gitlab.freedesktop.org/pkg-config/pkg-config/-/blob/master/NEWS
-rw-r--r--mesonbuild/dependencies/pkgconfig.py24
-rwxr-xr-xrun_unittests.py43
-rw-r--r--test cases/unit/97 link full name/.gitignore5
-rw-r--r--test cases/unit/97 link full name/libtestprovider/meson.build20
-rw-r--r--test cases/unit/97 link full name/libtestprovider/provider.c12
-rw-r--r--test cases/unit/97 link full name/proguser/meson.build11
-rw-r--r--test cases/unit/97 link full name/proguser/receiver.c19
7 files changed, 134 insertions, 0 deletions
diff --git a/mesonbuild/dependencies/pkgconfig.py b/mesonbuild/dependencies/pkgconfig.py
index 1e8d913..f097504 100644
--- a/mesonbuild/dependencies/pkgconfig.py
+++ b/mesonbuild/dependencies/pkgconfig.py
@@ -277,6 +277,30 @@ class PkgConfigDependency(ExternalDependency):
elif lib.startswith('-L'):
# We already handled library paths above
continue
+ elif lib.startswith('-l:'):
+ # see: https://stackoverflow.com/questions/48532868/gcc-library-option-with-a-colon-llibevent-a
+ # also : See the documentation of -lnamespec | --library=namespec in the linker manual
+ # https://sourceware.org/binutils/docs-2.18/ld/Options.html
+
+ # Don't resolve the same -l:libfoo.a argument again
+ if lib in libs_found:
+ continue
+ libfilename = lib[3:]
+ foundname = None
+ for libdir in libpaths:
+ target = os.path.join(libdir, libfilename)
+ if os.path.exists(target):
+ foundname = target
+ break
+ if foundname is None:
+ if lib in libs_notfound:
+ continue
+ else:
+ mlog.warning('Library {!r} not found for dependency {!r}, may '
+ 'not be successfully linked'.format(libfilename, self.name))
+ libs_notfound.append(lib)
+ else:
+ lib = foundname
elif lib.startswith('-l'):
# Don't resolve the same -lfoo argument again
if lib in libs_found:
diff --git a/run_unittests.py b/run_unittests.py
index 91f3f3c..9f853d8 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -7956,6 +7956,49 @@ class LinuxlikeTests(BasePlatformTests):
out = self._run(['otool', '-L', f])
# Ensure that the otool output does not contain self.installdir
self.assertNotRegex(out, self.installdir + '.*dylib ')
+
+ @skipIfNoPkgconfig
+ def test_link_arg_fullname(self):
+ '''
+ Test for support of -l:libfullname.a
+ see: https://github.com/mesonbuild/meson/issues/9000
+ https://stackoverflow.com/questions/48532868/gcc-library-option-with-a-colon-llibevent-a
+ '''
+ testdir = os.path.join(self.unit_test_dir, '97 link full name','libtestprovider')
+ oldprefix = self.prefix
+ # install into installdir without using DESTDIR
+ installdir = self.installdir
+ self.prefix = installdir
+ self.init(testdir)
+ self.prefix=oldprefix
+ self.build()
+ self.install(use_destdir=False)
+
+ self.new_builddir()
+ env = {'LIBRARY_PATH': os.path.join(installdir, self.libdir),
+ 'PKG_CONFIG_PATH': os.path.join(installdir, self.libdir, 'pkgconfig')}
+ testdir = os.path.join(self.unit_test_dir, '97 link full name','proguser')
+ self.init(testdir,override_envvars=env)
+
+ # test for link with full path
+ with open(os.path.join(self.builddir, 'build.ninja'), encoding='utf-8') as bfile:
+ for line in bfile:
+ if 'build dprovidertest:' in line:
+ self.assertIn('/libtestprovider.a', line)
+
+ if is_osx():
+ # macOS's ld do not supports `--whole-archive`, skip build & run
+ return
+
+ self.build(override_envvars=env)
+
+ # skip test if pkg-config is too old.
+ # before v0.28, Libs flags like -Wl will not kept in context order with -l flags.
+ # see https://gitlab.freedesktop.org/pkg-config/pkg-config/-/blob/master/NEWS
+ pkgconfigver = subprocess.check_output(['pkg-config', '--version'])
+ if b'0.28' > pkgconfigver:
+ raise unittest.SkipTest('pkg-config is too old to be correctly done this.')
+ self.run_tests()
@skipIfNoPkgconfig
def test_usage_pkgconfig_prefixes(self):
diff --git a/test cases/unit/97 link full name/.gitignore b/test cases/unit/97 link full name/.gitignore
new file mode 100644
index 0000000..8129601
--- /dev/null
+++ b/test cases/unit/97 link full name/.gitignore
@@ -0,0 +1,5 @@
+*.a
+*.o
+a.out
+libtestprovider.a
+build
diff --git a/test cases/unit/97 link full name/libtestprovider/meson.build b/test cases/unit/97 link full name/libtestprovider/meson.build
new file mode 100644
index 0000000..5855c81
--- /dev/null
+++ b/test cases/unit/97 link full name/libtestprovider/meson.build
@@ -0,0 +1,20 @@
+project('libtestprovider','c')
+
+libtestprovider=static_library('testprovider',
+ files('./provider.c'),
+ install:true,
+ c_args:['-Wall','-Werror'],
+)
+
+pkg = import('pkgconfig')
+
+
+pkg.generate(
+ name:'testprovider',
+ filebase:'libtestprovider',
+ description: 'fortest',
+ requires: [],
+ libraries_private: ['-Wl,--whole-archive'] +
+ ['-L${libdir}','-l:libtestprovider.a']+
+ ['-Wl,--no-whole-archive']
+)
diff --git a/test cases/unit/97 link full name/libtestprovider/provider.c b/test cases/unit/97 link full name/libtestprovider/provider.c
new file mode 100644
index 0000000..5e79966
--- /dev/null
+++ b/test cases/unit/97 link full name/libtestprovider/provider.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+static int g_checked = 0;
+
+static void __attribute__((constructor(101), used)) init_checked(void) {
+ g_checked=100;
+ fprintf(stdout, "inited\n");
+}
+
+
+int get_checked(void) {
+ return g_checked;
+}
diff --git a/test cases/unit/97 link full name/proguser/meson.build b/test cases/unit/97 link full name/proguser/meson.build
new file mode 100644
index 0000000..5be5bc9
--- /dev/null
+++ b/test cases/unit/97 link full name/proguser/meson.build
@@ -0,0 +1,11 @@
+project('testprovider','c')
+
+deplib = dependency('libtestprovider', static:true)
+
+dprovidertest = executable('dprovidertest',
+ files('./receiver.c'),
+ dependencies:[deplib],
+ c_args:['-Wall','-Werror'],
+)
+
+test('testprovider',dprovidertest)
diff --git a/test cases/unit/97 link full name/proguser/receiver.c b/test cases/unit/97 link full name/proguser/receiver.c
new file mode 100644
index 0000000..594601c
--- /dev/null
+++ b/test cases/unit/97 link full name/proguser/receiver.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+int __attribute__((weak)) get_checked(void) {
+ return -1;
+}
+
+
+#define CHECK_VALUE (100)
+#define TEST_SUCCESS (0)
+#define TEST_FAILTURE (-1)
+
+int main(void) {
+ if (get_checked() == CHECK_VALUE) {
+ fprintf(stdout,"good\n");
+ return TEST_SUCCESS;
+ }
+ fprintf(stdout,"bad\n");
+ return TEST_FAILTURE;
+}
+