Repository: mesonbuild/meson

Issue:
qt4 tool path misdetected
In qt5, the tool path is detected from pkg-config using the host_bins variable, as is currently done in the code, but for qt4, the .pc file looks like this:
moc_location=${prefix}/lib/x86_64-linux-gnu/qt4/bin/moc
uic_location=${prefix}/lib/x86_64-linux-gnu/qt4/bin/uic
rcc_location=${prefix}/lib/x86_64-linux-gnu/qt4/bin/rcc
lupdate_location=${prefix}/lib/x86_64-linux-gnu/qt4/bin/lupdate
lrelease_location=${prefix}/lib/x86_64-linux-gnu/qt4/bin/lrelease

So the default path is used to find tools. On debian, at least, this chooses the system default qt which may be qt4, or it may incorrectly be qt5 tools when using the qt4 module.


Discussion:

Resolving patch:
diff --git a/mesonbuild/dependencies.py b/mesonbuild/dependencies.py
--- a/mesonbuild/dependencies.py
+++ b/mesonbuild/dependencies.py
@@ -1010,7 +1010,7 @@ def _pkgconfig_detect(self, mods, env, kwargs):
             corekwargs = {'required': 'false', 'silent': 'true'}
             core = PkgConfigDependency(self.qtpkgname + 'Core', env, corekwargs)
         # Used by self.compilers_detect()
-        self.bindir = core.get_pkgconfig_variable('host_bins')
+        self.bindir = self.get_pkgconfig_host_bins(core)
         if not self.bindir:
             # If exec_prefix is not defined, the pkg-config file is broken
             prefix = core.get_pkgconfig_variable('exec_prefix')
@@ -1119,10 +1119,25 @@ class Qt5Dependency(QtBaseDependency):
     def __init__(self, env, kwargs):
         QtBaseDependency.__init__(self, 'qt5', env, kwargs)
 
+    def get_pkgconfig_host_bins(self, core):
+        return core.get_pkgconfig_variable('host_bins')
+
 class Qt4Dependency(QtBaseDependency):
     def __init__(self, env, kwargs):
         QtBaseDependency.__init__(self, 'qt4', env, kwargs)
 
+    def get_pkgconfig_host_bins(self, core):
+        # Only return one bins dir, because the tools are generally all in one
+        # directory for Qt4, in Qt5, they must all be in one directory. Return
+        # the first one found among the bin variables, in case one tool is not
+        # configured to be built.
+        applications = ['moc', 'uic', 'rcc', 'lupdate', 'lrelease']
+        for application in applications:
+            try:
+                return os.path.dirname(core.get_pkgconfig_variable('%s_location' % application))
+            except MesonException:
+                pass
+
 class GnuStepDependency(Dependency):
     def __init__(self, environment, kwargs):
         Dependency.__init__(self, 'gnustep')
diff --git a/run_unittests.py b/run_unittests.py
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -1023,6 +1023,25 @@ def test_vala_c_warnings(self):
         self.assertIn("'-Werror'", vala_command)
         self.assertIn("'-Werror'", c_command)
 
+    def test_qt5dependency_pkgconfig_detection(self):
+        '''
+        Test that qt4 and qt5 detection with pkgconfig works.
+        '''
+        # Verify Qt4 or Qt5 can be found with pkg-config
+        if not shutil.which('pkg-config'):
+            raise unittest.SkipTest('pkg-config not found')
+        qt4 = subprocess.call(['pkg-config', '--exists', 'QtCore'])
+        qt5 = subprocess.call(['pkg-config', '--exists', 'Qt5Core'])
+        if qt4 != 0 or qt5 != 0:
+            raise unittest.SkipTest('Qt not found with pkg-config')
+        testdir = os.path.join(self.framework_test_dir, '4 qt')
+        self.init(testdir)
+        # Confirm that the dependency was found with qmake
+        msg = 'Qt4 native `pkg-config` dependency (modules: Core, Gui) found: YES\n'
+        msg2 = 'Qt5 native `pkg-config` dependency (modules: Core, Gui) found: YES\n'
+        mesonlog = self.get_meson_log()
+        self.assertTrue(msg in mesonlog or msg2 in mesonlog)
+
     def test_qt5dependency_qmake_detection(self):
         '''
         Test that qt5 detection with qmake works. This can't be an ordinary


Test patch: