Now can compile all Qt5 tests with module.

pull/54/merge
Jussi Pakkanen 10 years ago
parent 6e6ac02eaf
commit 48477102c9
  1. 13
      build.py
  2. 2
      compilers.py
  3. 87
      dependencies.py
  4. 4
      modules/gnome.py
  5. 3
      modules/modtest.py
  6. 58
      modules/qt5.py
  7. 33
      ninjabackend.py
  8. 10
      test cases/frameworks/4 qt5/manualinclude.cpp
  9. 6
      test cases/frameworks/4 qt5/meson.build
  10. 12
      test cases/frameworks/4 qt5/mocinclude.cpp

@ -492,13 +492,12 @@ class Generator():
def __init__(self, args, kwargs):
if len(args) != 1:
raise InvalidArguments('Generator requires one and only one positional argument')
if hasattr(args[0], 'held_object'):
exe = args[0].held_object
if not isinstance(exe, Executable) and not isinstance(exe, dependencies.ExternalProgram):
raise InvalidArguments('First generator argument must be an executable.')
else:
raise InvalidArguments('First generator argument must be an executable object.')
exe = args[0]
if hasattr(exe, 'held_object'):
exe = exe.held_object
if not isinstance(exe, Executable) and not isinstance(exe, dependencies.ExternalProgram):
raise InvalidArguments('First generator argument must be an executable.')
self.exe = exe
self.process_kwargs(kwargs)

