Merge pull request #1010 from centricular/qt5-broken-moc-detection
Overhaul Qt4/5 detection with pkg-config/qmake and improve moc/uic/rcc detection
This commit is contained in:
commit
28b70ba4e5
|
@ -1,20 +0,0 @@
|
|||
#include <QApplication>
|
||||
#include "mainWindow.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
QApplication app(argc, argv);
|
||||
MainWindow *win = new MainWindow();
|
||||
QImage qi(":/thing.png");
|
||||
if(qi.width() != 640) {
|
||||
return 1;
|
||||
}
|
||||
QImage qi2(":/thing2.png");
|
||||
if(qi2.width() != 640) {
|
||||
return 1;
|
||||
}
|
||||
win->setWindowTitle("Meson Qt4 build test");
|
||||
|
||||
win->show();
|
||||
return app.exec();
|
||||
return 0;
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
project('qt4 build test', 'cpp')
|
||||
|
||||
# This is a manual test rather than an automatic one
|
||||
# because during Debian package builds only Qt4 or Qt5
|
||||
# can be active.
|
||||
|
||||
qt4 = import('qt4')
|
||||
qt4dep = dependency('qt4', modules : 'Gui')
|
||||
|
||||
prep = qt4.preprocess(moc_headers : ['mainWindow.h'], # These need to be fed through the moc tool before use.
|
||||
ui_files : 'mainWindow.ui', # XML files that need to be compiled with the uic tol.
|
||||
qresources : 'stuff.qrc', # Resource file for rcc compiler.
|
||||
)
|
||||
|
||||
q5exe = executable('qt4app',
|
||||
sources : ['main.cpp', 'mainWindow.cpp', # Sources that don't need preprocessing.
|
||||
prep],
|
||||
dependencies : qt4dep)
|
||||
|
||||
# We need a console test application because some test environments
|
||||
# do not have an X server.
|
||||
|
||||
qt4core = dependency('qt4', modules : 'Core')
|
||||
|
||||
qt4coreapp = executable('q4core', 'q4core.cpp',
|
||||
dependencies : qt4core)
|
||||
|
||||
test('qt4test', qt4coreapp)
|
||||
|
||||
# The build system needs to include the cpp files from
|
||||
# headers but the user must manually include moc
|
||||
# files from sources.
|
||||
manpreprocessed = qt4.preprocess(
|
||||
moc_sources : 'manualinclude.cpp',
|
||||
moc_headers : 'manualinclude.h')
|
||||
|
||||
q4maninclude = executable('q4maninclude',
|
||||
sources : ['manualinclude.cpp', manpreprocessed],
|
||||
dependencies : qt4core)
|
||||
|
||||
test('q4maninclude', q4maninclude)
|
|
@ -1,10 +0,0 @@
|
|||
#include <QCoreApplication>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
// Don't actually start the main loop so this
|
||||
// can be run as a unit test.
|
||||
//return app.exec();
|
||||
return 0;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<!DOCTYPE RCC>
|
||||
<RCC version="1.0">
|
||||
<qresource>
|
||||
<file>thing.png</file>
|
||||
<file>thing2.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -22,6 +22,7 @@
|
|||
import re
|
||||
import os, stat, glob, subprocess, shutil
|
||||
import sysconfig
|
||||
from collections import OrderedDict
|
||||
from . mesonlib import MesonException
|
||||
from . import mlog
|
||||
from . import mesonlib
|
||||
|
@ -806,11 +807,20 @@ class GMockDependency(Dependency):
|
|||
def found(self):
|
||||
return self.is_found
|
||||
|
||||
class Qt5Dependency(Dependency):
|
||||
def __init__(self, environment, kwargs):
|
||||
Dependency.__init__(self, 'qt5')
|
||||
self.name = 'qt5'
|
||||
class QtBaseDependency(Dependency):
|
||||
def __init__(self, name, env, kwargs):
|
||||
Dependency.__init__(self, name)
|
||||
self.name = name
|
||||
self.qtname = name.capitalize()
|
||||
self.qtver = name[-1]
|
||||
self.root = '/usr'
|
||||
self.bindir = None
|
||||
self.silent = kwargs.get('silent', False)
|
||||
# We store the value of required here instead of passing it on to
|
||||
# PkgConfigDependency etc because we want to try the qmake-based
|
||||
# fallback as well.
|
||||
self.required = kwargs.pop('required', True)
|
||||
kwargs['required'] = False
|
||||
mods = kwargs.get('modules', [])
|
||||
self.cargs = []
|
||||
self.largs = []
|
||||
|
@ -818,69 +828,130 @@ class Qt5Dependency(Dependency):
|
|||
if isinstance(mods, str):
|
||||
mods = [mods]
|
||||
if len(mods) == 0:
|
||||
raise DependencyException('No Qt5 modules specified.')
|
||||
type_text = 'native'
|
||||
if environment.is_cross_build() and kwargs.get('native', False):
|
||||
type_text = 'cross'
|
||||
self.pkgconfig_detect(mods, environment, kwargs)
|
||||
elif not environment.is_cross_build() and shutil.which('pkg-config') is not None:
|
||||
self.pkgconfig_detect(mods, environment, kwargs)
|
||||
elif shutil.which('qmake') is not None:
|
||||
self.qmake_detect(mods, kwargs)
|
||||
else:
|
||||
self.version = 'none'
|
||||
raise DependencyException('No ' + self.qtname + ' modules specified.')
|
||||
type_text = 'cross' if env.is_cross_build() else 'native'
|
||||
found_msg = '{} {} `{{}}` dependency found:'.format(self.qtname, type_text)
|
||||
from_text = 'pkg-config'
|
||||
# Prefer pkg-config, then fallback to `qmake -query`
|
||||
self._pkgconfig_detect(mods, env, kwargs)
|
||||
if not self.is_found:
|
||||
mlog.log('Qt5 %s dependency found: ' % type_text, mlog.red('NO'))
|
||||
else:
|
||||
mlog.log('Qt5 %s dependency found: ' % type_text, mlog.green('YES'))
|
||||
from_text = self._qmake_detect(mods, env, kwargs)
|
||||
if not self.is_found:
|
||||
from_text = '(checked pkg-config, qmake-{}, and qmake)' \
|
||||
''.format(self.name)
|
||||
self.version = 'none'
|
||||
if self.required:
|
||||
err_msg = '{} {} dependency not found {}' \
|
||||
''.format(self.qtname, type_text, from_text)
|
||||
raise DependencyException(err_msg)
|
||||
if not self.silent:
|
||||
mlog.log(found_msg.format(from_text), mlog.red('NO'))
|
||||
return
|
||||
if not self.silent:
|
||||
mlog.log(found_msg.format(from_text), mlog.green('YES'))
|
||||
|
||||
def pkgconfig_detect(self, mods, environment, kwargs):
|
||||
modules = []
|
||||
def compilers_detect(self):
|
||||
"Detect Qt (4 or 5) moc, uic, rcc in the specified bindir or in PATH"
|
||||
if self.bindir:
|
||||
moc = ExternalProgram(os.path.join(self.bindir, 'moc'), silent=True)
|
||||
uic = ExternalProgram(os.path.join(self.bindir, 'uic'), silent=True)
|
||||
rcc = ExternalProgram(os.path.join(self.bindir, 'rcc'), silent=True)
|
||||
else:
|
||||
# We don't accept unsuffixed 'moc', 'uic', and 'rcc' because they
|
||||
# are sometimes older, or newer versions.
|
||||
moc = ExternalProgram('moc-' + self.name, silent=True)
|
||||
uic = ExternalProgram('uic-' + self.name, silent=True)
|
||||
rcc = ExternalProgram('rcc-' + self.name, silent=True)
|
||||
return moc, uic, rcc
|
||||
|
||||
def _pkgconfig_detect(self, mods, env, kwargs):
|
||||
if self.qtver == "4":
|
||||
qtpkgname = 'Qt'
|
||||
else:
|
||||
qtpkgname = self.qtname
|
||||
modules = OrderedDict()
|
||||
for module in mods:
|
||||
modules.append(PkgConfigDependency('Qt5' + module, environment, kwargs))
|
||||
for m in modules:
|
||||
modules[module] = PkgConfigDependency(qtpkgname + module, env, kwargs)
|
||||
self.is_found = True
|
||||
for m in modules.values():
|
||||
if not m.found():
|
||||
self.is_found = False
|
||||
self.cargs += m.get_compile_args()
|
||||
self.largs += m.get_link_args()
|
||||
self.is_found = True
|
||||
self.version = modules[0].modversion
|
||||
self.version = m.modversion
|
||||
# Try to detect moc, uic, rcc
|
||||
if 'Core' in modules:
|
||||
core = modules['Core']
|
||||
else:
|
||||
corekwargs = {'required': 'false', 'silent': 'true'}
|
||||
core = PkgConfigDependency(qtpkgname + 'Core', env, corekwargs)
|
||||
# Used by self.compilers_detect()
|
||||
self.bindir = core.get_pkgconfig_variable('host_bins')
|
||||
if not self.bindir:
|
||||
# If exec_prefix is not defined, the pkg-config file is broken
|
||||
prefix = core.get_pkgconfig_variable('exec_prefix')
|
||||
if prefix:
|
||||
self.bindir = os.path.join(prefix, 'bin')
|
||||
|
||||
def qmake_detect(self, mods, kwargs):
|
||||
pc = subprocess.Popen(['qmake', '-v'], stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
(stdo, _) = pc.communicate()
|
||||
if pc.returncode != 0:
|
||||
def _find_qmake(self, qmake, env):
|
||||
# Even when cross-compiling, if we don't get a cross-info qmake, we
|
||||
# fallback to using the qmake in PATH because that's what we used to do
|
||||
if env.is_cross_build():
|
||||
qmake = env.cross_info.config['binaries'].get('qmake', qmake)
|
||||
return ExternalProgram(qmake, silent=True)
|
||||
|
||||
def _qmake_detect(self, mods, env, kwargs):
|
||||
for qmake in ('qmake-' + self.name, 'qmake'):
|
||||
self.qmake = self._find_qmake(qmake, env)
|
||||
if not self.qmake.found():
|
||||
continue
|
||||
# Check that the qmake is for qt5
|
||||
pc = subprocess.Popen(self.qmake.fullpath + ['-v'],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
||||
universal_newlines=True)
|
||||
stdo = pc.communicate()[0]
|
||||
if pc.returncode != 0:
|
||||
continue
|
||||
if not 'Qt version ' + self.qtver in stdo:
|
||||
mlog.log('QMake is not for ' + self.qtname)
|
||||
continue
|
||||
# Found qmake for Qt5!
|
||||
break
|
||||
else:
|
||||
# Didn't find qmake :(
|
||||
return
|
||||
stdo = stdo.decode()
|
||||
if not 'version 5' in stdo:
|
||||
mlog.log('QMake is not for Qt5.')
|
||||
return
|
||||
self.version = re.search('5(\.\d+)+', stdo).group(0)
|
||||
(stdo, _) = subprocess.Popen(['qmake', '-query'], stdout=subprocess.PIPE).communicate()
|
||||
self.version = re.search(self.qtver + '(\.\d+)+', stdo).group(0)
|
||||
# Query library path, header path, and binary path
|
||||
stdo = subprocess.Popen(self.qmake.fullpath + ['-query'],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
||||
universal_newlines=True).communicate()[0]
|
||||
qvars = {}
|
||||
for line in stdo.decode().split('\n'):
|
||||
for line in stdo.split('\n'):
|
||||
line = line.strip()
|
||||
if line == '':
|
||||
continue
|
||||
(k, v) = tuple(line.split(':', 1))
|
||||
qvars[k] = v
|
||||
if mesonlib.is_osx():
|
||||
return self.framework_detect(qvars, mods, kwargs)
|
||||
return self._framework_detect(qvars, mods, kwargs)
|
||||
incdir = qvars['QT_INSTALL_HEADERS']
|
||||
self.cargs.append('-I' + incdir)
|
||||
libdir = qvars['QT_INSTALL_LIBS']
|
||||
bindir = qvars['QT_INSTALL_BINS']
|
||||
# Used by self.compilers_detect()
|
||||
self.bindir = qvars['QT_INSTALL_BINS']
|
||||
#self.largs.append('-L' + libdir)
|
||||
for module in mods:
|
||||
mincdir = os.path.join(incdir, 'Qt' + module)
|
||||
self.cargs.append('-I' + mincdir)
|
||||
libfile = os.path.join(libdir, 'Qt5' + module + '.lib')
|
||||
libfile = os.path.join(libdir, self.qtname + module + '.lib')
|
||||
if not os.path.isfile(libfile):
|
||||
# MinGW links directly to .dll, not to .lib.
|
||||
libfile = os.path.join(bindir, 'Qt5' + module + '.dll')
|
||||
libfile = os.path.join(self.bindir, self.qtname + module + '.dll')
|
||||
self.largs.append(libfile)
|
||||
self.is_found = True
|
||||
return qmake
|
||||
|
||||
def framework_detect(self, qvars, modules, kwargs):
|
||||
def _framework_detect(self, qvars, modules, kwargs):
|
||||
libdir = qvars['QT_INSTALL_LIBS']
|
||||
for m in modules:
|
||||
fname = 'Qt' + m
|
||||
|
@ -890,7 +961,8 @@ class Qt5Dependency(Dependency):
|
|||
self.is_found = True
|
||||
self.cargs += fwdep.get_compile_args()
|
||||
self.largs += fwdep.get_link_args()
|
||||
|
||||
# Used by self.compilers_detect()
|
||||
self.bindir = qvars['QT_INSTALL_BINS']
|
||||
|
||||
def get_version(self):
|
||||
return self.version
|
||||
|
@ -917,43 +989,13 @@ class Qt5Dependency(Dependency):
|
|||
# Fix this to be more portable, especially to MSVC.
|
||||
return ['-fPIC']
|
||||
|
||||
class Qt4Dependency(Dependency):
|
||||
def __init__(self, environment, kwargs):
|
||||
Dependency.__init__(self, 'qt4')
|
||||
self.name = 'qt4'
|
||||
self.root = '/usr'
|
||||
self.modules = []
|
||||
mods = kwargs.get('modules', [])
|
||||
if isinstance(mods, str):
|
||||
mods = [mods]
|
||||
for module in mods:
|
||||
self.modules.append(PkgConfigDependency('Qt' + module, environment, kwargs))
|
||||
if len(self.modules) == 0:
|
||||
raise DependencyException('No Qt4 modules specified.')
|
||||
class Qt5Dependency(QtBaseDependency):
|
||||
def __init__(self, env, kwargs):
|
||||
QtBaseDependency.__init__(self, 'qt5', env, kwargs)
|
||||
|
||||
def get_version(self):
|
||||
return self.modules[0].get_version()
|
||||
|
||||
def get_compile_args(self):
|
||||
args = []
|
||||
for m in self.modules:
|
||||
args += m.get_compile_args()
|
||||
return args
|
||||
|
||||
def get_sources(self):
|
||||
return []
|
||||
|
||||
def get_link_args(self):
|
||||
args = []
|
||||
for module in self.modules:
|
||||
args += module.get_link_args()
|
||||
return args
|
||||
|
||||
def found(self):
|
||||
for i in self.modules:
|
||||
if not i.found():
|
||||
return False
|
||||
return True
|
||||
class Qt4Dependency(QtBaseDependency):
|
||||
def __init__(self, env, kwargs):
|
||||
QtBaseDependency.__init__(self, 'qt4', env, kwargs)
|
||||
|
||||
class GnuStepDependency(Dependency):
|
||||
def __init__(self, environment, kwargs):
|
||||
|
|
|
@ -12,26 +12,27 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from .. import dependencies, mlog
|
||||
import os, subprocess
|
||||
from .. import mlog
|
||||
from .. import build
|
||||
from ..mesonlib import MesonException
|
||||
from ..dependencies import Qt4Dependency
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
class Qt4Module():
|
||||
def __init__(self):
|
||||
mlog.log('Detecting Qt tools.')
|
||||
# The binaries have different names on different
|
||||
# distros. Joy.
|
||||
self.moc = dependencies.ExternalProgram('moc-qt4', silent=True)
|
||||
if not self.moc.found():
|
||||
self.moc = dependencies.ExternalProgram('moc', silent=True)
|
||||
self.uic = dependencies.ExternalProgram('uic-qt4', silent=True)
|
||||
if not self.uic.found():
|
||||
self.uic = dependencies.ExternalProgram('uic', silent=True)
|
||||
self.rcc = dependencies.ExternalProgram('rcc-qt4', silent=True)
|
||||
if not self.rcc.found():
|
||||
self.rcc = dependencies.ExternalProgram('rcc', silent=True)
|
||||
tools_detected = False
|
||||
|
||||
def _detect_tools(self, env):
|
||||
if self.tools_detected:
|
||||
return
|
||||
mlog.log('Detecting Qt4 tools')
|
||||
# FIXME: We currently require Qt4 to exist while importing the module.
|
||||
# We should make it gracefully degrade and not create any targets if
|
||||
# the import is marked as 'optional' (not implemented yet)
|
||||
kwargs = {'required': 'true', 'modules': 'Core', 'silent': 'true'}
|
||||
qt4 = Qt4Dependency(env, kwargs)
|
||||
# Get all tools and then make sure that they are the right version
|
||||
self.moc, self.uic, self.rcc = qt4.compilers_detect()
|
||||
# Moc, uic and rcc write their version strings to stderr.
|
||||
# Moc and rcc return a non-zero result when doing so.
|
||||
# What kind of an idiot thought that was a good idea?
|
||||
|
@ -80,6 +81,7 @@ class Qt4Module():
|
|||
% (' '.join(self.rcc.fullpath), rcc_ver.split()[-1]))
|
||||
else:
|
||||
mlog.log(' rcc:', mlog.red('NO'))
|
||||
self.tools_detected = True
|
||||
|
||||
def parse_qrc(self, state, fname):
|
||||
abspath = os.path.join(state.environment.source_dir, state.subdir, fname)
|
||||
|
@ -115,18 +117,29 @@ class Qt4Module():
|
|||
if not isinstance(srctmp, list):
|
||||
srctmp = [srctmp]
|
||||
sources = args[1:] + srctmp
|
||||
self._detect_tools(state.environment)
|
||||
err_msg = "{0} sources specified and couldn't find {1}, " \
|
||||
"please check your qt4 installation"
|
||||
if len(moc_headers) + len(moc_sources) > 0 and not self.moc.found():
|
||||
raise MesonException(err_msg.format('MOC', 'moc-qt4'))
|
||||
if len(rcc_files) > 0:
|
||||
rcc_kwargs = {'output' : '@BASENAME@.cpp',
|
||||
'arguments' : ['@INPUT@', '-o', '@OUTPUT@']}
|
||||
rcc_gen = build.Generator([self.rcc], rcc_kwargs)
|
||||
rcc_output = build.GeneratedList(rcc_gen)
|
||||
if not self.rcc.found():
|
||||
raise MesonException(err_msg.format('RCC', 'rcc-qt4'))
|
||||
qrc_deps = []
|
||||
for i in rcc_files:
|
||||
qrc_deps += self.parse_qrc(state, i)
|
||||
rcc_output.extra_depends = qrc_deps
|
||||
[rcc_output.add_file(os.path.join(state.subdir, a)) for a in rcc_files]
|
||||
sources.append(rcc_output)
|
||||
basename = os.path.split(rcc_files[0])[1]
|
||||
name = 'qt4-' + basename.replace('.', '_')
|
||||
rcc_kwargs = {'input' : rcc_files,
|
||||
'output' : name + '.cpp',
|
||||
'command' : [self.rcc, '-o', '@OUTPUT@', '@INPUT@'],
|
||||
'depend_files' : qrc_deps,
|
||||
}
|
||||
res_target = build.CustomTarget(name, state.subdir, rcc_kwargs)
|
||||
sources.append(res_target)
|
||||
if len(ui_files) > 0:
|
||||
if not self.uic.found():
|
||||
raise MesonException(err_msg.format('UIC', 'uic-qt4'))
|
||||
ui_kwargs = {'output' : 'ui_@BASENAME@.h',
|
||||
'arguments' : ['-o', '@OUTPUT@', '@INPUT@']}
|
||||
ui_gen = build.Generator([self.uic], ui_kwargs)
|
||||
|
|
|
@ -12,27 +12,27 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from .. import dependencies, mlog
|
||||
import os, subprocess
|
||||
from .. import mlog
|
||||
from .. import build
|
||||
from ..mesonlib import MesonException
|
||||
from ..dependencies import Qt5Dependency
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
class Qt5Module():
|
||||
tools_detected = False
|
||||
|
||||
def __init__(self):
|
||||
mlog.log('Detecting Qt tools.')
|
||||
# The binaries have different names on different
|
||||
# distros. Joy.
|
||||
self.moc = dependencies.ExternalProgram('moc-qt5', silent=True)
|
||||
if not self.moc.found():
|
||||
self.moc = dependencies.ExternalProgram('moc', silent=True)
|
||||
self.uic = dependencies.ExternalProgram('uic-qt5', silent=True)
|
||||
if not self.uic.found():
|
||||
self.uic = dependencies.ExternalProgram('uic', silent=True)
|
||||
self.rcc = dependencies.ExternalProgram('rcc-qt5', silent=True)
|
||||
if not self.rcc.found():
|
||||
self.rcc = dependencies.ExternalProgram('rcc', silent=True)
|
||||
def _detect_tools(self, env):
|
||||
if self.tools_detected:
|
||||
return
|
||||
mlog.log('Detecting Qt5 tools')
|
||||
# FIXME: We currently require Qt5 to exist while importing the module.
|
||||
# We should make it gracefully degrade and not create any targets if
|
||||
# the import is marked as 'optional' (not implemented yet)
|
||||
kwargs = {'required': 'true', 'modules': 'Core', 'silent': 'true'}
|
||||
qt5 = Qt5Dependency(env, kwargs)
|
||||
# Get all tools and then make sure that they are the right version
|
||||
self.moc, self.uic, self.rcc = qt5.compilers_detect()
|
||||
# Moc, uic and rcc write their version strings to stderr.
|
||||
# Moc and rcc return a non-zero result when doing so.
|
||||
# What kind of an idiot thought that was a good idea?
|
||||
|
@ -87,6 +87,7 @@ class Qt5Module():
|
|||
% (' '.join(self.rcc.fullpath), rcc_ver.split()[-1]))
|
||||
else:
|
||||
mlog.log(' rcc:', mlog.red('NO'))
|
||||
self.tools_detected = True
|
||||
|
||||
def parse_qrc(self, state, fname):
|
||||
abspath = os.path.join(state.environment.source_dir, state.subdir, fname)
|
||||
|
@ -122,7 +123,14 @@ class Qt5Module():
|
|||
if not isinstance(srctmp, list):
|
||||
srctmp = [srctmp]
|
||||
sources = args[1:] + srctmp
|
||||
self._detect_tools(state.environment)
|
||||
err_msg = "{0} sources specified and couldn't find {1}, " \
|
||||
"please check your qt5 installation"
|
||||
if len(moc_headers) + len(moc_sources) > 0 and not self.moc.found():
|
||||
raise MesonException(err_msg.format('MOC', 'moc-qt5'))
|
||||
if len(rcc_files) > 0:
|
||||
if not self.rcc.found():
|
||||
raise MesonException(err_msg.format('RCC', 'rcc-qt5'))
|
||||
qrc_deps = []
|
||||
for i in rcc_files:
|
||||
qrc_deps += self.parse_qrc(state, i)
|
||||
|
@ -132,11 +140,12 @@ class Qt5Module():
|
|||
'command' : [self.rcc, '-o', '@OUTPUT@', '@INPUT@'],
|
||||
'depend_files' : qrc_deps,
|
||||
}
|
||||
res_target = build.CustomTarget(basename.replace('.', '_'),
|
||||
state.subdir,
|
||||
rcc_kwargs)
|
||||
name = 'qt5-' + basename.replace('.', '_')
|
||||
res_target = build.CustomTarget(name, state.subdir, rcc_kwargs)
|
||||
sources.append(res_target)
|
||||
if len(ui_files) > 0:
|
||||
if not self.uic.found():
|
||||
raise MesonException(err_msg.format('UIC', 'uic-qt5'))
|
||||
ui_kwargs = {'output' : 'ui_@BASENAME@.h',
|
||||
'arguments' : ['-o', '@OUTPUT@', '@INPUT@']}
|
||||
ui_gen = build.Generator([self.uic], ui_kwargs)
|
||||
|
|
|
@ -19,7 +19,7 @@ import re, json
|
|||
import tempfile
|
||||
import mesonbuild.environment
|
||||
from mesonbuild.environment import detect_ninja
|
||||
from mesonbuild.dependencies import PkgConfigDependency
|
||||
from mesonbuild.dependencies import PkgConfigDependency, Qt5Dependency
|
||||
|
||||
def get_soname(fname):
|
||||
# HACK, fix to not use shell.
|
||||
|
@ -59,6 +59,7 @@ class LinuxlikeTests(unittest.TestCase):
|
|||
self.ninja_command = [detect_ninja(), '-C', self.builddir]
|
||||
self.common_test_dir = os.path.join(src_root, 'test cases/common')
|
||||
self.vala_test_dir = os.path.join(src_root, 'test cases/vala')
|
||||
self.framework_test_dir = os.path.join(src_root, 'test cases/frameworks')
|
||||
self.output = b''
|
||||
self.orig_env = os.environ.copy()
|
||||
|
||||
|
@ -67,22 +68,29 @@ class LinuxlikeTests(unittest.TestCase):
|
|||
os.environ = self.orig_env
|
||||
super().tearDown()
|
||||
|
||||
def _run(self, command):
|
||||
self.output += subprocess.check_output(command, env=os.environ.copy())
|
||||
|
||||
def init(self, srcdir):
|
||||
self.output += subprocess.check_output(self.meson_command + [srcdir, self.builddir])
|
||||
self._run(self.meson_command + [srcdir, self.builddir])
|
||||
|
||||
def build(self):
|
||||
self.output += subprocess.check_output(self.ninja_command)
|
||||
self._run(self.ninja_command)
|
||||
|
||||
def run_target(self, target):
|
||||
self.output += subprocess.check_output(self.ninja_command + [target])
|
||||
|
||||
def setconf(self, arg):
|
||||
self.output += subprocess.check_output(self.mconf_command + [arg, self.builddir])
|
||||
self._run(self.mconf_command + [arg, self.builddir])
|
||||
|
||||
def get_compdb(self):
|
||||
with open(os.path.join(self.builddir, 'compile_commands.json')) as ifile:
|
||||
return json.load(ifile)
|
||||
|
||||
def get_meson_log(self):
|
||||
with open(os.path.join(self.builddir, 'meson-logs', 'meson-log.txt')) as f:
|
||||
return f.readlines()
|
||||
|
||||
def introspect(self, arg):
|
||||
out = subprocess.check_output(self.mintro_command + [arg, self.builddir])
|
||||
return json.loads(out.decode('utf-8'))
|
||||
|
@ -181,5 +189,19 @@ class LinuxlikeTests(unittest.TestCase):
|
|||
self.init(testdir)
|
||||
self.run_target('check_exists')
|
||||
|
||||
def test_qt5dependency_qmake_detection(self):
|
||||
# Can't be sure that `qmake` is Qt5, so just try qmake-qt5.
|
||||
if not shutil.which('qmake-qt5'):
|
||||
raise unittest.SkipTest('qt5 not found')
|
||||
# Disable pkg-config codepath and force searching with qmake/qmake-qt5
|
||||
os.environ['PKG_CONFIG_LIBDIR'] = self.builddir
|
||||
os.environ['PKG_CONFIG_PATH'] = self.builddir
|
||||
testdir = os.path.join(self.framework_test_dir, '4 qt')
|
||||
self.init(testdir)
|
||||
# Confirm that the dependency was found with qmake
|
||||
msg = 'Qt5 native `qmake-qt5` dependency found: YES\n'
|
||||
mesonlog = self.get_meson_log()
|
||||
self.assertTrue(msg in mesonlog)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
project('qt4 and 5 build test', 'cpp')
|
||||
|
||||
foreach qt : ['qt4', 'qt5']
|
||||
qtdep = dependency(qt, modules : ['Core', 'Gui', 'Widgets'], required : qt == 'qt5')
|
||||
if qtdep.found()
|
||||
qtmodule = import(qt)
|
||||
|
||||
# The following has two resource files because having two in one target
|
||||
# requires you to do it properly or you get linker symbol clashes.
|
||||
|
||||
prep = qtmodule.preprocess(
|
||||
moc_headers : ['mainWindow.h'], # These need to be fed through the moc tool before use.
|
||||
ui_files : 'mainWindow.ui', # XML files that need to be compiled with the uic tol.
|
||||
qresources : ['stuff.qrc', 'stuff2.qrc'], # Resource file for rcc compiler.
|
||||
)
|
||||
|
||||
qexe = executable(qt + 'app',
|
||||
sources : ['main.cpp', 'mainWindow.cpp', # Sources that don't need preprocessing.
|
||||
prep],
|
||||
dependencies : qtdep)
|
||||
|
||||
# We need a console test application because some test environments
|
||||
# do not have an X server.
|
||||
|
||||
qtcore = dependency(qt, modules : 'Core')
|
||||
|
||||
qtcoreapp = executable(qt + 'core', 'q5core.cpp',
|
||||
dependencies : qtcore)
|
||||
|
||||
test(qt + 'test', qtcoreapp)
|
||||
|
||||
# The build system needs to include the cpp files from
|
||||
# headers but the user must manually include moc
|
||||
# files from sources.
|
||||
manpreprocessed = qtmodule.preprocess(
|
||||
moc_sources : 'manualinclude.cpp',
|
||||
moc_headers : 'manualinclude.h')
|
||||
|
||||
qtmaninclude = executable(qt + 'maninclude',
|
||||
sources : ['manualinclude.cpp', manpreprocessed],
|
||||
dependencies : qtcore)
|
||||
|
||||
test(qt + 'maninclude', qtmaninclude)
|
||||
endif
|
||||
endforeach
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
@ -1,8 +0,0 @@
|
|||
#include "mainWindow.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
|
||||
setupUi(this);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef MES_MAINWINDOW
|
||||
#define MES_MAINWINDOW
|
||||
|
||||
#include <QObject>
|
||||
#include <QMainWindow>
|
||||
#include "ui_mainWindow.h"
|
||||
|
||||
class NotificationModel;
|
||||
|
||||
class MainWindow : public QMainWindow, private Ui_MainWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent=0);
|
||||
~MainWindow();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>270</width>
|
||||
<height>115</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>241</width>
|
||||
<height>91</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>I am a button</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -1,20 +0,0 @@
|
|||
#include"manualinclude.h"
|
||||
#include<QCoreApplication>
|
||||
|
||||
#include<QObject>
|
||||
|
||||
ManualInclude::ManualInclude() {
|
||||
}
|
||||
|
||||
class MocClass : public QObject {
|
||||
Q_OBJECT
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
ManualInclude mi;
|
||||
MocClass mc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include"manualinclude.moc"
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef MANUALINCLUDE_H_
|
||||
#define MANUALINCLUDE_H_
|
||||
|
||||
#include<QObject>
|
||||
|
||||
class ManualInclude : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ManualInclude();
|
||||
|
||||
signals:
|
||||
int mysignal();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,41 +0,0 @@
|
|||
project('qt5 build test', 'cpp')
|
||||
|
||||
qt5 = import('qt5')
|
||||
qt5dep = dependency('qt5', modules : ['Core', 'Gui', 'Widgets'])
|
||||
|
||||
# The following has two resource files because having two in one target
|
||||
# requires you to do it properly or you get linker symbol clashes.
|
||||
|
||||
prep = qt5.preprocess(
|
||||
moc_headers : ['mainWindow.h'], # These need to be fed through the moc tool before use.
|
||||
ui_files : 'mainWindow.ui', # XML files that need to be compiled with the uic tol.
|
||||
qresources : ['stuff.qrc', 'stuff2.qrc'], # Resource file for rcc compiler.
|
||||
)
|
||||
|
||||
q5exe = executable('qt5app',
|
||||
sources : ['main.cpp', 'mainWindow.cpp', # Sources that don't need preprocessing.
|
||||
prep],
|
||||
dependencies : qt5dep)
|
||||
|
||||
# We need a console test application because some test environments
|
||||
# do not have an X server.
|
||||
|
||||
qt5core = dependency('qt5', modules : 'Core')
|
||||
|
||||
qt5coreapp = executable('q5core', 'q5core.cpp',
|
||||
dependencies : qt5core)
|
||||
|
||||
test('qt5test', qt5coreapp)
|
||||
|
||||
# The build system needs to include the cpp files from
|
||||
# headers but the user must manually include moc
|
||||
# files from sources.
|
||||
manpreprocessed = qt5.preprocess(
|
||||
moc_sources : 'manualinclude.cpp',
|
||||
moc_headers : 'manualinclude.h')
|
||||
|
||||
q5maninclude = executable('q5maninclude',
|
||||
sources : ['manualinclude.cpp', manpreprocessed],
|
||||
dependencies : qt5core)
|
||||
|
||||
test('q5maninclude', q5maninclude)
|
Binary file not shown.
Before Width: | Height: | Size: 39 KiB |
Binary file not shown.
Before Width: | Height: | Size: 39 KiB |
Loading…
Reference in New Issue