You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
636 lines
21 KiB
636 lines
21 KiB
15 years ago
|
## Thomas Nagy, 2005
|
||
|
""" Run scons -h to display the associated help, or look below """
|
||
|
|
||
|
import os, re, types, sys, string, shutil, stat, glob
|
||
|
import SCons.Defaults
|
||
|
import SCons.Tool
|
||
|
import SCons.Util
|
||
|
from SCons.Script.SConscript import SConsEnvironment
|
||
|
from SCons.Options import Options, PathOption
|
||
|
|
||
|
def getreldir(lenv):
|
||
|
cwd=os.getcwd()
|
||
|
root=SCons.Node.FS.default_fs.Dir('#').abspath
|
||
|
return cwd.replace(root,'').lstrip('/')
|
||
|
|
||
|
def dist(env, appname, version=None):
|
||
|
### To make a tarball of your masterpiece, use 'scons dist'
|
||
|
import os
|
||
|
if 'dist' in sys.argv:
|
||
|
if not version: VERSION=os.popen("cat VERSION").read().rstrip()
|
||
|
else: VERSION=version
|
||
|
FOLDER = appname+'-'+VERSION
|
||
|
TMPFOLD = ".tmp"+FOLDER
|
||
|
ARCHIVE = FOLDER+'.tar.bz2'
|
||
|
|
||
|
## check if the temporary directory already exists
|
||
|
os.popen('rm -rf %s %s %s' % (FOLDER, TMPFOLD, ARCHIVE) )
|
||
|
|
||
|
## create a temporary directory
|
||
|
startdir = os.getcwd()
|
||
|
|
||
|
os.popen("mkdir -p "+TMPFOLD)
|
||
|
os.popen("cp -R * "+TMPFOLD)
|
||
|
os.popen("mv "+TMPFOLD+" "+FOLDER)
|
||
|
|
||
|
## remove scons-local if it is unpacked
|
||
|
os.popen("rm -rf "+FOLDER+"/scons "+FOLDER+"/sconsign "+FOLDER+"/scons-local-0.96.1")
|
||
|
|
||
|
## remove our object files first
|
||
|
os.popen("find "+FOLDER+" -name \"cache\" | xargs rm -rf")
|
||
|
os.popen("find "+FOLDER+" -name \"build\" | xargs rm -rf")
|
||
|
os.popen("find "+FOLDER+" -name \"*.pyc\" | xargs rm -f")
|
||
|
|
||
|
## CVS cleanup
|
||
|
os.popen("find "+FOLDER+" -name \"CVS\" | xargs rm -rf")
|
||
|
os.popen("find "+FOLDER+" -name \".cvsignore\" | xargs rm -rf")
|
||
|
|
||
|
## Subversion cleanup
|
||
|
os.popen("find %s -name .svn -type d | xargs rm -rf" % FOLDER)
|
||
|
|
||
|
## GNU Arch cleanup
|
||
|
os.popen("find "+FOLDER+" -name \"{arch}\" | xargs rm -rf")
|
||
|
os.popen("find "+FOLDER+" -name \".arch-i*\" | xargs rm -rf")
|
||
|
|
||
|
## Create the tarball (coloured output)
|
||
|
print "\033[92m"+"Writing archive "+ARCHIVE+"\033[0m"
|
||
|
os.popen("tar cjf "+ARCHIVE+" "+FOLDER)
|
||
|
|
||
|
## Remove the temporary directory
|
||
|
os.popen('rm -rf '+FOLDER)
|
||
|
env.Exit(0)
|
||
|
|
||
|
if 'distclean' in sys.argv:
|
||
|
## Remove the cache directory
|
||
|
import os, shutil
|
||
|
if os.path.isdir(env['CACHEDIR']): shutil.rmtree(env['CACHEDIR'])
|
||
|
os.popen("find . -name \"*.pyc\" | xargs rm -rf")
|
||
|
env.Exit(0)
|
||
|
|
||
|
colors= {
|
||
|
'BOLD' :"\033[1m",
|
||
|
'RED' :"\033[91m",
|
||
|
'GREEN' :"\033[92m",
|
||
|
'YELLOW':"\033[1m", #"\033[93m" # unreadable on white backgrounds
|
||
|
'CYAN' :"\033[96m",
|
||
|
'NORMAL':"\033[0m",
|
||
|
}
|
||
|
|
||
|
def pprint(env, col, str, label=''):
|
||
|
if env.has_key('NOCOLORS'):
|
||
|
print "%s %s" % (str, label)
|
||
|
return
|
||
|
try: mycol=colors[col]
|
||
|
except: mycol=''
|
||
|
print "%s%s%s %s" % (mycol, str, colors['NORMAL'], label)
|
||
|
|
||
|
class genobj:
|
||
|
def __init__(self, val, env):
|
||
|
if not val in "program shlib kioslave staticlib".split():
|
||
|
print "unknown genobj given: "+val
|
||
|
env.Exit(1)
|
||
|
|
||
|
self.type = val
|
||
|
self.orenv = env
|
||
|
self.env = None
|
||
|
self.executed = 0
|
||
|
|
||
|
self.target=''
|
||
|
self.src=None
|
||
|
|
||
|
self.cxxflags=''
|
||
|
self.cflags=''
|
||
|
self.includes=''
|
||
|
|
||
|
self.linkflags=''
|
||
|
self.libpaths=''
|
||
|
self.libs=''
|
||
|
|
||
|
# vars used by shlibs
|
||
|
self.vnum=''
|
||
|
self.libprefix=''
|
||
|
|
||
|
# a directory where to install the targets (optional)
|
||
|
self.instdir=''
|
||
|
|
||
|
# change the working directory before reading the targets
|
||
|
self.chdir=''
|
||
|
|
||
|
# unix permissions
|
||
|
self.perms=''
|
||
|
|
||
|
# these members are private
|
||
|
self.chdir_lock=None
|
||
|
self.dirprefix='./'
|
||
|
self.old_os_dir=''
|
||
|
self.old_fs_dir=''
|
||
|
self.p_local_shlibs=[]
|
||
|
self.p_local_staticlibs=[]
|
||
|
self.p_global_shlibs=[]
|
||
|
|
||
|
self.p_localsource=None
|
||
|
self.p_localtarget=None
|
||
|
|
||
|
# work directory
|
||
|
self.workdir_lock=None
|
||
|
self.orig_fs_dir=SCons.Node.FS.default_fs.getcwd()
|
||
|
self.not_orig_fs_dir=''
|
||
|
self.not_orig_os_dir=''
|
||
|
|
||
|
if not env.has_key('USE_THE_FORCE_LUKE'): env['USE_THE_FORCE_LUKE']=[self]
|
||
|
else: env['USE_THE_FORCE_LUKE'].append(self)
|
||
|
|
||
|
def joinpath(self, val):
|
||
|
dir=self.dirprefix
|
||
|
|
||
|
thing=self.orenv.make_list(val)
|
||
|
files=[]
|
||
|
bdir="./"
|
||
|
if self.orenv.has_key('_BUILDDIR_'): bdir=self.orenv['_BUILDDIR_']
|
||
|
|
||
|
for v in thing:
|
||
|
files.append( self.orenv.join(bdir, dir, v) )
|
||
|
|
||
|
#for f in files: print f
|
||
|
#print "\n"
|
||
|
return files
|
||
|
|
||
|
# a list of paths, with absolute and relative ones
|
||
|
def fixpath(self, val):
|
||
|
dir=self.dirprefix
|
||
|
|
||
|
thing=self.orenv.make_list(val)
|
||
|
ret=[]
|
||
|
bdir="./"
|
||
|
if self.orenv.has_key('_BUILDDIR_'): bdir=self.orenv['_BUILDDIR_']
|
||
|
for v in thing:
|
||
|
if v[:2] == "./" or v[:3] == "../":
|
||
|
ret.append( self.orenv.join(bdir, dir, v) )
|
||
|
elif v[:1] == "#" or v[:1] == "/":
|
||
|
ret.append( v )
|
||
|
else:
|
||
|
ret.append( self.orenv.join(bdir, dir, v) )
|
||
|
return ret
|
||
|
|
||
|
def lockworkdir(self):
|
||
|
if self.workdir_lock: return
|
||
|
self.workdir_lock=1
|
||
|
self.not_orig_fs_dir=SCons.Node.FS.default_fs.getcwd()
|
||
|
self.not_orig_os_dir=os.getcwd()
|
||
|
SCons.Node.FS.default_fs.chdir( self.orig_fs_dir, change_os_dir=1)
|
||
|
|
||
|
def unlockworkdir(self):
|
||
|
if not self.workdir_lock: return
|
||
|
SCons.Node.FS.default_fs.chdir( self.not_orig_fs_dir, change_os_dir=0)
|
||
|
os.chdir(self.not_orig_os_dir)
|
||
|
self.workdir_lock=None
|
||
|
|
||
|
def lockchdir(self):
|
||
|
if not self.chdir: return
|
||
|
if self.chdir_lock: return
|
||
|
self.chdir_lock=1
|
||
|
SConfFS=SCons.Node.FS.default_fs
|
||
|
self.old_fs_dir=SConfFS.getcwd()
|
||
|
self.old_os_dir=os.getcwd()
|
||
|
SConfFS.chdir( SConfFS.Dir('#/'+self.chdir), change_os_dir=1)
|
||
|
|
||
|
def unlockchdir(self):
|
||
|
if not self.chdir: return
|
||
|
if not self.chdir_lock: return
|
||
|
SCons.Node.FS.default_fs.chdir(self.old_fs_dir, change_os_dir=0)
|
||
|
os.chdir(self.old_os_dir)
|
||
|
self.chdir_lock=None
|
||
|
|
||
|
def execute(self):
|
||
|
if self.executed: return
|
||
|
|
||
|
self.lockchdir()
|
||
|
|
||
|
if self.orenv.has_key('DUMPCONFIG'):
|
||
|
print self.xml()
|
||
|
self.unlockchdir()
|
||
|
self.executed=1
|
||
|
return
|
||
|
|
||
|
self.env = self.orenv.Copy()
|
||
|
|
||
|
if not self.p_localtarget: self.p_localtarget = self.joinpath(self.target)
|
||
|
if not self.p_localsource: self.p_localsource = self.joinpath(self.src)
|
||
|
|
||
|
if (not self.src or len(self.src) == 0) and not self.p_localsource:
|
||
|
self.env.pprint('RED',"no source file given to object - self.src")
|
||
|
self.env.Exit(1)
|
||
|
if not self.target:
|
||
|
self.env.pprint('RED',"no target given to object - self.target")
|
||
|
self.env.Exit(1)
|
||
|
if not self.env.has_key('nosmart_includes'): self.env.AppendUnique(CPPPATH=['./'])
|
||
|
if self.type == "kioslave": self.libprefix=''
|
||
|
|
||
|
if len(self.includes)>0: self.env.AppendUnique(CPPPATH=self.fixpath(self.includes))
|
||
|
if len(self.cxxflags)>0: self.env.AppendUnique(CXXFLAGS=self.env.make_list(self.cxxflags))
|
||
|
if len(self.cflags)>0: self.env.AppendUnique(CCFLAGS=self.env.make_list(self.cflags))
|
||
|
|
||
|
llist=self.env.make_list(self.libs)
|
||
|
lext=['.so', '.la']
|
||
|
sext='.a'.split()
|
||
|
for l in llist:
|
||
|
sal=SCons.Util.splitext(l)
|
||
|
if len(sal)>1:
|
||
|
if sal[1] in lext: self.p_local_shlibs.append(self.fixpath(sal[0]+'.so')[0])
|
||
|
elif sal[1] in sext: self.p_local_staticlibs.append(sal[0]+'.a')
|
||
|
else: self.p_global_shlibs.append(l)
|
||
|
|
||
|
if len(self.p_global_shlibs)>0: self.env.AppendUnique(LIBS=self.p_global_shlibs)
|
||
|
if len(self.libpaths)>0: self.env.PrependUnique(LIBPATH=self.fixpath(self.libpaths))
|
||
|
if len(self.linkflags)>0: self.env.PrependUnique(LINKFLAGS=self.env.make_list(self.linkflags))
|
||
|
if len(self.p_local_shlibs)>0:
|
||
|
self.env.link_local_shlib(self.p_local_shlibs)
|
||
|
if len(self.p_local_staticlibs)>0:
|
||
|
self.env.link_local_staticlib(self.p_local_staticlibs)
|
||
|
|
||
|
# the target to return - no more self.env modification is allowed after this part
|
||
|
ret=None
|
||
|
if self.type=='shlib' or self.type=='kioslave':
|
||
|
ret=self.env.bksys_shlib(self.p_localtarget, self.p_localsource, self.instdir,
|
||
|
self.libprefix, self.vnum)
|
||
|
elif self.type=='program':
|
||
|
ret=self.env.Program(self.p_localtarget, self.p_localsource)
|
||
|
if not self.env.has_key('NOAUTOINSTALL'):
|
||
|
ins=self.env.bksys_install(self.instdir, ret)
|
||
|
if self.perms: self.env.AddPostAction(ins, self.env.Chmod(ins, self.perms))
|
||
|
elif self.type=='staticlib':
|
||
|
ret=self.env.StaticLibrary(self.p_localtarget, self.p_localsource)
|
||
|
|
||
|
# we link the program against a shared library made locally, add the dependency
|
||
|
if len(self.p_local_shlibs)>0:
|
||
|
if ret: self.env.Depends( ret, self.p_local_shlibs )
|
||
|
if len(self.p_local_staticlibs)>0:
|
||
|
if ret: self.env.Depends( ret, self.p_local_staticlibs )
|
||
|
|
||
|
self.unlockchdir()
|
||
|
self.executed=1
|
||
|
|
||
|
## Copy function that honors symlinks
|
||
|
def copy_bksys(dest, source, env):
|
||
|
if os.path.islink(source):
|
||
|
#print "symlinking "+source+" "+dest
|
||
|
if os.path.islink(dest):
|
||
|
os.unlink(dest)
|
||
|
os.symlink(os.readlink(source), dest)
|
||
|
else:
|
||
|
shutil.copy2(source, dest)
|
||
|
st=os.stat(source)
|
||
|
os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
|
||
|
return 0
|
||
|
|
||
|
## Return a list of things
|
||
|
def make_list(env, s):
|
||
|
if type(s) is types.ListType: return s
|
||
|
else:
|
||
|
try: return s.split()
|
||
|
except AttributeError: return s
|
||
|
|
||
|
def join(lenv, s1, s2, s3=None, s4=None):
|
||
|
if s4 and s3: return lenv.join(s1, s2, lenv.join(s3, s4))
|
||
|
if s3 and s2: return lenv.join(s1, lenv.join(s2, s3))
|
||
|
elif not s2: return s1
|
||
|
# having s1, s2
|
||
|
#print "path1 is "+s1+" path2 is "+s2+" "+os.path.join(s1,string.lstrip(s2,'/'))
|
||
|
if not s1: s1="/"
|
||
|
return os.path.join(s1,string.lstrip(s2,'/'))
|
||
|
|
||
|
def exists(env):
|
||
|
return true
|
||
|
|
||
|
def generate(env):
|
||
|
## Bksys requires scons 0.96
|
||
|
env.EnsureSConsVersion(0, 96)
|
||
|
|
||
|
SConsEnvironment.pprint = pprint
|
||
|
SConsEnvironment.make_list = make_list
|
||
|
SConsEnvironment.join = join
|
||
|
SConsEnvironment.dist = dist
|
||
|
SConsEnvironment.getreldir = getreldir
|
||
|
|
||
|
env['HELP']=0
|
||
|
if '--help' in sys.argv or '-h' in sys.argv or 'help' in sys.argv: env['HELP']=1
|
||
|
if env['HELP']:
|
||
|
p=env.pprint
|
||
|
p('BOLD','*** Instructions ***')
|
||
|
p('BOLD','--------------------')
|
||
|
p('BOLD','* scons ','to compile')
|
||
|
p('BOLD','* scons -j4 ','to compile with several instances')
|
||
|
p('BOLD','* scons install ','to compile and install')
|
||
|
p('BOLD','* scons -c install','to uninstall')
|
||
|
p('BOLD','\n*** Generic options ***')
|
||
|
p('BOLD','--------------------')
|
||
|
p('BOLD','* debug ','debug=1 (-g) or debug=full (-g3, slower) else use environment CXXFLAGS, or -O2 by default')
|
||
|
p('BOLD','* prefix ','the installation path')
|
||
|
p('BOLD','* extraincludes','a list of paths separated by ":"')
|
||
|
p('BOLD','* scons configure debug=full prefix=/usr/local extraincludes=/tmp/include:/usr/local')
|
||
|
p('BOLD','* scons install prefix=/opt/local DESTDIR=/tmp/blah\n')
|
||
|
return
|
||
|
|
||
|
## Global cache directory
|
||
|
# Put all project files in it so a rm -rf cache will clean up the config
|
||
|
if not env.has_key('CACHEDIR'): env['CACHEDIR'] = env.join(os.getcwd(),'/cache/')
|
||
|
if not os.path.isdir(env['CACHEDIR']): os.mkdir(env['CACHEDIR'])
|
||
|
|
||
|
## SCons cache directory
|
||
|
# This avoids recompiling the same files over and over again:
|
||
|
# very handy when working with cvs
|
||
|
if os.getuid() != 0: env.CacheDir(os.getcwd()+'/cache/objects')
|
||
|
|
||
|
# Avoid spreading .sconsign files everywhere - keep this line
|
||
|
env.SConsignFile(env['CACHEDIR']+'/scons_signatures')
|
||
|
|
||
|
def makeHashTable(args):
|
||
|
table = { }
|
||
|
for arg in args:
|
||
|
if len(arg) > 1:
|
||
|
lst=arg.split('=')
|
||
|
if len(lst) < 2: continue
|
||
|
key=lst[0]
|
||
|
value=lst[1]
|
||
|
if len(key) > 0 and len(value) >0: table[key] = value
|
||
|
return table
|
||
|
|
||
|
env['ARGS']=makeHashTable(sys.argv)
|
||
|
|
||
|
SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod, lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
|
||
|
|
||
|
## Special trick for installing rpms ...
|
||
|
env['DESTDIR']=''
|
||
|
if 'install' in sys.argv:
|
||
|
dd=''
|
||
|
if os.environ.has_key('DESTDIR'): dd=os.environ['DESTDIR']
|
||
|
if not dd:
|
||
|
if env['ARGS'] and env['ARGS'].has_key('DESTDIR'): dd=env['ARGS']['DESTDIR']
|
||
|
if dd:
|
||
|
env['DESTDIR']=dd
|
||
|
env.pprint('CYAN','** Enabling DESTDIR for the project ** ',env['DESTDIR'])
|
||
|
|
||
|
## install symlinks for shared libraries properly
|
||
|
env['INSTALL'] = copy_bksys
|
||
|
|
||
|
## Use the same extension .o for all object files
|
||
|
env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
|
||
|
|
||
|
## no colors
|
||
|
if os.environ.has_key('NOCOLORS'): env['NOCOLORS']=1
|
||
|
|
||
|
## load the options
|
||
|
cachefile=env['CACHEDIR']+'generic.cache.py'
|
||
|
opts = Options(cachefile)
|
||
|
opts.AddOptions(
|
||
|
( 'GENCCFLAGS', 'C flags' ),
|
||
|
( 'GENCXXFLAGS', 'debug level for the project : full or just anything' ),
|
||
|
( 'GENLINKFLAGS', 'additional link flags' ),
|
||
|
( 'PREFIX', 'prefix for installation' ),
|
||
|
( 'EXTRAINCLUDES', 'extra include paths for the project' ),
|
||
|
( 'ISCONFIGURED', 'is the project configured' ),
|
||
|
)
|
||
|
opts.Update(env)
|
||
|
|
||
|
# Use this to avoid an error message 'how to make target configure ?'
|
||
|
env.Alias('configure', None)
|
||
|
|
||
|
# Check if the following command line arguments have been given
|
||
|
# and set a flag in the environment to show whether or not it was
|
||
|
# given.
|
||
|
if 'install' in sys.argv: env['_INSTALL']=1
|
||
|
else: env['_INSTALL']=0
|
||
|
if 'configure' in sys.argv: env['_CONFIGURE']=1
|
||
|
else: env['_CONFIGURE']=0
|
||
|
|
||
|
# Configure the environment if needed
|
||
|
if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('ISCONFIGURED')):
|
||
|
# be paranoid, unset existing variables
|
||
|
for var in ['GENCXXFLAGS', 'GENCCFLAGS', 'GENLINKFLAGS', 'PREFIX', 'EXTRAINCLUDES', 'ISCONFIGURED', 'EXTRAINCLUDES']:
|
||
|
if env.has_key(var): env.__delitem__(var)
|
||
|
|
||
|
if env['ARGS'].get('debug', None):
|
||
|
debuglevel = env['ARGS'].get('debug', None)
|
||
|
env.pprint('CYAN','** Enabling debug for the project **')
|
||
|
if (debuglevel == "full"): env['GENCXXFLAGS'] = ['-DDEBUG', '-g3', '-Wall']
|
||
|
else: env['GENCXXFLAGS'] = ['-DDEBUG', '-g', '-Wall']
|
||
|
else:
|
||
|
if os.environ.has_key('CXXFLAGS'):
|
||
|
# user-defined flags (gentooers will be elighted)
|
||
|
env['GENCXXFLAGS'] = SCons.Util.CLVar( os.environ['CXXFLAGS'] )
|
||
|
env.Append( GENCXXFLAGS = ['-DNDEBUG', '-DNO_DEBUG'] )
|
||
|
else:
|
||
|
env.Append(GENCXXFLAGS = ['-O2', '-DNDEBUG', '-DNO_DEBUG'])
|
||
|
|
||
|
if os.environ.has_key('CFLAGS'): env['GENCCFLAGS'] = SCons.Util.CLVar( os.environ['CFLAGS'] )
|
||
|
|
||
|
## FreeBSD settings (contributed by will at freebsd dot org)
|
||
|
if os.uname()[0] == "FreeBSD":
|
||
|
if os.environ.has_key('PTHREAD_LIBS'):
|
||
|
env.AppendUnique( GENLINKFLAGS = SCons.Util.CLVar( os.environ['PTHREAD_LIBS'] ) )
|
||
|
else:
|
||
|
syspf = os.popen('/sbin/sysctl kern.osreldate')
|
||
|
osreldate = int(syspf.read().split()[1])
|
||
|
syspf.close()
|
||
|
if osreldate < 500016:
|
||
|
env.AppendUnique( GENLINKFLAGS = ['-pthread'])
|
||
|
env.AppendUnique( GENCXXFLAGS = ['-D_THREAD_SAFE'])
|
||
|
elif osreldate < 502102:
|
||
|
env.AppendUnique( GENLINKFLAGS = ['-lc_r'])
|
||
|
env.AppendUnique( GENCXXFLAGS = ['-D_THREAD_SAFE'])
|
||
|
else:
|
||
|
env.AppendUnique( GENLINKFLAGS = ['-pthread'])
|
||
|
|
||
|
# User-specified prefix
|
||
|
if env['ARGS'].has_key('prefix'):
|
||
|
env['PREFIX'] = os.path.abspath( env['ARGS'].get('prefix', '') )
|
||
|
env.pprint('CYAN','** installation prefix for the project set to:',env['PREFIX'])
|
||
|
|
||
|
# User-specified include paths
|
||
|
env['EXTRAINCLUDES'] = env['ARGS'].get('extraincludes', None)
|
||
|
if env['EXTRAINCLUDES']:
|
||
|
env.pprint('CYAN','** extra include paths for the project set to:',env['EXTRAINCLUDES'])
|
||
|
|
||
|
env['ISCONFIGURED']=1
|
||
|
|
||
|
# And finally save the options in the cache
|
||
|
opts.Save(cachefile, env)
|
||
|
|
||
|
def bksys_install(lenv, subdir, files, destfile=None, perms=None):
|
||
|
""" Install files on 'scons install' """
|
||
|
if not env['_INSTALL']: return
|
||
|
basedir = env['DESTDIR']
|
||
|
install_list=None
|
||
|
if not destfile: install_list = env.Install(lenv.join(basedir,subdir), lenv.make_list(files))
|
||
|
elif subdir: install_list = env.InstallAs(lenv.join(basedir,subdir,destfile), lenv.make_list(files))
|
||
|
else: install_list = env.InstallAs(lenv.join(basedir,destfile), lenv.make_list(files))
|
||
|
if perms and install_list: lenv.AddPostAction(install_list, lenv.Chmod(install_list, perms))
|
||
|
env.Alias('install', install_list)
|
||
|
return install_list
|
||
|
|
||
|
def build_la_file(target, source, env):
|
||
|
""" Writes a .la file, used by libtool """
|
||
|
dest=open(target[0].path, 'w')
|
||
|
sname=source[0].name
|
||
|
dest.write("# Generated by ltmain.sh - GNU libtool 1.5.18 - (pwn3d by bksys)\n#\n#\n")
|
||
|
if len(env['BKSYS_VNUM'])>0:
|
||
|
vnum=env['BKSYS_VNUM']
|
||
|
nums=vnum.split('.')
|
||
|
src=source[0].name
|
||
|
name = src.split('so.')[0] + 'so'
|
||
|
strn = src+" "+name+"."+str(nums[0])+" "+name
|
||
|
dest.write("dlname='%s'\n" % (name+'.'+str(nums[0])) )
|
||
|
dest.write("library_names='%s'\n" % (strn) )
|
||
|
else:
|
||
|
dest.write("dlname='%s'\n" % sname)
|
||
|
dest.write("library_names='%s %s %s'\n" % (sname, sname, sname) )
|
||
|
dest.write("old_library=''\ndependency_libs=''\ncurrent=0\n")
|
||
|
dest.write("age=0\nrevision=0\ninstalled=yes\nshouldnotlink=no\n")
|
||
|
dest.write("dlopen=''\ndlpreopen=''\n")
|
||
|
dest.write("libdir='%s'" % env['BKSYS_DESTDIR'])
|
||
|
dest.close()
|
||
|
return 0
|
||
|
|
||
|
def string_la_file(target, source, env):
|
||
|
print "building '%s' from '%s'" % (target[0].name, source[0].name)
|
||
|
la_file = env.Action(build_la_file, string_la_file, 'BKSYS_VNUM', 'BKSYS_DESTDIR')
|
||
|
env['BUILDERS']['LaFile'] = env.Builder(action=la_file,suffix='.la',src_suffix=env['SHLIBSUFFIX'])
|
||
|
|
||
|
## Function for building shared libraries
|
||
|
def bksys_shlib(lenv, ntarget, source, libdir, libprefix='lib', vnum='', noinst=None):
|
||
|
""" Install a shared library.
|
||
|
|
||
|
Installs a shared library, with or without a version number, and create a
|
||
|
.la file for use by libtool.
|
||
|
|
||
|
If library version numbering is to be used, the version number
|
||
|
should be passed as a period-delimited version number (e.g.
|
||
|
vnum = '1.2.3'). This causes the library to be installed
|
||
|
with its full version number, and with symlinks pointing to it.
|
||
|
|
||
|
For example, for libfoo version 1.2.3, install the file
|
||
|
libfoo.so.1.2.3, and create symlinks libfoo.so and
|
||
|
libfoo.so.1 that point to it.
|
||
|
"""
|
||
|
# parameter can be a list
|
||
|
if type(ntarget) is types.ListType: target=ntarget[0]
|
||
|
else: target=ntarget
|
||
|
|
||
|
thisenv = lenv.Copy() # copying an existing environment is cheap
|
||
|
thisenv['BKSYS_DESTDIR']=libdir
|
||
|
thisenv['BKSYS_VNUM']=vnum
|
||
|
thisenv['SHLIBPREFIX']=libprefix
|
||
|
|
||
|
if len(vnum)>0:
|
||
|
thisenv['SHLIBSUFFIX']='.so.'+vnum
|
||
|
thisenv.Depends(target, thisenv.Value(vnum))
|
||
|
num=vnum.split('.')[0]
|
||
|
lst=target.split('/')
|
||
|
tname=lst[len(lst)-1]
|
||
|
libname=tname.split('.')[0]
|
||
|
thisenv.AppendUnique(LINKFLAGS = ["-Wl,--soname=%s.so.%s" % (libname, num)] )
|
||
|
|
||
|
# Fix against a scons bug - shared libs and ordinal out of range(128)
|
||
|
if type(source) is types.ListType:
|
||
|
src2=[]
|
||
|
for i in source: src2.append( str(i) )
|
||
|
source=src2
|
||
|
|
||
|
library_list = thisenv.SharedLibrary(target, source)
|
||
|
lafile_list = thisenv.LaFile(target, library_list)
|
||
|
|
||
|
## Install the libraries automatically
|
||
|
if not thisenv.has_key('NOAUTOINSTALL') and not noinst:
|
||
|
thisenv.bksys_install(libdir, library_list)
|
||
|
thisenv.bksys_install(libdir, lafile_list)
|
||
|
|
||
|
## Handle the versioning
|
||
|
if len(vnum)>0:
|
||
|
nums=vnum.split('.')
|
||
|
symlinkcom = ('cd $TARGET.dir && rm -f $TARGET.name && ln -s $SOURCE.name $TARGET.name')
|
||
|
tg = target+'.so.'+vnum
|
||
|
nm1 = target+'.so'
|
||
|
nm2 = target+'.so.'+nums[0]
|
||
|
thisenv.Command(nm1, tg, symlinkcom)
|
||
|
thisenv.Command(nm2, tg, symlinkcom)
|
||
|
thisenv.bksys_install(libdir, nm1)
|
||
|
thisenv.bksys_install(libdir, nm2)
|
||
|
return library_list
|
||
|
|
||
|
# Declare scons scripts to process
|
||
|
def subdirs(lenv, folderlist):
|
||
|
flist=lenv.make_list(folderlist)
|
||
|
for i in flist:
|
||
|
lenv.SConscript(lenv.join(i, 'SConscript'))
|
||
|
# take all objects - warn those who are not already executed
|
||
|
if lenv.has_key('USE_THE_FORCE_LUKE'):
|
||
|
for ke in lenv['USE_THE_FORCE_LUKE']:
|
||
|
if ke.executed: continue
|
||
|
#lenv.pprint('GREEN',"you forgot to execute object "+ke.target)
|
||
|
ke.lockworkdir()
|
||
|
ke.execute()
|
||
|
ke.unlockworkdir()
|
||
|
|
||
|
def link_local_shlib(lenv, str):
|
||
|
""" Links against a shared library made in the project """
|
||
|
lst = lenv.make_list(str)
|
||
|
for file in lst:
|
||
|
import re
|
||
|
reg=re.compile("(.*)/lib(.*).(la|so)$")
|
||
|
result=reg.match(file)
|
||
|
if not result:
|
||
|
reg = re.compile("(.*)/lib(.*).(la|so)\.(.)")
|
||
|
result=reg.match(file)
|
||
|
if not result:
|
||
|
print "Unknown la file given "+file
|
||
|
continue
|
||
|
dir = result.group(1)
|
||
|
link = result.group(2)
|
||
|
else:
|
||
|
dir = result.group(1)
|
||
|
link = result.group(2)
|
||
|
|
||
|
lenv.AppendUnique(LIBS = [link])
|
||
|
lenv.PrependUnique(LIBPATH = [dir])
|
||
|
|
||
|
def link_local_staticlib(lenv, str):
|
||
|
""" Links against a shared library made in the project """
|
||
|
lst = lenv.make_list(str)
|
||
|
for file in lst:
|
||
|
import re
|
||
|
reg = re.compile("(.*)/(lib.*.a)")
|
||
|
result = reg.match(file)
|
||
|
if not result:
|
||
|
print "Unknown archive file given "+file
|
||
|
continue
|
||
|
f=SCons.Node.FS.default_fs.File(file)
|
||
|
lenv.Append(LINKFLAGS=[f.path])
|
||
|
|
||
|
def set_build_dir(lenv, dirs, buildto):
|
||
|
lenv.SetOption('duplicate', 'soft-copy')
|
||
|
lenv['_BUILDDIR_']=buildto
|
||
|
ldirs=lenv.make_list(dirs)
|
||
|
for dir in ldirs:
|
||
|
lenv.BuildDir(buildto+os.path.sep+dir, dir)
|
||
|
|
||
|
#valid_targets = "program shlib kioslave staticlib".split()
|
||
|
SConsEnvironment.bksys_install = bksys_install
|
||
|
SConsEnvironment.bksys_shlib = bksys_shlib
|
||
|
SConsEnvironment.subdirs = subdirs
|
||
|
SConsEnvironment.link_local_shlib = link_local_shlib
|
||
|
SConsEnvironment.link_local_staticlib = link_local_staticlib
|
||
|
SConsEnvironment.genobj=genobj
|
||
|
SConsEnvironment.set_build_dir=set_build_dir
|
||
|
|
||
|
if env.has_key('GENCXXFLAGS'): env.AppendUnique( CPPFLAGS = env['GENCXXFLAGS'] )
|
||
|
if env.has_key('GENCCFLAGS'): env.AppendUnique( CCFLAGS = env['GENCCFLAGS'] )
|
||
|
if env.has_key('GENLINKFLAGS'): env.AppendUnique( LINKFLAGS = env['GENLINKFLAGS'] )
|
||
|
|
||
|
if env.has_key('EXTRAINCLUDES'):
|
||
|
if env['EXTRAINCLUDES']:
|
||
|
incpaths = []
|
||
|
for dir in str(env['EXTRAINCLUDES']).split(':'): incpaths.append( dir )
|
||
|
env.Append(CPPPATH = incpaths)
|
||
|
|
||
|
env.Export('env')
|