@ -21,7 +21,7 @@ from coredata import MesonException
about. To support a new compiler, add its information below.
Also add corresponding autodetection code in environment.py."""
header_suffixes = ['h', 'hh', 'hpp', 'hxx', 'H']
header_suffixes = ['h', 'hh', 'hpp', 'hxx', 'H', 'moc']
cpp_suffixes = ['cc', 'cpp', 'cxx', 'h', 'hh', 'hpp', 'hxx', 'c++']
c_suffixes = ['c']
clike_suffixes = c_suffixes + cpp_suffixes

@ -533,8 +533,6 @@ class GMockDependency(Dependency):
def found(self):
return self.is_found
qt5toolinfo_printed = False
class Qt5Dependency(Dependency):
def __init__(self, kwargs):
Dependency.__init__(self)
@ -548,85 +546,6 @@ class Qt5Dependency(Dependency):
self.modules.append(PkgConfigDependency('Qt5' + module, kwargs))
if len(self.modules) == 0:
raise DependencyException('No Qt5 modules specified.')
if not qt5toolinfo_printed:
mlog.log('Dependency Qt5 tools:')
self.find_exes()
def find_exes(self):
# The binaries have different names on different
# distros. Joy.
global qt5toolinfo_printed
self.moc = ExternalProgram('moc', silent=True)
if not self.moc.found():
self.moc = ExternalProgram('moc-qt5', silent=True)
self.uic = ExternalProgram('uic', silent=True)
if not self.uic.found():
self.uic = ExternalProgram('uic-qt5', silent=True)
self.rcc = ExternalProgram('rcc', silent=True)
if not self.rcc.found():
self.rcc = ExternalProgram('rcc-qt5', silent=True)
# 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?
if self.moc.found():
mp = subprocess.Popen(self.moc.get_command() + ['-v'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = mp.communicate()
stdout = stdout.decode().strip()
stderr = stderr.decode().strip()
if 'Qt 5' in stderr:
moc_ver = stderr
elif '5.' in stdout:
moc_ver = stdout
else:
raise DependencyException('Moc preprocessor is not for Qt 5. Output:\n%s\n%s' %
(stdout, stderr))
if not qt5toolinfo_printed:
mlog.log(' moc:', mlog.green('YES'), '(%s, %s)' % \
(' '.join(self.moc.fullpath), moc_ver.split()[-1]))
else:
if not qt5toolinfo_printed:
mlog.log(' moc:', mlog.red('NO'))
if self.uic.found():
up = subprocess.Popen(self.uic.get_command() + ['-v'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = up.communicate()
stdout = stdout.decode().strip()
stderr = stderr.decode().strip()
if 'version 5.' in stderr:
uic_ver = stderr
elif '5.' in stdout:
uic_ver = stdout
else:
raise DependencyException('Uic compiler is not for Qt 5. Output:\n%s\n%s' %
(stdout, stderr))
if not qt5toolinfo_printed:
mlog.log(' uic:', mlog.green('YES'), '(%s, %s)' % \
(' '.join(self.uic.fullpath), uic_ver.split()[-1]))
else:
if not qt5toolinfo_printed:
mlog.log(' uic:', mlog.red('NO'))
if self.rcc.found():
rp = subprocess.Popen(self.rcc.get_command() + ['-v'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = rp.communicate()
stdout = stdout.decode().strip()
stderr = stderr.decode().strip()
if 'version 5.' in stderr:
rcc_ver = stderr
elif '5.' in stdout:
rcc_ver = stdout
else:
raise DependencyException('Rcc compiler is not for Qt 5. Output:\n%s\n%s' %
(stdout, stderr))
if not qt5toolinfo_printed:
mlog.log(' rcc:', mlog.green('YES'), '(%s, %s)'\
% (' '.join(self.rcc.fullpath), rcc_ver.split()[-1]))
else:
if not qt5toolinfo_printed:
mlog.log(' rcc:', mlog.red('NO'))
qt5toolinfo_printed = True
def get_version(self):
return self.modules[0].get_version()
@ -647,12 +566,6 @@ class Qt5Dependency(Dependency):
return args
def found(self):
if not self.moc.found():
return False
if not self.uic.found():
return False
if not self.rcc.found():
return False
for i in self.modules:
if not i.found():
return False

@ -21,9 +21,7 @@ import subprocess
from coredata import MesonException
class GnomeModule:
def get_rules(self, ):
return []
def compile_resources(self, state, args, kwargs):
cmd = ['glib-compile-resources', '@INPUT@', '--generate']
if 'source_dir' in kwargs:

@ -14,9 +14,6 @@
class TestModule:
def get_rules(self):
return []
def print_hello(self, state, args, kwargs):
print('Hello from a Meson module')

@ -12,14 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import dependencies, mlog, subprocess
import dependencies, mlog
import os, subprocess
import build
from coredata import MesonException
class Qt5Module():
def __init__(self):
mlog.log('Detecting Qt tools.')
# The binaries have different names on different
# distros. Joy.
@ -87,33 +87,53 @@ class Qt5Module():
else:
mlog.log(' rcc:', mlog.red('NO'))
def get_rules(self):
global moc, uic, rcc
moc_rule = dependencies.CustomRule(self.moc.get_command() + ['$mocargs', '@INFILE@', '-o', '@OUTFILE@'],
'moc_@BASENAME@.cpp', 'moc_headers', 'moc_hdr_compile',
'Compiling header @INFILE@ with the moc preprocessor')
mocsrc_rule = dependencies.CustomRule(self.moc.get_command() + ['$mocargs', '@INFILE@', '-o', '@OUTFILE@'],
'@BASENAME@.moc', 'moc_sources', 'moc_src_compile',
'Compiling source @INFILE@ with the moc preprocessor')
ui_rule = dependencies.CustomRule(self.uic.get_command() + ['@INFILE@', '-o', '@OUTFILE@'],
'ui_@BASENAME@.h', 'ui_files', 'ui_compile',
'Compiling @INFILE@ with the ui compiler')
rrc_rule = dependencies.CustomRule(self.rcc.get_command() + ['@INFILE@', '-o', '@OUTFILE@',
'${rcc_args}'], '@BASENAME@.cpp','qresources',
'rc_compile', 'Compiling @INFILE@ with the rrc compiler')
return [moc_rule, mocsrc_rule, ui_rule, rrc_rule]
def executable(self, state, args, kwargs):
rcc_files = kwargs.pop('qresources', [])
uic_files = kwargs.pop('ui_files', [])
if not isinstance(rcc_files, list):
rcc_files = [rcc_files]
ui_files = kwargs.pop('ui_files', [])
if not isinstance(ui_files, list):
ui_files = [ui_files]
moc_headers = kwargs.pop('moc_headers', [])
if not isinstance(moc_headers, list):
moc_headers = [moc_headers]
moc_sources = kwargs.pop('moc_sources', [])
if not isinstance(moc_sources, list):
moc_sources = [moc_sources]
name = args[0]
srctmp = kwargs.pop('sources', [])
if not isinstance(srctmp, list):
srctmp = [srctmp]
sources = args[1:] + srctmp
objects = []
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)
[rcc_output.add_file(os.path.join(state.subdir, a)) for a in rcc_files]
sources.append(rcc_output)
if len(ui_files) > 0:
ui_kwargs = {'output' : 'ui_@BASENAME@.h',
'arguments' : ['-o', '@OUTPUT@', '@INPUT@']}
ui_gen = build.Generator([self.uic], ui_kwargs)
ui_output = build.GeneratedList(ui_gen)
[ui_output.add_file(os.path.join(state.subdir, a)) for a in ui_files]
sources.append(ui_output)
if len(moc_headers) > 0:
moc_kwargs = {'output' : 'moc_@BASENAME@.cpp',
'arguments' : ['@INPUT@', '-o', '@OUTPUT@']}
moc_gen = build.Generator([self.moc], moc_kwargs)
moc_output = build.GeneratedList(moc_gen)
[moc_output.add_file(os.path.join(state.subdir, a)) for a in moc_headers]
sources.append(moc_output)
if len(moc_sources) > 0:
moc_kwargs = {'output' : '@BASENAME@.moc',
'arguments' : ['@INPUT@', '-o', '@OUTPUT@']}
moc_gen = build.Generator([self.moc], moc_kwargs)
moc_output = build.GeneratedList(moc_gen)
[moc_output.add_file(os.path.join(state.subdir, a)) for a in moc_sources]
sources.append(moc_output)
return build.Executable(name, state.subdir, state.environment.is_cross_build(), sources, objects,
state.environment, kwargs)

@ -499,23 +499,6 @@ class NinjaBackend(backends.Backend):
velem.add_item('pool', 'console')
velem.write(outfile)
def generate_module_rules(self, outfile):
outfile.write('# Rules coming from modules.\n\n')
for mod in self.build.modules.values():
for rule in mod.get_rules():
outfile.write('rule %s\n' % rule.name)
command = ' '.join([ninja_quote(x) for x in rule.cmd_list])
command = command.replace('@INFILE@', '$in').replace('@OUTFILE@', '$out')
command = command.replace('@SOURCE_ROOT@', self.environment.get_source_dir())
command = command.replace('@BUILD_ROOT@', self.environment.get_build_dir())
outfile.write(' command = %s\n' % command)
desc = rule.description.replace('@INFILE@', '$in')
outfile.write(' description = %s\n' % desc)
if rule.src_keyword in self.dep_rules:
raise InvalidArguments('Multiple rules for keyword %s.' % rule.src_keyword)
self.dep_rules[rule.src_keyword] = rule
outfile.write('\n')
def generate_rules(self, outfile):
outfile.write('# Rules for compiling.\n\n')
self.generate_compile_rules(outfile)
@ -524,7 +507,6 @@ class NinjaBackend(backends.Backend):
self.generate_static_link_rules(True, outfile)
self.generate_static_link_rules(False, outfile)
self.generate_dynamic_link_rules(outfile)
self.generate_module_rules(outfile)
outfile.write('# Other rules\n\n')
outfile.write('rule CUSTOM_COMMAND\n')
outfile.write(' command = $COMMAND\n')
@ -1373,24 +1355,11 @@ rule FORTRAN_DEP_HACK
outfilename = os.path.join(self.get_target_private_dir(target), outname)
infilename = os.path.join(self.build_to_src, target.get_source_subdir(), src)
elem = NinjaBuildElement(outfilename, rule.name, infilename)
if rule.name == 'rc_compile':
elem.add_item('rcc_args', ['--name', basename])
if rule.name == 'moc_hdr_compile' or rule.name == 'moc_src_compile':
elem.add_item('mocargs', ['-I', target.subdir])
elem.write(outfile)
if self.is_compilable_file(outfilename):
if rule.name == 'moc_hdr_compile' or rule.name == 'moc_src_compile':
manual_mocs = target.get_original_kwargs().get('manual_moc_include', [])
if src in manual_mocs:
other_deps.append(outfilename)
else:
src_deps.append(outfilename)
else:
src_deps.append(outfilename)
src_deps.append(outfilename)
else:
other_deps.append(outfilename)
if rule.name == 'moc_src_compile': #HACK
src_deps.append(infilename)
return (src_deps, other_deps)
def generate_ending(self, outfile):

@ -1,10 +1,20 @@
#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"

@ -3,6 +3,10 @@ project('qt5 build test', 'cpp')
qt5 = import('qt5')
qt5dep = dependency('qt5', modules : 'Widgets')
if meson.get_compiler('cpp').get_id() != 'msvc'
add_global_arguments('-std=c++11', language : 'cpp')
endif
q5exe = qt5.executable('qt5app',
sources : ['main.cpp', 'mainWindow.cpp'], # Sources that don't need preprocessing.
moc_headers : ['mainWindow.h'], # These need to be fed through the moc tool before use.
@ -25,7 +29,7 @@ test('qt5test', qt5coreapp)
# files from sources.
q5maninclude = qt5.executable('q5maninclude',
sources : 'manualinclude.cpp',
moc_sources : 'mocinclude.cpp',
moc_sources : 'manualinclude.cpp',
moc_headers : 'manualinclude.h',
dependencies : qt5core)

@ -1,12 +0,0 @@
#include<QObject>
class MocClass : public QObject {
Q_OBJECT
};
int mocfunc() {
MocClass m;
return 0;
}
#include"mocinclude.moc"
Loading…
Cancel
Save