Repository: mesonbuild/meson

Issue:
Optional dependency added to generated pkgconfig file even when not found
If I have an optional dependency `foo`:

```meson
foo_dep = dependency('foo', required: false)
```

and I use `foo_dep` to build a shared library that will then be fed to `pkgconfig.generate()`, the dependency on `foo` will be added to the `Requires.private` field, regardless of whether `foo_dep` was found or not. This behaviour changed between Meson 0.44.0 and 0.44.0-176-g81100f06.

As a real world issue: building libdrm with `-Dvalgrind=false`, and without Valgrind installed, with Meson 0.44 will generate a libdrm.pc file that does not depend on `valgrind`, whereas doing the same with Meson master will generate a libdrm.pc file that adds a dependency on `valgrind`:

```
--- /home/ebassi/Junk/libdrm-meson-stable.pc	2018-01-13 14:13:20.247204072 +0000
+++ /home/ebassi/Junk/libdrm-meson-master.pc	2018-01-13 14:17:00.365290492 +0000
@@ -5,5 +5,7 @@ includedir=${prefix}/include
 Name: libdrm
 Description: Userspace interface to kernel DRM services
 Version: 2.4.89
+Requires.private: valgrind
 Libs: -L${libdir} -ldrm
+Libs.private: -lm
 Cflags: -I${includedir} -I${includedir}/libdrm
```


Discussion:

Resolving patch:
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -79,7 +79,7 @@ def _process_libs(self, libs, public):
                     if not hasattr(obj, 'generated_pc'):
                         obj.generated_pc = self.name
                     self.add_priv_libs(obj.get_dependencies())
-                    self.add_priv_libs(obj.get_external_deps())
+                    self.add_priv_libs(self.strip_unfound(obj.get_external_deps()))
             elif isinstance(obj, str):
                 processed_libs.append(obj)
             else:
@@ -87,6 +87,9 @@ def _process_libs(self, libs, public):
 
         return processed_libs, processed_reqs, processed_cflags
 
+    def strip_unfound(self, deps):
+        return [x for x in deps if not hasattr(x, 'found') or x.found()]
+
     def remove_dups(self):
         self.pub_libs = list(set(self.pub_libs))
         self.pub_reqs = list(set(self.pub_reqs))
diff --git a/run_unittests.py b/run_unittests.py
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -436,6 +436,7 @@ def setUp(self):
         # In case the directory is inside a symlinked directory, find the real
         # path otherwise we might not find the srcdir from inside the builddir.
         self.builddir = os.path.realpath(tempfile.mkdtemp())
+        self.privatedir = os.path.join(self.builddir, 'meson-private')
         self.logdir = os.path.join(self.builddir, 'meson-logs')
         self.prefix = '/usr'
         self.libdir = os.path.join(self.prefix, 'lib')
@@ -1702,7 +1703,7 @@ def test_subproject_promotion(self):
         self.build()
 
     def test_warning_location(self):
-        tdir = os.path.join(self.unit_test_dir, '20 warning location')
+        tdir = os.path.join(self.unit_test_dir, '21 warning location')
         out = self.init(tdir)
         for expected in [
             r'WARNING: Keyword argument "link_with" defined multiple times in file meson.build, line 4',
@@ -2085,6 +2086,12 @@ def test_pkgconfig_gen_deps(self):
                                               '-llibinternal', '-lcustom2',
                                               '-lfoo']))
 
+    def test_pkg_unfound(self):
+        testdir = os.path.join(self.unit_test_dir, '22 unfound pkgconfig')
+        self.init(testdir)
+        pcfile = open(os.path.join(self.privatedir, 'somename.pc')).read()
+        self.assertFalse('blub_blob_blib' in pcfile)
+
     def test_vala_c_warnings(self):
         '''
         Test that no warnings are emitted for C code generated by Vala. This


Test patch:
diff --git a/test cases/unit/20 warning location/a.c b/test cases/unit/21 warning location/a.c
similarity index 100%
rename from test cases/unit/20 warning location/a.c
rename to test cases/unit/21 warning location/a.c
diff --git a/test cases/unit/20 warning location/b.c b/test cases/unit/21 warning location/b.c
similarity index 100%
rename from test cases/unit/20 warning location/b.c
rename to test cases/unit/21 warning location/b.c
diff --git a/test cases/unit/20 warning location/conf.in b/test cases/unit/21 warning location/conf.in
similarity index 100%
rename from test cases/unit/20 warning location/conf.in
rename to test cases/unit/21 warning location/conf.in
diff --git a/test cases/unit/20 warning location/main.c b/test cases/unit/21 warning location/main.c
similarity index 100%
rename from test cases/unit/20 warning location/main.c
rename to test cases/unit/21 warning location/main.c
diff --git a/test cases/unit/20 warning location/meson.build b/test cases/unit/21 warning location/meson.build
similarity index 100%
rename from test cases/unit/20 warning location/meson.build
rename to test cases/unit/21 warning location/meson.build
diff --git a/test cases/unit/20 warning location/sub/c.c b/test cases/unit/21 warning location/sub/c.c
similarity index 100%
rename from test cases/unit/20 warning location/sub/c.c
rename to test cases/unit/21 warning location/sub/c.c
diff --git a/test cases/unit/20 warning location/sub/d.c b/test cases/unit/21 warning location/sub/d.c
similarity index 100%
rename from test cases/unit/20 warning location/sub/d.c
rename to test cases/unit/21 warning location/sub/d.c
diff --git a/test cases/unit/20 warning location/sub/meson.build b/test cases/unit/21 warning location/sub/meson.build
similarity index 100%
rename from test cases/unit/20 warning location/sub/meson.build
rename to test cases/unit/21 warning location/sub/meson.build
diff --git a/test cases/unit/20 warning location/sub/sub.c b/test cases/unit/21 warning location/sub/sub.c
similarity index 100%
rename from test cases/unit/20 warning location/sub/sub.c
rename to test cases/unit/21 warning location/sub/sub.c
diff --git a/test cases/unit/22 unfound pkgconfig/meson.build b/test cases/unit/22 unfound pkgconfig/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/unit/22 unfound pkgconfig/meson.build	
@@ -0,0 +1,15 @@
+project('foobar', 'c')
+
+unfound = dependency('blub_blob_blib', required : false)
+
+pkgg = import('pkgconfig')
+
+l = shared_library('somename', 'some.c',
+  dependencies : unfound)
+
+pkgg.generate(
+  libraries : l,
+  name : 'somename',
+  version : '1.0.0',
+  description : 'A test library.',
+)
diff --git a/test cases/unit/22 unfound pkgconfig/some.c b/test cases/unit/22 unfound pkgconfig/some.c
new file mode 100644
--- /dev/null
+++ b/test cases/unit/22 unfound pkgconfig/some.c	
@@ -0,0 +1,3 @@
+int some() {
+    return 6;
+}