Add support (configure, build and install) for building on Windows and cross-compiling for Windows using the Waf build system.

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@3847 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Enrico Tröger 2009-06-08 19:59:48 +00:00
parent 17657b71c9
commit 583c4bdd09
2 changed files with 191 additions and 108 deletions

View File

@ -3,6 +3,9 @@
* src/callbacks.c: * src/callbacks.c:
Add backslash to the wordchars on Windows when using Add backslash to the wordchars on Windows when using
'Open Selected File'. 'Open Selected File'.
* src/wscript:
Add support (configure, build and install) for building on Windows
and cross-compiling for Windows using the Waf build system.
2009-06-05 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com> 2009-06-05 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>

296
wscript
View File

@ -121,7 +121,8 @@ def configure(conf):
# try SVN # try SVN
elif os.path.exists('.svn'): elif os.path.exists('.svn'):
try: try:
stdout = Utils.cmd_output(cmd='svn info --non-interactive', env={'LANG' : 'C'}) _env = None if is_win32 else {'LANG' : 'C'}
stdout = Utils.cmd_output(cmd='svn info --non-interactive', silent=True, env=_env)
lines = stdout.splitlines(True) lines = stdout.splitlines(True)
for line in lines: for line in lines:
if line.startswith('Last Changed Rev'): if line.startswith('Last Changed Rev'):
@ -141,7 +142,9 @@ def configure(conf):
elif default_value: elif default_value:
conf.define(define_name, default_value, quote) conf.define(define_name, default_value, quote)
conf.check_tool('compiler_cc') conf.check_tool('compiler_cc')
is_win32 = target_is_win32(conf.env)
conf.check(header_name='fcntl.h') conf.check(header_name='fcntl.h')
conf.check(header_name='fnmatch.h') conf.check(header_name='fnmatch.h')
@ -173,12 +176,19 @@ def configure(conf):
# check for cxx after the header and function checks have been done to ensure they are # check for cxx after the header and function checks have been done to ensure they are
# checked with cc not cxx # checked with cc not cxx
conf.check_tool('compiler_cxx intltool misc') conf.check_tool('compiler_cxx misc')
if is_win32:
conf.check_tool('winres')
# we don't require intltool on Windows (it would require Perl) though it works well
try:
conf.check_tool('intltool')
except:
pass
# GTK / GIO version check
conf.check_cfg(package='gtk+-2.0', atleast_version='2.8.0', uselib_store='GTK', conf.check_cfg(package='gtk+-2.0', atleast_version='2.8.0', uselib_store='GTK',
mandatory=True, args='--cflags --libs') mandatory=True, args='--cflags --libs')
# GTK version check
have_gtk_210 = False have_gtk_210 = False
gtk_version = conf.check_cfg(modversion='gtk+-2.0', uselib_store='GTK') gtk_version = conf.check_cfg(modversion='gtk+-2.0', uselib_store='GTK')
if gtk_version: if gtk_version:
@ -186,20 +196,46 @@ def configure(conf):
have_gtk_210 = True have_gtk_210 = True
else: else:
gtk_version = 'Unknown' gtk_version = 'Unknown'
# GIO check
conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=False) conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=False)
conf_define_from_opt('LIBDIR', Options.options.libdir, conf.env['PREFIX'] + '/lib') # Windows specials
conf_define_from_opt('DOCDIR', Options.options.docdir, conf.env['DATADIR'] + '/doc/geany') if is_win32:
conf_define_from_opt('MANDIR', Options.options.mandir, conf.env['DATADIR'] + '/man') prefix = os.path.splitdrive(conf.srcdir)[1]
conf.define('PREFIX', os.path.join(prefix, '%s-%s' % (APPNAME, VERSION)), 1)
conf.define('DOCDIR', os.path.join(conf.env['PREFIX'], 'doc'), 1)
conf.define('LOCALEDIR', os.path.join(conf.env['PREFIX'], 'share\locale'), 1)
conf.define('LIBDIR', conf.env['PREFIX'], 1)
# DATADIR is defined in objidl.h, so we remove it from config.h but keep it in env
conf.undefine('DATADIR')
conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'data')
# hack: we add the parent directory of the first include directory as this is missing in
# list returned from pkg-config
conf.env['CPPPATH_GTK'].insert(0, os.path.dirname(conf.env['CPPPATH_GTK'][0]))
# we don't need -fPIC when compiling on or for Windows
if '-fPIC' in conf.env['shlib_CCFLAGS']:
conf.env['shlib_CCFLAGS'].remove('-fPIC')
if '-fPIC' in conf.env['CXXFLAGS']:
conf.env['CXXFLAGS'].remove('-fPIC')
conf.env.append_value('program_LINKFLAGS', '-mwindows')
conf.env.append_value('LIB_WIN32', [ 'wsock32', 'uuid', 'ole32', 'iberty' ])
conf.env['shlib_PATTERN'] = '%s.dll'
conf.env['program_PATTERN'] = '%s.exe'
else:
conf.env['shlib_PATTERN'] = '%s.so'
conf_define_from_opt('DOCDIR', Options.options.docdir,
os.path.join(conf.env['DATADIR'], 'doc/geany'))
conf_define_from_opt('LIBDIR', Options.options.libdir,
os.path.join(conf.env['PREFIX'], 'lib'))
conf_define_from_opt('MANDIR', Options.options.mandir,
os.path.join(conf.env['DATADIR'], 'man'))
svn_rev = conf_get_svn_rev() svn_rev = conf_get_svn_rev()
conf.define('ENABLE_NLS', 1) conf.define('ENABLE_NLS', 1)
conf.define('GEANY_LOCALEDIR', 'LOCALEDIR', 0) conf.define('GEANY_LOCALEDIR', '' if is_win32 else conf.env['LOCALEDIR'], 1)
conf.define('GEANY_DATADIR', 'DATADIR', 0) conf.define('GEANY_DATADIR', 'data' if is_win32 else conf.env['DATADIR'], 1)
conf.define('GEANY_DOCDIR', 'DOCDIR', 0) conf.define('GEANY_DOCDIR', conf.env['DOCDIR'], 1)
conf.define('GEANY_LIBDIR', 'LIBDIR', 0) conf.define('GEANY_LIBDIR', '' if is_win32 else conf.env['LIBDIR'], 1)
conf.define('GEANY_PREFIX', conf.env['PREFIX'], 1) conf.define('GEANY_PREFIX', '' if is_win32 else conf.env['PREFIX'], 1)
conf.define('PACKAGE', APPNAME, 1) conf.define('PACKAGE', APPNAME, 1)
conf.define('VERSION', VERSION, 1) conf.define('VERSION', VERSION, 1)
conf.define('REVISION', svn_rev, 1) conf.define('REVISION', svn_rev, 1)
@ -238,7 +274,7 @@ def set_options(opt):
help='compile without plugin support [default: No]', dest='no_plugins') help='compile without plugin support [default: No]', dest='no_plugins')
opt.add_option('--disable-socket', action='store_true', default=False, opt.add_option('--disable-socket', action='store_true', default=False,
help='compile without support to detect a running instance [[default: No]', dest='no_socket') help='compile without support to detect a running instance [[default: No]', dest='no_socket')
opt.add_option('--disable-vte', action='store_true', default=False, opt.add_option('--disable-vte', action='store_true', default=target_is_win32(os.environ),
help='compile without support for an embedded virtual terminal [[default: No]', dest='no_vte') help='compile without support for an embedded virtual terminal [[default: No]', dest='no_vte')
opt.add_option('--enable-gnu-regex', action='store_true', default=False, opt.add_option('--enable-gnu-regex', action='store_true', default=False,
help='compile with included GNU regex library [default: No]', dest='gnu_regex') help='compile with included GNU regex library [default: No]', dest='gnu_regex')
@ -259,21 +295,22 @@ def set_options(opt):
def build(bld): def build(bld):
is_win32 = target_is_win32(bld.env)
def build_plugin(plugin_name, install = True): def build_plugin(plugin_name, install = True):
if install: if install:
instpath = '${LIBDIR}/geany/' instpath = '${PREFIX}/lib' if is_win32 else '${LIBDIR}/geany/'
else: else:
instpath = None instpath = None
bld.new_task_gen( bld.new_task_gen(
features ='cc cshlib', features = 'cc cshlib',
source = 'plugins/' + plugin_name + '.c', source = 'plugins/' + plugin_name + '.c',
includes = '. plugins/ src/ scintilla/include tagmanager/include', includes = '. plugins/ src/ scintilla/include tagmanager/include',
target = plugin_name, target = plugin_name,
uselib = 'GTK', uselib = 'GTK',
install_path = instpath, install_path = instpath
) )
bld.env['shlib_PATTERN'] = '%s.so'
# Tagmanager # Tagmanager
@ -303,16 +340,18 @@ def build(bld):
# Geany # Geany
if bld.env['HAVE_VTE'] == 1: if bld.env['HAVE_VTE'] == 1:
geany_sources.append('src/vte.c') geany_sources.append('src/vte.c')
if sys.platform == "win32": if is_win32:
geany_sources.append('src/win32.c') geany_sources.append('src/win32.c')
bld.new_task_gen( bld.new_task_gen(
features = 'cc cxx cprogram', features = 'cc cxx cprogram',
name = 'geany', name = 'geany',
target = 'geany', target = 'geany',
source = geany_sources, source = geany_sources,
includes = '. src/ scintilla/include/ tagmanager/include/', includes = '. src/ scintilla/include/ tagmanager/include/',
uselib = 'GTK GIO', uselib = 'GTK GIO WIN32',
uselib_local = 'scintilla tagmanager' uselib_local = 'scintilla tagmanager',
add_objects = 'geany-rc' if is_win32 else None
) )
# geanyfunctions.h # geanyfunctions.h
@ -332,114 +371,139 @@ def build(bld):
build_plugin('filebrowser') build_plugin('filebrowser')
build_plugin('htmlchars') build_plugin('htmlchars')
build_plugin('saveactions') build_plugin('saveactions')
build_plugin('splitwindow') build_plugin('splitwindow', not is_win32)
# Translations # Translations
bld.new_task_gen( if bld.env['INTLTOOL']:
features = 'intltool_po', bld.new_task_gen(
podir = 'po', features = 'intltool_po',
appname = 'geany' podir = 'po',
) install_path = '${LOCALEDIR}',
appname = 'geany'
)
bld.new_task_gen( if not is_win32:
features = 'intltool_in', # geany.desktop
source = 'geany.desktop.in', if bld.env['INTLTOOL']:
flags = '-d', bld.new_task_gen(
install_path = '${DATADIR}/applications' features = 'intltool_in',
) source = 'geany.desktop.in',
flags = [ '-d', '-q', '-u', '-c' ],
install_path = '${DATADIR}/applications'
)
# geany.pc # geany.pc
bld.new_task_gen( bld.new_task_gen(
features = 'subst', features = 'subst',
source = 'geany.pc.in', source = 'geany.pc.in',
target = 'geany.pc', target = 'geany.pc',
dict = { 'VERSION' : VERSION, dict = { 'VERSION' : VERSION,
'prefix': bld.env['PREFIX'], 'prefix': bld.env['PREFIX'],
'exec_prefix': '${prefix}', 'exec_prefix': '${prefix}',
'libdir': '${exec_prefix}/lib', 'libdir': '${exec_prefix}/lib',
'includedir': '${prefix}/include', 'includedir': '${prefix}/include',
'datarootdir': '${prefix}/share', 'datarootdir': '${prefix}/share',
'datadir': '${datarootdir}', 'datadir': '${datarootdir}',
'localedir': '${datarootdir}/locale' }, 'localedir': '${datarootdir}/locale' },
install_path = '${LIBDIR}/pkgconfig' install_path = '${LIBDIR}/pkgconfig'
) )
# geany.1 # geany.1
bld.new_task_gen( bld.new_task_gen(
features = 'subst', features = 'subst',
source = 'doc/geany.1.in', source = 'doc/geany.1.in',
target = 'geany.1', target = 'geany.1',
dict = { 'VERSION' : VERSION, dict = { 'VERSION' : VERSION,
'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany' }, 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany' },
install_path = '${MANDIR}/man1' install_path = '${MANDIR}/man1'
) )
# geany.spec # geany.spec
bld.new_task_gen( bld.new_task_gen(
features = 'subst', features = 'subst',
source = 'geany.spec.in', source = 'geany.spec.in',
target = 'geany.spec', target = 'geany.spec',
install_path = None, install_path = None,
dict = { 'VERSION' : VERSION } dict = { 'VERSION' : VERSION }
) )
# Doxyfile # Doxyfile
bld.new_task_gen( bld.new_task_gen(
features = 'subst', features = 'subst',
source = 'doc/Doxyfile.in', source = 'doc/Doxyfile.in',
target = 'doc/Doxyfile', target = 'doc/Doxyfile',
install_path = None, install_path = None,
dict = { 'VERSION' : VERSION } dict = { 'VERSION' : VERSION }
) )
else:
bld.new_task_gen(
features = 'cc',
name = 'geany-rc',
source = 'geany_private.rc'
)
### ###
# Install files # Install files
### ###
# Headers if not is_win32:
bld.install_files('${PREFIX}/include/geany', ''' # Headers
src/dialogs.h src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h bld.install_files('${PREFIX}/include/geany', '''
src/highlighting.h src/keybindings.h src/main.h src/msgwindow.h src/plugindata.h src/plugins.h src/dialogs.h src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h
src/prefs.h src/project.h src/sciwrappers.h src/search.h src/support.h src/templates.h src/highlighting.h src/keybindings.h src/main.h src/msgwindow.h src/plugindata.h
src/toolbar.h src/ui_utils.h src/utils.h src/plugins.h src/prefs.h src/project.h src/sciwrappers.h src/search.h src/support.h
plugins/pluginmacros.h plugins/geanyfunctions.h ''') src/templates.h src/toolbar.h src/ui_utils.h src/utils.h plugins/pluginmacros.h
bld.install_files('${PREFIX}/include/geany/scintilla', ''' plugins/geanyfunctions.h ''')
scintilla/include/SciLexer.h scintilla/include/Scintilla.h scintilla/include/Scintilla.iface bld.install_files('${PREFIX}/include/geany/scintilla', '''
scintilla/include/ScintillaWidget.h ''') scintilla/include/SciLexer.h scintilla/include/Scintilla.h
bld.install_files('${PREFIX}/include/geany/tagmanager', ''' scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
tagmanager/include/tm_file_entry.h tagmanager/include/tm_project.h tagmanager/include/tm_source_file.h bld.install_files('${PREFIX}/include/geany/tagmanager', '''
tagmanager/include/tm_symbol.h tagmanager/include/tm_tag.h tagmanager/include/tm_tagmanager.h tagmanager/include/tm_file_entry.h tagmanager/include/tm_project.h
tagmanager/include/tm_work_object.h tagmanager/include/tm_workspace.h ''') tagmanager/include/tm_source_file.h
tagmanager/include/tm_symbol.h tagmanager/include/tm_tag.h
tagmanager/include/tm_tagmanager.h tagmanager/include/tm_work_object.h
tagmanager/include/tm_workspace.h ''')
# Docs # Docs
bld.install_files('${DOCDIR}', 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO') base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}'
bld.install_files('${DOCDIR}/html/images', 'doc/images/*.png') ext = '.txt' if is_win32 else ''
bld.install_as('${DOCDIR}/manual.txt', 'doc/geany.txt') html_dir = '' if is_win32 else 'html/'
bld.install_as('${DOCDIR}/html/index.html', 'doc/geany.html') html_name = 'Manual.html' if is_win32 else 'index.html'
for f in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
bld.install_as("%s/%s%s" % (base_dir, ucFirst(f, is_win32), ext), f)
bld.install_files('${DOCDIR}/%simages' % html_dir, 'doc/images/*.png')
bld.install_as('${DOCDIR}/%s' % ucFirst('manual.txt', is_win32), 'doc/geany.txt')
bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt') bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
if is_win32:
bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
# Data # Data
bld.install_files('${DATADIR}/geany', 'data/filetype*') dir = '' if is_win32 else 'geany'
bld.install_files('${DATADIR}/geany', 'data/*.tags') bld.install_files('${DATADIR}/%s' % dir, 'data/filetype*')
bld.install_files('${DATADIR}/geany', 'data/snippets.conf') bld.install_files('${DATADIR}/%s' % dir, 'data/*.tags')
bld.install_files('${DATADIR}/geany', 'data/ui_toolbar.xml') bld.install_files('${DATADIR}/%s' % dir, 'data/snippets.conf')
bld.install_as('${DATADIR}/geany/GPL-2', 'COPYING') bld.install_files('${DATADIR}/%s' % dir, 'data/ui_toolbar.xml')
bld.install_as('${DATADIR}/%s/GPL-2' % dir, 'COPYING')
# Icons # Icons
bld.install_files('${DATADIR}/icons/hicolor/16x16/apps', 'icons/16x16/*.png') bld.install_files('${PREFIX}/share/icons'
bld.install_files('${DATADIR}/icons/hicolor/48x48/apps', 'icons/48x48/*.png') if is_win32 else '${DATADIR}/icons/hicolor/16x16/apps', 'icons/16x16/*.png')
bld.install_files('${DATADIR}/icons/hicolor/scalable/apps', 'icons/scalable/*.svg') if not is_win32:
bld.install_files('${DATADIR}/icons/hicolor/48x48/apps', 'icons/48x48/*.png')
bld.install_files('${DATADIR}/icons/hicolor/scalable/apps', 'icons/scalable/*.svg')
def shutdown(): def shutdown():
is_win32 = target_is_win32(Build.bld.env)
# the following code was taken from midori's WAF script, thanks # the following code was taken from midori's WAF script, thanks
if Options.commands['install'] or Options.commands['uninstall']: if not is_win32 and not Options.options.destdir and (Options.commands['install'] or Options.commands['uninstall']):
dir = Build.bld.get_install_path('${DATADIR}/icons/hicolor') dir = Build.bld.get_install_path('${DATADIR}/icons/hicolor')
icon_cache_updated = False icon_cache_updated = False
if not Options.options.destdir: try:
try: Utils.exec_command('gtk-update-icon-cache -q -f -t %s' % dir)
Utils.exec_command('gtk-update-icon-cache -q -f -t %s' % dir) Utils.pprint('GREEN', 'GTK icon cache updated.')
Utils.pprint('GREEN', 'GTK icon cache updated.') icon_cache_updated = True
icon_cache_updated = True except:
except: Utils.pprint('YELLOW', 'Failed to update icon cache for %s.' % dir)
Utils.pprint('YELLOW', 'Failed to update icon cache for ' + dir + '.') if not icon_cache_updated:
if not icon_cache_updated and not Options.options.destdir:
print 'Icon cache not updated. After install, run this:' print 'Icon cache not updated. After install, run this:'
print 'gtk-update-icon-cache -q -f -t %s' % dir print 'gtk-update-icon-cache -q -f -t %s' % dir
@ -510,3 +574,19 @@ def print_message(conf, msg, result, color = 'GREEN'):
conf.check_message_1(msg) conf.check_message_1(msg)
conf.check_message_2(result, color) conf.check_message_2(result, color)
def ucFirst(s, is_win32):
if is_win32:
return s.title()
return s
def target_is_win32(env):
if sys.platform == 'win32':
return True
if env and 'CC' in env:
cc = env['CC']
if not isinstance(cc, str):
cc = ''.join(cc)
return cc.find('mingw') != -1
return False