adchpp-docker/src/build_util.py

212 lines
6.9 KiB
Python

import glob
import sys
import os
class Dev:
def __init__(self, env):
self.env = env
self.build_root = '#/build/' + env['mode'] + '-' + env['tools']
if env['arch'] != 'x86':
self.build_root += '-' + env['arch']
self.build_root += '/'
def prepare(self):
if not self.env['verbose']:
self.env['CCCOMSTR'] = "Compiling $TARGET (static)"
self.env['SHCCCOMSTR'] = "Compiling $TARGET (shared)"
self.env['CXXCOMSTR'] = "Compiling $TARGET (static)"
self.env['SHCXXCOMSTR'] = "Compiling $TARGET (shared)"
self.env['PCHCOMSTR'] = "Compiling $TARGET (precompiled header)"
self.env['GCHCOMSTR'] = "Compiling $TARGET (static precompiled header)"
self.env['GCHSHCOMSTR'] = "Compiling $TARGET (shared precompiled header)"
self.env['SHLINKCOMSTR'] = "Linking $TARGET (shared)"
self.env['LINKCOMSTR'] = "Linking $TARGET (static)"
self.env['ARCOMSTR'] = "Archiving $TARGET"
self.env['RCCOMSTR'] = "Resource $TARGET"
self.env.SConsignFile()
self.env.SetOption('implicit_cache', '1')
self.env.SetOption('max_drift', 60*10)
self.env.Decider('MD5-timestamp')
if 'mingw' in self.env['TOOLS']:
self.env.Append(LINKFLAGS=["-Wl,--enable-runtime-pseudo-reloc"])
prefix = ''
if self.env.get('prefix') is not None:
prefix = self.env['prefix']
elif sys.platform != 'win32':
prefix = 'i386-mingw32-'
self.env['CC'] = prefix + 'gcc'
self.env['CXX'] = prefix + 'g++'
self.env['LINK'] = prefix + 'g++'
self.env['AR'] = prefix + 'ar'
self.env['RANLIB'] = prefix + 'ranlib'
self.env['RC'] = prefix + 'windres'
if sys.platform != 'win32':
self.env['PROGSUFFIX'] = '.exe'
self.env['LIBPREFIX'] = 'lib'
self.env['LIBSUFFIX'] = '.a'
self.env['SHLIBSUFFIX'] = '.dll'
# some distros of windres fail when they receive Win paths as input, so convert...
self.env['RCCOM'] = self.env['RCCOM'].replace('-i $SOURCE', '-i ${SOURCE.posix}', 1)
def is_win32(self):
return sys.platform == 'win32' or 'mingw' in self.env['TOOLS']
def get_build_root(self):
return self.build_root
def get_build_path(self, source_path):
return self.get_build_root() + source_path
def get_target(self, source_path, name, in_bin = True):
if in_bin:
return self.get_build_root() + 'bin/' + name
else:
return self.get_build_root() + source_path + name
def get_sources(self, source_path, source_glob):
return map(lambda x: self.get_build_path(source_path) + x, glob.glob(source_glob))
def prepare_build(self, source_path, name, source_glob = '*.cpp', in_bin = True,
precompiled_header = None, shared_precompiled_header = None):
build_path = self.get_build_path(source_path)
env = self.env.Clone()
env.VariantDir(build_path, '.', duplicate = 0)
sources = self.get_sources(source_path, source_glob)
if precompiled_header is not None or shared_precompiled_header is not None:
# TODO we work around the 2 problems described on
# <http://scons.tigris.org/issues/show_bug.cgi?id=2680> - remove once not needed
if shared_precompiled_header is None:
pch = precompiled_header
else:
pch = shared_precompiled_header
for i, source in enumerate(sources):
if source.find(pch + '.cpp') != -1:
# the PCH/GCH builder will take care of this one
del sources[i]
if 'msvc' in env['TOOLS']:
env['PCHSTOP'] = pch + '.h'
pch = env.PCH(build_path + pch + '.pch', pch + '.cpp')
env['PCH'] = pch[0]
env['ARFLAGS'] = env['ARFLAGS'] + ' ' + str(pch[1])
env['LINKFLAGS'] = env['LINKFLAGS'] + ' ' + str(pch[1])
elif 'gcc' in env['TOOLS']:
if shared_precompiled_header is None:
gch_tool = 'Gch'
else:
gch_tool = 'GchSh'
exec("env['" + gch_tool + "'] = env." +
gch_tool + "(build_path + pch + '.h.gch', pch + '.h')[0]")
# little dance to add the pch object to include paths, while overriding the current directory
env['CXXCOM'] = env['CXXCOM'] + ' -include ' + env.Dir(build_path).abspath + '/' + pch + '.h'
return (env, self.get_target(source_path, name, in_bin), sources)
def build(self, source_path, local_env = None):
if not local_env:
local_env = self.env
full_path = local_env.Dir('.').path + '/' + source_path
return local_env.SConscript(source_path + 'SConscript', exports={'dev' : self, 'source_path' : full_path })
def i18n (self, source_path, buildenv, sources, name):
if not self.env['i18n']:
return
p_oze = glob.glob('po/*.po')
potfile = 'po/' + name + '.pot'
buildenv['PACKAGE'] = name
ret = buildenv.PotBuild(potfile, sources)
for po_file in p_oze:
buildenv.Precious(buildenv.PoBuild(po_file, [potfile]))
lang = os.path.basename(po_file)[:-3]
locale_path = self.get_target(source_path, 'locale/' + lang + '/')
buildenv.MoBuild(locale_path + 'LC_MESSAGES/' + name + '.mo', po_file,
NAME_FILE = buildenv.File(locale_path + 'name.txt'))
# languages = [ os.path.basename(po).replace ('.po', '') for po in p_oze ]
# for lang in languages:
# modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
# moname = domain + '.mo'
# installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
return ret
# support installs that only have an asciidoc.py file but no executable
def get_asciidoc(self):
if 'PATHEXT' in self.env['ENV']:
pathext = self.env['ENV']['PATHEXT'] + ';.py'
else:
pathext = ''
asciidoc = self.env.WhereIs('asciidoc', pathext = pathext)
if asciidoc is None:
return None
if asciidoc[-3:] == '.py':
if self.env.WhereIs('python') is None:
return None
asciidoc = 'python ' + asciidoc
return asciidoc
def CheckPKGConfig(self, context, version):
context.Message( 'Checking for pkg-config... ' )
ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
context.Result( ret )
return ret
def CheckPKG(self, context, name):
context.Message( 'Checking for %s... ' % name )
ret = context.TryAction('pkg-config --exists "%s"' % name)[0]
if ret:
context.env.ParseConfig('pkg-config --cflags --libs "%s"' % name)
context.Result( ret )
return ret
def CheckLuaPKG(self, context, name, version):
context.Message( 'Checking for %s version %s... ' % (name, version) )
res = context.TryAction('$lua -l %s -e "os.exit"(("%s._VERSION == \'%s\'")" and 0 or 1")' % (name, name, version)) [0]
context.Result( res)
return res
def CheckBoost(self, context, version):
v_arr = version.split(".")
version_n = 0
if len(v_arr) > 0:
version_n += int(v_arr[0])*100000
if len(v_arr) > 1:
version_n += int(v_arr[1])*100
if len(v_arr) > 2:
version_n += int(v_arr[2])
context.Message('Checking for Boost version >= %s... ' % (version))
ret = context.TryCompile("""
#include <boost/version.hpp>
#if BOOST_VERSION < %d
#error Installed boost is too old!
#endif
int main() { return 0; }
""" % version_n, '.cpp')
context.Result(ret)
return ret
def array_remove(array, to_remove):
if to_remove in array:
array.remove(to_remove)