blob: 759e6cc176b5f9f3ee5ce4b3a99a5f6fc16b7928 [file] [log] [blame]
project('qt4, qt5, and qt6 build test', 'cpp',
# Qt6 requires C++ 17 support
default_options : ['cpp_std=c++17'])
# Visit the subdir before entering the loop
subdir('mocdep')
qt5_modules = ['Widgets']
qt6_modules = ['Widgets']
foreach qt : ['qt4', 'qt5', 'qt6']
qt_modules = ['Core', 'Gui']
if qt == 'qt5'
qt_modules += qt5_modules
elif qt == 'qt6'
qt_modules += qt6_modules
endif
# Test that invalid modules are indeed not found
fakeqtdep = dependency(qt, modules : ['DefinitelyNotFound'], required : false, method : get_option('method'))
if fakeqtdep.found()
error('Invalid qt dep incorrectly found!')
endif
# Test that partially-invalid modules are indeed not found
fakeqtdep = dependency(qt, modules : ['Core', 'DefinitelyNotFound'], required : false, method : get_option('method'))
if fakeqtdep.found()
error('Invalid qt dep incorrectly found!')
endif
# This test should be skipped if the required version of Qt isn't found
#
# (In the CI environment, the specified version of Qt is definitely present.
# An unexpected skip here is treated as a failure, so we are testing that the
# detection mechanism is able to find Qt.)
needed_qt = get_option('required').to_lower()
required = (qt == needed_qt)
if required
dep = dependency(qt, modules : ['Core'], required : false, method : get_option('method'))
if not dep.found()
error('MESON_SKIP_TEST @0@ not found.'.format(needed_qt))
endif
endif
# Ensure that the "no-Core-module-specified" code branch is hit
nocoredep = dependency(qt, modules : ['Gui'], required : required, method : get_option('method'))
# If 'qt' modules are found, test that.
qtdep = dependency(qt, modules : qt_modules, main : true, private_headers: true, required : required, method : get_option('method'))
if qtdep.found()
qtmodule = import(qt)
assert(qtmodule.has_tools())
# Test that fetching a variable works and yields a non-empty value
assert(qtdep.get_variable('prefix', configtool: 'QT_INSTALL_PREFIX') != '')
# 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.
method : get_option('method')
)
# XML files that need to be compiled with the uic tol.
prep += qtmodule.compile_ui(
sources : 'ui/mainWindow.ui',
method: get_option('method'),
preserve_paths: true)
qtmodule.preprocess(
ui_files : 'ui/mainWindow.ui',
method: get_option('method'),
preserve_paths: true)
# Resource file(s) for rcc compiler
extra_cpp_args = []
if meson.is_unity()
extra_cpp_args += '-DUNITY_BUILD'
prep_rcc = qtmodule.preprocess(qt + '_unity_resource', qresources : ['stuff.qrc', 'stuff2.qrc'], method : get_option('method'))
else
prep_rcc = qtmodule.preprocess(qresources : ['stuff.qrc', 'stuff2.qrc'], method : get_option('method'))
endif
# Test that setting a unique name with a positional argument works
qtmodule.compile_resources(
name : qt + 'teststuff',
sources : files(['stuff.qrc', 'stuff2.qrc']),
method : get_option('method')
)
# Test that passing extra arguments to rcc works
# qt4-rcc and qt5-rcc take different arguments, for example qt4: ['-compress', '3']; qt5: '--compress=3'
qtmodule.preprocess(qt + 'testrccarg', qresources : files(['stuff.qrc', 'stuff2.qrc']), rcc_extra_arguments : '--compress=3', method : get_option('method'))
translations_cpp = qtmodule.compile_translations(qresource: qt+'_lang.qrc')
# unity builds suck and definitely cannot handle two qrc embeds in one compilation unit
unityproof_translations = static_library(qt+'unityproof_translations', translations_cpp, dependencies: qtdep)
extra_cpp_args += '-DQT="@0@"'.format(qt)
qexe = executable(qt + 'app',
sources : ['main.cpp', 'mainWindow.cpp', # Sources that don't need preprocessing.
prep, prep_rcc],
dependencies : qtdep,
link_with: unityproof_translations,
cpp_args: extra_cpp_args,
gui_app : true)
# We need a console test application because some test environments
# do not have an X server.
translations = qtmodule.compile_translations(ts_files : qt+'core_fr.ts', build_by_default : true)
qtcore = dependency(qt, modules : 'Core', method : get_option('method'))
qtcoreapp = executable(qt + 'core', 'q5core.cpp',
cpp_args: '-DQT="@0@"'.format(qt),
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.
qtmodule.preprocess(
moc_extra_arguments : ['-DMOC_EXTRA_FLAG'], # This is just a random macro to test `extra_arguments`
moc_sources : 'manualinclude.cpp',
moc_headers : 'manualinclude.h',
method : get_option('method'),
dependencies: mocdep,
)
manpreprocessed = qtmodule.compile_moc(
extra_args : ['-DMOC_EXTRA_FLAG'], # This is just a random macro to test `extra_arguments`
sources : 'manualinclude.cpp',
headers : 'manualinclude.h',
method : get_option('method'),
dependencies: mocdep,
)
qtmaninclude = executable(qt + 'maninclude',
sources : ['manualinclude.cpp', manpreprocessed],
dependencies : [qtcore, mocdep])
test(qt + 'maninclude', qtmaninclude)
# building Qt plugins implies to give include path to moc
plugin_includes = include_directories('pluginInterface', 'plugin')
pluginpreprocess = qtmodule.preprocess(
moc_headers : 'plugin/plugin.h',
include_directories : plugin_includes
)
plugin = library(qt + 'plugin', 'plugin/plugin.cpp', pluginpreprocess,
include_directories : plugin_includes,
dependencies : qtcore)
# implementing Qt interfaces requires passing Qt include paths to moc
qtinterfacepreprocess = qtmodule.preprocess(
moc_sources : 'qtinterface.cpp',
dependencies : qtdep
)
qtinterface = library(qt + 'qtinterface',
sources : ['qtinterface.cpp', qtinterfacepreprocess],
dependencies : qtdep)
if qt == 'qt5'
subdir('subfolder')
endif
# Check we can apply a version constraint
accept_versions = ['>=@0@'.format(qtdep.version()), '<@0@'.format(qtdep.version()[0].to_int() + 1)]
dependency(qt, modules: qt_modules, version: accept_versions, method : get_option('method'))
endif
endforeach