diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2018-03-19 23:43:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-19 23:43:35 +0200 |
commit | e984e1072b28abfa4ac278992a8ef6d138c15608 (patch) | |
tree | 43cac94062456f8d5ecccc2bcc114623e8200d33 | |
parent | 7eb187c5f2cf55c6d441db08a87bac02cb58a9dc (diff) | |
parent | cf5f1a83d55d05412e29058844e4fda5e420553b (diff) | |
download | meson-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.py | 15 | ||||
-rwxr-xr-x | run_unittests.py | 44 | ||||
-rw-r--r-- | test cases/common/51 pkgconfig-gen/dependencies/meson.build | 2 | ||||
-rw-r--r-- | test cases/unit/24 pkgconfig usage/dependee/meson.build | 7 | ||||
-rw-r--r-- | test cases/unit/24 pkgconfig usage/dependee/pkguser.c | 6 | ||||
-rw-r--r-- | test cases/unit/24 pkgconfig usage/dependency/meson.build | 24 | ||||
-rw-r--r-- | test cases/unit/24 pkgconfig usage/dependency/pkgdep.c | 7 | ||||
-rw-r--r-- | test cases/unit/24 pkgconfig usage/dependency/pkgdep.h | 3 | ||||
-rw-r--r-- | test cases/unit/24 pkgconfig usage/dependency/privatelib.c | 3 |
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; +} |