aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2018-03-19 23:43:35 +0200
committerGitHub <noreply@github.com>2018-03-19 23:43:35 +0200
commite984e1072b28abfa4ac278992a8ef6d138c15608 (patch)
tree43cac94062456f8d5ecccc2bcc114623e8200d33
parent7eb187c5f2cf55c6d441db08a87bac02cb58a9dc (diff)
parentcf5f1a83d55d05412e29058844e4fda5e420553b (diff)
downloadmeson-e984e1072b28abfa4ac278992a8ef6d138c15608.zip
meson-e984e1072b28abfa4ac278992a8ef6d138c15608.tar.gz
meson-e984e1072b28abfa4ac278992a8ef6d138c15608.tar.bz2
Merge pull request #3251 from mesonbuild/fixpkgconfigdeps
Fix pkg-config dependencies leaking out (debbug 892956)
-rw-r--r--mesonbuild/modules/pkgconfig.py15
-rwxr-xr-xrun_unittests.py44
-rw-r--r--test cases/common/51 pkgconfig-gen/dependencies/meson.build2
-rw-r--r--test cases/unit/24 pkgconfig usage/dependee/meson.build7
-rw-r--r--test cases/unit/24 pkgconfig usage/dependee/pkguser.c6
-rw-r--r--test cases/unit/24 pkgconfig usage/dependency/meson.build24
-rw-r--r--test cases/unit/24 pkgconfig usage/dependency/pkgdep.c7
-rw-r--r--test cases/unit/24 pkgconfig usage/dependency/pkgdep.h3
-rw-r--r--test cases/unit/24 pkgconfig usage/dependency/privatelib.c3
9 files changed, 106 insertions, 5 deletions
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
index 074fc5a..c89f657 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -96,7 +96,20 @@ class DependenciesHelper:
if obj.found():
processed_libs += obj.get_link_args()
processed_cflags += obj.get_compile_args()
- elif isinstance(obj, (build.SharedLibrary, build.StaticLibrary)):
+ elif isinstance(obj, build.SharedLibrary):
+ processed_libs.append(obj)
+ if public:
+ if not hasattr(obj, 'generated_pc'):
+ obj.generated_pc = self.name
+ elif isinstance(obj, build.StaticLibrary):
+ # Due to a "feature" in pkgconfig, it leaks out private dependencies.
+ # Thus we will not add them to the pc file unless the target
+ # we are processing is a static library.
+ #
+ # This way (hopefully) "pkgconfig --libs --static foobar" works
+ # and "pkgconfig --cflags/--libs foobar" does not have any trace
+ # of dependencies that the build file creator has not explicitly
+ # added to the dependency list.
processed_libs.append(obj)
if public:
if not hasattr(obj, 'generated_pc'):
diff --git a/run_unittests.py b/run_unittests.py
index 6e9970e..3ea0412 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -513,7 +513,8 @@ class BasePlatformTests(unittest.TestCase):
windows_proof_rmtree(path)
except FileNotFoundError:
pass
- os.environ = self.orig_env
+ os.environ.clear()
+ os.environ.update(self.orig_env)
super().tearDown()
def _run(self, command, workdir=None):
@@ -588,10 +589,11 @@ class BasePlatformTests(unittest.TestCase):
def run_tests(self):
self._run(self.test_command, workdir=self.builddir)
- def install(self):
+ def install(self, *, use_destdir=True):
if self.backend is not Backend.ninja:
raise unittest.SkipTest('{!r} backend can\'t install files'.format(self.backend.name))
- os.environ['DESTDIR'] = self.installdir
+ if use_destdir:
+ os.environ['DESTDIR'] = self.installdir
self._run(self.install_command, workdir=self.builddir)
def uninstall(self):
@@ -2735,6 +2737,42 @@ endian = 'little'
self.build()
mesonbuild.modules.gnome.native_glib_version = None
+ @unittest.skipIf(shutil.which('pkg-config') is None, 'Pkg-config not found.')
+ def test_pkgconfig_usage(self):
+ testdir1 = os.path.join(self.unit_test_dir, '24 pkgconfig usage/dependency')
+ testdir2 = os.path.join(self.unit_test_dir, '24 pkgconfig usage/dependee')
+ if subprocess.call(['pkg-config', '--cflags', 'glib-2.0'],
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL) != 0:
+ raise unittest.SkipTest('Glib 2.0 dependency not available.')
+ with tempfile.TemporaryDirectory() as tempdirname:
+ self.init(testdir1, ['--prefix=' + tempdirname, '--libdir=lib'], default_args=False)
+ self.install(use_destdir=False)
+ shutil.rmtree(self.builddir)
+ os.mkdir(self.builddir)
+ pkg_dir = os.path.join(tempdirname, 'lib/pkgconfig')
+ self.assertTrue(os.path.exists(os.path.join(pkg_dir, 'libpkgdep.pc')))
+ lib_dir = os.path.join(tempdirname, 'lib')
+ os.environ['PKG_CONFIG_PATH'] = pkg_dir
+ # Private internal libraries must not leak out.
+ pkg_out = subprocess.check_output(['pkg-config', '--static', '--libs', 'libpkgdep'])
+ self.assertFalse(b'libpkgdep-int' in pkg_out, 'Internal library leaked out.')
+ # Dependencies must not leak to cflags when building only a shared library.
+ pkg_out = subprocess.check_output(['pkg-config', '--cflags', 'libpkgdep'])
+ self.assertFalse(b'glib' in pkg_out, 'Internal dependency leaked to headers.')
+ # Test that the result is usable.
+ self.init(testdir2)
+ self.build()
+ myenv = os.environ.copy()
+ myenv['LD_LIBRARY_PATH'] = lib_dir
+ if is_cygwin():
+ bin_dir = os.path.join(tempdirname, 'bin')
+ myenv['PATH'] = bin_dir + os.pathsep + myenv['PATH']
+ self.assertTrue(os.path.isdir(lib_dir))
+ test_exe = os.path.join(self.builddir, 'pkguser')
+ self.assertTrue(os.path.isfile(test_exe))
+ subprocess.check_call(test_exe, env=myenv)
+
class LinuxArmCrossCompileTests(BasePlatformTests):
'''
diff --git a/test cases/common/51 pkgconfig-gen/dependencies/meson.build b/test cases/common/51 pkgconfig-gen/dependencies/meson.build
index 018b72f..2e00943 100644
--- a/test cases/common/51 pkgconfig-gen/dependencies/meson.build
+++ b/test cases/common/51 pkgconfig-gen/dependencies/meson.build
@@ -5,7 +5,7 @@ pkgg = import('pkgconfig')
# libmain internally use libinternal and expose libexpose in its API
exposed_lib = shared_library('libexposed', 'exposed.c')
internal_lib = shared_library('libinternal', 'internal.c')
-main_lib = shared_library('libmain', link_with : [exposed_lib, internal_lib])
+main_lib = static_library('libmain', link_with : [exposed_lib, internal_lib])
pkgg.generate(libraries : exposed_lib,
version : '1.0',
diff --git a/test cases/unit/24 pkgconfig usage/dependee/meson.build b/test cases/unit/24 pkgconfig usage/dependee/meson.build
new file mode 100644
index 0000000..beb446c
--- /dev/null
+++ b/test cases/unit/24 pkgconfig usage/dependee/meson.build
@@ -0,0 +1,7 @@
+project('pkgconfig user', 'c')
+
+pkgdep = dependency('libpkgdep')
+
+executable('pkguser', 'pkguser.c',
+ dependencies : pkgdep)
+
diff --git a/test cases/unit/24 pkgconfig usage/dependee/pkguser.c b/test cases/unit/24 pkgconfig usage/dependee/pkguser.c
new file mode 100644
index 0000000..2bff316
--- /dev/null
+++ b/test cases/unit/24 pkgconfig usage/dependee/pkguser.c
@@ -0,0 +1,6 @@
+#include<pkgdep.h>
+
+int main(int argc, char **argv) {
+ int res = pkgdep();
+ return res != 99;
+}
diff --git a/test cases/unit/24 pkgconfig usage/dependency/meson.build b/test cases/unit/24 pkgconfig usage/dependency/meson.build
new file mode 100644
index 0000000..89fae8e
--- /dev/null
+++ b/test cases/unit/24 pkgconfig usage/dependency/meson.build
@@ -0,0 +1,24 @@
+project('pkgconfig dep', 'c',
+ version : '1.0.0')
+
+# This is not used in the code, only to check that it does not
+# leak out to --libs.
+glib_dep = dependency('glib-2.0')
+
+pkgconfig = import('pkgconfig')
+
+intlib = static_library('libpkgdep-int', 'privatelib.c')
+intdep = declare_dependency(link_with : intlib)
+
+lib = shared_library('pkgdep', 'pkgdep.c',
+ dependencies : [glib_dep, intdep],
+ install : true)
+
+install_headers('pkgdep.h')
+
+pkgconfig.generate(
+ filebase : 'libpkgdep',
+ name : 'Libpkgdep',
+ description : 'Sample pkgconfig dependency library',
+ version : meson.project_version(),
+ libraries : lib)
diff --git a/test cases/unit/24 pkgconfig usage/dependency/pkgdep.c b/test cases/unit/24 pkgconfig usage/dependency/pkgdep.c
new file mode 100644
index 0000000..bd5c3f4
--- /dev/null
+++ b/test cases/unit/24 pkgconfig usage/dependency/pkgdep.c
@@ -0,0 +1,7 @@
+#include<pkgdep.h>
+
+int internal_thingy();
+
+int pkgdep() {
+ return internal_thingy();
+}
diff --git a/test cases/unit/24 pkgconfig usage/dependency/pkgdep.h b/test cases/unit/24 pkgconfig usage/dependency/pkgdep.h
new file mode 100644
index 0000000..16d622e
--- /dev/null
+++ b/test cases/unit/24 pkgconfig usage/dependency/pkgdep.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int pkgdep();
diff --git a/test cases/unit/24 pkgconfig usage/dependency/privatelib.c b/test cases/unit/24 pkgconfig usage/dependency/privatelib.c
new file mode 100644
index 0000000..71d2179
--- /dev/null
+++ b/test cases/unit/24 pkgconfig usage/dependency/privatelib.c
@@ -0,0 +1,3 @@
+int internal_thingy() {
+ return 99;
+}