midori/wscript
2013-10-23 20:45:02 -07:00

752 lines
32 KiB
Python

#! /usr/bin/env python
# WAF build script for midori
# This file is licensed under the terms of the expat license, see the file EXPAT.
import sys
# Waf version check, for global waf installs
try:
from Constants import WAFVERSION
except:
WAFVERSION='1.0.0'
if WAFVERSION[:3] != '1.5':
print ('Incompatible Waf, use 1.5')
sys.exit (1)
import Build
import Options
import Utils
import pproc as subprocess
import os
try:
import UnitTest
except:
import unittestw as UnitTest
import Task
from TaskGen import extension, feature, taskgen
import misc
from Configure import find_program_impl
APPNAME = 'midori'
VERSION = VERSION_FULL = '0.5.2'
VERSION_SUFFIX = ' (%s)' % VERSION
try:
if os.path.isdir ('.git'):
git = Utils.cmd_output (['git', 'describe'], silent=True)
if git:
VERSION_FULL = git.strip ()
elif os.path.isdir ('.bzr'):
bzr = Utils.cmd_output (['bzr', 'revno'], silent=True)
if bzr:
VERSION_FULL = '%s~r%s' % (VERSION, bzr.strip ())
else:
folder = os.getcwd ()
if VERSION in folder:
VERSION_FULL = os.path.basename (folder)
if VERSION in VERSION_FULL:
VERSION_SUFFIX = VERSION_FULL.replace (VERSION, '')
except:
pass
srcdir = '.'
blddir = '_build' # recognized by ack
def option_enabled (option):
if getattr (Options.options, 'enable_' + option):
return True
if getattr (Options.options, 'disable_' + option):
return False
return True
def is_mingw (env):
if 'CC' in env:
cc = env['CC']
if not isinstance (cc, str):
cc = ''.join (cc)
return cc.find ('mingw') != -1# or cc.find ('wine') != -1
return False
def is_win32 (env):
return is_mingw (env) or Options.platform == 'win32'
# Compile Win32 res files to (resource) object files
def rc_file(self, node):
rctask = self.create_task ('winrc')
rctask.set_inputs (node)
rctask.set_outputs (node.change_ext ('.rc.o'))
self.compiled_tasks.append (rctask)
rc_file = extension ('.rc')(rc_file)
Task.simple_task_type ('winrc', '${WINRC} -o${TGT} ${SRC}', color='BLUE',
before='cc cxx', shell=False)
def configure (conf):
def option_checkfatal (option, desc):
if hasattr (Options.options, 'enable_' + option):
if getattr (Options.options, 'enable_' + option):
Utils.pprint ('RED', desc + ' N/A')
sys.exit (1)
def dirname_default (dirname, default, defname=None):
if getattr (Options.options, dirname) == '':
dirvalue = default
else:
dirvalue = getattr (Options.options, dirname)
if not defname:
defname = dirname
conf.define (defname, dirvalue)
return dirvalue
def check_version (given_version, major, minor, micro):
if '.' in given_version:
given_major, given_minor, given_micro = given_version.split ('.', 2)
if '.' in given_micro:
given_micro, given_pico = given_micro.split ('.', 1)
else:
given_major, given_minor, given_micro = given_version
return int(given_major) > major or \
int(given_major) == major and int(given_minor) > minor or \
int(given_major) == major and int(given_minor) == minor and int(given_micro) >= micro
conf.check_message_custom ('release version', '', VERSION_FULL)
conf.check_tool ('compiler_cc')
conf.check_tool ('vala')
conf.check_tool ('glib2')
if not check_version (conf.env['VALAC_VERSION'], 0, 14, 0):
Utils.pprint ('RED', 'Vala 0.14.0 or later is required.')
sys.exit (1)
if option_enabled ('nls'):
conf.check_tool ('intltool')
if not conf.env['INTLTOOL'] and conf.env['POCOM']:
option_checkfatal ('nls', 'localization')
conf.define ('ENABLE_NLS', 0)
else:
conf.define ('ENABLE_NLS', 1)
else:
conf.define ('ENABLE_NLS', 0)
conf.check_message_custom ('nls', '', 'disabled')
conf.find_program ('rsvg-convert', var='RSVG_CONVERT')
if is_win32 (conf.env):
conf.find_program ('windres', var='WINRC')
conf.env['platform'] = 'win32'
# This is specific to cross compiling with mingw
if is_mingw (conf.env) and Options.platform != 'win32':
if not 'AR' in os.environ and not 'RANLIB' in os.environ:
conf.env['AR'] = os.environ['CC'][:-3] + 'ar'
if conf.find_program (os.environ['CC'][:-3] + 'windres', var='WINRC'):
os.environ['WINRC'] = os.environ['CC'][:-3] + 'windres'
Options.platform = 'win32'
# Make sure we don't have -fPIC in the CCFLAGS
conf.env["shlib_CCFLAGS"] = []
# Adjust file naming
conf.env["shlib_PATTERN"] = 'lib%s.dll'
conf.env['program_PATTERN'] = '%s.exe'
# Use Visual C++ compatible alignment
conf.env.append_value ('CCFLAGS', '-mms-bitfields')
conf.env['staticlib_LINKFLAGS'] = []
Utils.pprint ('BLUE', 'Mingw recognized, assuming cross compile.')
dirname_default ('LIBDIR', os.path.join (conf.env['PREFIX'], 'lib'))
if conf.env['PREFIX'] == '/usr':
dirname_default ('SYSCONFDIR', '/etc')
else:
dirname_default ('SYSCONFDIR', os.path.join (conf.env['PREFIX'], 'etc'))
dirname_default ('DATADIR', os.path.join (conf.env['PREFIX'], 'share'),
# Use MDATADIR because DATADIR is a constant in objidl.h on Windows
'MDATADIR')
conf.undefine ('DATADIR')
dirname_default ('DOCDIR', os.path.join (conf.env['MDATADIR'], 'doc'))
if not APPNAME in conf.env['DOCDIR']:
conf.env['DOCDIR'] += '/' + APPNAME
conf.define ('DOCDIR', conf.env['DOCDIR'])
if option_enabled ('apidocs'):
conf.find_program ('gtkdoc-scan', var='GTKDOC_SCAN')
conf.find_program ('gtkdoc-mktmpl', var='GTKDOC_MKTMPL')
conf.find_program ('gtkdoc-mkdb', var='GTKDOC_MKDB')
conf.find_program ('gtkdoc-mkhtml', var='GTKDOC_MKHTML')
if conf.env['GTKDOC_SCAN'] and conf.env['GTKDOC_MKTMPL'] \
and conf.env['GTKDOC_MKDB'] and conf.env['GTKDOC_MKHTML']:
pass
else:
option_checkfatal ('apidocs', 'API documentation')
else:
conf.check_message_custom ('gtk-doc', '', 'disabled')
def check_pkg (name, version='', mandatory=True, var=None, args=''):
if not var:
var = name.split ('-')[0].upper ()
ver_str = ['',' >= ' + version][version != '']
def okmsg_ver (kw):
return conf.check_cfg (modversion=name, uselibstore=var)
conf.check_cfg (msg='Checking for ' + name + ver_str, okmsg=okmsg_ver,
package=name, uselib_store=var, args='--cflags --libs ' + args,
atleast_version=version, mandatory=mandatory)
have = conf.env['HAVE_' + var] == 1
conf.define (var + '_VERSION', ['No', conf.check_cfg (modversion=name,
uselib_store=var, errmsg=name + ver_str + ' not found')][have])
return have
if option_enabled ('libnotify'):
if not check_pkg ('libnotify', mandatory=False):
option_checkfatal ('libnotify', 'notifications')
else:
conf.define ('LIBNOTIFY_VERSION', 'No')
conf.check_message_custom ('libnotify', '', 'disabled')
conf.define ('HAVE_LIBNOTIFY', [0,1][conf.env['LIBNOTIFY_VERSION'] != 'No'])
if option_enabled ('granite'):
check_pkg ('granite', '0.2', mandatory=False)
granite = ['N/A', 'yes'][conf.env['HAVE_GRANITE'] == 1]
if granite != 'yes':
option_checkfatal ('granite', 'new notebook, pop-overs')
conf.define ('GRANITE_VERSION', 'No')
else:
conf.env.append_value ('VALAFLAGS', '-D HAVE_GRANITE')
else:
conf.define ('GRANITE_VERSION', 'No')
conf.check_message_custom ('granite', '', 'disabled')
if option_enabled ('zeitgeist'):
check_pkg ('zeitgeist-1.0', '0.3.14')
else:
conf.check_message_custom ('zeitgeist', '', 'disabled')
conf.check (lib='m')
check_pkg ('gmodule-2.0')
check_pkg ('gio-2.0', '2.22.0')
if check_version (conf.env['GIO_VERSION'], 2, 30, 0) \
and check_version (conf.env['VALAC_VERSION'], 0, 16, 0):
# Older Vala doesn't have GLib 2.30 bindings
conf.env.append_value ('VALAFLAGS', '-D HAVE_GLIB_2_30')
args = ''
if Options.platform == 'win32':
args = '--define-variable=target=win32'
conf.env.append_value ('VALAFLAGS', '-D HAVE_WIN32')
elif sys.platform != 'darwin':
if sys.platform.startswith ('freebsd'):
conf.env.append_value ('VALAFLAGS', '-D HAVE_FREEBSD')
check_pkg ('x11')
# Pass /usr/X11R6/include for OpenBSD
conf.check (header_name='X11/extensions/scrnsaver.h',
includes='/usr/X11R6/include', mandatory=False)
conf.check (lib='Xss', libpath='/usr/X11R6/lib', mandatory=False)
have_gtk3 = option_enabled ('gtk3') or option_enabled ('webkit2') or option_enabled ('granite')
if have_gtk3:
check_pkg ('gtk+-3.0', '3.0.0', var='GTK', mandatory=False)
check_pkg ('gcr-3', '2.32', mandatory=False)
if option_enabled ('webkit2'):
# 2.0.0 matches 1.11.91 API; 1.11.92 > 2.0.0
check_pkg ('webkit2gtk-3.0', '1.11.91', var='WEBKIT', mandatory=False)
if not conf.env['HAVE_WEBKIT']:
Utils.pprint ('RED', 'WebKit2/ GTK+3 was not found.\n' \
'Pass --disable-webkit2 to build without WebKit2.')
sys.exit (1)
conf.define ('HAVE_WEBKIT2', 1)
conf.env.append_value ('VALAFLAGS', '-D HAVE_WEBKIT2')
else:
check_pkg ('webkitgtk-3.0', '1.1.17', var='WEBKIT', mandatory=False)
if not conf.env['HAVE_GTK'] or not conf.env['HAVE_WEBKIT']:
Utils.pprint ('RED', 'GTK+3 was not found.\n' \
'Pass --disable-gtk3 to build without GTK+3.')
sys.exit (1)
if check_version (conf.env['WEBKIT_VERSION'], 1, 5, 1):
check_pkg ('javascriptcoregtk-3.0', '1.5.1', args=args)
conf.env.append_value ('VALAFLAGS', '-D HAVE_GTK3')
conf.env.append_value ('VALAFLAGS', '-D HAVE_OFFSCREEN')
conf.env.append_value ('VALAFLAGS', '-D HAVE_DOM')
else:
check_pkg ('gtk+-2.0', '2.16.0', var='GTK')
check_pkg ('webkit-1.0', '1.1.17', args=args)
check_pkg ('gcr-3-gtk2', '2.32', mandatory=False)
if check_version (conf.env['WEBKIT_VERSION'], 1, 5, 1):
check_pkg ('javascriptcoregtk-1.0', '1.5.1', args=args)
if check_version (conf.env['GTK_VERSION'], 2, 20, 0):
conf.env.append_value ('VALAFLAGS', '-D HAVE_OFFSCREEN')
conf.env['HAVE_GTK3'] = have_gtk3
conf.env['HAVE_WEBKIT2'] = option_enabled ('webkit2')
if option_enabled ('unique'):
if have_gtk3: unique_pkg = 'unique-3.0'
else: unique_pkg = 'unique-1.0'
if not check_pkg (unique_pkg, '0.9', mandatory=False):
option_checkfatal ('unique', 'single instance')
else:
conf.define ('UNIQUE_VERSION', 'No')
conf.check_message_custom ('unique', '', 'disabled')
conf.define ('HAVE_UNIQUE', [0,1][conf.env['UNIQUE_VERSION'] != 'No'])
check_pkg ('libsoup-2.4', '2.27.90', var='LIBSOUP')
if check_version (conf.env['LIBSOUP_VERSION'], 2, 29, 91):
conf.define ('HAVE_LIBSOUP_2_29_91', 1)
if check_version (conf.env['LIBSOUP_VERSION'], 2, 34, 0):
conf.define ('HAVE_LIBSOUP_2_34_0', 1)
conf.env.append_value ('VALAFLAGS', '-D HAVE_LIBSOUP_2_34_0')
if check_version (conf.env['LIBSOUP_VERSION'], 2, 37, 1):
conf.define ('HAVE_LIBSOUP_2_37_1', 1)
if check_version (conf.env['WEBKIT_VERSION'], 1, 3, 8):
conf.env.append_value ('VALAFLAGS', '-D HAVE_WEBKIT_1_3_8')
if check_version (conf.env['WEBKIT_VERSION'], 1, 3, 13):
conf.env.append_value ('VALAFLAGS', '-D HAVE_WEBKIT_1_3_13')
if check_version (conf.env['WEBKIT_VERSION'], 1, 8, 0):
conf.env.append_value ('VALAFLAGS', '-D HAVE_WEBKIT_1_8_0')
check_pkg ('libxml-2.0', '2.6')
conf.undefine ('LIBXML_VERSION') # Defined in xmlversion.h
check_pkg ('sqlite3', '3.6.19', var='SQLITE')
# Store options in env, since 'Options' is not persistent
if 'CC' in os.environ: conf.env['CC'] = os.environ['CC'].split()
conf.env['addons'] = option_enabled ('addons')
conf.env['tests'] = option_enabled ('tests')
conf.env['docs'] = option_enabled ('docs')
if 'LINGUAS' in os.environ: conf.env['LINGUAS'] = os.environ['LINGUAS']
if not check_version (conf.env['GIO_VERSION'], 2, 26, 0):
conf.env['addons'] = False
Utils.pprint ('YELLOW', 'Glib < 2.26.0, disabling addons')
conf.check (header_name='unistd.h')
if not conf.env['HAVE_UNIQUE']:
if Options.platform == 'win32':
conf.check (lib='ws2_32')
conf.define ('HAVE_NETDB_H', [0,1][conf.check (header_name='netdb.h')])
conf.check (header_name='sys/wait.h')
conf.check (header_name='sys/select.h')
conf.check (function_name='inet_aton', header_name='sys/types.h sys/socket.h netinet/in.h arpa/inet.h')
conf.check (function_name='inet_addr', header_name='sys/types.h sys/socket.h netinet/in.h arpa/inet.h')
conf.define ('HAVE_OSX', int(sys.platform == 'darwin'))
if Options.platform == 'win32':
conf.env.append_value ('LINKFLAGS', '-mwindows')
conf.env.append_value ('program_LINKFLAGS', ['-Wl,--out-implib=default/midori/libmidori.a', '-Wl,--export-all-symbols'])
else:
conf.check (header_name='signal.h')
conf.define ('PACKAGE_NAME', APPNAME)
conf.define ('PACKAGE_BUGREPORT', 'https://bugs.launchpad.net/midori')
conf.define ('GETTEXT_PACKAGE', APPNAME)
conf.define ('MIDORI_VERSION', VERSION)
major, minor, micro = VERSION.split ('.', 2)
conf.define ('MIDORI_MAJOR_VERSION', int (major))
conf.define ('MIDORI_MINOR_VERSION', int (minor))
conf.define ('MIDORI_MICRO_VERSION', int (micro))
conf.env.append_value ('CCFLAGS', '-DHAVE_CONFIG_H -include config.h'.split ())
debug_level = Options.options.debug_level
compiler = conf.env['CC_NAME']
if debug_level == 'full':
conf.define ('PACKAGE_VERSION', '%s (debug)' % VERSION_FULL)
conf.env.append_value ('CCFLAGS', '-DMIDORI_VERSION_SUFFIX="%s (debug)"' % VERSION_SUFFIX)
else:
conf.define ('PACKAGE_VERSION', VERSION_FULL)
conf.env.append_value ('CCFLAGS', '-DMIDORI_VERSION_SUFFIX="%s"' % VERSION_SUFFIX)
conf.write_config_header ('config.h')
if debug_level == 'debug':
conf.env.append_value ('VALAFLAGS', '--debug --enable-deprecated'.split ())
if compiler == 'gcc':
conf.env.append_value ('CCFLAGS', '-O2 -g -Wall -Wno-deprecated-declarations'.split ())
elif debug_level == 'full':
conf.env.append_value ('VALAFLAGS', '--debug --enable-checking'.split ())
if compiler == 'gcc':
conf.env.append_value ('CCFLAGS',
'-O2 -g -Wall -Wextra -DG_ENABLE_DEBUG '
'-Waggregate-return -Wno-unused-parameter '
'-Wno-missing-field-initializers '
'-Wredundant-decls -Wmissing-noreturn '
'-Wshadow -Wpointer-arith -Wcast-align '
'-Winline -Wformat-security -fno-common '
'-Winit-self -Wundef -Wdeclaration-after-statement '
'-Wmissing-format-attribute -Wnested-externs'.split ())
conf.env.append_value ('CCFLAGS', '-Wno-unused-variable -Wno-comment'.split ())
if conf.env['UNIQUE_VERSION'] == '1.0.4':
Utils.pprint ('RED', 'unique 1.0.4 found, this version is erroneous.')
Utils.pprint ('RED', 'Please use an older or newer version.')
sys.exit (1)
if check_version (conf.env['LIBSOUP_VERSION'], 2, 33, 4) \
and check_version (conf.env['GIO_VERSION'], 2, 32, 1) \
and not check_version (conf.env['GIO_VERSION'], 2, 32, 3):
Utils.pprint ('RED', 'libsoup >= 2.33.4 found with glib >= 2.32.1 < 2.32.3:')
Utils.pprint ('RED', 'This combination breaks the download GUI.')
Utils.pprint ('RED', 'See https://bugs.launchpad.net/midori/+bug/780133/comments/14')
sys.exit (1)
def set_options (opt):
def add_enable_option (option, desc, group=None, disable=False):
if group == None:
group = opt
option_ = option.replace ('-', '_')
group.add_option ('--enable-' + option, action='store_true', default=False,
help='Enable ' + desc + ' [Default: ' + str (not disable) + ']',
dest='enable_' + option_)
group.add_option ('--disable-' + option, action='store_true',
default=disable, help='Disable ' + desc, dest='disable_' + option_)
opt.tool_options ('compiler_cc')
opt.get_option_group ('--check-c-compiler').add_option('-d', '--debug-level',
action = 'store', default = 'debug',
help = 'Specify the debugging level. [\'none\', \'debug\', \'full\']',
choices = ['none', 'debug', 'full'], dest = 'debug_level')
opt.tool_options ('gnu_dirs')
opt.parser.remove_option ('--oldincludedir')
opt.parser.remove_option ('--htmldir')
opt.parser.remove_option ('--dvidir')
opt.parser.remove_option ('--pdfdir')
opt.parser.remove_option ('--psdir')
opt.tool_options ('intltool')
opt.add_option ('--run', action='store_true', default=False,
help='Run application after building it', dest='run')
group = opt.add_option_group ('Localization and documentation', '')
add_enable_option ('nls', 'native language support', group)
group.add_option ('--update-po', action='store_true', default=False,
help='Update localization files', dest='update_po')
add_enable_option ('docs', 'informational text files', group)
add_enable_option ('apidocs', 'API documentation', group, disable=True)
group = opt.add_option_group ('Optional features', '')
add_enable_option ('unique', 'single instance support', group, disable=is_win32 (os.environ))
add_enable_option ('libnotify', 'notification support', group)
add_enable_option ('granite', 'new notebook, pop-overs', group, disable=True)
add_enable_option ('addons', 'building of extensions', group)
add_enable_option ('tests', 'install tests', group, disable=True)
add_enable_option ('gtk3', 'GTK+3 and WebKitGTK+3 support', group, disable=True)
add_enable_option ('webkit2', 'WebKit2 support', group, disable=True)
add_enable_option ('zeitgeist', 'Zeitgeist history integration', group, disable=is_win32 (os.environ))
# Provided for compatibility
opt.add_option ('--build', help='Ignored')
opt.add_option ('--disable-maintainer-mode', help='Ignored')
# Taken from Geany's wscript, modified to support LINGUAS variable
def write_linguas_file (self):
linguas = ''
# Depending on Waf version, getcwd() is different
if os.path.exists ('./po'):
podir = './po'
else:
podir = '../po'
if 'LINGUAS' in Build.bld.env:
files = Build.bld.env['LINGUAS']
for f in files.split (' '):
if os.path.exists (podir + '/' + f + '.po'):
linguas += f + ' '
else:
files = os.listdir (podir)
for f in files:
if f.endswith ('.po'):
linguas += '%s ' % f[:-3]
f = open (podir + '/LINGUAS', 'w')
f.write ('# This file is autogenerated. Do not edit.\n%s\n' % linguas)
f.close ()
write_linguas_file = feature ('intltool_po')(write_linguas_file)
def build (bld):
bld.add_group ()
bld.add_subdirs ('midori icons')
if bld.env['addons']:
bld.add_subdirs ('extensions')
bld.add_group ()
if bld.env['docs']:
bld.install_files ('${DOCDIR}/', \
'AUTHORS COPYING ChangeLog EXPAT README data/faq.html data/faq.css')
# Install default configuration
bld.install_files ('${SYSCONFDIR}/xdg/' + APPNAME + '/', 'data/search')
if bld.env['INTLTOOL']:
obj = bld.new_task_gen ('intltool_po')
obj.podir = 'po'
obj.appname = APPNAME
if bld.env['GTKDOC_SCAN'] and Options.commands['build']:
bld.add_subdirs ('docs/api')
bld.install_files ('${DOCDIR}/api/', blddir + '/docs/api/*')
for desktop in [APPNAME + '.desktop', APPNAME + '-private.desktop']:
if is_win32 (bld.env):
break
appdir = '${MDATADIR}/applications'
if bld.env['INTLTOOL']:
obj = bld.new_task_gen ('intltool_in')
obj.source = 'data/' + desktop + '.in'
obj.install_path = appdir
obj.flags = ['-d', '-c']
bld.install_files (appdir, 'data/' + desktop)
else:
folder = os.path.abspath (blddir + '/default/data')
Utils.check_dir (folder)
pre = open ('data/' + desktop + '.in')
after = open (folder + '/' + desktop, 'w')
try:
try:
for line in pre:
if line != '':
if line[0] == '_':
after.write (line[1:])
else:
after.write (line)
after.close ()
Utils.pprint ('BLUE', desktop + '.in -> ' + desktop)
bld.install_files (appdir, folder + '/' + desktop)
except:
Utils.pprint ('BLUE', 'File ' + desktop + ' not generated')
finally:
pre.close ()
if bld.env['RSVG_CONVERT']:
Utils.check_dir (blddir + '/data')
command = bld.env['RSVG_CONVERT'] + \
' -o ' + blddir + '/data/logo-shade.png ' + \
srcdir + '/data/logo-shade.svg'
if not Utils.exec_command (command):
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', blddir + '/data/logo-shade.png')
else:
Utils.pprint ('BLUE', "logo-shade could not be rasterized.")
for res_file in ['about.css', 'error.html', 'close.png', 'gtk3.css', 'speeddial-head.html']:
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/' + res_file)
if bld.env['addons']:
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/autosuggestcontrol.js')
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/autosuggestcontrol.css')
if 1:
extensions = os.listdir ('data/extensions')
for extension in extensions:
source = 'data/extensions/' + extension + '/config'
if os.path.exists (source):
bld.install_files ('${SYSCONFDIR}/xdg/' + APPNAME + \
'/extensions/' + extension, source)
if Options.commands['check'] or bld.env['tests']:
bld.add_subdirs ('tests')
if Options.commands['clean']:
distclean ()
def check (ctx):
# The real work happens in shutdown ()
pass
def distclean ():
if os.path.exists ('po/LINGUAS'):
os.remove ('po/LINGUAS')
if os.path.exists ('po/midori.pot'):
os.remove ('po/midori.pot')
def shutdown ():
if Options.commands['install'] or Options.commands['uninstall']:
dir = Build.bld.get_install_path ('${MDATADIR}/icons/hicolor')
icon_cache_updated = False
if not Options.options.destdir:
# update the pixmap cache directory
try:
command = 'gtk-update-icon-cache -q -f -t %s' % dir
if not Utils.exec_command (command):
Utils.pprint ('YELLOW', "Updated Gtk icon cache.")
icon_cache_updated = True
except:
Utils.pprint ('RED', "Failed to update icon cache.")
if not icon_cache_updated:
Utils.pprint ('YELLOW', "Icon cache not updated. "
"After install, run this:")
Utils.pprint ('YELLOW', "gtk-update-icon-cache -q -f -t %s" % dir)
elif Options.commands['check']:
def reset_xdg_dirs ():
import tempfile, shutil
base = os.path.join (tempfile.gettempdir (), 'midori-test', '%s')
if os.path.exists (base % ''):
shutil.rmtree (base % '')
for x in ['XDG_CONFIG_HOME', 'XDG_CACHE_HOME', 'XDG_DATA_HOME', 'XDG_RUNTIME_DIR', 'TMPDIR']:
os.environ[x] = (base % x).lower ()
Utils.check_dir (os.environ[x])
def subprocess_popen_timeout (args, stdout=None, stderr=None):
import threading, signal
def t_kill ():
Utils.pprint ('RED', 'timed out')
os.kill (pp.pid, signal.SIGABRT)
t = threading.Timer (int(os.environ.get ('MIDORI_TIMEOUT', '42')), t_kill)
t.start ()
if is_mingw (Build.bld.env):
args.insert (0, 'wine')
cwd = Build.bld.env['PREFIX'] + os.sep + 'bin'
pp = subprocess.Popen (args, cwd=cwd, stdout=stdout, stderr=stderr)
if stdout is None:
(out, err) = pp.communicate ()
t.cancel ()
return pp
# Avoid i18n-related false failures
os.environ['LC_ALL'] = 'C'
os.environ['UNIQUE_BACKEND'] = 'bacon'
if is_mingw (Build.bld.env):
os.environ['MIDORI_EXEC_PATH'] = Build.bld.env['PREFIX']
test = UnitTest.unit_test ()
reset_xdg_dirs ()
if True:
test.unit_test_results = {}
for obj in Build.bld.all_task_gen:
if getattr (obj, 'unit_test', '') and 'cprogram' in obj.features:
if 'MIDORI_UNITS' in os.environ and not obj.target.split('-')[1] in os.environ['MIDORI_UNITS']:
continue
output = obj.path
filename = os.path.join (output.abspath (obj.env), obj.target)
srcdir = output.abspath ()
label = os.path.join (output.bldpath (obj.env), obj.target)
test.unit_tests[label] = (filename, srcdir)
Utils.pprint ('GREEN', 'Running the unit tests')
for label in test.unit_tests.allkeys:
filename = test.unit_tests[label][0]
test.unit_test_results[label] = 0
try:
if is_mingw (Build.bld.env):
filename += '.exe'
args = [filename]
pp = subprocess_popen_timeout (args)
test.unit_test_results[label] = int (pp.returncode == 0)
if not test.unit_test_results[label]:
test.num_tests_failed += 1
except OSError:
msg = sys.exc_info()[1] # Python 2/3 compatibility
Utils.pprint ('RED', '%s: %s' % (args, msg))
test.num_tests_err += 1
except KeyboardInterrupt:
pass
else:
test.want_to_see_test_output = True
test.want_to_see_test_error = True
test.run ()
reset_xdg_dirs ()
for label in test.unit_tests.allkeys:
if not test.unit_test_results[label]:
Utils.pprint ('YELLOW', label + '...FAILED')
filename = test.unit_tests[label][0]
try:
if is_mingw (Build.bld.env):
filename += '.exe'
args = ['gdb', '--batch', '-ex', 'set print thread-events off', '-ex', 'run', '-ex', 'bt', filename]
pp = subprocess_popen_timeout (args)
except OSError:
Utils.pprint ('RED', 'Install gdb to see backtraces')
except KeyboardInterrupt:
pass
else:
Utils.pprint ('GREEN', label + '.......OK')
filename = test.unit_tests[label][0]
if is_mingw (Build.bld.env):
filename += '.exe'
if os.environ.get ('MIDORI_TEST') == 'valgrind':
args = ['valgrind', '-q', '--leak-check=no', '--num-callers=4', '--show-possibly-lost=no', '--undef-value-errors=yes', '--track-origins=yes', filename]
elif os.environ.get ('MIDORI_TEST') == 'callgrind':
args = ['valgrind', '--tool=callgrind', '--callgrind-out-file=%s.callgrind' % filename, filename]
else:
continue
try:
pp = subprocess_popen_timeout (args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
skip = False
for line in iter(pp.stdout.readline, ''):
if line[:2] != '==':
continue
if line == '':
skip = False
elif 'Conditional jump or move' in line:
skip = True
elif 'Uninitialised value was created by a stack allocation' in line:
skip = True
elif not skip:
sys.stdout.write (line[9:])
except OSError:
Utils.pprint ('YELLOW', 'Install valgrind to perform memory checks')
except KeyboardInterrupt:
pass
if not 'MIDORI_UNITS' in os.environ:
Utils.pprint ('BLUE', 'Set MIDORI_UNITS to select a subset of test cases')
if not 'MIDORI_TEST' in os.environ:
Utils.pprint ('BLUE', 'Set MIDORI_TEST to "valgrind" or "callgrind" to perform memory checks')
if not 'MIDORI_TIMEOUT' in os.environ:
Utils.pprint ('BLUE', 'Set MIDORI_TIMEOUT to set the maximum test runtime (default: 42)')
# if test.num_tests_failed > 0 or test.num_tests_err > 0:
# sys.exit (1)
elif Options.options.update_po:
os.chdir('./po')
try:
try:
size_old = os.stat (APPNAME + '.pot').st_size
except:
size_old = 0
subprocess.call (['intltool-update', '-p', '-g', APPNAME])
size_new = os.stat (APPNAME + '.pot').st_size
if size_new != size_old:
Utils.pprint ('YELLOW', "Updated po template.")
try:
command = 'intltool-update -r -g %s' % APPNAME
Utils.exec_command (command)
Utils.pprint ('YELLOW', "Updated translations.")
except:
Utils.pprint ('RED', "Failed to update translations.")
except:
Utils.pprint ('RED', "Failed to generate po template.")
Utils.pprint ('RED', "Make sure intltool is installed.")
os.chdir ('..')
elif Options.options.run:
folder = os.path.abspath (blddir + '/default')
try:
relfolder = folder
if not is_mingw (Build.bld.env):
relfolder = os.path.relpath (folder)
except:
pass
try:
nls = 'MIDORI_NLSPATH=' + relfolder + os.sep + 'po'
lang = os.environ['LANG']
try:
for lang in os.listdir (folder + os.sep + 'po'):
if lang[3:] == 'mo':
lang = lang[:-3]
else:
continue
Utils.check_dir (folder + os.sep + 'po' + os.sep + lang)
Utils.check_dir (folder + os.sep + 'po' + os.sep + lang + \
os.sep + 'LC_MESSAGES')
os.symlink (folder + os.sep + 'po' + os.sep + lang + '.mo',
folder + os.sep + 'po' + os.sep + lang + os.sep + \
'LC_MESSAGES' + os.sep + APPNAME + '.mo')
except:
pass
command = nls + ' '
if is_mingw (Build.bld.env):
# This works only if everything is installed to that prefix
os.chdir (Build.bld.env['PREFIX'] + os.sep + 'bin')
command += ' wine cmd /k "PATH=%PATH%;' + Build.bld.env['PREFIX'] + os.sep + 'bin' + ' && ' + APPNAME + '.exe"'
else:
command += ' ' + relfolder + os.sep + APPNAME + os.sep + APPNAME
print (command)
Utils.exec_command (command)
except Exception:
msg = sys.exc_info()[1] # Python 2/3 compatibility
Utils.pprint ('RED', "Failed to run application: " + str (msg))