def generate(env): """ Detect the freetype library """ from SCons.Options import Options cachefile = env['CACHEDIR'] + '/freetype.cache.py' opts = Options(cachefile) opts.AddOptions(('FREETYPE_CPPPATH', 'flags for the SDL_LIBRARY'), ('FREETYPE_LIBPATH', 'flags for the SDL_LIBRARY'), ('FREETYPE_FLAGS', 'flags for the SDL_LIBRARY'), ('FREETYPE_LIBS', 'flags for the SDL_LIBRARY')) opts.Update(env) if 'configure' in env['TARGS'] or not env.has_key('FREETYPE_FLAGS'): from SCons.Environment import Base freetype_env = Base() freetype_env.ParseConfig( 'pkg-config --cflags --libs freetype2 || freetype-config --cflags --libs' ) freetype_cflags = freetype_env.Dictionary()['CCFLAGS'] freetype_include = freetype_env.Dictionary()['CPPPATH'] freetype_libpath = freetype_env.Dictionary()['LIBPATH'] freetype_lib = freetype_env.Dictionary()['LIBS'] env['FREETYPE_FLAGS'] = freetype_cflags env['FREETYPE_LIBS'] = freetype_lib env['FREETYPE_LIBPATH'] = freetype_libpath env['FREETYPE_CPPPATH'] = freetype_include opts.Save(cachefile, env) env.AppendUnique(LIBS=env['FREETYPE_LIBS'], CXXFLAGS=env['FREETYPE_FLAGS'], CCFLAGS=env['FREETYPE_FLAGS'], LIBPATH=env['FREETYPE_LIBPATH'], CPPPATH=env['FREETYPE_CPPPATH'])
def generate(env): # Detect the CEGUI optionfile = env['CACHEDIR'] + 'cegui.cache.py' opts = Options(optionfile) min_ver = "0.4.0" lib_name = "CEGUI-OPENGL" opts.AddOptions( ('CEGUI_FLAGS', 'compilation flags for CEGUI'), ('CEGUI_LDFLAGS', 'link flags for CEGUI'), ('CEGUIISCONFIGURED', 'configuration succeeded'), ) opts.Update(env) if env['HELP']: return # this condition is used to check when to redetect the configuration (do not remove) if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('CEGUIISCONFIGURED')): print "Checking for CEGUI-OPENGL : ", if env.has_key('CEGUIISCONFIGURED'): env.__delitem__('CEGUIISCONFIGURED') # clear options set previously if env.has_key('CEGUI_FLAGS'): env.__delitem__('CEGUI_FLAGS') if env.has_key('CEGUI_LDFLAGS'): env.__delitem__('CEGUI_LDFLAGS') pkgconfig = os.popen( 'command -v pkg-config 2>/dev/null').read().strip() if len(pkgconfig) < 1: env.pprint( 'RED', '[failed] pkg-config not found ! Check your installation.') env.Exit(1) haslib = os.system('pkg-config --exists ' + lib_name) if haslib != 0: env.pprint('RED', '[failed] library not found !') env.Exit(1) lib_version = os.popen('pkg-config --modversion ' + lib_name).read().strip() if lib_version < min_ver: env.pprint( 'RED', '[failed] found ' + lib_version + ' version but >= ' + min_ver + ' is required.') env.Exit(1) env['CEGUI_FLAGS'] = os.popen('pkg-config --cflags ' + lib_name).read().strip() env['CEGUI_LDFLAGS'] = os.popen('pkg-config --libs ' + lib_name).read().strip() # success env['CEGUIISCONFIGURED'] = 1 env.pprint('GREEN', '[ ok ] ' + lib_version) # save the options opts.Save(optionfile, env)
def generate(env): """ Detect the SDL_Image library """ from SCons.Options import Options cachefile = env['CACHEDIR']+'/sdl_image.cache.py' opts = Options(cachefile) opts.AddOptions( ( 'SDL_IMAGE_CPPPATH', 'flags for the SDL_LIBRARY' ), ( 'SDL_IMAGE_LIBPATH', 'flags for the SDL_LIBRARY' ), ) opts.Update(env) if 'configure' in env['TARGS'] or not env.has_key('SDL_IMAGE_CPPPATH'): conf = SCons.SConf.SConf( env ) if not conf.CheckLib('SDL_image', symbol="IMG_Load"): print 'We really need the SDL_image library !' print 'Get SDL_image' import sys sys.exit(1) env['SDL_IMAGE_CPPPATH']=[''] env['SDL_IMAGE_LIBPATH']=[''] opts.Save(cachefile, env) env.AppendUnique(LIBS=['SDL_image'], LIBPATH=env['SDL_IMAGE_LIBPATH'], CPPPATH=env['SDL_IMAGE_CPPPATH'] )
def generate(env): # Detect the FOX optionfile = env['CACHEDIR'] + 'fox1.4.cache.py' opts = Options(optionfile) min_ver = "1.4.16" lib_config = ["fox-config", "fox-config-1.4"] opts.AddOptions( ('FOX_FLAGS', 'compilation flags for FOX'), ('FOX_LDFLAGS', 'link flags for FOX'), ('FOXISCONFIGURED', 'configuration succeeded'), ) opts.Update(env) if env['HELP']: return # this condition is used to check when to redetect the configuration (do not remove) if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('FOXISCONFIGURED')): print "Checking for LibFox 1.4 : ", if env.has_key('FOXISCONFIGURED'): env.__delitem__('FOXISCONFIGURED') # clear options set previously if env.has_key('FOX_FLAGS'): env.__delitem__('FOX_FLAGS') if env.has_key('FOX_LDFLAGS'): env.__delitem__('FOX_LDFLAGS') haslib = '' for prog in lib_config: haslib = os.popen('command -v ' + prog + ' 2>/dev/null').read().strip() if len(haslib) >= 1: break if len(haslib) < 1: env.pprint('RED', '[failed] library not found !') env.Exit(1) lib_version = os.popen(haslib + ' --version').read().strip() if lib_version < min_ver: env.pprint( 'RED', '[failed] found ' + lib_version + ' version but >= ' + min_ver + ' is required.') env.Exit(1) env['FOX_FLAGS'] = os.popen(haslib + ' --cflags').read().strip() env['FOX_LDFLAGS'] = os.popen(haslib + ' --libs').read().strip() # success env['FOXISCONFIGURED'] = 1 env.pprint('GREEN', '[ ok ] ' + lib_version) # save the options opts.Save(optionfile, env)
def generate(env): # Detect OPAL optionfile = env['CACHEDIR'] + 'opal.cache.py' opts = Options(optionfile) opts.AddOptions( ('OPAL_FLAGS', 'compilation flags for OPAL'), ('OPAL_LDFLAGS', 'link flags for OPAL'), ('OPALISCONFIGURED', 'configuration succeeded'), ) opts.Update(env) if env['HELP']: return # this condition is used to check when to redetect the configuration (do not remove) if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('OPALISCONFIGURED')): print "Checking for OPAL : ", if env.has_key('OPALISCONFIGURED'): env.__delitem__('OPALISCONFIGURED') # clear options set previously if env.has_key('OPAL_FLAGS'): env.__delitem__('OPAL_FLAGS') if env.has_key('OPAL_LDFLAGS'): env.__delitem__('OPAL_LDFLAGS') fd_path = env.Dir('#./__library/linux/include/opal').abspath hasfd = os.path.exists(fd_path) if hasfd != True: env.pprint('RED', '[failed] include not found !') env.Exit(1) env['OPAL_FLAGS'] = '-I' + env.Dir('#./__library/linux/include').path fd_path = env.File( '#./__library/linux/lib/opal/libopal-ode.so').abspath hasfd = os.path.exists(fd_path) if hasfd != True: env.pprint('RED', '[failed] library not found !') env.Exit(1) env['OPAL_LDFLAGS'] = '-L' + env.Dir( '#./__library/linux/lib/opal').path + ' -lopal-ode' # success env['OPALISCONFIGURED'] = 1 env.pprint('GREEN', '[ ok ]') # save the options opts.Save(optionfile, env)
def generate(env): if env['DEBUG'] == 0: return # Detect ElectricFence optionfile = env['CACHEDIR']+'efence.cache.py' opts = Options(optionfile) opts.AddOptions( ( 'EFENCE_LDFLAGS', 'link flags for EFENCE' ), ( 'EFENCEISCONFIGURED', 'configuration succeeded' ), ) opts.Update(env) if env['HELP']: return # this condition is used to check when to redetect the configuration (do not remove) if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('EFENCEISCONFIGURED')): print "Checking for ElectricFence : ", if env.has_key('EFENCEISCONFIGURED'): env.__delitem__('EFENCEISCONFIGURED') # clear options set previously if env.has_key('EFENCE_LDFLAGS'): env.__delitem__('EFENCE_LDFLAGS') libs_path = """/usr/lib /usr/local/lib /opt/lib /mingw/lib""".split() library = '' for lib in libs_path: if os.path.exists(lib+'/libefence.so'): library = lib if library == '': env.pprint('RED','[failed] library not found !') env.Exit(1) env['EFENCE_LDFLAGS'] = "-lefence" # success env['EFENCEISCONFIGURED']=1 env.pprint('GREEN', '[ ok ]') # save the options opts.Save(optionfile, env)
def Options(self, *args, **kwds): """ Add each tool options """ opts = Options(*args, **kwds) self.UpdateOptions(opts) return opts
def generate(env): # Detect the Lua 5.0 optionfile = env['CACHEDIR'] + 'lua50.cache.py' opts = Options(optionfile) lib_config = "lua-config" opts.AddOptions( ('LUA50_FLAGS', 'compilation flags for LUA50'), ('LUA50_LDFLAGS', 'link flags for LUA50'), ('LUA50ISCONFIGURED', 'configuration succeeded'), ) opts.Update(env) if env['HELP']: return # this condition is used to check when to redetect the configuration (do not remove) if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('LUA50ISCONFIGURED')): print "Checking for Lua 5.0 : ", if env.has_key('LUA50ISCONFIGURED'): env.__delitem__('LUA50ISCONFIGURED') # clear options set previously if env.has_key('LUA50_FLAGS'): env.__delitem__('LUA50_FLAGS') if env.has_key('LUA50_LDFLAGS'): env.__delitem__('LUA50_LDFLAGS') haslib = os.popen('command -v ' + lib_config + ' 2>/dev/null').read().strip() if len(haslib) < 1: env.pprint('RED', '[failed] library not found !') env.Exit(1) env['LUA50_FLAGS'] = os.popen(lib_config + ' --include').read().strip() env['LUA50_LDFLAGS'] = os.popen(lib_config + ' --libs').read().strip() # success env['LUA50ISCONFIGURED'] = 1 env.pprint('GREEN', '[ ok ] ') # save the options opts.Save(optionfile, env)
def generate(env): """ Detect the cg library (nvidia) """ from SCons.Options import Options cachefile = env['CACHEDIR'] + '/cg.cache.py' opts = Options(cachefile) opts.AddOptions(('HASCG', 'has the cg library'), ) opts.Update(env) if 'configure' in env['TARGS'] or not env.has_key('HASCG'): import SCons.SConf conf = SCons.SConf.SConf(env) if not conf.CheckCHeader('Cg/cg.h'): print 'We really need the cg library !' print 'Get ftp://download.nvidia.com/developer/cg/Cg_1.3/Linux/Cg-1.3.0501-0700.i386.tar.gz and unpack it in your root directory' import sys sys.exit(1) env['HASCG'] = 1 env = conf.Finish() opts.Save(cachefile, env) env.AppendUnique(LIBS=['Cg', 'CgGL', 'GL'])
def generate(env): """ Detect the SDL library """ from SCons.Options import Options cachefile = env['CACHEDIR']+'/sdl.cache.py' opts = Options(cachefile) opts.AddOptions( ( 'SDL_CPPPATH', 'flags for the SDL_LIBRARY' ), ( 'SDL_LIBPATH', 'flags for the SDL_LIBRARY' ), ( 'SDL_FLAGS', 'flags for the SDL_LIBRARY' ), ( 'SDL_LIBS', 'flags for the SDL_LIBRARY' ) ) opts.Update(env) if 'configure' in env['TARGS'] or not env.has_key('SDL_FLAGS'): from SCons.Environment import Base sdl_env = Base() sdl_env.ParseConfig('sdl-config --cflags --libs') sdl_cflags = sdl_env.Dictionary()['CCFLAGS'] sdl_include = sdl_env.Dictionary()['CPPPATH'] sdl_libpath = sdl_env.Dictionary()['LIBPATH'] sdl_lib = sdl_env.Dictionary()['LIBS'] # conf = SCons.SConf.SConf( env ) # if not conf.CheckCHeader('Cg/cg.h'): # print 'We really need the cg library !' # print 'Get ftp://download.nvidia.com/developer/cg/Cg_1.3/Linux/Cg-1.3.0501-0700.i386.tar.gz and unpack it in your root directory' # import sys # sys.exit(1) env['SDL_FLAGS']=sdl_cflags env['SDL_LIBS']=sdl_lib env['SDL_LIBPATH']=sdl_libpath env['SDL_CPPPATH']=sdl_include opts.Save(cachefile, env) env.AppendUnique(LIBS=env['SDL_LIBS'], CXXFLAGS=env['SDL_FLAGS'], CCFLAGS=env['SDL_FLAGS'], LIBPATH=env['SDL_LIBPATH'], CPPPATH=env['SDL_CPPPATH'] )
def generate(env): # Detect the FastDelegate optionfile = env['CACHEDIR'] + 'fastdelegate.cache.py' opts = Options(optionfile) opts.AddOptions( ('FastDelegate_FLAGS', 'compilation flags for FastDelegate'), ('FastDelegateISCONFIGURED', 'configuration succeeded'), ) opts.Update(env) if env['HELP']: return # this condition is used to check when to redetect the configuration (do not remove) if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('FastDelegateISCONFIGURED')): print "Checking for FastDelegate : ", if env.has_key('FastDelegateISCONFIGURED'): env.__delitem__('FastDelegateISCONFIGURED') # clear options set previously if env.has_key('FastDelegate_FLAGS'): env.__delitem__('FastDelegate_FLAGS') fd_path = env.Dir('#./__library/common/').abspath hasfd = os.path.exists(fd_path) if hasfd != True: env.pprint('RED', '[failed]') env.Exit(1) env['FastDelegate_FLAGS'] = '-I' + fd_path # success env['FastDelegateISCONFIGURED'] = 1 env.pprint('GREEN', '[ ok ] path is ' + fd_path) # save the options opts.Save(optionfile, env)
def generate(env): """ Detect the openGL library """ from SCons.Options import Options cachefile = env['CACHEDIR'] + '/opengl.cache.py' opts = Options(cachefile) opts.AddOptions(('HASGL', 'has the openGL library'), ) opts.Update(env) if 'configure' in env['TARGS'] or not env.has_key('HASGL'): import SCons.SConf conf = SCons.SConf.SConf(env) if not conf.CheckCHeader('GL/gl.h'): print 'We really need the openGL library !' import sys sys.exit(1) env['HASGL'] = 1 env = conf.Finish() opts.Save(cachefile, env) env.AppendUnique(LIBS=['GL', 'GLU'], LIBPATH=['/usr/lib', '/usr/X11R6/lib'], CPPPATH=['/usr/include', '/usr/X11R6/include'])
def __call__(self, env, *args, **kw): if self.init_kw is not None: # Merge call kws into init kws; # but don't bash self.init_kw. if kw is not None: call_kw = kw kw = self.init_kw.copy() kw.update(call_kw) else: kw = self.init_kw env.Append(TOOLS=[self.name]) if hasattr(self, 'options'): from SCons.Options import Options if not env.has_key('options'): from SCons.Script import ARGUMENTS env['options'] = Options(args=ARGUMENTS) opts = env['options'] self.options(opts) opts.Update(env) apply(self.generate, (env, ) + args, kw)
def generate(env): # We break unitsync if the filename of the shared object has a 'lib' prefix. # It is also nicer for the AI shared objects. env['LIBPREFIX'] = '' # I don't see any reason to make this configurable --tvo. # Note that commenting out / setting this to `None' will break the buildsystem. env['builddir'] = 'build' # SCons chokes in env.SConsignFile() if path doesn't exist. if not os.path.exists(env['builddir']): os.makedirs(env['builddir']) # Avoid spreading .sconsign files everywhere - keep this line # Use os.path.abspath() here because somehow the argument to SConsignFile is relative to the # directory of the toplevel trunk/SConstruct and not the current directory, trunk/rts/SConstruct. env.SConsignFile( os.path.abspath(os.path.join(env['builddir'], 'scons_signatures'))) usrcachefile = os.path.join(env['builddir'], 'usropts.py') intcachefile = os.path.join(env['builddir'], 'intopts.py') usropts = Options(usrcachefile) intopts = Options(intcachefile) #user visible options usropts.AddOptions( #permanent options ('platform', 'Set to linux, freebsd or windows', None), ('debug', 'Set to yes to produce a binary with debug information', 0), ('optimize', 'Enable processor optimizations during compilation', 1), ('profile', 'Set to yes to produce a binary with profiling information', False), ('prefix', 'Install prefix', '/usr/local'), ('datadir', 'Data directory', '$prefix/games/taspring'), ('strip', 'Discard symbols from the executable (only when neither debugging nor profiling)', True), #porting options - optional in a first phase ('disable_avi', 'Set to no to turn on avi support', True), ('disable_clipboard', 'Set to no to turn on clipboard code', True), #other ported parts ('disable_lua', 'Set to no to turn on Lua support', True), ('use_tcmalloc', 'Use tcmalloc from goog-perftools for memory allocation', False), ('use_mmgr', 'Use memory manager', False), ('cachedir', 'Cache directory (see scons manual)', None)) #internal options intopts.AddOptions( ('LINKFLAGS', 'linker flags'), ('LIBPATH', 'library path'), ('LIBS', 'libraries'), ('CCFLAGS', 'c compiler flags'), ('CXXFLAGS', 'c++ compiler flags'), ('CPPDEFINES', 'c preprocessor defines'), ('CPPPATH', 'c preprocessor include path'), ('CC', 'c compiler'), ('CXX', 'c++ compiler'), ('is_configured', 'configuration version stamp')) usropts.Update(env) intopts.Update(env) env.Help(usropts.GenerateHelpText(env)) # Use this to avoid an error message 'how to make target configure ?' env.Alias('configure', None) if not 'configure' in sys.argv and not ( (env.has_key('is_configured') and env['is_configured'] == 1) or env.GetOption('clean')): print "Not configured or configure script updated. Run `scons configure' first." print "Use `scons --help' to show available configure options to `scons configure'." env.Exit(1) if 'configure' in sys.argv: # be paranoid, unset existing variables for key in [ 'platform', 'debug', 'optimize', 'profile', 'prefix', 'datadir', 'cachedir', 'strip', 'disable_avi', 'disable_lua', 'disable_aio', 'use_tcmalloc', 'use_mmgr', 'LINKFLAGS', 'LIBPATH', 'LIBS', 'CCFLAGS', 'CXXFLAGS', 'CPPDEFINES', 'CPPPATH', 'is_configured' ]: if env.has_key(key): env.__delitem__(key) print "\nNow configuring. If something fails, consult `config.log' for details.\n" #parse cmdline 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 args = makeHashTable(sys.argv) env['is_configured'] = 1 if args.has_key('platform'): env['platform'] = args['platform'] else: env['platform'] = detect.platform() fix_windows_spawn(env) if os.environ.has_key('CC'): env['CC'] = os.environ['CC'] if os.environ.has_key('CXX'): env['CXX'] = os.environ['CXX'] gcc_version = config.check_gcc_version(env) # Declare some helper functions for boolean and string options. def bool_opt(key, default): if args.has_key(key): if args[key] == 'no' or args[key] == 'false' or args[ key] == '0': env[key] = False elif args[key] == 'yes' or args[key] == 'true' or args[ key] == '1': env[key] = True else: print "\ninvalid", key, "option, must be one of: yes, true, no, false, 0, 1." env.Exit(1) else: env[key] = default def string_opt(key, default): if args.has_key(key): env[key] = args[key] else: env[key] = default # start with empty FLAGS, in case everything is disabled. env['CCFLAGS'] = [] # profile? bool_opt('profile', False) if env['profile']: print "profiling enabled,", env.AppendUnique(CCFLAGS=['-pg'], LINKFLAGS=['-pg']) else: print "profiling NOT enabled,", # debug? if args.has_key('debug'): level = args['debug'] if level == 'no' or level == 'false': level = '0' elif level == 'yes' or level == 'true': level = '3' else: level = '0' if int(level) == 0: print "debugging NOT enabled,", env['debug'] = 0 elif int(level) >= 1 and int(level) <= 3: print "level", level, "debugging enabled,", env['debug'] = level # MinGW gdb chokes on the dwarf debugging format produced by '-ggdb', # so use the more generic '-g' instead. if env['platform'] == 'windows': env.AppendUnique(CCFLAGS=['-g'], CPPDEFINES=['DEBUG', '_DEBUG']) else: env.AppendUnique(CCFLAGS=['-ggdb' + level], CPPDEFINES=['DEBUG', '_DEBUG']) else: print "\ninvalid debug option, must be one of: yes, true, no, false, 0, 1, 2, 3." env.Exit(1) # optimize? if args.has_key('optimize'): level = args['optimize'] if level == 'no' or level == 'false': level = '0' elif level == 'yes' or level == 'true': level = '2' else: if env['debug']: level = '0' else: level = '1' if level == 's' or level == 'size' or (int(level) >= 1 and int(level) <= 3): print "level", level, "optimizing enabled" env['optimize'] = level archflags = detect.processor(gcc_version >= ['3', '4', '0']) env.AppendUnique(CCFLAGS=['-O' + level, '-pipe'] + archflags) elif int(level) == 0: print "optimizing NOT enabled,", env['optimize'] = 0 else: print "\ninvalid optimize option, must be one of: yes, true, no, false, 0, 1, 2, 3, s, size." env.Exit(1) # it seems only gcc 4.0 and higher supports this if gcc_version >= ['4', '0', '0']: env['CCFLAGS'] += ['-fvisibility=hidden'] env['CXXFLAGS'] = env['CCFLAGS'] # This is broken, first, scons passes it to .c files compilation too (which is an error), # second, linking of a shared object fails with: # /usr/bin/ld: build/tools/unitsync/unitsync.os: relocation R_X86_64_PC32 against `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()@@GLIBCXX_3.4' can not be used when making a shared object; recompile with -fPIC # Even though -fPIC was passed on compilation of each object. #env['CXXFLAGS'] += ['-fvisibility-inlines-hidden'] # fall back to environment variables if neither debug nor optimize options are present if not args.has_key('debug') and not args.has_key('optimize'): if os.environ.has_key('CFLAGS'): print "using CFLAGS:", os.environ['CFLAGS'] env['CCFLAGS'] = SCons.Util.CLVar(os.environ['CFLAGS']) if os.environ.has_key('CXXFLAGS'): print "using CXXFLAGS:", os.environ['CXXFLAGS'] env['CXXFLAGS'] = SCons.Util.CLVar(os.environ['CXXFLAGS']) else: env['CXXFLAGS'] = env['CCFLAGS'] bool_opt('strip', True) bool_opt('disable_avi', True) bool_opt('disable_clipboard', True) bool_opt('disable_lua', True) bool_opt('use_tcmalloc', False) bool_opt('use_mmgr', False) string_opt('prefix', '/usr/local') string_opt('datadir', '$prefix/games/taspring') string_opt('cachedir', None) defines = ['_REENTRANT', 'DIRECT_CONTROL_ALLOWED', '_SZ_ONE_DIRECTORY'] #Don't define this: it causes a full recompile when you change it, even though it is only used in Main.cpp, #and some AIs maybe. Just make exceptions in SConstruct. #defines += ['SPRING_DATADIR="\\"'+env['datadir']+'\\""'] if env['disable_clipboard']: defines += ['NO_CLIPBOARD'] if env['disable_avi']: defines += ['NO_AVI'] if env['disable_lua']: defines += ['NO_LUA'] if env['use_mmgr']: defines += ['USE_MMGR'] env.AppendUnique(CPPDEFINES=defines) include_path = ['rts', 'rts/System'] lib_path = [] if env['platform'] == 'freebsd': include_path += [ '/usr/local/include', '/usr/X11R6/include', '/usr/X11R6/include/GL' ] lib_path += ['/usr/local/lib', '/usr/X11R6/lib'] env.AppendUnique(CCFLAGS=['-pthread'], CXXFLAGS=['-pthread']) elif env['platform'] == 'linux': include_path += ['/usr/include', '/usr/include/GL'] env.AppendUnique(CCFLAGS=['-pthread'], CXXFLAGS=['-pthread'], LINKFLAGS=['-Wl,-E']) elif env['platform'] == 'darwin': include_path += [ '/usr/include', '/usr/local/include', '/opt/local/include', '/usr/X11R6/include' ] lib_path += ['/opt/local/lib', '/usr/local/lib'] env['SHLINKFLAGS'] = '$LINKFLAGS -dynamic' env['SHLIBSUFFIX'] = '.dylib' elif env['platform'] == 'windows': include_path += ['mingwlibs\\include'] lib_path += ['mingwlibs\\lib'] if os.environ.has_key('MINGDIR'): include_path += [ os.path.join(os.environ['MINGDIR'], 'include') ] lib_path += [os.path.join(os.environ['MINGDIR'], 'lib')] else: print 'ERROR: MINGDIR environment variable not set and MSVC build unsupported.' print 'Set it to your Dev-Cpp or MinGW install directory (e.g. C:\\Dev-Cpp) and try again.' env.Exit(1) env.AppendUnique(CCFLAGS=['-mthreads'], CXXFLAGS=['-mthreads'], LINKFLAGS=['-mwindows']) # use '-pthreads' for Solaris, according to /usr/include/boost/config/requires_threads.hpp env.AppendUnique(CPPPATH=include_path, LIBPATH=lib_path) config.configure(env, conf_dir=os.path.join(env['builddir'], 'sconf_temp')) usropts.Save(usrcachefile, env) intopts.Save(intcachefile, env) #Should we strip the exe? if env.has_key('strip') and env['strip'] and not env['debug'] and not env[ 'profile'] and not env.GetOption('clean'): env['strip'] = True else: env['strip'] = False #BuildDir support code if env['builddir']: for d in filelist.list_directories(env, 'rts'): env.BuildDir(os.path.join(env['builddir'], d), d, duplicate=False) env.BuildDir(os.path.join(env['builddir'], 'tools/unitsync'), 'tools/unitsync', duplicate=False) for d in filelist.list_directories(env, 'AI'): env.BuildDir(os.path.join(env['builddir'], d), d, duplicate=False) #CacheDir support code if env.has_key('cachedir') and env['cachedir']: if not os.path.exists(env['cachedir']): os.makedirs(env['cachedir']) env.CacheDir(env['cachedir']) fix_windows_spawn(env)
def GetBuildEnvironment(targets,arguments): env = Environment(); env.EnsurePythonVersion(2,3) env.EnsureSConsVersion(0,96) env.SetOption('implicit_cache',1) env.TargetSignatures('build') if 'mode' in arguments: buildname = arguments['mode'] else: buildname = 'default' options_file = '.' + buildname + '_options' if not exists(options_file): opts = Options('.options_cache',arguments) else: opts = Options(options_file,arguments) opts.AddOptions( BoolOption('assertions','Include assertions in the code',1), BoolOption('debug','Build with debug options turned on',1), BoolOption('inline','Cause inline code to be inline',0), BoolOption('optimize','Build object files with optimization',0), BoolOption('profile','Generate profiling aware code',0), BoolOption('small','Generate smaller code rather than faster',0), BoolOption('strip','Strip executables of their symbols',0), ) opts.Add('confpath','Specify additional configuration dirs to search','') opts.Add('prefix','Specify where to install HLVM','/usr/local') opts.Add('suites','Specify a list of test suites to run') opts.Add('with_llvm','Specify where LLVM is located','/usr/local') opts.Add('with_apr','Specify where apr is located','/usr/local/apr') opts.Add('with_apru','Specify where apr-utils is located','/usr/local/apr') opts.Add('with_libxml2','Specify where LibXml2 is located','/usr/local') opts.Add('with_gxx','Specify where the GCC C++ compiler is located', '/usr/local/bin/g++') opts.Add('with_llc','Specify where the LLVM compiler is located', '/usr/local/bin/llc') opts.Add('with_llvm_ld','Specify where the LLVM GCC Linker is located', '/usr/local/bin/llvm-ld') opts.Add('with_llvmdis','Specify where the LLVM disassembler is located', '/usr/local/bin/llvm-dis') opts.Add('with_llvmas','Specify where the LLVM assembler is located', '/usr/local/bin/llvm-as') opts.Add('with_llvmgcc','Specify where the LLVM C compiler is located', '/usr/local/bin/llvm-gcc') opts.Add('with_llvmgxx','Specify where the LLVM C++ compiler is located', '/usr/local/bin/llvm-g++') opts.Add('with_llvmar','Specify where the LLVM bytecode archiver is located', '/usr/local/bin/llvm-g++') opts.Add('with_llvm2cpp','Specify where the LLVM llvm2cpp program is located', '/usr/local/bin/llvm2cpp') opts.Add('with_gperf','Specify where the gperf program is located', '/usr/local/bin/gperf') opts.Add('with_runtest','Specify where DejaGnu runtest program is located', '/usr/local/bin/runtest') opts.Add('with_doxygen','Specify where the doxygen program is located', '/usr/local/bin/doxygen') opts.Add('with_xsltproc','Specify where the XSLT processor is located', '/usr/local/bin/xsltproc') opts.Add('with_pod2html','Specify where the POD to HTML generator is located', '/usr/local/bin/pod2html') opts.Add('with_pod2man','Specify where the POD to MAN generator is located', '/usr/local/bin/pod2man') opts.Add('with_xmllint','Specify where the xmllint program is located', '/usr/local/bin/xmllint') opts.Update(env) env['HLVM_Copyright'] = 'Copyright (c) 2006 Reid Spencer' env['HLVM_Maintainer'] = 'Reid Spencer <rspencer@reidspencer>' env['HLVM_Version'] = '0.2svn' env['HLVM_SO_CURRENT'] = '0' env['HLVM_SO_REVISION'] = '1' env['HLVM_SO_AGE'] = '0' env['HLVM_SO_VERSION'] = env['HLVM_SO_CURRENT']+':'+env['HLVM_SO_REVISION'] env['HLVM_SO_VERSION'] += ':' + env['HLVM_SO_AGE'] env['CCFLAGS'] = ' -pipe -Wall -Wcast-align -Wpointer-arith -Wno-long-long' env['CCFLAGS'] += ' -pedantic' env['CXXFLAGS'] = ' -pipe -Wall -Wcast-align -Wpointer-arith -Wno-deprecated' env['CXXFLAGS']+= ' -Wold-style-cast -Woverloaded-virtual -Wno-unused' env['CXXFLAGS']+= ' -Wno-long-long -pedantic -fno-operator-names -ffor-scope' env['CXXFLAGS']+= ' -fconst-strings' env['CPPDEFINES'] = { '__STDC_LIMIT_MACROS':None, '_GNU_SOURCE':None } VariantName='' if env['small'] == 1: VariantName='S' env.Append(CCFLAGS=' -Os') env.Append(CXXFLAGS=' -Os') else : VariantName='s' if env['profile'] == 1: VariantName+='P' env.Append(CCFLAGS=' -pg') env.Append(CXXFLAGS=' -pg') else : VariantName+='p' if env['assertions'] == 1: VariantName+='A' env.Append(CPPDEFINES={'HLVM_ASSERT':None}) else : VariantName+='a' if env['debug'] == 1 : VariantName += 'D' env.Append(CCFLAGS=' -ggdb') env.Append(CXXFLAGS=' -ggdb') env.Append(CPPDEFINES={'HLVM_DEBUG':None}) env.Append(LINKFLAGS='-ggdb') else : VariantName+='d' if env['inline'] == 1: VariantName+='I' else : VariantName+='i' env.Append(CXXFLAGS=' -fno-inline') if env['optimize'] == 1 : VariantName+='O' env.Append(CCFLAGS=' -O3') env.Append(CXXFLAGS=' -O3') env.Append(LINKFLAGS='-O3') else : VariantName+='o' if env['strip']: VariantName +='T' env['LINKFLAGS'] += ' -s' else: VariantName += 't' BuildDir = buildname env['Variant'] = VariantName env['BuildDir'] = BuildDir env['AbsObjRoot'] = env.Dir('#' + BuildDir).abspath env['AbsSrcRoot'] = env.Dir('#').abspath env.Prepend(CPPPATH=[pjoin('#',BuildDir)]) env.Prepend(CPPPATH=['#']) env['LIBPATH'] = [] env['BINPATH'] = [] env['LLVMASFLAGS'] = '' env['LLVM2CPPFLAGS'] = '' env['LLVMGXXFLAGS'] = '' env['LLVMGCCFLAGS'] = '' env.BuildDir(BuildDir,'#',duplicate=0) env.SConsignFile(pjoin(BuildDir,'sconsign')) if 'install' in COMMAND_LINE_TARGETS: env.Alias('install',[ env.Dir(pjoin(env['prefix'],'bin')), env.Dir(pjoin(env['prefix'],'lib')), env.Dir(pjoin(env['prefix'],'include')), env.Dir(pjoin(env['prefix'],'docs')) ]) env.Help(""" HLVM Build Environment Usage Examples:: scons - to do a normal build scons --clean - to remove all derived (built) objects scons check - to run the DejaGnu test suite scons install - to install HLVM to a target directory scons docs - to generate the doxygen documentation Options: """ + opts.GenerateHelpText(env,sort=cmp)) print "HLVM BUILD MODE: " + VariantName + " (" + buildname + ")" ConfigureHLVM(env) now = datetime.datetime.utcnow(); env['HLVM_ConfigTime'] = now.ctime(); opts.Save(options_file,env) return env
def generate(env): ## Bksys requires scons 0.96 env.EnsureSConsVersion(0, 96) import sys env['HELP'] = 0 if '--help' in sys.argv or '-h' in sys.argv or 'help' in sys.argv: env['HELP'] = 1 if env['HELP']: print """ """ + BOLD + """*** Generic options *** -----------------------""" + NORMAL + """ """ + BOLD + """* debug """ + NORMAL + """: debug=1 (-g) or debug=full (-g3, slower) else use environment CXXFLAGS, or -O2 by default """ + BOLD + """* prefix """ + NORMAL + """: the installation path """ + BOLD + """* extraincludes """ + NORMAL + """: a list of paths separated by ':' ie: """ + BOLD + """scons configure debug=full prefix=/usr/local extraincludes=/tmp/include:/usr/local """ + NORMAL ## 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'] = 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 env.CacheDir(os.getcwd() + '/cache/objects') ## Avoid spreading .sconsign files everywhere - keep this line env.SConsignFile(env['CACHEDIR'] + '/scons_signatures') # Special trick for installing rpms ... env['DESTDIR'] = '' if 'install' in sys.argv and os.environ.has_key('DESTDIR'): env['DESTDIR'] = os.environ['DESTDIR'] + '/' print CYAN + '** Enabling DESTDIR for the project ** ' + NORMAL + env[ 'DESTDIR'] # load the options from SCons.Options import Options, PathOption cachefile = env['CACHEDIR'] + 'generic.cache.py' opts = Options(cachefile) opts.AddOptions( ('KDECCFLAGS', 'C flags'), ('KDECXXFLAGS', 'debug level for the project : full or just anything'), ('KDELINKFLAGS', '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) import SCons.Util 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')): import re 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) # be paranoid, unset existing variables if env.has_key('KDECXXFLAGS'): env.__delitem__('KDECXXFLAGS') if env.has_key('KDECCFLAGS'): env.__delitem__('KDECCFLAGS') if env.has_key('KDELINKFLAGS'): env.__delitem__('KDELINKFLAGS') if env.has_key('PREFIX'): env.__delitem__('PREFIX') if env.has_key('EXTRAINCLUDES'): env.__delitem__('EXTRAINCLUDES') if env.has_key('ISCONFIGURED'): env.__delitem__('ISCONFIGURED') if env['ARGS'].get('debug', None): debuglevel = env['ARGS'].get('debug', None) print CYAN + '** Enabling debug for the project **' + NORMAL if (debuglevel == "full"): env['KDECXXFLAGS'] = ['-DDEBUG', '-g3'] else: env['KDECXXFLAGS'] = ['-DDEBUG', '-g'] else: if os.environ.has_key('CXXFLAGS'): # user-defined flags (gentooers will be elighted) env['KDECXXFLAGS'] = SCons.Util.CLVar(os.environ['CXXFLAGS']) env.Append(KDECXXFLAGS=['-DNDEBUG', '-DNO_DEBUG']) else: env.Append(KDECXXFLAGS=['-O2', '-DNDEBUG', '-DNO_DEBUG']) if os.environ.has_key('CFLAGS'): env['KDECCFLAGS'] = 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( KDELINKFLAGS=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(KDELINKFLAGS=['-pthread']) env.AppendUnique(KDECXXFLAGS=['-D_THREAD_SAFE']) elif osreldate < 502102: env.AppendUnique(KDELINKFLAGS=['-lc_r']) env.AppendUnique(KDECXXFLAGS=['-D_THREAD_SAFE']) else: env.AppendUnique(KDELINKFLAGS=['-pthread']) # User-specified prefix if env['ARGS'].get('prefix', None): env['PREFIX'] = env['ARGS'].get('prefix', None) print CYAN + '** set the installation prefix for the project : ' + env[ 'PREFIX'] + ' **' + NORMAL elif env.has_key('PREFIX'): env.__delitem__('PREFIX') # User-specified include paths env['EXTRAINCLUDES'] = env['ARGS'].get('extraincludes', None) if env['ARGS'].get('extraincludes', None): print CYAN + '** set extra include paths for the project : ' + env[ 'EXTRAINCLUDES'] + ' **' + NORMAL elif env.has_key('EXTRAINCLUDES'): env.__delitem__('EXTRAINCLUDES') env['ISCONFIGURED'] = 1 # And finally save the options in the cache opts.Save(cachefile, env) if env.has_key('KDECXXFLAGS'): env.AppendUnique(CPPFLAGS=env['KDECXXFLAGS']) if env.has_key('KDECCFLAGS'): env.AppendUnique(CCFLAGS=env['KDECCFLAGS']) if env.has_key('KDELINKFLAGS'): env.AppendUnique(LINKFLAGS=env['KDELINKFLAGS']) if env.has_key('EXTRAINCLUDES'): incpaths = [] for dir in str(env['EXTRAINCLUDES']).split(':'): incpaths.append(dir) env.Append(CPPPATH=incpaths) env.Export("env")
def generate(env): if env['HELP']: p = env.pprint p("BOLD", "*** Pkgconfig Options ***") p("BOLD", "--------------------") p( "BOLD", "* pcfile_path ", ": where pc files should be installed into, $libdir/pkgconfig by default" ) print " ie.", p("BOLD", "scons install pcfile_path=/usr/lib64/pkgconfig") return import SCons.Util, os REQUIRED_LIBSCIM_VERSION = env['REQUIRED_LIBSCIM_VERSION'] # the following two functions are used to detect the packages using pkg-config - scons feature def Check_pkg_config(context, version): context.Message('Checking for pkg-config : ') PKGCONFIG = 'pkg-config' if os.environ.has_key("PKG_CONFIG"): PKGCONFIG = os.environ["PKG_CONFIG"] default_include = "/usr/local/lib/pkgconfig" if os.environ.has_key("PKG_CONFIG_PATH"): os.environ["PKG_CONFIG_PATH"] = os.environ[ "PKG_CONFIG_PATH"] + ":" + default_include else: os.environ["PKG_CONFIG_PATH"] = default_include PKGCONFIG = "PKG_CONFIG_PATH=" + os.environ[ "PKG_CONFIG_PATH"] + " " + PKGCONFIG ret = context.TryAction(PKGCONFIG + ' --atleast-pkgconfig-version=%s' % version)[0] if (ret): env['PKGCONFIG'] = PKGCONFIG context.Result(GREEN + " Found" + NORMAL) else: context.Result(RED + " Not Found" + NORMAL) return ret def PKGcheckmodules(env, context, varname, pattern): context.Message('Checking for %s ... ' % (pattern)) pkg_config_command = env['PKGCONFIG'] ret = context.TryAction(pkg_config_command + ' --exists "%s"' % (pattern))[0] if ret: #env.ParseConfig(pkg_config_command+' %s --cflags --libs' % module); env[varname + '_CFLAGS'] = \ SCons.Util.CLVar( os.popen(pkg_config_command+' "%s" --cflags 2>/dev/null' % pattern).read().strip() ) env[varname + '_LIBS'] = \ SCons.Util.CLVar( os.popen(pkg_config_command+' "%s" --libs 2>/dev/null' % pattern).read().strip() ) context.Result(GREEN + " Found" + NORMAL) else: context.Result(RED + " Not Found" + NORMAL) return ret if env['HELP']: return # these are our options from SCons.Options import Options, PathOption cachefile = env['CACHEDIR'] + '/pkg.cache.py' opts = Options(cachefile) opts.AddOptions( ('PKGCONFIG_ISCONFIGURED', 'whether it is necessary to run configure or not'), ('PKGCONFIG', 'The command of pkg-config'), ('PCFILE_PATH', 'where to install pc files'), ) opts.Update(env) # detect the scim packages when needed if not env.has_key('PKGCONFIG_ISCONFIGURED'): conf = env.Configure( custom_tests={'Check_pkg_config': Check_pkg_config}) # delete the cached variables for var in "PKGCONFIG_ISCONFIGURED PKGCONFIG PCFILE_PATH".split(): if env.has_key(var): env.__delitem__(var) REQUIRE_PKGCONFIG_VERSION = '0.15' if not conf.Check_pkg_config(REQUIRE_PKGCONFIG_VERSION): print 'pkg-config >= ' + PKGCONFIG_VERSION + ' not found.' print 'Make sure it is in your path, or set the ' print 'PKG_CONFIG environment variable to the ' print 'full path to pkg-config.' env.Exit(1) env = conf.Finish() env['PKGCONFIG_ISCONFIGURED'] = 1 env['PCFILE_PATH'] = '' if env.has_key('ARGS'): env['PCFILE_PATH'] = env['ARGS'].get('pcfile_path', '') if len(env['PCFILE_PATH']) == 0: def getpath(varname): if not env.has_key('ARGS'): return None v = env['ARGS'].get(varname, None) if v: v = os.path.abspath(v) return v libdir = getpath('libdir') libsuffix = '' if env.has_key('ARGS'): libsuffix = env['ARGS'].get('libsuffix', '') if libdir: libdir = libdir + libsuffix else: libdir = env['ARGS'].get('execprefix', env['ARGS'].get( 'prefix', '/usr')) + "/lib" + libsuffix env['PCFILE_PATH'] = os.path.join(libdir, 'pkgconfig') # store the config opts.Save(cachefile, env) # Attach the functions to the environment so that sconscripts or other modules can use them from SCons.Script.SConscript import SConsEnvironment SConsEnvironment.PKGcheckmodules = PKGcheckmodules
def generate(env): # Detect ToLua++ optionfile = env['CACHEDIR'] + 'tolua++.cache.py' opts = Options(optionfile) opts.AddOptions( ('TOLUA_FLAGS', 'compilation flags for TOLUA'), ('TOLUA_LDFLAGS', 'link flags for TOLUA'), ('TOLUAISCONFIGURED', 'configuration succeeded'), ) opts.Update(env) if env['HELP']: return # this condition is used to check when to redetect the configuration (do not remove) if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('TOLUAISCONFIGURED')): print "Checking for ToLua++ : ", if env.has_key('TOLUAISCONFIGURED'): env.__delitem__('TOLUAISCONFIGURED') # clear options set previously if env.has_key('TOLUA_FLAGS'): env.__delitem__('TOLUA_FLAGS') if env.has_key('TOLUA_LDFLAGS'): env.__delitem__('TOLUA_LDFLAGS') hastolua = os.popen('command -v tolua++ 2>/dev/null').read().strip() if len(hastolua) < 1: env.pprint('RED', '[failed] tolua++ binary not found !') env.Exit(1) includes_path = """/usr/include /usr/local/include /opt/include /mingw/include """.split() include = '' for inc in includes_path: if os.path.exists(inc + '/tolua++.h'): include = inc break if include == '': env.pprint('RED', '[failed] includes not found !') env.Exit(1) libs_path = """/usr/lib /usr/local/lib /opt/lib /mingw/lib""".split() library = '' for lib in libs_path: if os.path.exists(lib + '/libtolua++.a'): library = lib if library == '': env.pprint('RED', '[failed] libraries not found !') env.Exit(1) env['TOLUA_FLAGS'] = "-I" + include env['TOLUA_LDFLAGS'] = "-ltolua++" # success env['TOLUAISCONFIGURED'] = 1 env.pprint('GREEN', '[ ok ]') # save the options opts.Save(optionfile, env)
def generate(env): # Detect GLEW optionfile = env['CACHEDIR'] + 'glew.cache.py' opts = Options(optionfile) opts.AddOptions( ('GLEW_FLAGS', 'compilation flags for GLEW'), ('GLEW_LDFLAGS', 'link flags for GLEW'), ('GLEWISCONFIGURED', 'configuration succeeded'), ) opts.Update(env) if env['HELP']: return # this condition is used to check when to redetect the configuration (do not remove) if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('GLEWISCONFIGURED')): print "Checking for GLEW : ", if env.has_key('GLEWISCONFIGURED'): env.__delitem__('GLEWISCONFIGURED') # clear options set previously if env.has_key('GLEW_FLAGS'): env.__delitem__('GLEW_FLAGS') if env.has_key('GLEW_LDFLAGS'): env.__delitem__('GLEW_LDFLAGS') includes_path = """/usr/include /usr/local/include /opt/include /mingw/include """.split() include = '' for inc in includes_path: if os.path.exists(inc + '/GL/glew.h'): include = inc break if include == '': env.pprint('RED', '[failed] includes not found !') env.Exit(1) libs_path = """/usr/lib /usr/local/lib /opt/lib /mingw/lib""".split() library = '' for lib in libs_path: if os.path.exists(lib + '/libGLEW.so'): library = lib if library == '': env.pprint('RED', '[failed] libraries not found !') env.Exit(1) env['GLEW_FLAGS'] = "-I" + include env['GLEW_LDFLAGS'] = "-lGLEW" # success env['GLEWISCONFIGURED'] = 1 env.pprint('GREEN', '[ ok ]') # save the options opts.Save(optionfile, env)
def generate(env): """Set up the qt environment and builders - the moc part can be difficult to understand """ if env['HELP']: p = env.pprint p('BOLD', '*** QT4 options ***') p('BOLD', '--------------------') p('BOLD', '* prefix ', 'base install path, ie: /usr/local') p('BOLD', '* execprefix ', 'install path for binaries, ie: /usr/bin') p('BOLD', '* datadir ', 'install path for the data, ie: /usr/local/share') p('BOLD', '* libdir ', 'install path for the libs, ie: /usr/lib') p('BOLD', '* libsuffix ', 'suffix of libraries on amd64, ie: 64, 32') p('BOLD', '* qtincludes ', 'qt includes path (/usr/include/qt on debian, ..)') p('BOLD', '* qtlibs ', 'qt libraries path, for linking the program') p( 'BOLD', '* scons configure libdir=/usr/local/lib qtincludes=/usr/include/qt\n' ) return import SCons.Defaults import SCons.Tool import SCons.Util import SCons.Node CLVar = SCons.Util.CLVar splitext = SCons.Util.splitext Builder = SCons.Builder.Builder # Detect the environment - replaces ./configure implicitely and store the options into a cache from SCons.Options import Options cachefile = env['CACHEDIR'] + 'qt4.cache.py' opts = Options(cachefile) opts.AddOptions( ('PREFIX', 'root of the program installation'), ('QTDIR', ''), ('QTLIBPATH', 'path to the qt libraries'), ('QTINCLUDEPATH', 'path to the qt includes'), ('QT_UIC', 'uic command'), ('QT_MOC', 'moc command'), ('QT_RCC', 'rcc command'), ('QTPLUGINS', 'uic executable command'), ('QTLOCALE', 'install po files to this path'), ) opts.Update(env) # reconfigure when things are missing if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('QTDIR')): #from qt4_config import detect_qt4 detect_qt4(env) opts.Save(cachefile, env) ## set default variables, one can override them in sconscript files env.Append(CXXFLAGS=[ '-I' + env['QTINCLUDEPATH'], '-I' + env['QTINCLUDEPATH'] + 'Qt' ], LIBPATH=[env['QTLIBPATH']]) env['QT_AUTOSCAN'] = 1 env['QT_DEBUG'] = 0 env['MSGFMT'] = 'msgfmt' ## ui file processing def uic_processing(target, source, env): comp_h = '$QT_UIC -o %s %s' % (target[0].path, source[0].path) return env.Execute(comp_h) def uicEmitter(target, source, env): adjustixes = SCons.Util.adjustixes bs = SCons.Util.splitext(str(source[0].name))[0] bs = os.path.join(str(target[0].get_dir()), bs) #target.append(bs+'.cpp') #target.append(bs+'.moc') return target, source env['BUILDERS']['Uic'] = Builder(action=uic_processing, emitter=uicEmitter, suffix='.h', src_suffix='.ui3') def qrc_buildit(target, source, env): dir = str(source[0].get_dir()) name = SCons.Util.splitext(source[0].name)[0] comp = 'cd %s && %s -name %s %s -o %s' % ( dir, env['QT_RCC'], name, source[0].name, target[0].name) return env.Execute(comp) def qrc_stringit(target, source, env): print "processing %s to get %s" % (source[0].name, target[0].name) env['BUILDERS']['Qrc'] = Builder(action=env.Action(qrc_buildit, qrc_stringit), suffix='_qrc.cpp', src_suffix='.qrc') def kcfg_buildit(target, source, env): comp = 'kconfig_compiler -d%s %s %s' % (str( source[0].get_dir()), source[1].path, source[0].path) return env.Execute(comp) def kcfg_stringit(target, source, env): print "processing %s to get %s and %s" % ( source[0].name, target[0].name, target[1].name) def kcfgEmitter(target, source, env): adjustixes = SCons.Util.adjustixes bs = SCons.Util.splitext(str(source[0].name))[0] bs = os.path.join(str(target[0].get_dir()), bs) # .h file is already there target.append(bs + '.cpp') if not os.path.isfile(str(source[0])): lenv.pprint( 'RED', 'kcfg file given' + str(source[0]) + ' does not exist !') return target, source kfcgfilename = "" kcfgFileDeclRx = re.compile("^[fF]ile\s*=\s*(.+)\s*$") for line in file(str(source[0]), "r").readlines(): match = kcfgFileDeclRx.match(line.strip()) if match: kcfgfilename = match.group(1) break if not kcfgfilename: print 'invalid kcfgc file' return 0 source.append(env.join(str(source[0].get_dir()), kcfgfilename)) return target, source env['BUILDERS']['Kcfg'] = Builder(action=env.Action( kcfg_buildit, kcfg_stringit), emitter=kcfgEmitter, suffix='.h', src_suffix='.kcfgc') ## MOC processing env['BUILDERS']['Moc'] = Builder(action='$QT_MOC -o $TARGET $SOURCE', suffix='.moc', src_suffix='.h') env['BUILDERS']['Moccpp'] = Builder(action='$QT_MOC -o $TARGET $SOURCE', suffix='_moc.cpp', src_suffix='.h') ## DOCUMENTATION env['BUILDERS']['Meinproc'] = Builder( action='$MEINPROC --check --cache $TARGET $SOURCE', suffix='.cache.bz2') ## TRANSLATIONS env['BUILDERS']['Transfiles'] = Builder( action='$MSGFMT $SOURCE -o $TARGET', suffix='.gmo', src_suffix='.po') ## Handy helpers for building kde programs ## You should not have to modify them .. ## Return a list of things def make_list(e): if type(e) is types.ListType: return e else: return e.split() ui_ext = [".ui"] header_ext = [".h", ".hxx", ".hpp", ".hh"] cpp_ext = [".cpp", ".cxx", ".cc"] def QT4files(lenv, target, source): """ Returns a list of files for scons (handles qt4 tricks like .qrc) """ q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]') def scan_moc(cppfile): addfile = None # try to find the header orifile = cppfile.srcnode().name bs = SCons.Util.splitext(orifile)[0] h_file = '' dir = cppfile.dir for n_h_ext in header_ext: afile = dir.File(bs + n_h_ext) if afile.rexists(): #h_ext=n_h_ext h_file = afile break # We have the header corresponding to the cpp file if h_file: h_contents = h_file.get_contents() if q_object_search.search(h_contents): # we know now there is Q_OBJECT macro reg = '\n\s*#include\s*("|<)' + str(bs) + '.moc("|>)' meta_object_search = re.compile(reg) #cpp_contents = open(file_cpp, 'rb').read() cpp_contents = cppfile.get_contents() if meta_object_search.search(cpp_contents): lenv.Moc(h_file) else: lenv.Moccpp(h_file) addfile = bs + '_moc.cpp' print "WARNING: moc.cpp for " + h_file.name + " consider using #include <file.moc> instead" return addfile src = [] ui_files = [] other_files = [] source_ = make_list(source) # For each file, check wether it is a dcop file or not, and create the complete list of sources for file in source_: sfile = SCons.Node.FS.default_fs.File(str(file)) bs = SCons.Util.splitext(file)[0] ext = SCons.Util.splitext(file)[1] if ext == ".moch": lenv.Moccpp(bs + '.h') src.append(bs + '_moc.cpp') elif ext == ".qrc": src.append(bs + '_qrc.cpp') lenv.Qrc(file) parser = make_parser() curHandler = SconsHandler(lenv) parser.setContentHandler(curHandler) parser.parse(open(sfile.srcnode().abspath)) files = curHandler.files lenv.Depends(bs + '_qrc.cpp', files) #for i in files: # print " -> "+i elif ext in cpp_ext: src.append(file) if not env.has_key('NOMOCFILE'): ret = scan_moc(sfile) if ret: src.append(ret) elif ext in ui_ext: lenv.Uic(file) #src.append(bs+'.cpp') else: src.append(file) # Now check against typical newbie errors for file in ui_files: for ofile in other_files: if ofile == file: lenv.pprint( 'RED', "WARNING: You have included " + file + ".ui and another file of the same prefix") print "Files generated by uic (file.h, file.cpp must not be included" return src """ In the future, these functions will contain the code that will dump the configuration for re-use from an IDE """ import glob def getInstDirForResType(lenv, restype): if len(restype) == 0 or not lenv.has_key(restype): lenv.pprint('RED', "unknown resource type " + restype) lenv.Exit(1) else: instdir = lenv[restype] if env['ARGS'] and env['ARGS'].has_key('prefix'): instdir = instdir.replace(lenv['PREFIX'], env['ARGS']['prefix']) return instdir #if restype == "QT4BIN": return env['PREFIX']+'/bin' #if restype == "QT4MODULE" or restype == "QT4LIB": return env['PREFIX']+'/lib' #return env['PREFIX'] def QT4install(lenv, restype, subdir, files): if not env['_INSTALL']: return dir = getInstDirForResType(lenv, restype) install_list = lenv.bksys_install(lenv.join(dir, subdir), files, nodestdir=1) return install_list def QT4installas(lenv, restype, destfile, file): if not env['_INSTALL']: return dir = getInstDirForResType(lenv, restype) install_list = lenv.InstallAs(lenv.join(dir, destfile), file) env.Alias('install', install_list) return install_list def QT4lang(lenv, folder, appname): """ Process translations (.po files) in a po/ dir """ transfiles = glob.glob(folder + '/*.po') for lang in transfiles: result = lenv.Transfiles(lang) country = SCons.Util.splitext(result[0].name)[0] lenv.QT4installas( 'QTLOCALE', lenv.join(country, 'LC_MESSAGES', appname + '.mo'), result) def QT4icon(lenv, icname='*', path='./', restype='QT4ICONS', subdir=''): """Contributed by: "Andrey Golovizin" <grooz()gorodok()net> modified by "Martin Ellis" <m.a.ellis()ncl()ac()uk> Installs icons with filenames such as cr22-action-frame.png into QT4 icon hierachy with names like icons/crystalsvg/22x22/actions/frame.png. Global QT4 icons can be installed simply using env.QT4icon('name'). The second parameter, path, is optional, and specifies the icons location in the source, relative to the SConscript file. To install icons that need to go under an applications directory (to avoid name conflicts, for example), use e.g. env.QT4icon('name', './', 'QT4DATA', 'appname/icons')""" type_dic = { 'action': 'actions', 'app': 'apps', 'device': 'devices', 'filesys': 'filesystems', 'mime': 'mimetypes' } dir_dic = { 'los': 'locolor/16x16', 'lom': 'locolor/32x32', 'him': 'hicolor/32x32', 'hil': 'hicolor/48x48', 'lo16': 'locolor/16x16', 'lo22': 'locolor/22x22', 'lo32': 'locolor/32x32', 'hi16': 'hicolor/16x16', 'hi22': 'hicolor/22x22', 'hi32': 'hicolor/32x32', 'hi48': 'hicolor/48x48', 'hi64': 'hicolor/64x64', 'hi128': 'hicolor/128x128', 'hisc': 'hicolor/scalable', 'cr16': 'crystalsvg/16x16', 'cr22': 'crystalsvg/22x22', 'cr32': 'crystalsvg/32x32', 'cr48': 'crystalsvg/48x48', 'cr64': 'crystalsvg/64x64', 'cr128': 'crystalsvg/128x128', 'crsc': 'crystalsvg/scalable' } iconfiles = [] for ext in "png xpm mng svg svgz".split(): files = glob.glob(path + '/' + '*-*-%s.%s' % (icname, ext)) iconfiles += files for iconfile in iconfiles: lst = iconfile.split('/') filename = lst[len(lst) - 1] tmp = filename.split('-') if len(tmp) != 3: lenv.pprint( 'RED', 'WARNING: icon filename has unknown format: ' + iconfile) continue [icon_dir, icon_type, icon_filename] = tmp try: basedir = getInstDirForResType(lenv, restype) destfile = '%s/%s/%s/%s/%s' % ( basedir, subdir, dir_dic[icon_dir], type_dic[icon_type], icon_filename) except KeyError: lenv.pprint('RED', 'WARNING: unknown icon type: ' + iconfile) continue ## Do not use QT4installas here, as parsing from an ide will be necessary if env['_INSTALL']: env.Alias('install', env.InstallAs(destfile, iconfile)) import generic class qt4obj(generic.genobj): def __init__(self, val, senv=None): if senv: generic.genobj.__init__(self, val, senv) else: generic.genobj.__init__(self, val, env) self.iskdelib = 0 def execute(self): if self.orenv.has_key('DUMPCONFIG'): print self.xml() return self.env = self.orenv.Copy() #self.env.AppendUnique(LIBPATH=env['LIBPATH_KDE4']) # then add the includes for qt inctypes = "QtXml QtGui QtCore QtOpenGL Qt3Support".split() qtincludes = [] for dir in inctypes: qtincludes.append(env.join(env['QTINCLUDEPATH'], dir)) self.env.AppendUnique(CPPPATH=qtincludes) self.setsource(QT4files(env, self.target, self.source)) generic.genobj.execute(self) def xml(self): ret = '<compile type="%s" dirprefix="%s" target="%s" cxxflags="%s" cflags="%s" includes="%s" linkflags="%s" libpaths="%s" libs="%s" vnum="%s" iskdelib="%s" libprefix="%s">\n' % ( self.type, self.dirprefix, self.target, self.cxxflags, self.cflags, self.includes, self.linkflags, self.libpaths, self.libs, self.vnum, self.iskdelib, self.libprefix) if self.source: for i in self.orenv.make_list(self.source): ret += ' <source file="%s"/>\n' % i ret += "</compile>" return ret # Attach the functions to the environment so that SConscripts can use them from SCons.Script.SConscript import SConsEnvironment SConsEnvironment.QT4install = QT4install SConsEnvironment.QT4installas = QT4installas SConsEnvironment.QT4lang = QT4lang SConsEnvironment.QT4icon = QT4icon SConsEnvironment.qt4obj = qt4obj
def generate(env): # Fix scons & gcc borkedness (scons not looking in PATH for gcc # and mingw gcc 4.1 linker crashing if TMP or TEMP isn't set). env['ENV']['PATH'] = os.environ['PATH'] if os.environ.has_key('MINGDIR'): env['ENV']['MINGDIR'] = os.environ['MINGDIR'] if os.environ.has_key('TMP'): env['ENV']['TMP'] = os.environ['TMP'] if os.environ.has_key('TEMP'): env['ENV']['TEMP'] = os.environ['TEMP'] #parse cmdline 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 args = makeHashTable(sys.argv) # We break unitsync if the filename of the shared object has a 'lib' prefix. # It is also nicer for the AI shared objects. env['LIBPREFIX'] = '' # I don't see any reason to make this configurable --tvo. # Note that commenting out / setting this to `None' will break the buildsystem. env['builddir'] = '#build' if args.has_key('builddir'): env['builddir'] = args['builddir'] bd = filelist.getAbsDir(env, env['builddir']) # SCons chokes in env.SConsignFile() if path doesn't exist. if not os.path.exists(bd): os.makedirs(bd) # Avoid spreading .sconsign files everywhere - keep this line env.SConsignFile(os.path.join(bd, 'scons_signatures')) usrcachefile = os.path.join(bd, 'usropts.py') intcachefile = os.path.join(bd, 'intopts.py') usropts = Options(usrcachefile) intopts = Options(intcachefile) #user visible options usropts.AddOptions( #permanent options ('platform', 'Set to linux, freebsd or windows', None), ('gml', 'Set to yes to enable the OpenGL Multithreading Library', False), ('gmlsim', 'Set to yes to enable parallel threads for Sim/Draw', False), ('gmldebug', 'Set to yes to enable GML call debugging', False), ('debug', 'Set to yes to produce a binary with debug information', 0), ('debugdefines', 'Set to no to suppress DEBUG and _DEBUG preprocessor #defines (use to add symbols to release build)', True), ('syncdebug', 'Set to yes to enable the sync debugger', False), ('synccheck', 'Set to yes to enable sync checker & resyncer', True), ('synctrace', 'Enable sync tracing', False), ('optimize', 'Enable processor optimizations during compilation', 1), ('arch', 'CPU architecture to use', 'auto'), ('profile', 'Set to yes to produce a binary with profiling information', False), ('profile_generate', 'Set to yes to compile with -fprofile-generate to generate profiling information', False), ('profile_use', 'Set to yes to compile with -fprofile-use to use profiling information', False), ('ai_interfaces', 'Which AI Interfaces (and AIs using them) to build [all|native|java|none]', 'all'), ('cpppath', 'Set path to extra header files', []), ('libpath', 'Set path to extra libraries', []), ('fpmath', 'Set to 387 or SSE on i386 and AMD64 architectures', 'sse'), ('prefix', 'Install prefix used at runtime', '/usr/local'), ('installprefix', 'Install prefix used for installion', '$prefix'), ('builddir', 'Build directory, used at build-time', '#build'), ('mingwlibsdir', 'MinGW libraries dir', '#mingwlibs'), ('datadir', 'Data directory (relative to prefix)', 'share/games/spring'), ('bindir', 'Directory for executables (rel. to prefix)', 'games'), ('libdir', 'Directory for AI plugin modules (rel. to prefix)', 'lib/spring'), ('strip', 'Discard symbols from the executable (only when neither debugging nor profiling)', False), #porting options - optional in a first phase ('disable_avi', 'Set to no to turn on avi support', 'False on windows, True otherwise'), #other ported parts ('use_tcmalloc', 'Use tcmalloc from goog-perftools for memory allocation', False), ('use_nedmalloc', 'Use nedmalloc for memory allocation', False), ('use_mmgr', 'Use memory manager', False), ('use_gch', 'Use gcc precompiled header', True), ('dc_allowed', 'Specifies whether FPS mode (Direct Control) is allowed in game', True), ('cachedir', 'Cache directory (see scons manual)', None)) #internal options intopts.AddOptions( ('LINKFLAGS', 'linker flags'), ('LIBPATH', 'library path'), ('LIBS', 'libraries'), ('CCFLAGS', 'c compiler flags'), ('CXXFLAGS', 'c++ compiler flags'), ('CPPDEFINES', 'c preprocessor defines'), ('CPPPATH', 'c preprocessor include path'), ('CC', 'c compiler'), ('CXX', 'c++ compiler'), ('RANLIB', 'ranlib'), ('AR', 'ar'), ('spring_defines', 'extra c preprocessor defines for spring'), ('streflop_extra', 'extra options for streflop Makefile'), ('is_configured', 'configuration version stamp')) usropts.Update(env) intopts.Update(env) env.Help(usropts.GenerateHelpText(env)) # make the build dir globally absolute env['builddir'] = bd # Use this to avoid an error message 'how to make target configure ?' env.Alias('configure', None) if not 'configure' in sys.argv and not ( (env.has_key('is_configured') and env['is_configured'] == 8) or env.GetOption('clean')): print "Not configured or configure script updated. Run `scons configure' first." print "Use `scons --help' to show available configure options to `scons configure'." env.Exit(1) # Dont throw an exception if scons -c is run before scons configure (this is done by debian build system for example) if not env.has_key('is_configured') and env.GetOption('clean'): print "Not configured: nothing to clean" env.Exit(0) if 'configure' in sys.argv: # be paranoid, unset existing variables for key in [ 'platform', 'gml', 'gmlsim', 'gmldebug', 'debug', 'optimize', 'profile', 'profile_use', 'profile_generate', 'cpppath', 'libpath', 'prefix', 'installprefix', 'builddir', 'mingwlibsdir', 'datadir', 'bindir', 'libdir', 'cachedir', 'strip', 'disable_avi', 'use_tcmalloc', 'use_nedmalloc', 'use_mmgr', 'use_gch', 'ai_interfaces', 'LINKFLAGS', 'LIBPATH', 'LIBS', 'CCFLAGS', 'CXXFLAGS', 'CPPDEFINES', 'CPPPATH', 'CC', 'CXX', 'is_configured', 'spring_defines', 'arch' ]: if env.has_key(key): env.__delitem__(key) print "\nNow configuring. If something fails, consult `config.log' for details.\n" env['is_configured'] = 8 if args.has_key('platform'): env['platform'] = args['platform'] else: env['platform'] = detect.platform() fix_windows_spawn(env) if os.environ.has_key('CC'): env['CC'] = os.environ['CC'] else: env['CC'] = 'gcc' if os.environ.has_key('CXX'): env['CXX'] = os.environ['CXX'] else: env['CXX'] = 'g++' # select proper tools for win crosscompilation by default is_crosscompiling = env['platform'] == 'windows' and os.name != 'nt' if os.environ.has_key('AR'): env['AR'] = os.environ['AR'] elif is_crosscompiling: env['AR'] = 'i586-mingw32msvc-ar' if os.environ.has_key('RANLIB'): env['RANLIB'] = os.environ['RANLIB'] elif is_crosscompiling: env['RANLIB'] = 'i586-mingw32msvc-ranlib' gcc_version = config.check_gcc_version(env) print 'Toolchain options:' print 'CC=%s' % env['CC'] print 'CXX=%s' % env['CXX'] print 'AR=%s' % env['AR'] print 'RANLIB=%s' % env['RANLIB'] print # Declare some helper functions for boolean and string options. def bool_opt(key, default): if args.has_key(key): if args[key] == 'no' or args[key] == 'false' or args[ key] == '0': env[key] = False elif args[key] == 'yes' or args[key] == 'true' or args[ key] == '1': env[key] = True else: print "\ninvalid", key, "option, must be one of: yes, true, no, false, 0, 1." env.Exit(1) else: env[key] = default def string_opt(key, default): if args.has_key(key): env[key] = args[key] else: env[key] = default def stringarray_opt(key, default): if args.has_key(key): env[key] = args[key].split(';') else: env[key] = default # Use single precision constants only. # This should be redundant with the modifications done by tools/double_to_single_precision.sed. # Other options copied from streflop makefiles. env['CCFLAGS'] = [ '-fsingle-precision-constant', '-frounding-math', '-fsignaling-nans', '-mieee-fp' ] # set architecture if 'arch' in args and args['arch'] != 'auto': arch = args['arch'] if not arch or arch == 'none': print 'Configuring for default architecture' marchFlag = '' else: print 'Configuring for', arch marchFlag = '-march=' + arch else: bits, archname = platform.architecture() if bits == '32bit' or env['platform'] == 'windows': print 'Configuring for i686' marchFlag = '-march=i686' else: print 'Configuring for default architecture' marchFlag = '' env['CCFLAGS'] += [marchFlag] env['streflop_extra'] = [marchFlag] # profile? bool_opt('profile', False) if env['profile']: print "profiling enabled,", env.AppendUnique(CCFLAGS=['-pg'], LINKFLAGS=['-pg']) else: print "profiling NOT enabled,", # debug? gcc_warnings = [ '-Wchar-subscripts', '-Wformat=2', '-Winit-self', '-Wimplicit', '-Wmissing-braces', '-Wparentheses', '-Wsequence-point', '-Wreturn-type', '-Wswitch', '-Wtrigraphs', '-Wunused', '-Wuninitialized', '-Wunknown-pragmas' ] if args.has_key('debug'): level = args['debug'] if level == 'no' or level == 'false': level = '0' elif level == 'yes' or level == 'true': level = '3' else: level = '0' if int(level) == 0: print "debugging NOT enabled,", env['debug'] = 0 elif int(level) >= 1 and int(level) <= 3: print "level", level, "debugging enabled,", env['debug'] = level # MinGW gdb chokes on the dwarf debugging format produced by '-ggdb', # so use the more generic '-g' instead. # MinGW 4.2.1 gdb does not like the DWARF2 debug format generated by default, # so produce STABS instead if env['platform'] == 'windows' or env['syncdebug']: env.AppendUnique(CCFLAGS=['-gstabs']) else: env.AppendUnique(CCFLAGS=['-ggdb' + level]) # We can't enable -Wall because that silently enables an order of # initialization warning for initializers in constructors that # can not be disabled. (and it takes days to fix them all in code) env.AppendUnique(CFLAGS=gcc_warnings, CCFLAGS=gcc_warnings) if not args.has_key('debugdefines') or not args['debugdefines']: env.AppendUnique( CPPDEFINES=['DEBUG', '_DEBUG', 'NO_CATCH_EXCEPTIONS']) else: env.AppendUnique(CPPDEFINES=['NDEBUG']) else: print "\ninvalid debug option, must be one of: yes, true, no, false, 0, 1, 2, 3." env.Exit(1) if args.has_key('debugdefines') and args['debugdefines']: env.AppendUnique( CPPDEFINES=['DEBUG', '_DEBUG', 'NO_CATCH_EXCEPTIONS'], CFLAGS=gcc_warnings, CCFLAGS=gcc_warnings) # optimize? if args.has_key('optimize'): level = args['optimize'] if level == 'no' or level == 'false': level = '0' elif level == 'yes' or level == 'true': level = '2' else: if env['debug']: level = '0' else: level = '2' if level == 's' or level == 'size' or (int(level) >= 1 and int(level) <= 3): print "level", level, "optimizing enabled" env['optimize'] = level #archflags = detect.processor(gcc_version >= ['3','4','0']) # -fstrict-aliasing causes constructs like: # float f = 10.0f; int x = *(int*)&f; # to break. # Since those constructs are used in the netcode and MathTest code, we disable the optimization. env.AppendUnique( CCFLAGS=['-O' + level, '-pipe', '-fno-strict-aliasing']) # MinGW 4.2 compiled binaries insta crash with this on... #if int(level) <= 2: # env.AppendUnique(CCFLAGS=['-finline-functions','-funroll-loops']) elif int(level) == 0: print "optimizing NOT enabled", env['optimize'] = 0 else: print "\ninvalid optimize option, must be one of: yes, true, no, false, 0, 1, 2, 3, s, size." env.Exit(1) # Generate profiling information? (for profile directed optimization) bool_opt('profile_generate', False) if env['profile_generate']: print "build will generate profiling information" env.AppendUnique(CCFLAGS=['-fprofile-generate'], LINKFLAGS=['-fprofile-generate']) # Use profiling information? (for profile directed optimization) bool_opt('profile_use', False) if env['profile_use']: print "build will use profiling information" env.AppendUnique(CCFLAGS=['-fprofile-use'], LINKFLAGS=['-fprofile-use']) # Must come before the '-fvisibility=hidden' code. bool_opt('syncdebug', False) bool_opt('synccheck', True) bool_opt('synctrace', False) string_opt('fpmath', 'sse') # If sync debugger is on, disable inlining, as it makes it much harder to follow backtraces. if env['syncdebug']: # Disable all possible inlining, just to be sure. env['CCFLAGS'] += [ '-fno-default-inline', '-fno-inline', '-fno-inline-functions', '-fno-inline-functions-called-once' ] # It seems only gcc 4.0 and higher supports this. if gcc_version >= ['4', '0', '0'] and env['platform'] != 'windows': env['CCFLAGS'] += ['-fvisibility=hidden'] # Allow easy switching between 387 and SSE fpmath. if env['fpmath']: env['CCFLAGS'] += ['-mfpmath=' + env['fpmath']] env['streflop_extra'] += ['-mfpmath=' + env['fpmath']] if env['fpmath'] == '387': print "WARNING: SSE math vs X87 math is unsynced!" print "WARNING: Do not go online with the binary you are currently building!" else: env['CCFLAGS'] += ['-msse'] env['streflop_extra'] += ['-msse'] env['CXXFLAGS'] = env['CCFLAGS'] # Do not do this anymore because it may severely mess up our carefully selected options. # Print a warning and ignore them instead. # fall back to environment variables if neither debug nor optimize options are present if not args.has_key('debug') and not args.has_key('optimize'): if os.environ.has_key('CFLAGS'): #print "using CFLAGS:", os.environ['CFLAGS'] #env['CCFLAGS'] = SCons.Util.CLVar(os.environ['CFLAGS']) print "WARNING: attempt to use environment CFLAGS has been ignored." if os.environ.has_key('CXXFLAGS'): #print "using CXXFLAGS:", os.environ['CXXFLAGS'] #env['CXXFLAGS'] = SCons.Util.CLVar(os.environ['CXXFLAGS']) print "WARNING: attempt to use environment CXXFLAGS has been ignored." #else: # env['CXXFLAGS'] = env['CCFLAGS'] # nedmalloc crashes horribly when crosscompiled # on mingw gcc 4.2.1 nedmalloc_default = False bool_opt('gml', False) bool_opt('gmlsim', False) bool_opt('gmldebug', False) bool_opt('strip', False) bool_opt('disable_avi', env['platform'] != 'windows') bool_opt('use_tcmalloc', False) bool_opt('use_nedmalloc', nedmalloc_default) bool_opt('use_mmgr', False) bool_opt('use_gch', True) bool_opt('dc_allowed', True) string_opt('prefix', '/usr/local') string_opt('installprefix', '$prefix') string_opt('builddir', '#build'), string_opt('mingwlibsdir', '#mingwlibs'), string_opt('datadir', 'share/games/spring') string_opt('bindir', 'games') string_opt('libdir', 'lib/spring') string_opt('cachedir', None) string_opt('ai_interfaces', 'all') # Make a list of preprocessor defines. env.AppendUnique(CPPDEFINES=['_REENTRANT', '_SZ_ONE_DIRECTORY']) spring_defines = [] if env['use_gch']: env.AppendUnique(CXXFLAGS=['-DUSE_PRECOMPILED_HEADER']) print 'Precompiled header enabled' else: print 'Precompiled header disabled' spring_defines += ['_WIN32_WINNT=0x500'] # gml library if env['gml']: env.AppendUnique(CCFLAGS=['-mno-tls-direct-seg-refs'], CXXFLAGS=['-mno-tls-direct-seg-refs'], LINKFLAGS=['-mno-tls-direct-seg-refs']) spring_defines += ['USE_GML'] print 'OpenGL Multithreading Library is enabled' if env['gmlsim']: spring_defines += ['USE_GML_SIM'] print 'Parallel threads for Sim/Draw is enabled' if env['gmldebug']: spring_defines += ['USE_GML_DEBUG'] print 'GML call debugging is enabled' else: print 'GML call debugging is NOT enabled' else: print 'Parallel threads for Sim/Draw is NOT enabled' else: print 'OpenGL Multithreading Library and parallel threads for Sim/Draw are NOT enabled' # Add define specifying type of floating point math to use. if env['fpmath']: if env['fpmath'] == 'sse': spring_defines += ['STREFLOP_SSE'] if env['fpmath'] == '387': spring_defines += ['STREFLOP_X87'] # Add/remove SYNCDEBUG to enable/disable sync debugging. if env['syncdebug']: spring_defines += ['SYNCDEBUG'] if env['synccheck']: spring_defines += ['SYNCCHECK'] if env['synctrace']: spring_defines += ['TRACE_SYNC'] # Don't define this: it causes a full recompile when you change it, even though it is only used in Main.cpp, # and some AIs maybe. Just make exceptions in SConstruct. #defines += ['SPRING_DATADIR="\\"'+env['datadir']+'\\""'] if not env['disable_avi']: spring_defines += ['AVI_CAPTURING'] if env['use_mmgr']: spring_defines += ['USE_MMGR'] if env['dc_allowed']: spring_defines += ['DIRECT_CONTROL_ALLOWED'] env['spring_defines'] = spring_defines stringarray_opt('cpppath', []) stringarray_opt('libpath', []) include_path = env['cpppath'] + ['#rts', '#rts/System'] include_path += ['#rts/lib/lua/include', '#rts/lib/streflop'] lib_path = env['libpath'] if env['platform'] == 'freebsd': include_path += [ '/usr/local/include', '/usr/X11R6/include', '/usr/X11R6/include/GL' ] lib_path += ['/usr/local/lib', '/usr/X11R6/lib'] env.AppendUnique(CCFLAGS=['-pthread'], CXXFLAGS=['-pthread']) elif env['platform'] == 'linux': include_path += ['/usr/include', '/usr/include/GL'] env.AppendUnique(CCFLAGS=['-pthread'], CXXFLAGS=['-pthread'], LINKFLAGS=['-Wl,-E']) elif env['platform'] == 'darwin': include_path += [ '/usr/include', '/usr/local/include', '/opt/local/include', '/usr/X11R6/include' ] lib_path += ['/opt/local/lib', '/usr/local/lib'] env['SHLINKFLAGS'] = '$LINKFLAGS -dynamic' env['SHLIBSUFFIX'] = '.dylib' elif env['platform'] == 'windows': include_path += [os.path.join(env['mingwlibsdir'], 'include')] lib_path += [os.path.join(env['mingwlibsdir'], 'lib')] lib_path += [os.path.join(env['mingwlibsdir'], 'dll')] include_path += [ os.path.abspath(os.path.join(env['mingwlibsdir'], 'include')) ] lib_path += [ os.path.abspath(os.path.join(env['mingwlibsdir'], 'lib')) ] lib_path += [ os.path.abspath(os.path.join(env['mingwlibsdir'], 'dll')) ] if os.environ.has_key('MINGDIR'): include_path += [ os.path.join(os.environ['MINGDIR'], 'include') ] lib_path += [os.path.join(os.environ['MINGDIR'], 'lib')] lib_path += [os.path.join(os.environ['MINGDIR'], 'dll')] else: print 'ERROR: MINGDIR environment variable not set and MSVC build unsupported.' print 'Set it to your Dev-Cpp or MinGW install directory (e.g. C:\\Dev-Cpp) and try again.' env.Exit(1) env.AppendUnique(CCFLAGS=['-mthreads'], CXXFLAGS=['-mthreads'], LINKFLAGS=['-mwindows', '-mthreads']) # use '-pthreads' for Solaris, according to /usr/include/boost/config/requires_threads.hpp env.AppendUnique(CPPPATH=include_path, LIBPATH=lib_path) config.configure(env, conf_dir=os.path.join(env['builddir'], 'sconf_temp')) usropts.Save(usrcachefile, env) intopts.Save(intcachefile, env) # make the prefix absolute env['prefix'] = filelist.getAbsDir(env, env['prefix']) # Substitute prefix in installprefix, and make installprefix absolute env['installprefix'] = filelist.getAbsDir(env, env.subst(env['installprefix'])) # Fix up some suffices for mingw crosscompile. if env['platform'] == 'windows': env['SHLIBSUFFIX'] = '.dll' env['PROGSUFFIX'] = '.exe' #Should we strip the exe? if env.has_key('strip') and env['strip'] and not env['debug'] and not env[ 'profile'] and not env.GetOption('clean'): env['strip'] = True else: env['strip'] = False #BuildDir support code if env['builddir']: for d in filelist.list_directories(env, 'rts'): env.BuildDir(os.path.join(env['builddir'], d), d, duplicate=False) for d in filelist.list_directories(env, 'AI'): env.BuildDir(os.path.join(env['builddir'], d), d, duplicate=False) #CacheDir support code if env.has_key('cachedir') and env['cachedir']: if not os.path.exists(env['cachedir']): os.makedirs(env['cachedir']) env.CacheDir(env['cachedir']) fix_windows_spawn(env)
def generate(env): """"Set up the qt and kde environment and builders - the moc part is difficult to understand """ # attach this function immediately SConsEnvironment.KDEuse = KDEuse if env['HELP']: print """\033[1m*** KDE options *** -------------------\033[0m \033[1m* prefix \033[0m: base install path, ie: /usr/local \033[1m* execprefix \033[0m: install path for binaries, ie: /usr/bin \033[1m* datadir \033[0m: install path for the data, ie: /usr/local/share \033[1m* libdir \033[0m: install path for the libs, ie: /usr/lib \033[1m* libsuffix \033[0m: suffix of libraries on amd64, ie: 64, 32 \033[1m* kdeincludes\033[0m: path to the kde includes (/usr/include/kde on debian, ...) \033[1m* qtincludes \033[0m: same punishment, for qt includes (/usr/include/qt on debian, ...) \033[1m* kdelibs \033[0m: path to the kde libs, for linking the programs \033[1m* qtlibs \033[0m: same punishment, for qt libraries ie: \033[1mscons configure libdir=/usr/local/lib qtincludes=/usr/include/qt\033[0m """ return import SCons.Defaults import SCons.Tool import SCons.Util import SCons.Node CLVar = SCons.Util.CLVar splitext = SCons.Util.splitext Builder = SCons.Builder.Builder # Detect the environment - replaces ./configure implicitely and store the options into a cache from SCons.Options import Options cachefile=env['CACHEDIR']+'kde.cache.py' opts = Options(cachefile) opts.AddOptions( ('PREFIX', 'root of the program installation'), ('QTDIR', ''), ('QTLIBPATH', 'path to the qt libraries'), ('QTINCLUDEPATH', 'path to the qt includes'), ('QT_UIC', 'uic command'), ('QT_MOC', 'moc command'), ('QTPLUGINS', 'uic executable command'), ('KDEDIR', ''), ('KDELIBPATH', 'path to the installed kde libs'), ('KDEINCLUDEPATH', 'path to the installed kde includes'), ('KDEBIN', 'inst path of the kde binaries'), ('KDEINCLUDE', 'inst path of the kde include files'), ('KDELIB', 'inst path of the kde libraries'), ('KDEMODULE', 'inst path of the parts and libs'), ('KDEDATA', 'inst path of the application data'), ('KDELOCALE', ''), ('KDEDOC', ''), ('KDEKCFG', ''), ('KDEXDG', ''), ('KDEXDGDIR', ''), ('KDEMENU', ''), ('KDEMIME', ''), ('KDEICONS', ''), ('KDESERV', ''), ('KDESERVTYPES', ''), ('KDEAPPS', ''), ) opts.Update(env) def getInstDirForResType(lenv,restype): if len(restype) == 0 or not lenv.has_key(restype): print RED+"unknown resource type "+restype+NORMAL lenv.Exit(1) else: instdir = lenv[restype] if env['ARGS'] and env['ARGS'].has_key('prefix'): instdir = instdir.replace(lenv['PREFIX'], env['ARGS']['prefix']) return instdir # reconfigure when things are missing if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('QTDIR') or not env.has_key('KDEDIR')): detect_kde(env) opts.Save(cachefile, env) ## set default variables, one can override them in sconscript files env.Append(CXXFLAGS = ['-I'+env['KDEINCLUDEPATH'], '-I'+env['QTINCLUDEPATH'] ], LIBPATH = [env['KDELIBPATH'], env['QTLIBPATH'] ]) env['QT_AUTOSCAN'] = 1 env['QT_DEBUG'] = 0 env['MEINPROC'] = 'meinproc' env['MSGFMT'] = 'msgfmt' ## ui file processing def uic_processing(target, source, env): inc_kde ='#include <klocale.h>\n#include <kdialog.h>\n' inc_moc ='#include "%s"\n' % target[2].name comp_h ='$QT_UIC -L $QTPLUGINS -nounload -o %s %s' % (target[0].path, source[0].path) comp_c ='$QT_UIC -L $QTPLUGINS -nounload -tr tr2i18n -impl %s %s' % (target[0].path, source[0].path) comp_moc ='$QT_MOC -o %s %s' % (target[2].path, target[0].path) if env.Execute(comp_h): return ret dest = open( target[1].path, "w" ) dest.write(inc_kde) dest.close() if env.Execute( comp_c+" >> "+target[1].path ): return ret dest = open( target[1].path, "a" ) dest.write(inc_moc) dest.close() ret = env.Execute( comp_moc ) return ret def uicEmitter(target, source, env): adjustixes = SCons.Util.adjustixes bs = SCons.Util.splitext(str(source[0].name))[0] bs = os.path.join(str(target[0].get_dir()),bs) target.append(bs+'.cpp') target.append(bs+'.moc') return target, source env['BUILDERS']['Uic']=Builder(action=uic_processing,emitter=uicEmitter,suffix='.h',src_suffix='.ui') def kcfg_buildit(target, source, env): comp='kconfig_compiler -d%s %s %s' % (str(source[0].get_dir()), source[1].path, source[0].path) return env.Execute(comp) def kcfg_stringit(target, source, env): print "processing %s to get %s and %s" % (source[0].name, target[0].name, target[1].name) def kcfgEmitter(target, source, env): adjustixes = SCons.Util.adjustixes bs = SCons.Util.splitext(str(source[0].name))[0] bs = os.path.join(str(target[0].get_dir()),bs) # .h file is already there target.append(bs+'.cpp') if not os.path.isfile(str(source[0])): print RED+'kcfg file given '+str(source[0])+' does not exist !'+NORMAL print os.popen('pwd').read() return target, source kfcgfilename="" kcfgFileDeclRx = re.compile("^[fF]ile\s*=\s*(.+)\s*$") for line in file(str(source[0]), "r").readlines(): match = kcfgFileDeclRx.match(line.strip()) if match: kcfgfilename = match.group(1) break if not kcfgfilename: print 'invalid kcfgc file' return 0 source.append( os.path.join( str(source[0].get_dir()), kcfgfilename) ) return target, source env['BUILDERS']['Kcfg']=Builder(action=env.Action(kcfg_buildit, kcfg_stringit), emitter=kcfgEmitter, suffix='.h', src_suffix='.kcfgc') ## MOC processing env['BUILDERS']['Moc']=Builder(action='$QT_MOC -o $TARGET $SOURCE',suffix='.moc',src_suffix='.h') env['BUILDERS']['Moccpp']=Builder(action='$QT_MOC -o $TARGET $SOURCE',suffix='_moc.cpp',src_suffix='.h') ## KIDL file env['BUILDERS']['Kidl']=Builder(action= 'dcopidl $SOURCE > $TARGET || (rm -f $TARGET ; false)', suffix='.kidl', src_suffix='.h') ## DCOP env['BUILDERS']['Dcop']=Builder(action='dcopidl2cpp --c++-suffix cpp --no-signals --no-stub $SOURCE', suffix='_skel.cpp', src_suffix='.kidl') ## STUB env['BUILDERS']['Stub']=Builder(action= 'dcopidl2cpp --c++-suffix cpp --no-signals --no-skel $SOURCE', suffix='_stub.cpp', src_suffix='.kidl') ## DOCUMENTATION env['BUILDERS']['Meinproc']=Builder(action='$MEINPROC --check --cache $TARGET $SOURCE',suffix='.cache.bz2') ## TRANSLATIONS env['BUILDERS']['Transfiles']=Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po') ## Handy helpers for building kde programs ## You should not have to modify them .. ui_ext = [".ui"] kcfg_ext = ['.kcfgc'] header_ext = [".h", ".hxx", ".hpp", ".hh"] cpp_ext = [".cpp", ".cxx", ".cc"] skel_ext = [".skel", ".SKEL"] stub_ext = [".stub", ".STUB"] def KDEfiles(lenv, target, source): """ Returns a list of files for scons (handles kde tricks like .skel) It also makes custom checks against double includes like : ['file.ui', 'file.cpp'] (file.cpp is already included because of file.ui) """ q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]') def scan_moc(bs, file_cpp): addfile=None # try to find the header h_ext='' for n_h_ext in header_ext: if os.path.isfile(bs+n_h_ext): h_ext=n_h_ext break # We have the header corresponding to the cpp file if h_ext: needscan=0 # User asked for fastmoc, try to avoid scanning if env.has_key('BKSYS_FASTMOC'): if os.path.isfile(bs+'.moc'): lenv.Moc(bs+h_ext) elif os.path.isfile(bs+'_moc.cpp'): lenv.Moccpp(bs+h_ext) addfile=bs+'_moc.cpp' else: #print "need scanning "+os.getcwd()+'/'+bs+".moc" needscan=1 else: needscan=1 # We cannot avoid scanning the files ... if needscan: file_h=bs+h_ext h_contents = open(file_h, 'rb').read() if q_object_search.search(h_contents): # we know now there is Q_OBJECT macro lst = bs.split('/') val = lst[ len(lst) - 1 ] reg = '\n\s*#include\s*("|<)'+val+'.moc("|>)' meta_object_search = re.compile(reg) cpp_contents = open(file_cpp, 'rb').read() if meta_object_search.search(cpp_contents): lenv.Moc(file_h) else: lenv.Moccpp(file_h) addfile=bs+'_moc.cpp' print "WARNING: moc.cpp for "+bs+h_ext+" consider using #include <file.moc> instead" return addfile src=[] ui_files=[] kcfg_files=[] other_files=[] kidl=[] source_=lenv.make_list(source) # For each file, check wether it is a dcop file or not, and create the complete list of sources for file in source_: bs = SCons.Util.splitext(file)[0] ext = SCons.Util.splitext(file)[1] if ext in skel_ext: if not bs in kidl: kidl.append(bs) lenv.Dcop(bs+'.kidl') src.append(bs+'_skel.cpp') elif ext in stub_ext: if not bs in kidl: kidl.append(bs) lenv.Stub(bs+'.kidl') src.append(bs+'_stub.cpp') elif ext == ".moch": lenv.Moccpp(bs+'.h') src.append(bs+'_moc.cpp') elif ext in cpp_ext: src.append(file) if not env.has_key('NOMOCFILE'): ret = scan_moc(bs, file) if ret: src.append( ret ) elif ext in ui_ext: lenv.Uic(file) src.append(bs+'.cpp') elif ext in kcfg_ext: lenv.Kcfg(file) src.append(bs+'.cpp') else: src.append(file) for base in kidl: lenv.Kidl(base+'.h') # Now check against typical newbie errors for file in ui_files: for ofile in other_files: if ofile == file: print RED+"WARNING: You have included "+file+".ui and another file of the same prefix"+NORMAL print "Files generated by uic (file.h, file.cpp must not be included" for file in kcfg_files: for ofile in other_files: if ofile == file: print RED+"WARNING: You have included "+file+".kcfg and another file of the same prefix"+NORMAL print "Files generated by kconfig_compiler (settings.h, settings.cpp) must not be included" return src """ In the future, these functions will contain the code that will dump the configuration for re-use from an IDE """ import glob def KDEinstall(lenv, restype, subdir, files, perms=None): if env.has_key('DUMPCONFIG'): print "<install type=\"%s\" subdir=\"%s\">" % (restype, subdir) for i in lenv.make_list(files): print " <file name=\"%s\"/>" % i print "</install>" return if not env['_INSTALL']: return dir = getInstDirForResType(lenv, restype) p=None if not perms: if restype=='KDEBIN': p=0755 else: p=perms install_list = lenv.bksys_install(os.path.join(dir, subdir), files, perms=p) return install_list def KDEinstallas(lenv, restype, destfile, file): if not env['_INSTALL']: return dir = getInstDirForResType(lenv, restype) install_list = lenv.InstallAs(os.path.join(dir, destfile), file) env.Alias('install', install_list) return install_list def KDEprogram(lenv, target, source, includes='', localshlibs='', globallibs='', globalcxxflags=''): """ Makes a kde program The program is installed except if one sets env['NOAUTOINSTALL'] """ src = KDEfiles(lenv, target, source) program_list = lenv.Program(target, src) # we link the program against a shared library done locally, add the dependency if not lenv.has_key('nosmart_includes'): lenv.AppendUnique(CPPPATH=['./']) if len(localshlibs)>0: lst=lenv.make_list(localshlibs) lenv.link_local_shlib(lst) lenv.Depends( program_list, lst ) if len(includes)>0: lenv.KDEaddpaths_includes(includes) if len(globallibs)>0: lenv.KDEaddlibs(globallibs) if len(globalcxxflags)>0: lenv.KDEaddflags_cxx(globalcxxflags) if not lenv.has_key('NOAUTOINSTALL'): KDEinstall(lenv, 'KDEBIN', '', target) return program_list def KDEshlib(lenv, target, source, kdelib=0, libprefix='lib', includes='', localshlibs='', globallibs='', globalcxxflags='', vnum=''): """ Makes a shared library for kde (.la file for klibloader) The library is installed except if one sets env['NOAUTOINSTALL'] """ src = KDEfiles(lenv, target, source) if not lenv.has_key('nosmart_includes'): lenv.AppendUnique(CPPPATH=['./']) # we link the program against a shared library done locally, add the dependency lst=[] if len(localshlibs)>0: lst=lenv.make_list(localshlibs) lenv.link_local_shlib(lst) if len(includes)>0: lenv.KDEaddpaths_includes(includes) if len(globallibs)>0: lenv.KDEaddlibs(globallibs) if len(globalcxxflags)>0: lenv.KDEaddflags_cxx(globalcxxflags) restype = 'KDEMODULE' if kdelib==1: restype = 'KDELIB' library_list = lenv.bksys_shlib(target, src, getInstDirForResType(lenv, restype), libprefix, vnum) if len(lst)>0: lenv.Depends( library_list, lst ) return library_list def KDEstaticlib(lenv, target, source): """ Makes a static library for kde - in practice you should not use static libraries 1. they take more memory than shared ones 2. makefile.am needed it because of limitations (cannot handle sources in separate folders - takes extra processing) """ if not lenv.has_key('nosmart_includes'): lenv.AppendUnique(CPPPATH=['./']) src = KDEfiles(lenv, target, source) return lenv.StaticLibrary(target, src) # do not install static libraries by default def KDEaddflags_cxx(lenv, fl): """ Compilation flags for C++ programs """ lenv.AppendUnique(CXXFLAGS = lenv.make_list(fl)) def KDEaddflags_c(lenv, fl): """ Compilation flags for C programs """ lenv.AppendUnique(CFLAGS = lenv.make_list(fl)) def KDEaddflags_link(lenv, fl): """ Add link flags - Use this if KDEaddlibs below is not enough """ lenv.PrependUnique(LINKFLAGS = lenv.make_list(fl)) def KDEaddlibs(lenv, libs): """ Helper function """ lenv.AppendUnique(LIBS = lenv.make_list(libs)) def KDEaddpaths_includes(lenv, paths): """ Add new include paths """ lenv.AppendUnique(CPPPATH = lenv.make_list(paths)) def KDEaddpaths_libs(lenv, paths): """ Add paths to libraries """ lenv.PrependUnique(LIBPATH = lenv.make_list(paths)) def KDElang(lenv, folder, appname): """ Process translations (.po files) in a po/ dir """ transfiles = glob.glob(folder+'/*.po') languages=None if lenv['ARGS'] and lenv['ARGS'].has_key('languages'): languages=lenv.make_list(lenv['ARGS']['languages']) for f in transfiles: file=SCons.Node.FS.default_fs.File(f) country = SCons.Util.splitext(file.name)[0] if not languages or country in languages: result = lenv.Transfiles(file) dir=os.path.join( getInstDirForResType(lenv, 'KDELOCALE'), country) lenv.bksys_install(os.path.join(dir, 'LC_MESSAGES'), result, destfile=appname+'.mo') def KDEicon(lenv, icname='*', path='./', restype='KDEICONS', subdir=''): """Contributed by: "Andrey Golovizin" <grooz()gorodok()net> modified by "Martin Ellis" <m.a.ellis()ncl()ac()uk> Installs icons with filenames such as cr22-action-frame.png into KDE icon hierachy with names like icons/crystalsvg/22x22/actions/frame.png. Global KDE icons can be installed simply using env.KDEicon('name'). The second parameter, path, is optional, and specifies the icons location in the source, relative to the SConscript file. To install icons that need to go under an applications directory (to avoid name conflicts, for example), use e.g. env.KDEicon('name', './', 'KDEDATA', 'appname/icons')""" if env.has_key('DUMPCONFIG'): print "<icondirent subdir=\"%s\">" % (path+subdir) return type_dic = { 'action' : 'actions', 'app' : 'apps', 'device' : 'devices', 'filesys' : 'filesystems', 'mime' : 'mimetypes' } dir_dic = { 'los' :'locolor/16x16', 'lom' :'locolor/32x32', 'him' :'hicolor/32x32', 'hil' :'hicolor/48x48', 'lo16' :'locolor/16x16', 'lo22' :'locolor/22x22', 'lo32' :'locolor/32x32', 'hi16' :'hicolor/16x16', 'hi22' :'hicolor/22x22', 'hi32' :'hicolor/32x32', 'hi48' :'hicolor/48x48', 'hi64' :'hicolor/64x64', 'hi128':'hicolor/128x128', 'hisc' :'hicolor/scalable', 'cr16' :'crystalsvg/16x16', 'cr22' :'crystalsvg/22x22', 'cr32' :'crystalsvg/32x32', 'cr48' :'crystalsvg/48x48', 'cr64' :'crystalsvg/64x64', 'cr128':'crystalsvg/128x128', 'crsc' :'crystalsvg/scalable' } iconfiles = [] for ext in "png xpm mng svg svgz".split(): files = glob.glob(path+'/'+'*-*-%s.%s' % (icname, ext)) iconfiles += files for iconfile in iconfiles: lst = iconfile.split('/') filename = lst[ len(lst) - 1 ] tmp = filename.split('-') if len(tmp)!=3: print RED+'WARNING: icon filename has unknown format: '+iconfile+NORMAL continue [icon_dir, icon_type, icon_filename]=tmp try: basedir=getInstDirForResType(lenv, restype) destdir = '%s/%s/%s/%s/' % (basedir, subdir, dir_dic[icon_dir], type_dic[icon_type]) except KeyError: print RED+'WARNING: unknown icon type: '+iconfile+NORMAL continue lenv.bksys_install(destdir, iconfile, icon_filename) ## This function uses env imported above def docfolder(lenv, folder, lang, destination=""): # folder is the folder to process # lang is the language # destination is the subdirectory in KDEDOC docfiles = glob.glob(folder+"/???*.*") # file files that are at least 4 chars wide :) # warn about errors #if len(lang) != 2: # print "error, lang must be a two-letter string, like 'en'" # when the destination is not given, use the folder if len(destination) == 0: destination=folder docbook_list = [] for file in docfiles: # do not process folders if not os.path.isfile(file): continue # do not process the cache file if file == 'index.cache.bz2': continue # ignore invalid files (TODO??) if len( SCons.Util.splitext( file ) ) <= 1 : continue ext = SCons.Util.splitext( file )[1] # handle images (*.png) if ext == '.png': lenv.KDEinstall('KDEDOC', lang+'/'+destination, file) # docbook files are processed by meinproc if ext != '.docbook': continue docbook_list.append( file ) lenv.KDEinstall('KDEDOC', os.path.join(lang, destination), file) # Now process the index.docbook files .. if len(docbook_list) == 0: return if not os.path.isfile( folder+'/index.docbook' ): print "Error, index.docbook was not found in "+folder+'/index.docbook' return ## Define this to 1 if you are writing documentation else to 0 :) if env.has_key('i_am_a_documentation_writer'): for file in docbook_list: lenv.Depends( folder+'index.cache.bz2', file ) lenv.Meinproc( folder+'/index.cache.bz2', folder+'/index.docbook' ) lenv.KDEinstall( 'KDEDOC', os.path.join(lang, destination), os.path.join(folder, 'index.cache.bz2') ) #valid_targets = "program shlib kioslave staticlib".split() import generic class kobject(generic.genobj): def __init__(self, val, senv=None): if senv: generic.genobj.__init__(self, val, senv) else: generic.genobj.__init__(self, val, env) self.iskdelib=0 def it_is_a_kdelib(self): self.iskdelib=1 def execute(self): if self.executed: return self.lockchdir() if self.orenv.has_key('DUMPCONFIG'): print self.xml() self.unlockchdir() return if (self.type=='shlib' or self.type=='kioslave'): install_dir = 'KDEMODULE' if self.iskdelib==1: install_dir = 'KDELIB' self.instdir=getInstDirForResType(self.orenv, install_dir) elif self.type=='program': self.instdir=getInstDirForResType(self.orenv, 'KDEBIN') self.perms=0755 self.src=KDEfiles(env, self.target, self.source) generic.genobj.execute(self) self.unlockchdir() def xml(self): ret= '<compile type="%s" chdir="%s" target="%s" cxxflags="%s" cflags="%s" includes="%s" linkflags="%s" libpaths="%s" libs="%s" vnum="%s" iskdelib="%s" libprefix="%s">\n' % (self.type, self.chdir, self.target, self.cxxflags, self.cflags, self.includes, self.linkflags, self.libpaths, self.libs, self.vnum, self.iskdelib, self.libprefix) if self.source: for i in self.orenv.make_list(self.source): ret += ' <source file="%s"/>\n' % i ret += "</compile>" return ret # Attach the functions to the environment so that SConscripts can use them SConsEnvironment.KDEprogram = KDEprogram SConsEnvironment.KDEshlib = KDEshlib SConsEnvironment.KDEstaticlib = KDEstaticlib SConsEnvironment.KDEinstall = KDEinstall SConsEnvironment.KDEinstallas = KDEinstallas SConsEnvironment.KDElang = KDElang SConsEnvironment.KDEicon = KDEicon SConsEnvironment.KDEaddflags_cxx = KDEaddflags_cxx SConsEnvironment.KDEaddflags_c = KDEaddflags_c SConsEnvironment.KDEaddflags_link = KDEaddflags_link SConsEnvironment.KDEaddlibs = KDEaddlibs SConsEnvironment.KDEaddpaths_includes = KDEaddpaths_includes SConsEnvironment.KDEaddpaths_libs = KDEaddpaths_libs SConsEnvironment.docfolder = docfolder SConsEnvironment.getInstDirForResType = getInstDirForResType SConsEnvironment.kobject = kobject
def generate(env): import SCons.Util, os if env['HELP']: return REQUIRED_LIBSCIM_VERSION = env['REQUIRED_LIBSCIM_VERSION'] def SCIMinstallpath(env, restype, versioned): if restype == 'SCIMCONFIGLIB': if versioned: return env['SCIM_LIBDIR'] + "/scim-1.0/" + \ env['SCIM_BINARY_VERSION'] + "/Config" else: return env['SCIM_LIBDIR'] + "/scim-1.0/Config" return '' def SCIMinstall(env, restype, subdir, files): if not env['_INSTALL']: return basedir = env['DESTDIR'] if len(restype) > 0: if not env.has_key(restype): print RED + "unknown resource type " + restype + NORMAL else: basedir += env[restype] + '/' else: print "You must give a restype for SCIMinstall" env.exit(1) #print file # <- useful to trace stuff :) scim_install_list = env.Install(basedir + subdir + '/', files) env.Alias('install', scim_install_list) return scim_install_list def SCIMshlib(env, restype, target, source, versioned=0, localshlibs=""): """ Makes a shared library for SCIM (and corresponding .la file) The library is installed except if one sets env['NOAUTOINSTALL']. this function will automatically add necessary compile and link parameters of libscim""" env.AppendUnique(CCFLAGS=env['SCIM_CFLAGS']) env.AppendUnique(LINKFLAGS=env['SCIM_LIBS']) # we link the program against a shared library done locally, add the dependency lst = [] if len(localshlibs) > 0: lst = env.make_list(localshlibs) env.link_local_shlib(lst) library_list = env.bksys_shlib( target, source, SCIMinstallpath(env, restype, versioned), '') if len(lst) > 0: env.Depends(library_list, lst) return library_list def Add_define(env, name): if env.has_key(name): env.AppendUnique(CCFLAGS='-D' + name + '=\\"' + env[name] + '\\"') return # these are our options from SCons.Options import Options, PathOption cachefile = env['CACHEDIR'] + '/scim.cache.py' opts = Options(cachefile) opts.AddOptions( ('SCIM_ISCONFIGURED', 'whether it is necessary to run configure or not'), ('SCIM_VERSION', 'The version of installed scim'), ('SCIM_BINARY_VERSION', 'The binary version of installed scim'), ('SCIM_LIBDIR', 'The libdir of installed scim'), ('SCIM_CFLAGS', 'additional compilation flags from libscim'), ('SCIM_LIBS', 'additional link flags from libscim'), ('SCIM_X11_CFLAGS', 'additional compilation flags from libscim-x11utils'), ('SCIM_X11_LIBS', 'additional link flags from libscim-x11utils'), ('SCIM_ICONDIR', 'install path for scim icons'), ('ENABLE_DEBUG', ''), ) opts.Update(env) # detect the scim packages when needed if not env.has_key('SCIM_ISCONFIGURED'): if not env.has_key('PKGCONFIG'): print 'you should add pkg module to the Environment constructor' env.Exit(1) conf = env.Configure( custom_tests={'PKGcheckmodules': env.PKGcheckmodules}) # delete the cached variables if env.has_key('SCIM_VERSION'): env.__delitem__('SCIM_VERSION') if env.has_key('SCIM_BINARY_VERSION'): env.__delitem__('SCIM_BINARY_VERSION') if env.has_key('SCIM_LIBDIR'): env.__delitem__('SCIM_LIBDIR') if env.has_key('SCIM_CFLAGS'): env.__delitem__('SCIM_CFLAGS') if env.has_key('SCIM_LIBS'): env.__delitem__('SCIM_LIBS') if env.has_key('SCIM_X11_CFLAGS'): env.__delitem__('SCIM_X11_CFLAGS') if env.has_key('SCIM_X11_LIBS'): env.__delitem__('SCIM_X11_LIBS') if env.has_key('ENABLE_DEBUG'): env.__delitem__('ENABLE_DEBUG') have_scim = conf.PKGcheckmodules('SCIM', 'scim >= ' + REQUIRED_LIBSCIM_VERSION) have_scim_x11utils = conf.PKGcheckmodules('SCIM_X11', 'scim-x11utils') env = conf.Finish() # if the config worked, read the necessary variables and cache them if not have_scim: print RED + 'scim >= ' + REQUIRED_LIBSCIM_VERSION + ' was not found (mandatory).' + NORMAL print 'Perhaps you should add the directory containing "scim.pc"\nto the PKG_CONFIG_PATH environment variable' env.Exit(1) if env['ARGS'].get('debug', None): env['ENABLE_DEBUG'] = 1 env['SCIM_ISCONFIGURED'] = 1 env['SCIM_VERSION'] = os.popen(env['PKGCONFIG'] + " --modversion scim").read().strip() env['SCIM_BINARY_VERSION'] = os.popen( env['PKGCONFIG'] + " --variable=scim_binary_version scim").read().strip() env['SCIM_LIBDIR'] = os.popen( env['PKGCONFIG'] + " --variable=libdir scim").read().strip() env['SCIM_ICONDIR'] = env.join( os.popen(env['PKGCONFIG'] + " --variable=datadir scim").read().strip(), '/scim/icons') # store the config opts.Save(cachefile, env) if env.has_key('ENABLE_DEBUG'): env.AppendUnique(CXXFLAGS=['-DENABLE_DEBUG=1']) else: env.AppendUnique(CXXFLAGS=['-DENABLE_DEBUG=0']) # Attach the functions to the environment so that sconscripts or other modules can use them from SCons.Script.SConscript import SConsEnvironment SConsEnvironment.Add_define = Add_define SConsEnvironment.SCIMinstall = SCIMinstall SConsEnvironment.SCIMshlib = SCIMshlib
def generate(env): import SCons.Util, os REQUIRED_LIBSKIM_VERSION = env['REQUIRED_LIBSKIM_VERSION'] def SKIMinstall(env, restype, subdir, files): if not env['_INSTALL']: return basedir=env['DESTDIR'] if len(restype)>0: if not env.has_key(restype): print RED+"unknown resource type "+restype+NORMAL else: basedir += env[restype]+'/' else: print "You must give a restype for SKIMinstall" env.exit(1) #print file # <- useful to trace stuff :) skim_install_list = env.Install(basedir+subdir+'/', files) env.Alias('install', skim_install_list) return skim_install_list def SKIMshlib(env, restype, target, source): """ Makes a shared library for SKIM (and corresponding .la file) The library is installed except if one sets env['NOAUTOINSTALL']. this function will automatically add necessary compile and link parameters of libskim""" env.AppendUnique(CCFLAGS = env['SCIM_CFLAGS'] ) env.AppendUnique(LINKFLAGS = env['SCIM_LIBS'] ) if not env.has_key('BUILDING_SKIM') env.AppendUnique(CCFLAGS = env['SKIM_CFLAGS'] ) env.AppendUnique(LINKFLAGS = env['SKIM_LIBS'] ) else env.KDEaddpaths_includes( "#/src #/utils" ) library_list = env.bksys_shlib(target, source, env[restype]) return library_list # these are our options from SCons.Options import Options, PathOption cachefile = env['CACHEDIR']+'/skim.cache.py' opts = Options(cachefile) opts.AddOptions( ( 'SKIM_ISCONFIGURED', 'whether it is necessary to run configure or not' ), ( 'SKIM_VERSION', 'The version of installed skim' ), ( 'SKIM_LIBDIR', 'The libdir of installed skim' ), ( 'SKIM_CFLAGS', 'additional compilation flags from libskim' ), ( 'SKIM_LIBS', 'additional link flags from libskim' ), ( 'SKIM_KDEUTILS_CFLAGS', 'additional compilation flags from libskim-x11utils' ), ( 'SKIM_KDEUTILS_LIBS', 'additional link flags from libskim-x11utils' ), ( 'HAS_XCOMPOSITE', 'Whether XComposite extension is available'), ) opts.Update(env) # detect the skim packages when needed if not env.has_key('BUILDING_SKIM') and not env.has_key('SKIM_ISCONFIGURED'): if not env.has_key('PKGCONFIG'): print 'you should add pkg module to the Environment constructor' env.Exit(1) conf = env.Configure() # delete the cached variables for var in "SKIM_VERSION SKIM_LIBDIR SKIM_CFLAGS SKIM_LIBS SKIM_KDEUTILS_CFLAGS SKIM_KDEUTILS_LIBS HAS_XCOMPOSITE".split(): if env.has_key(var): env.__delitem__(var) have_skim = conf.PKGcheckmodules('SKIM', 'skim >= ' + REQUIRED_LIBSKIM_VERSION) have_skim_x11utils = conf.PKGcheckmodules('SKIM_X11', 'skim-x11utils') env = conf.Finish() # if the config worked, read the necessary variables and cache them if not have_skim: print RED+'skim >= ' + REQUIRED_LIBSKIM_VERSION + ' was not found (mandatory).'+NORMAL env.Exit(1) # mark the config as done - libxml2 and libxslt are found env['SKIM_ISCONFIGURED'] = 1 env['SKIM_VERSION'] = os.popen(env['PKGCONFIG'] + " --modversion skim").read().strip() env['SKIM_BINARY_VERSION'] = os.popen(env['PKGCONFIG'] + " --variable=skim_binary_version skim").read().strip() env['SKIM_LIBDIR'] = os.popen(env['PKGCONFIG'] + " --variable=libdir skim").read().strip() env['SKIMCONFIGLIB_VERSIONED'] = env['SKIM_LIBDIR'] + "/skim-1.0/" + \ env['SKIM_BINARY_VERSION'] + "/Config" # Attach the functions to the environment so that sconscripts or other modules can use them from SCons.Script.SConscript import SConsEnvironment SConsEnvironment.SKIMinstall = SKIMinstall SConsEnvironment.SKIMshlib = SKIMshlib
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')
def generate(env): # Fix scons & gcc borkedness (scons not looking in PATH for gcc # and mingw gcc 4.1 linker crashing if TMP or TEMP isn't set). env['ENV']['PATH'] = os.environ['PATH'] if os.environ.has_key('MINGDIR'): env['ENV']['MINGDIR'] = os.environ['MINGDIR'] if os.environ.has_key('TMP'): env['ENV']['TMP'] = os.environ['TMP'] if os.environ.has_key('TEMP'): env['ENV']['TEMP'] = os.environ['TEMP'] # We break unitsync if the filename of the shared object has a 'lib' prefix. # It is also nicer for the AI shared objects. env['LIBPREFIX'] = '' # I don't see any reason to make this configurable --tvo. # Note that commenting out / setting this to `None' will break the buildsystem. env['builddir'] = 'build' # SCons chokes in env.SConsignFile() if path doesn't exist. if not os.path.exists(env['builddir']): os.makedirs(env['builddir']) # Avoid spreading .sconsign files everywhere - keep this line # Use os.path.abspath() here because somehow the argument to SConsignFile is relative to the # directory of the toplevel trunk/SConstruct and not the current directory, trunk/rts/SConstruct. env.SConsignFile( os.path.abspath(os.path.join(env['builddir'], 'scons_signatures'))) usrcachefile = os.path.join(env['builddir'], 'usropts.py') intcachefile = os.path.join(env['builddir'], 'intopts.py') usropts = Options(usrcachefile) intopts = Options(intcachefile) #user visible options usropts.AddOptions( #permanent options ('platform', 'Set to linux, freebsd or windows', None), ('debug', 'Set to yes to produce a binary with debug information', 0), ('syncdebug', 'Set to yes to enable the sync debugger', False), ('synccheck', 'Set to yes to enable sync checker & resyncer', False), ('optimize', 'Enable processor optimizations during compilation', 1), ('profile', 'Set to yes to produce a binary with profiling information', False), ('cpppath', 'Set path to extra header files', []), ('libpath', 'Set path to extra libraries', []), ('fpmath', 'Set to 387 or SSE on i386 and AMD64 architectures', '387'), ('prefix', 'Install prefix used at runtime', '/usr/local'), ('installprefix', 'Install prefix used for installion', '$prefix'), ('datadir', 'Data directory (relative to prefix)', 'share/games/spring'), ('bindir', 'Directory for executables (rel. to prefix)', 'games'), ('libdir', 'Directory for AI plugin modules (rel. to prefix)', 'lib/spring'), ('strip', 'Discard symbols from the executable (only when neither debugging nor profiling)', True), #porting options - optional in a first phase ('disable_avi', 'Set to no to turn on avi support', 'False on windows, True otherwise'), #other ported parts ('use_tcmalloc', 'Use tcmalloc from goog-perftools for memory allocation', False), ('use_mmgr', 'Use memory manager', False), ('cachedir', 'Cache directory (see scons manual)', None)) #internal options intopts.AddOptions( ('LINKFLAGS', 'linker flags'), ('LIBPATH', 'library path'), ('LIBS', 'libraries'), ('CCFLAGS', 'c compiler flags'), ('CXXFLAGS', 'c++ compiler flags'), ('CPPDEFINES', 'c preprocessor defines'), ('CPPPATH', 'c preprocessor include path'), ('CC', 'c compiler'), ('CXX', 'c++ compiler'), ('spring_defines', 'extra c preprocessor defines for spring'), ('is_configured', 'configuration version stamp')) usropts.Update(env) intopts.Update(env) env.Help(usropts.GenerateHelpText(env)) # Use this to avoid an error message 'how to make target configure ?' env.Alias('configure', None) if not 'configure' in sys.argv and not ( (env.has_key('is_configured') and env['is_configured'] == 5) or env.GetOption('clean')): print "Not configured or configure script updated. Run `scons configure' first." print "Use `scons --help' to show available configure options to `scons configure'." env.Exit(1) if 'configure' in sys.argv: # be paranoid, unset existing variables for key in [ 'platform', 'debug', 'optimize', 'profile', 'cpppath', 'libpath', 'prefix', 'installprefix', 'datadir', 'bindir', 'libdir', 'cachedir', 'strip', 'disable_avi', 'use_tcmalloc', 'use_mmgr', 'LINKFLAGS', 'LIBPATH', 'LIBS', 'CCFLAGS', 'CXXFLAGS', 'CPPDEFINES', 'CPPPATH', 'CC', 'CXX', 'is_configured', 'spring_defines' ]: if env.has_key(key): env.__delitem__(key) print "\nNow configuring. If something fails, consult `config.log' for details.\n" #parse cmdline 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 args = makeHashTable(sys.argv) env['is_configured'] = 5 if args.has_key('platform'): env['platform'] = args['platform'] else: env['platform'] = detect.platform() fix_windows_spawn(env) if os.environ.has_key('CC'): env['CC'] = os.environ['CC'] else: env['CC'] = 'gcc' if os.environ.has_key('CXX'): env['CXX'] = os.environ['CXX'] else: env['CXX'] = 'g++' gcc_version = config.check_gcc_version(env) # Declare some helper functions for boolean and string options. def bool_opt(key, default): if args.has_key(key): if args[key] == 'no' or args[key] == 'false' or args[ key] == '0': env[key] = False elif args[key] == 'yes' or args[key] == 'true' or args[ key] == '1': env[key] = True else: print "\ninvalid", key, "option, must be one of: yes, true, no, false, 0, 1." env.Exit(1) else: env[key] = default def string_opt(key, default): if args.has_key(key): env[key] = args[key] else: env[key] = default def stringarray_opt(key, default): if args.has_key(key): env[key] = args[key].split(';') else: env[key] = default # Use single precision constants only. # This should be redundant with the modifications done by tools/double_to_single_precision.sed. # Other options copied from streflop makefiles. env['CCFLAGS'] = [ '-fsingle-precision-constant', '-frounding-math', '-fsignaling-nans', '-mieee-fp' ] # profile? bool_opt('profile', False) if env['profile']: print "profiling enabled,", env.AppendUnique(CCFLAGS=['-pg'], LINKFLAGS=['-pg']) else: print "profiling NOT enabled,", # debug? if args.has_key('debug'): level = args['debug'] if level == 'no' or level == 'false': level = '0' elif level == 'yes' or level == 'true': level = '3' else: level = '0' if int(level) == 0: print "debugging NOT enabled,", env['debug'] = 0 env.AppendUnique(CPPDEFINES=['NDEBUG']) elif int(level) >= 1 and int(level) <= 3: print "level", level, "debugging enabled,", env['debug'] = level # MinGW gdb chokes on the dwarf debugging format produced by '-ggdb', # so use the more generic '-g' instead. if env['platform'] == 'windows' or env['syncdebug']: env.AppendUnique(CCFLAGS=['-g'], CPPDEFINES=['DEBUG', '_DEBUG']) else: env.AppendUnique(CCFLAGS=['-ggdb' + level], CPPDEFINES=['DEBUG', '_DEBUG']) else: print "\ninvalid debug option, must be one of: yes, true, no, false, 0, 1, 2, 3." env.Exit(1) # optimize? if args.has_key('optimize'): level = args['optimize'] if level == 'no' or level == 'false': level = '0' elif level == 'yes' or level == 'true': level = '2' else: if env['debug']: level = '0' else: level = '2' if level == 's' or level == 'size' or (int(level) >= 1 and int(level) <= 3): print "level", level, "optimizing enabled" env['optimize'] = level #archflags = detect.processor(gcc_version >= ['3','4','0']) # -fstrict-aliasing causes constructs like: # float f = 10.0f; int x = *(int*)&f; # to break. # Since those constructs are used in the netcode and MathTest code, we disable the optimization. env.AppendUnique( CCFLAGS=['-O' + level, '-pipe', '-fno-strict-aliasing']) elif int(level) == 0: print "optimizing NOT enabled", env['optimize'] = 0 else: print "\ninvalid optimize option, must be one of: yes, true, no, false, 0, 1, 2, 3, s, size." env.Exit(1) # Must come before the '-fvisibility=hidden' code. bool_opt('syncdebug', False) bool_opt('synccheck', False) if env['syncdebug'] and env['synccheck']: print "syncdebug and synccheck are mutually exclusive. Please choose one." env.Exit(1) string_opt('fpmath', '387') # If sync debugger is on, disable inlining, as it makes it much harder to follow backtraces. if env['syncdebug']: # Disable all possible inlining, just to be sure. env['CCFLAGS'] += [ '-fno-default-inline', '-fno-inline', '-fno-inline-functions', '-fno-inline-functions-called-once' ] # It seems only gcc 4.0 and higher supports this. if gcc_version >= ['4', '0', '0'] and env['platform'] != 'windows': env['CCFLAGS'] += ['-fvisibility=hidden'] # Allow easy switching between 387 and SSE fpmath. if env['fpmath']: env['CCFLAGS'] += ['-mfpmath=' + env['fpmath']] if env['fpmath'] == 'sse': print "WARNING: SSE math vs X87 math is unsynced!" print "WARNING: Do not go online with the binary you are currently building!" env['CCFLAGS'] += ['-msse', '-msse2'] env['CXXFLAGS'] = env['CCFLAGS'] # Do not do this anymore because it may severely mess up our carefully selected options. # Print a warning and ignore them instead. # fall back to environment variables if neither debug nor optimize options are present if not args.has_key('debug') and not args.has_key('optimize'): if os.environ.has_key('CFLAGS'): #print "using CFLAGS:", os.environ['CFLAGS'] #env['CCFLAGS'] = SCons.Util.CLVar(os.environ['CFLAGS']) print "WARNING: attempt to use environment CFLAGS has been ignored." if os.environ.has_key('CXXFLAGS'): #print "using CXXFLAGS:", os.environ['CXXFLAGS'] #env['CXXFLAGS'] = SCons.Util.CLVar(os.environ['CXXFLAGS']) print "WARNING: attempt to use environment CXXFLAGS has been ignored." #else: # env['CXXFLAGS'] = env['CCFLAGS'] bool_opt('strip', True) bool_opt('disable_avi', env['platform'] != 'windows') bool_opt('use_tcmalloc', False) bool_opt('use_mmgr', False) string_opt('prefix', '/usr/local') string_opt('installprefix', '$prefix') string_opt('datadir', 'share/games/spring') string_opt('bindir', 'games') string_opt('libdir', 'lib/spring') string_opt('cachedir', None) # Make a list of preprocessor defines. env.AppendUnique(CPPDEFINES=['_REENTRANT', '_SZ_ONE_DIRECTORY']) spring_defines = ['DIRECT_CONTROL_ALLOWED'] # Add define specifying type of floating point math to use. if env['fpmath']: if env['fpmath'] == 'sse': spring_defines += ['STREFLOP_SSE'] if env['fpmath'] == '387': spring_defines += ['STREFLOP_X87'] # Add/remove SYNCDEBUG to enable/disable sync debugging. if env['syncdebug']: spring_defines += ['SYNCDEBUG'] if env['synccheck']: spring_defines += ['SYNCCHECK'] # Don't define this: it causes a full recompile when you change it, even though it is only used in Main.cpp, # and some AIs maybe. Just make exceptions in SConstruct. #defines += ['SPRING_DATADIR="\\"'+env['datadir']+'\\""'] if env['disable_avi']: spring_defines += ['NO_AVI'] if env['use_mmgr']: spring_defines += ['USE_MMGR'] env['spring_defines'] = spring_defines stringarray_opt('cpppath', []) stringarray_opt('libpath', []) include_path = env['cpppath'] + ['rts', 'rts/System'] include_path += ['lua/luabind', 'lua/lua/include'] lib_path = env['libpath'] + ['rts/lib/streflop'] if env['platform'] == 'freebsd': include_path += [ '/usr/local/include', '/usr/X11R6/include', '/usr/X11R6/include/GL' ] lib_path += ['/usr/local/lib', '/usr/X11R6/lib'] env.AppendUnique(CCFLAGS=['-pthread'], CXXFLAGS=['-pthread']) elif env['platform'] == 'linux': include_path += ['/usr/include', '/usr/include/GL'] env.AppendUnique(CCFLAGS=['-pthread'], CXXFLAGS=['-pthread'], LINKFLAGS=['-Wl,-E']) elif env['platform'] == 'darwin': include_path += [ '/usr/include', '/usr/local/include', '/opt/local/include', '/usr/X11R6/include' ] lib_path += ['/opt/local/lib', '/usr/local/lib'] env['SHLINKFLAGS'] = '$LINKFLAGS -dynamic' env['SHLIBSUFFIX'] = '.dylib' elif env['platform'] == 'windows': include_path += [os.path.join('mingwlibs', 'include')] lib_path += [os.path.join('mingwlibs', 'lib')] if os.environ.has_key('MINGDIR'): include_path += [ os.path.join(os.environ['MINGDIR'], 'include') ] lib_path += [os.path.join(os.environ['MINGDIR'], 'lib')] else: print 'ERROR: MINGDIR environment variable not set and MSVC build unsupported.' print 'Set it to your Dev-Cpp or MinGW install directory (e.g. C:\\Dev-Cpp) and try again.' env.Exit(1) env.AppendUnique(CCFLAGS=['-mthreads'], CXXFLAGS=['-mthreads'], LINKFLAGS=['-mwindows']) # use '-pthreads' for Solaris, according to /usr/include/boost/config/requires_threads.hpp env.AppendUnique(CPPPATH=include_path, LIBPATH=lib_path) config.configure(env, conf_dir=os.path.join(env['builddir'], 'sconf_temp')) env.AppendUnique(LIBS=['streflop']) usropts.Save(usrcachefile, env) intopts.Save(intcachefile, env) # Substitute prefix in installprefix env['installprefix'] = env.subst(env['installprefix']) # Fix up some suffices for mingw crosscompile. if env['platform'] == 'windows': env['SHLIBSUFFIX'] = '.dll' env['PROGSUFFIX'] = '.exe' #Should we strip the exe? if env.has_key('strip') and env['strip'] and not env['debug'] and not env[ 'profile'] and not env.GetOption('clean'): env['strip'] = True else: env['strip'] = False #BuildDir support code if env['builddir']: for d in filelist.list_directories(env, 'rts'): env.BuildDir(os.path.join(env['builddir'], d), d, duplicate=False) for d in filelist.list_directories(env, 'lua'): env.BuildDir(os.path.join(env['builddir'], d), d, duplicate=False) for d in filelist.list_directories(env, 'AI'): env.BuildDir(os.path.join(env['builddir'], d), d, duplicate=False) #CacheDir support code if env.has_key('cachedir') and env['cachedir']: if not os.path.exists(env['cachedir']): os.makedirs(env['cachedir']) env.CacheDir(env['cachedir']) fix_windows_spawn(env)
def generate(env): """"Set up the qt and kde environment and builders - the moc part is difficult to understand """ if env['HELP']: print """ """+BOLD+"""*** KDE options *** -------------------"""+NORMAL+""" """+BOLD+"""* prefix """+NORMAL+""": base install path, ie: /usr/local """+BOLD+"""* execprefix """+NORMAL+""": install path for binaries, ie: /usr/bin """+BOLD+"""* datadir """+NORMAL+""": install path for the data, ie: /usr/local/share """+BOLD+"""* libdir """+NORMAL+""": install path for the libs, ie: /usr/lib """+BOLD+"""* libsuffix """+NORMAL+""": suffix of libraries on amd64, ie: 64, 32 """+BOLD+"""* kdeincludes"""+NORMAL+""": path to the kde includes (/usr/include/kde on debian, ...) """+BOLD+"""* qtincludes """+NORMAL+""": same punishment, for qt includes (/usr/include/qt on debian, ...) """+BOLD+"""* kdelibs """+NORMAL+""": path to the kde libs, for linking the programs """+BOLD+"""* qtlibs """+NORMAL+""": same punishment, for qt libraries ie: """+BOLD+"""scons configure libdir=/usr/local/lib qtincludes=/usr/include/qt """+NORMAL import SCons.Defaults import SCons.Tool import SCons.Util ui_extensions = [".ui"] header_extensions = [".h", ".hxx", ".hpp", ".hh"] source_extensions = [".cpp", ".cxx", ".cc"] def find_file(filename, paths, node_factory): retval = None for dir in paths: node = node_factory(filename, dir) if node.rexists(): return node return None class _Metasources: """ Callable class, which works as an emitter for Programs, SharedLibraries and StaticLibraries.""" def __init__(self, objBuilderName): self.objBuilderName = objBuilderName def __call__(self, target, source, env): """ Smart autoscan function. Gets the list of objects for the Program or Lib. Adds objects and builders for the special qt files. """ try: if int(env.subst('$QT_AUTOSCAN')) == 0: return target, source except ValueError: pass try: qtdebug = int(env.subst('$QT_DEBUG')) except ValueError: qtdebug = 0 # some shortcuts used in the scanner FS = SCons.Node.FS.default_fs splitext = SCons.Util.splitext objBuilder = getattr(env, self.objBuilderName) # some regular expressions: # Q_OBJECT detection q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]') # The following is kind of hacky to get builders working properly (FIXME) ?? objBuilderEnv = objBuilder.env objBuilder.env = env mocBuilderEnv = env.Moc.env env.Moc.env = env # make a deep copy for the result; MocH objects will be appended out_sources = source[:] for obj in source: if not obj.has_builder(): # binary obj file provided if qtdebug: print "scons: qt: '%s' seems to be a binary. Discarded." % str(obj) continue cpp = obj.sources[0] if not splitext(str(cpp))[1] in source_extensions: if qtdebug: print "scons: qt: '%s' is no cxx file. Discarded." % str(cpp) # c or fortran source continue #cpp_contents = comment.sub('', cpp.get_contents()) cpp_contents = cpp.get_contents() h = None ui = None for ui_ext in ui_extensions: # try to find the ui file in the corresponding source directory uiname = splitext(cpp.name)[0] + ui_ext ui = find_file(uiname, (cpp.get_dir(),), FS.File) if ui: if qtdebug: print "scons: qt: found .ui file of header" #% (str(h), str(cpp)) #h_contents = comment.sub('', h.get_contents()) break # if we have a .ui file, do not continue, it is automatically handled by Uic if ui: continue for h_ext in header_extensions: # try to find the header file in the corresponding source # directory hname = splitext(cpp.name)[0] + h_ext h = find_file(hname, (cpp.get_dir(),), FS.File) if h: if qtdebug: print "scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp)) #h_contents = comment.sub('', h.get_contents()) h_contents = h.get_contents() break if not h and qtdebug: print "scons: qt: no header for '%s'." % (str(cpp)) if h and q_object_search.search(h_contents): # h file with the Q_OBJECT macro found -> add .moc or _moc.cpp file moc_cpp = None if env.has_key('NOMOCSCAN'): moc_cpp = env.Moc(h) else: reg = '\n\s*#include\s*("|<)'+splitext(cpp.name)[0]+'.moc("|>)' meta_object_search = re.compile(reg) if meta_object_search.search(cpp_contents): moc_cpp = env.Moc(h) else: moc_cpp = env.Moccpp(h) moc_o = objBuilder(moc_cpp) out_sources.append(moc_o) if qtdebug: print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp[0])) if cpp and q_object_search.search(cpp_contents): print "error, bksys cannot handle cpp files with Q_OBJECT classes" print "if you are sure this is a feature worth the effort, " print "report this to the authors tnagyemail-mail yahoo.fr" # restore the original env attributes (FIXME) objBuilder.env = objBuilderEnv env.Moc.env = mocBuilderEnv return (target, out_sources) MetasourcesShared = _Metasources('SharedObject') MetasourcesStatic = _Metasources('StaticObject') CLVar = SCons.Util.CLVar splitext = SCons.Util.splitext Builder = SCons.Builder.Builder # Detect the environment - replaces ./configure implicitely and store the options into a cache from SCons.Options import Options cachefile=env['CACHEDIR']+'kde.cache.py' opts = Options(cachefile) opts.AddOptions( ('PREFIX', 'root of the program installation'), ('QTDIR', 'root of qt directory'), ('QTLIBPATH', 'path to the qt libraries'), ('QTINCLUDEPATH', 'path to the qt includes'), ('QT_UIC', 'moc directory'), ('QT_MOC', 'moc executable command'), ('QTPLUGINS', 'uic executable command'), ('KDEDIR', 'root of kde directory'), ('KDELIBPATH', 'path to the kde libs'), ('KDEINCLUDEPATH', 'path to the kde includes'), ('KDEBIN', 'installation path of the kde binaries'), ('KDEMODULE', 'installation path of the parts and libs'), ('KDEAPPS', ''), ('KDEDATA', 'installation path of the application data'), ('KDELOCALE', ''), ('KDEDOC', 'installation path of the application documentation'), ('KDEKCFG', 'installation path of the .kcfg files'), ('KDEXDG', 'installation path of the service types'), ('KDEXDGDIR', 'installation path of the xdg service directories'), ('KDEMENU', ''), ('KDEMIME', 'installation path of to the mimetypes'), ('KDEICONS', ''), ('KDESERV', ''), ) opts.Update(env) # reconfigure when things are missing if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('QTDIR') or not env.has_key('KDEDIR')): detect_kde(env) # finally save the configuration to the cache file opts.Save(cachefile, env) ## set default variables, one can override them in sconscript files env.Append(CXXFLAGS = ['-I'+env['KDEINCLUDEPATH'], '-I'+env['QTINCLUDEPATH'] ]) env.Append(LIBPATH = [env['KDELIBPATH'], env['QTLIBPATH'] ]) env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 env['QT_AUTOSCAN'] = 1 env['QT_DEBUG'] = 0 env['QT_UIC_HFLAGS'] = '-L $QTPLUGINS -nounload' env['QT_UIC_CFLAGS'] = '$QT_UIC_HFLAGS -tr tr2i18n' env['QT_LIBS'] = 'qt-mt' env['QT_UICIMPLPREFIX'] = '' env['QT_UICIMPLSUFFIX'] = '.cpp' env['QT_MOCHPREFIX'] = '' env['QT_MOCHSUFFIX'] = '.moc' env['KDE_KCFG_IMPLPREFIX'] = '' env['KDE_KCFG_IMPL_HSUFFIX'] = '.h' env['KDE_KCFG_IMPL_CSUFFIX'] = '.cpp' env['KDE_SKEL_IMPL_SUFFIX'] = '.skel' env['MEINPROC'] = 'meinproc' env['MSGFMT'] = 'msgfmt' ## ui file processing def uic_processing(target, source, env): inc_kde = '#include <klocale.h>\n#include <kdialog.h>\n' inc_moc = '#include "%s"\n' % target[2].name comp_h = '$QT_UIC $QT_UIC_HFLAGS -o %s %s' % (target[0].path, source[0].path) comp_c = '$QT_UIC $QT_UIC_CFLAGS -impl %s %s' % (target[0].path, source[0].path) comp_moc = '$QT_MOC -o %s %s' % (target[2].path, target[0].path) ret = env.Execute(comp_h) if ret: return ret dest = open( target[1].path, "w" ) dest.write(inc_kde) dest.close() ret = env.Execute( comp_c+" >> "+target[1].path ) if ret: return ret dest = open( target[1].path, "a" ) dest.write(inc_moc) dest.close() ret = env.Execute( comp_moc ) return ret def uicEmitter(target, source, env): adjustixes = SCons.Util.adjustixes bs = SCons.Util.splitext(str(source[0].name))[0] bs = os.path.join(str(target[0].get_dir()),bs) # first target is automatically added by builder (.h file) if len(target) < 2: # second target is .cpp file target.append(adjustixes(bs, env.subst('$QT_UICIMPLPREFIX'), env.subst('$QT_UICIMPLSUFFIX'))) if len(target) < 3: # third target is .moc file target.append(adjustixes(bs, env.subst('$QT_MOCHPREFIX'), env.subst('$QT_MOCHSUFFIX'))) return target, source UIC_BUILDER = Builder( action = uic_processing, emitter = uicEmitter, suffix = '.h', src_suffix = '.ui') ## moc file processing env['QT_MOCCOM'] = ('$QT_MOC -o ${TARGETS[0]} $SOURCE') MOC_BUILDER = Builder( action = '$QT_MOCCOM', suffix = '.moc', src_suffix = '.h') MOCCPP_BUILDER = Builder( action = '$QT_MOCCOM', suffix = '_moc.cpp', src_suffix = '.h') ## kcfg file processing def kcfgGenerator(target, source, env, for_signature): act=[] act.append('kconfig_compiler -d'+str(source[0].get_dir())+' '+source[1].path+' '+source[0].path) return act def kcfgEmitter(target, source, env): adjustixes = SCons.Util.adjustixes bs = SCons.Util.splitext(str(source[0].name))[0] bs = os.path.join(str(target[0].get_dir()),bs) # .h file is automatically added if len(target) < 2: # add .cpp file target.append(adjustixes(bs, env.subst('$KDE_KCFG_IMPLPREFIX'), env.subst('$KDE_KCFG_IMPL_CSUFFIX'))) if len(source) <2: if not os.path.isfile(str(source[0])): print RED+'kcfg file given'+str(source[0])+' does not exist !'+NORMAL return target, source kfcgfilename="" kcfgFileDeclRx = re.compile("^[fF]ile\s*=\s*(.+)\s*$") for line in file(str(source[0]), "r").readlines(): match = kcfgFileDeclRx.match(line.strip()) if match: kcfgfilename = match.group(1) break source.append(str(source[0].get_dir())+'/'+kcfgfilename) return target, source KCFG_BUILDER = Builder( generator = kcfgGenerator, emitter = kcfgEmitter, suffix = '.h', src_suffix = '.kcfgc') ## dcop processing def dcopGenerator(target, source, env, for_signature): act=[] act.append('dcopidl '+source[0].path+' > '+target[1].path+'|| ( rm -f '+target[1].path+' ; false)') act.append('dcopidl2cpp --c++-suffix cpp --no-signals --no-stub '+target[1].path) return act def dcopEmitter(target, source, env): bs = SCons.Util.splitext(str(source[0].name))[0] bs = os.path.join(str(target[0].get_dir()),bs) target.append(bs+'.kidl') #target.append(bs+'_skel.cpp') return target, source DCOP_BUILDER = Builder( generator = dcopGenerator, emitter = dcopEmitter, suffix = '_skel.cpp', src_suffix = '.h') ## documentation processing MEINPROC_BUILDER = Builder( action = '$MEINPROC --check --cache $TARGET $SOURCE', suffix = '.cache.bz2') ## translation files builder TRANSFILES_BUILDER = Builder( action = '$MSGFMT $SOURCE -o $TARGET', suffix = '.gmo', src_suffix = '.po') ## libtool file builder def la_file(target, source, env): dest=open(target[0].path, 'w') sname=source[0].name dest.write("dlname='%s'\n" % sname) dest.write("library_names='%s %s %s'\n" % (sname, sname, sname)) dest.write("old_library=''\n") dest.write("dependency_libs=''\n") dest.write("current=0\n") dest.write("age=0\n") dest.write("revision=0\n") dest.write("installed=yes\n") dest.write("shouldnotlink=no\n") dest.write("dlopen=''\n") dest.write("dlpreopen=''\n") dest.write("libdir='%s'" % env['KDEMODULE']) dest.close() return 0 LA_BUILDER = Builder( action = la_file, suffix = '.la', src_suffix = env['SHLIBSUFFIX']) ## register the builders env['BUILDERS']['Uic'] = UIC_BUILDER env['BUILDERS']['Moc'] = MOC_BUILDER env['BUILDERS']['Moccpp'] = MOCCPP_BUILDER env['BUILDERS']['Dcop'] = DCOP_BUILDER env['BUILDERS']['Kcfg'] = KCFG_BUILDER env['BUILDERS']['LaFile'] = LA_BUILDER env['BUILDERS']['Meinproc'] = MEINPROC_BUILDER env['BUILDERS']['Transfiles']= TRANSFILES_BUILDER static_obj, shared_obj = SCons.Tool.createObjBuilders(env) static_obj.src_builder.append('Uic') shared_obj.src_builder.append('Uic') static_obj.src_builder.append('Kcfg') shared_obj.src_builder.append('Kcfg') static_obj.src_builder.append('LaFile') shared_obj.src_builder.append('LaFile') static_obj.src_builder.append('Meinproc') shared_obj.src_builder.append('Meinproc') static_obj.src_builder.append('Transfiles') shared_obj.src_builder.append('Transfiles') ## Find the files to moc, dcop, and link against kde and qt env.AppendUnique(PROGEMITTER = [MetasourcesStatic], SHLIBEMITTER=[MetasourcesShared], LIBEMITTER =[MetasourcesStatic]) ## Handy helpers for building kde programs ## You should not have to modify them .. ## return a list of things def make_list(e): if type(e) is types.ListType: return e else: return e.split() #import SCons.Util skel_ext = [".skel", ".SKEL"] def KDEfiles(lenv, target, source): """ Returns a list of files for scons (handles kde tricks like .skel) It also makes custom checks against double includes like : ['file.ui', 'file.cpp'] (file.cpp is already included because of file.ui) """ src=[] ui_files=[] kcfg_files=[] skel_files=[] other_files=[] source_=make_list(source) # For each file, check wether it is a dcop file or not, and create the complete list of sources for file in source_: bs = SCons.Util.splitext(file)[0] ext = SCons.Util.splitext(file)[1] if ext in skel_ext: lenv.Dcop(bs+'.h') src.append(bs+'_skel.cpp') elif ext == ".moch": lenv.Moccpp(bs+'.h') src.append(bs+'_moc.cpp') else: src.append(file) if ext == '.ui': ui_files.append(bs) elif ext == '.kcfgc': kcfg_files.append(bs) elif ext == '.skel': skel_files.append(bs) else: other_files.append(bs) # Now check against typical newbie errors for file in ui_files: for ofile in other_files: if ofile == file: print RED+"WARNING: You have included "+file+".ui and another file of the same prefix"+NORMAL print "Files generated by uic (file.h, file.cpp must not be included" for file in kcfg_files: for ofile in other_files: if ofile == file: print RED+"WARNING: You have included "+file+".kcfg and another file of the same prefix"+NORMAL print "Files generated by kconfig_compiler (settings.h, settings.cpp) must not be included" return src """ In the future, these functions will contain the code that will dump the configuration for re-use from an IDE """ import glob def KDEinstall(lenv, restype, subdir, files): if not env['_INSTALL']: return basedir=env['DESTDIR'] if len(restype)>0: if not lenv.has_key(restype): print RED+"unknown resource type "+restype+NORMAL else: basedir += lenv[restype]+'/' #print file # <- useful to trace stuff :) install_list = env.Install(basedir+subdir+'/', files) env.Alias('install', install_list) return install_list def KDEinstallas(lenv, restype, destfile, file): if not env['_INSTALL']: return basedir=env['DESTDIR'] if len(restype)>0: if not lenv.has_key(restype): print RED+"unknown resource type "+restype+NORMAL else: basedir += lenv[restype]+'/' install_list = env.InstallAs(basedir+destfile, file) env.Alias('install', install_list) return install_list def KDEprogram(lenv, target, source): """ Makes a kde program The program is installed except if one sets env['NOAUTOINSTALL'] """ src = KDEfiles(lenv, target, source) program_list = lenv.Program(target, src) if not lenv.has_key('NOAUTOINSTALL'): KDEinstall(lenv, 'KDEBIN', '', target) return program_list def KDEshlib(lenv, target, source, kdelib=0, libprefix='lib'): """ Makes a shared library for kde (.la file for klibloader) The library is installed except if one sets env['NOAUTOINSTALL'] """ src = KDEfiles(lenv, target, source) lenv['LIBPREFIX']=libprefix library_list = lenv.SharedLibrary(target, src) lafile_list = lenv.LaFile(target, library_list) if not lenv.has_key('NOAUTOINSTALL'): install_dir = 'KDEMODULE' if kdelib==1: install_dir = 'KDELIBPATH' KDEinstall(lenv, install_dir, '', library_list) KDEinstall(lenv, install_dir, '', lafile_list) return library_list def KDEstaticlib(lenv, target, source): """ Makes a static library for kde - in practice you should not use static libraries 1. they take more memory than shared ones 2. makefile.am needed it because of limitations (cannot handle sources in separate folders - takes extra processing) """ src = KDEfiles(lenv, target, source) return lenv.StaticLibrary(target, src) # do not install static libraries by default def KDEaddflags_cxx(lenv, fl): """ Compilation flags for C++ programs """ lenv.AppendUnique(CXXFLAGS = make_list(fl)) def KDEaddflags_c(lenv, fl): """ Compilation flags for C programs """ lenv.AppendUnique(CFLAGS = make_list(fl)) def KDEaddflags_link(lenv, fl): """ Add link flags - Use this if KDEaddlibs below is not enough """ lenv.AppendUnique(LINKFLAGS = make_list(fl)) def KDEaddlibs(lenv, libs): """ Helper function """ lenv.AppendUnique(LIBS = make_list(libs)) def KDEaddpaths_includes(lenv, paths): """ Add new include paths """ lenv.AppendUnique(CPPPATH = make_list(paths)) def KDEaddpaths_libs(lenv, paths): """ Add paths to libraries """ lenv.AppendUnique(LIBPATH = make_list(paths)) def KDElang(lenv, folder, appname): """ Process translations (.po files) in a po/ dir """ transfiles = glob.glob(folder+'/*.po') for lang in transfiles: result = lenv.Transfiles(lang) country = SCons.Util.splitext(result[0].name)[0] KDEinstallas(lenv, 'KDELOCALE', country+'/LC_MESSAGES/'+appname+'.mo', result) def subdirs(lenv, folderlist): flist=make_list(folderlist) for i in flist: lenv.SConscript(i+"/SConscript") def KDEicon(lenv, icname='*', path='./'): """ Emulates the behaviour of Makefile.am to install icons Contributed by: "Andrey Golovizin" <grooz@gorodok@net> """ type_dic = { 'action' : 'actions', 'app' : 'apps', 'device' : 'devices', 'filesys' : 'filesystems', 'mime' : 'mimetypes' } dir_dic = { 'los' :'locolor/16x16', 'lom' :'locolor/32x32', 'him' :'hicolor/32x32', 'hil' :'hicolor/48x48', 'lo16' :'locolor/16x16', 'lo22' :'locolor/22x22', 'lo32' :'locolor/32x32', 'hi16' :'hicolor/16x16', 'hi22' :'hicolor/22x22', 'hi32' :'hicolor/32x32', 'hi48' :'hicolor/48x48', 'hi64' :'hicolor/64x64', 'hi128':'hicolor/128x128', 'hisc' :'hicolor/scalable', 'cr16' :'crystalsvg/16x16', 'cr22' :'crystalsvg/22x22', 'cr32' :'crystalsvg/32x32', 'cr48' :'crystalsvg/48x48', 'cr64' :'crystalsvg/64x64', 'cr128':'crystalsvg/128x128', 'crsc' :'crystalsvg/scalable' } iconfiles = [] for ext in "png xpm mng svg svgz".split(): files = glob.glob(path+'/'+'*-*-%s.%s' % (icname, ext)) iconfiles += files for iconfile in iconfiles: lst = iconfile.split('/') filename = lst[ len(lst) - 1 ] tmp = filename.split('-') if len(tmp)!=3: print RED+'WARNING: icon filename has unknown format: '+iconfile+NORMAL continue [icon_dir, icon_type, icon_filename]=tmp try: destfile = '%s/%s/%s/%s' % (lenv['KDEICONS'], dir_dic[icon_dir], type_dic[icon_type], icon_filename) except KeyError: print RED+'WARNING: unknown icon type: '+iconfile+NORMAL continue ## Do not use KDEinstallas here, as parsing from an ide will be necessary if env['_INSTALL']: env.Alias('install', env.InstallAs( env['DESTDIR']+'/'+destfile, iconfile ) ) def KDEuse(lenv, flags): _flags=make_list(flags) if 'environ' in _flags: ## The scons developers advise against using this but it is mostly innocuous :) import os lenv.AppendUnique( ENV = os.environ ) if not 'lang_qt' in _flags: ## Use this define if you are using the kde translation scheme (.po files) lenv.Append( CPPFLAGS = '-DQT_NO_TRANSLATION' ) if 'rpath' in _flags: ## Use this to set rpath - this may cause trouble if folders are moved (chrpath) lenv.Append( RPATH = [env['QTLIBPATH'], env['KDELIBPATH'], env['KDEMODULE']] ) if 'thread' in _flags: ## Uncomment the following if you need threading support lenv.KDEaddflags_cxx( ['-DQT_THREAD_SUPPORT', '-D_REENTRANT'] ) if not 'nohelp' in _flags: if lenv['_CONFIGURE'] or lenv['HELP']: env.Exit(0) ## To use kdDebug(intvalue)<<"some trace"<<endl; you need to define -DDEBUG ## it is done in admin/generic.py automatically when you do scons configure debug=1 # Attach the functions to the environment so that sconscripts can use them from SCons.Script.SConscript import SConsEnvironment SConsEnvironment.KDEprogram = KDEprogram SConsEnvironment.KDEshlib = KDEshlib SConsEnvironment.KDEstaticlib = KDEstaticlib SConsEnvironment.KDEinstall = KDEinstall SConsEnvironment.KDEinstallas = KDEinstallas SConsEnvironment.KDElang = KDElang SConsEnvironment.KDEicon = KDEicon SConsEnvironment.KDEaddflags_cxx = KDEaddflags_cxx SConsEnvironment.KDEaddflags_c = KDEaddflags_c SConsEnvironment.KDEaddflags_link = KDEaddflags_link SConsEnvironment.KDEaddlibs = KDEaddlibs SConsEnvironment.KDEaddpaths_includes = KDEaddpaths_includes SConsEnvironment.KDEaddpaths_libs = KDEaddpaths_libs SConsEnvironment.subdirs = subdirs SConsEnvironment.KDEuse = KDEuse
def generate(env): # Detect the Boost optionfile = env['CACHEDIR'] + 'boost.cache.py' opts = Options(optionfile) opts.AddOptions( ('Boost_FLAGS', 'compilation flags for Boost'), ('Boost_LDFLAGS', 'link flags for Boost'), ('BoostISCONFIGURED', 'configuration succeeded'), ) opts.Update(env) if env['HELP']: return # this condition is used to check when to redetect the configuration (do not remove) if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('BoostISCONFIGURED')): print "Checking for Boost : ", if env.has_key('BoostISCONFIGURED'): env.__delitem__('BoostISCONFIGURED') # clear options set previously if env.has_key('Boost_FLAGS'): env.__delitem__('Boost_FLAGS') if env.has_key('Boost_LDFLAGS'): env.__delitem__('Boost_LDFLAGS') boost_includes = """/usr/include /usr/local/include /opt/include /mingw/include /usr/include/boost-1_33 /usr/local/include/boost-1_33 /opt/include/boost-1_33 /mingw/include/boost-1_33 """.split() boost_include = '' for include_path in boost_includes: if os.path.exists(include_path + '/boost/any.hpp'): boost_include = include_path break if boost_include == '': env.pprint('RED', '[failed] includes not found !') env.Exit(1) boost_libs = """/usr/lib /usr/local/lib /opt/lib /mingw/lib""".split() boost_lib = '' for lib_path in boost_libs: fs_exists = os.popen( 'ls ' + lib_path + '/libboost_filesystem*.so 2>/dev/null').read().strip() thread_exists = os.popen( 'ls ' + lib_path + '/libboost_thread*.so 2>/dev/null').read().strip() if len(fs_exists) > 0 and len(thread_exists) > 0: boost_lib = lib_path if boost_lib == '': env.pprint('RED', '[failed] libraries not found !') env.Exit(1) env['Boost_FLAGS'] = "-I" + boost_include env['Boost_LDFLAGS'] = "-lboost_filesystem -lboost_thread" # success env['BoostISCONFIGURED'] = 1 env.pprint('GREEN', '[ ok ]') # save the options opts.Save(optionfile, env)
def generate(env): # I don't see any reason to make this configurable --tvo. # Note that commenting out / setting this to `None' will break the buildsystem. env['builddir'] = 'build' # SCons chokes in env.SConsignFile() if path doesn't exist. if not os.path.exists(env['builddir']): os.makedirs(env['builddir']) # Avoid spreading .sconsign files everywhere - keep this line # Use os.path.abspath() here because somehow the argument to SConsignFile is relative to the # directory of the toplevel trunk/SConstruct and not the current directory, trunk/rts/SConstruct. env.SConsignFile( os.path.abspath(os.path.join(env['builddir'], 'scons_signatures'))) usrcachefile = os.path.join(env['builddir'], 'usropts.py') intcachefile = os.path.join(env['builddir'], 'intopts.py') usropts = Options(usrcachefile) intopts = Options(intcachefile) #user visible options usropts.AddOptions( #permanent options ('platform', 'Set to linux, freebsd or windows', None), ('debug', 'Set to yes to produce a binary with debug information', 0), ('optimize', 'Enable processor optimizations during compilation', 1), ('profile', 'Set to yes to produce a binary with profiling information', False), ('prefix', 'Install prefix', '/usr/local'), ('datadir', 'Data directory', '$prefix/games/taspring'), ('strip', 'Discard symbols from the executable (only when neither debugging nor profiling)', True), #porting options - optional in a first phase ('disable_avi', 'Set to no to turn on avi support', True), ('disable_clipboard', 'Set to no to turn on clipboard code', True), #other ported parts ('disable_hpi', 'Set to no to turn on hpi support', False), ('disable_lua', 'Set to no to turn on Lua support', True), ('use_tcmalloc', 'Use tcmalloc from goog-perftools for memory allocation', False), ('use_mmgr', 'Use memory manager', False), ('cachedir', 'Cache directory (see scons manual)', None)) #internal options intopts.AddOptions(('LINKFLAGS', 'linker flags'), ('LIBPATH', 'library path'), ('LIBS', 'libraries'), ('CCFLAGS', 'c compiler flags'), ('CXXFLAGS', 'c++ compiler flags'), ('CPPDEFINES', 'c preprocessor defines'), ('CPPPATH', 'c preprocessor include path'), ('is_configured', 'configuration version stamp')) usropts.Update(env) intopts.Update(env) env.Help(usropts.GenerateHelpText(env)) # Use this to avoid an error message 'how to make target configure ?' env.Alias('configure', None) if not 'configure' in sys.argv and not ( (env.has_key('is_configured') and env['is_configured'] == 1) or env.GetOption('clean')): print "Not configured or configure script updated. Run `scons configure' first." print "Use `scons --help' to show available configure options to `scons configure'." env.Exit(1) if 'configure' in sys.argv: # be paranoid, unset existing variables for key in [ 'platform', 'debug', 'optimize', 'profile', 'prefix', 'datadir', 'cachedir', 'strip', 'disable_avi', 'disable_hpi', 'disable_lua', 'disable_aio', 'use_tcmalloc', 'use_mmgr', 'LINKFLAGS', 'LIBPATH', 'LIBS', 'CCFLAGS', 'CXXFLAGS', 'CPPDEFINES', 'CPPPATH', 'is_configured' ]: if env.has_key(key): env.__delitem__(key) print "\nNow configuring. If something fails, consult `config.log' for details.\n" #parse cmdline 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 args = makeHashTable(sys.argv) env['is_configured'] = 1 if args.has_key('platform'): env['platform'] = args['platform'] else: env['platform'] = detect.platform() # Declare some helper functions for boolean and string options. def bool_opt(key, default): if args.has_key(key): if args[key] == 'no' or args[key] == 'false' or args[ key] == '0': env[key] = False elif args[key] == 'yes' or args[key] == 'true' or args[ key] == '1': env[key] = True else: print "\ninvalid", key, "option, must be one of: yes, true, no, false, 0, 1." env.Exit(1) else: env[key] = default def string_opt(key, default): if args.has_key(key): env[key] = args[key] else: env[key] = default # profile? bool_opt('profile', False) if env['profile']: print "profiling enabled,", env.AppendUnique(CCFLAGS=['-pg'], LINKFLAGS=['-pg']) else: print "profiling NOT enabled,", # debug? if args.has_key('debug'): level = args['debug'] if level == 'no' or level == 'false': level = '0' elif level == 'yes' or level == 'true': level = '3' else: level = '0' if int(level) == 0: print "debugging NOT enabled,", env['debug'] = 0 elif int(level) >= 1 and int(level) <= 3: print "level", level, "debugging enabled,", env['debug'] = level env.AppendUnique(CCFLAGS=['-ggdb' + level], CPPDEFINES=['DEBUG', '_DEBUG']) else: print "\ninvalid debug option, must be one of: yes, true, no, false, 0, 1, 2, 3." env.Exit(1) # optimize? if args.has_key('optimize'): level = args['optimize'] if level == 'no' or level == 'false': level = '0' elif level == 'yes' or level == 'true': level = '2' else: if env['debug']: level = '0' else: level = '1' if int(level) == 0: print "optimizing NOT enabled,", env['optimize'] = 0 elif (int(level) >= 1 and int(level) <= 3) or level == 's' or level == 'size': print "level", level, "optimizing enabled" env['optimize'] = level archflags = detect.processor( config.check_gcc_version(env) >= ['3', '4', '0']) env.AppendUnique(CCFLAGS=['-O' + level, '-pipe'] + archflags) else: print "\ninvalid optimize option, must be one of: yes, true, no, false, 0, 1, 2, 3, s, size." env.Exit(1) env['CXXFLAGS'] = env['CCFLAGS'] # fall back to environment variables if neither debug nor optimize options are present if not args.has_key('debug') and not args.has_key('optimize'): if os.environ.has_key('CFLAGS'): print "using CFLAGS:", os.environ['CFLAGS'] env['CCFLAGS'] = SCons.Util.CLVar(os.environ['CFLAGS']) if os.environ.has_key('CXXFLAGS'): print "using CXXFLAGS:", os.environ['CXXFLAGS'] env['CXXFLAGS'] = SCons.Util.CLVar(os.environ['CXXFLAGS']) else: env['CXXFLAGS'] = env['CCFLAGS'] bool_opt('strip', True) bool_opt('disable_avi', True) bool_opt('disable_clipboard', True) bool_opt('disable_hpi', False) bool_opt('disable_lua', True) bool_opt('use_tcmalloc', False) bool_opt('use_mmgr', False) string_opt('prefix', '/usr/local') string_opt('datadir', '$prefix/games/taspring') string_opt('cachedir', None) defines = ['_REENTRANT', 'DIRECT_CONTROL_ALLOWED', '_SZ_ONE_DIRECTORY'] defines += ['SPRING_DATADIR="\\"' + env['datadir'] + '\\""'] if env['disable_hpi']: defines += ['NO_HPI'] if env['disable_clipboard']: defines += ['NO_CLIPBOARD'] if env['disable_avi']: defines += ['NO_AVI'] if env['disable_lua']: defines += ['NO_LUA'] if env['use_mmgr']: defines += ['USE_MMGR'] env.AppendUnique(CPPDEFINES=defines) include_path = ['rts', 'rts/System'] lib_path = [] if env['platform'] == 'freebsd': include_path += [ '/usr/local/include', '/usr/X11R6/include', '/usr/X11R6/include/GL' ] lib_path += ['/usr/local/lib', '/usr/X11R6/lib'] env.AppendUnique(CCFLAGS=['-pthread'], CXXFLAGS=['-pthread']) elif env['platform'] == 'linux': include_path += [ '/usr/include', '/usr/include/GL', '/usr/include/CEGUI' ] env.AppendUnique(CCFLAGS=['-pthread'], CXXFLAGS=['-pthread']) elif env['platform'] == 'darwin': include_path += [ '/usr/include', '/usr/local/include', '/opt/local/include', '/usr/X11R6/include' ] lib_path += ['/opt/local/lib', '/usr/local/lib'] env['SHLINKFLAGS'] = '$LINKFLAGS -dynamic' env['SHLIBSUFFIX'] = '.dylib' elif env['platform'] == 'windows': include_path += ['crashrpt/include'] lib_path += ['crashrpt/lib'] env.AppendUnique(CCFLAGS=['-mthreads'], CXXFLAGS=['-mthreads']) # use '-pthreads' for Solaris, according to /usr/include/boost/config/requires_threads.hpp env.AppendUnique(CPPPATH=include_path, LIBPATH=lib_path) config.configure(env, conf_dir=os.path.join(env['builddir'], 'sconf_temp')) usropts.Save(usrcachefile, env) intopts.Save(intcachefile, env) #Should we strip the exe? if env.has_key('strip') and env['strip'] and not env['debug'] and not env[ 'profile'] and not env.GetOption('clean'): env['strip'] = True else: env['strip'] = False #BuildDir support code if env['builddir']: for d in filelist.list_directories(env, 'rts'): env.BuildDir(os.path.join(env['builddir'], d), d, duplicate=False) for d in filelist.list_directories(env, 'AI'): env.BuildDir(os.path.join(env['builddir'], d), d, duplicate=False) #CacheDir support code if env.has_key('cachedir') and env['cachedir']: if not os.path.exists(env['cachedir']): os.makedirs(env['cachedir']) env.CacheDir(env['cachedir'])
def generate(env): SConsEnvironment.pprint = pprint if '--help' in sys.argv: 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)') p('BOLD', '* prefix ', 'the installation path') p('BOLD', '* scons configure prefix=/usr/local') p('BOLD', '* scons install prefix=/opt/local\n') sys.exit(0) if not env.has_key('CACHEDIR'): env['CACHEDIR'] = os.path.join(os.getcwd(), 'cache') if not os.path.isdir(env['CACHEDIR']): os.mkdir(env['CACHEDIR']) env.SConsignFile(env['CACHEDIR'] + '/scons_signatures') env.Alias('configure', None) 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) ## load the options cachefile = os.path.join(env['CACHEDIR'], 'generic.cache.py') opts = Options(cachefile) opts.AddOptions(('PREFIX', 'prefix for installation'), ('DEBUG', 'Enable debug'), ('CONFIGURED', 'True if already configured')) opts.Update(env) #Set config options if needed if not env.has_key('CONFIGURED') or 'configure' in sys.argv: #Get installation prefix if env['ARGS'].has_key('prefix'): env['PREFIX'] = os.path.abspath(env['ARGS'].get('prefix', '')) else: env['PREFIX'] = '/usr/local/' if env['ARGS'].has_key('debug'): env['DEBUG'] = env['ARGS'].get('debug', 0) else: env['DEBUG'] = '0' env['CONFIGURED'] = 1 opts.Save(cachefile, env) #Set debug options if env['DEBUG'] == '1': env.AppendUnique(CXXFLAGS='-g -Wall -DDEBUG', CFLAGS='-g -Wall -DDEBUG') else: env.AppendUnique(CXXFLAGS='--fast-math -O2 -DNDEBUG', CFLAGS='--fast-math -O2 -DNDEBUG')