get the basics of a new scons build system together
[xonotic/netradiant.git] / SConstruct
index d5d6c824dc85f93c651b64683d1c74842b0e8534..a8307a6e62459c337ff87c8caff908542ee461e3 100644 (file)
-# scons build script\r
+# -*- mode: python -*-\r
+# ZeroRadiant build scripts\r
+# TTimo <ttimo@idsoftware.com>\r
 # http://scons.sourceforge.net\r
 \r
-import commands, re, sys, os, pickle, string, popen2\r
-from makeversion import radiant_makeversion, get_version\r
-from osx_setup import do_osx_setup\r
+import sys, os, platform, cPickle\r
 \r
-# to access some internal stuff\r
-import SCons\r
+import utils, config\r
 \r
-conf_filename='site.conf'\r
-# there is a default hardcoded value, you can override on command line, those are saved between runs\r
-# we only handle strings\r
-serialized=['CC', 'CXX', 'JOBS', 'BUILD', 'SETUP']\r
+conf_filename = 'site.sconf'\r
 \r
-# help -------------------------------------------\r
-\r
-Help("""\r
-Usage: scons [OPTIONS] [TARGET] [CONFIG]\r
-\r
-[OPTIONS] and [TARGET] are covered in command line options, use scons -H\r
-\r
-[CONFIG]: KEY="VALUE" [...]\r
-a number of configuration options saved between runs in the """ + conf_filename + """ file\r
-erase """ + conf_filename + """ to start with default settings again\r
-\r
-CC\r
-CXX\r
-       Specify C and C++ compilers (defaults gcc and g++)\r
-       ex: CC="gcc-3.2"\r
-       You can use ccache and distcc, for instance:\r
-       CC="ccache distcc gcc" CXX="ccache distcc g++"\r
-\r
-JOBS\r
-       Parallel build\r
-       ex: JOBS="4" is a good setting on SMP machines\r
-\r
-BUILD\r
-       Use debug/release to select build settings\r
-       ex: BUILD="release" - default is debug\r
-       OSX: use BUILD="info" to generate the set of release files\r
-\r
-SETUP\r
-  Build a setup - default 0\r
-"""\r
-)\r
-\r
-# end help ---------------------------------------\r
-  \r
-# sanity -----------------------------------------\r
-\r
-# use q decently recent python release\r
-EnsurePythonVersion( 2, 1 )\r
-# above 0.90\r
-EnsureSConsVersion( 0, 95 )\r
-print 'SCons ' + SCons.__version__\r
-\r
-# end sanity -------------------------------------\r
-\r
-# system detection -------------------------------\r
-\r
-# CPU type\r
-g_cpu = commands.getoutput('uname -m')\r
-exp = re.compile('.*i?86.*')\r
-if (g_cpu == 'Power Macintosh'):\r
-  g_cpu = 'ppc'\r
-elif exp.match(g_cpu):\r
-  g_cpu = 'x86'\r
-else:\r
-  g_cpu = 'cpu'\r
-\r
-# OS\r
-OS = commands.getoutput('uname')\r
-\r
-if (OS == 'Linux'):\r
-  # libc .. do the little magic!\r
-  # NOTE: this used to work fine up to libc 2.3\r
-  libc = commands.getoutput('/lib/libc.so.6 |grep "GNU C "|grep version|awk -F "version " \'{ print $2 }\'|cut -b -3')\r
-\r
-# end system detection ---------------------------\r
-\r
-# default settings -------------------------------\r
-\r
-CC='gcc'\r
-CXX='g++'\r
-JOBS='1'\r
-BUILD='debug'\r
-INSTALL='#install'\r
-SETUP='0'\r
-g_build_root = 'build'\r
-\r
-# end default settings ---------------------------\r
-\r
-# site settings ----------------------------------\r
-\r
-site_dict = {}\r
-if (os.path.exists(conf_filename)):\r
-       site_file = open(conf_filename, 'r')\r
-       p = pickle.Unpickler(site_file)\r
-       site_dict = p.load()\r
-       print 'Loading build configuration from ' + conf_filename\r
-       for k, v in site_dict.items():\r
-               exec_cmd = k + '=\"' + v + '\"'\r
-               print exec_cmd\r
-               exec(exec_cmd)\r
-\r
-# end site settings ------------------------------\r
-\r
-# command line settings --------------------------\r
-\r
-for k in serialized:\r
-       if (ARGUMENTS.has_key(k)):\r
-               exec_cmd = k + '=\"' + ARGUMENTS[k] + '\"'\r
-               print 'Command line: ' + exec_cmd\r
-               exec(exec_cmd)\r
-\r
-# end command line settings ----------------------\r
-\r
-# sanity check -----------------------------------\r
-\r
-if (SETUP == '1' and BUILD != 'release' and BUILD != 'info'):\r
-  print 'Forcing release build for setup'\r
-  BUILD = 'release'\r
-\r
-def GetGCCVersion(name):\r
-  ret = commands.getstatusoutput('%s -dumpversion' % name)\r
-  if ( ret[0] != 0 ):\r
-    return None\r
-  vers = string.split(ret[1], '.')\r
-  if ( len(vers) == 2 ):\r
-    return [ vers[0], vers[1], 0 ]\r
-  elif ( len(vers) == 3 ):\r
-    return vers\r
-  return None\r
-\r
-ver_cc = GetGCCVersion(CC)\r
-ver_cxx = GetGCCVersion(CXX)\r
-\r
-# end sanity check -------------------------------\r
-\r
-# save site configuration ----------------------\r
-\r
-for k in serialized:\r
-       exec_cmd = 'site_dict[\'' + k + '\'] = ' + k\r
-       exec(exec_cmd)\r
-\r
-site_file = open(conf_filename, 'w')\r
-p = pickle.Pickler(site_file)\r
-p.dump(site_dict)\r
-site_file.close()\r
-\r
-# end save site configuration ------------------\r
-\r
-# general configuration, target selection --------\r
-\r
-SConsignFile( "scons.signatures" )\r
-\r
-g_build = g_build_root + '/' + BUILD\r
-\r
-SetOption('num_jobs', JOBS)\r
-\r
-LINK = CXX\r
-# common flags\r
-CCFLAGS = ''\r
-CXXFLAGS = '-pipe -DQ_NO_STLPORT '\r
-CPPPATH = []\r
-if (BUILD == 'debug'):\r
-       CXXFLAGS += '-g -D_DEBUG '\r
-       CCFLAGS += '-g -D_DEBUG '\r
-elif (BUILD == 'release'):\r
-       CXXFLAGS += '-g -O2 '\r
-       CCFLAGS += '-g -O2 '\r
-elif ( BUILD == 'info' ):\r
-       print 'Preparing OSX release'\r
-       ( line, major, minor ) = get_version()\r
-       do_osx_setup( major, minor, 'osx-radiant-%s.run' % line )\r
-       sys.exit( 0 )\r
+try:\r
+       sys.argv.index( '-h' )\r
+except:\r
+       pass\r
 else:\r
-       print 'Unknown build configuration ' + BUILD\r
-       sys.exit( 0 )\r
-\r
-LINKFLAGS = ''\r
-if ( OS == 'Linux' ):\r
-  LINKFLAGS += '-Wl,-fini,fini_stub '\r
-if ( OS == 'Darwin' ):\r
-  CCFLAGS += '-force_cpusubtype_ALL -fPIC '\r
-  CXXFLAGS += '-force_cpusubtype_ALL -fPIC -fno-exceptions -fno-rtti '\r
-  CPPPATH.append('/sw/include')\r
-  CPPPATH.append('/usr/X11R6/include')\r
-  LINKFLAGS += '-L/sw/lib -L/usr/lib -L/usr/X11R6/lib '\r
-\r
-CPPPATH.append('libs')\r
-\r
-# extend the standard Environment a bit\r
-class idEnvironment(Environment):\r
-\r
-  def useGlib2(self):\r
-    self['CXXFLAGS'] += '`pkg-config glib-2.0 --cflags` '\r
-    self['CCFLAGS'] += '`pkg-config glib-2.0 --cflags` '\r
-    self['LINKFLAGS'] += '`pkg-config glib-2.0 --libs` '\r
-    \r
-  def useXML2(self):\r
-    self['CXXFLAGS'] += '`xml2-config --cflags` '      \r
-    self['CCFLAGS'] += '`xml2-config --cflags` '      \r
-    self['LINKFLAGS'] += '`xml2-config --libs` '\r
-\r
-  def useGtk2(self):\r
-    self['CXXFLAGS'] += '`pkg-config gtk+-2.0 --cflags` '\r
-    self['CCFLAGS'] += '`pkg-config gtk+-2.0 --cflags` '\r
-    self['LINKFLAGS'] += '`pkg-config gtk+-2.0 --libs-only-L` `pkg-config gtk+-2.0 --libs-only-l` '\r
-   \r
-  def useGtkGLExt(self):\r
-    self['CXXFLAGS'] += '`pkg-config gtkglext-1.0 --cflags` '\r
-    self['CCFLAGS'] += '`pkg-config gtkglext-1.0 --cflags` '\r
-    self['LINKFLAGS'] += '`pkg-config gtkglext-1.0 --libs-only-L` `pkg-config gtkglext-1.0 --libs-only-l` '      \r
-    \r
-  def usePNG(self):\r
-    self['CXXFLAGS'] += '`libpng-config --cflags` '\r
-    self['CCFLAGS'] += '`libpng-config --cflags` '\r
-    self['LINKFLAGS'] += '`libpng-config --ldflags` '\r
-\r
-  def usePThread(self):\r
-    if ( OS == 'Darwin' ):\r
-      self['LINKFLAGS'] += '-lpthread -Wl,-stack_size,0x400000 '\r
-    else:\r
-      self['LINKFLAGS'] += '-lpthread '\r
-\r
-  def CheckLDD(self, target, source, env):\r
-    file = target[0]\r
-    if (not os.path.isfile(file.abspath)):\r
-        print('ERROR: CheckLDD: target %s not found\n' % target[0])\r
-        Exit(1)\r
-    # not using os.popen3 as I want to check the return code\r
-    ldd = popen2.Popen3('`which ldd` -r %s' % target[0], 1)\r
-    stdout_lines = ldd.fromchild.readlines()\r
-    stderr_lines = ldd.childerr.readlines()\r
-    ldd_ret = ldd.wait()\r
-    del ldd\r
-    have_undef = 0\r
-    if ( ldd_ret != 0 ):\r
-        print "ERROR: ldd command returned with exit code %d" % ldd_ret\r
-        os.system('rm %s' % target[0])\r
-        Exit()\r
-    for i_line in stderr_lines:\r
-        print repr(i_line)\r
-        regex = re.compile('undefined symbol: (.*)\t\\((.*)\\)\n')\r
-        if ( regex.match(i_line) ):\r
-            symbol = regex.sub('\\1', i_line)\r
-            try:\r
-                env['ALLOWED_SYMBOLS'].index(symbol)\r
-            except:\r
-                have_undef = 1\r
-        else:\r
-            print "ERROR: failed to parse ldd stderr line: %s" % i_line\r
-            os.system('rm %s' % target[0])\r
-            Exit(1)\r
-    if ( have_undef ):\r
-        print "ERROR: undefined symbols"\r
-        os.system('rm %s' % target[0])\r
-        Exit(1)\r
-  \r
-  def SharedLibrarySafe(self, target, source):\r
-    self.SharedLibrary(target, source)\r
-    if (OS != 'Darwin'):\r
-      AddPostAction(target + '.so', self.CheckLDD)\r
-\r
-g_env = idEnvironment(ENV = os.environ, \r
-  CC = CC,\r
-  CXX = CXX,\r
-  LINK = LINK,\r
-  CCFLAGS = CCFLAGS,\r
-  CXXFLAGS = CXXFLAGS,\r
-  CPPPATH = CPPPATH,\r
-  LINKFLAGS = LINKFLAGS)\r
-\r
-# export the globals\r
-GLOBALS = 'g_env INSTALL SETUP g_cpu'\r
-\r
-radiant_makeversion('\\ngcc version: %s.%s.%s' % ( ver_cc[0], ver_cc[1], ver_cc[2] ) )\r
-\r
-# end general configuration ----------------------\r
-\r
-# targets ----------------------------------------\r
-\r
-Default('.')\r
-\r
-Export('GLOBALS ' + GLOBALS)\r
-BuildDir(g_build, '.', duplicate = 0)\r
-SConscript(g_build + '/SConscript')\r
-\r
-# end targets ------------------------------------\r
+       Help(\r
+"""\r
+======================================================================\r
+ZeroRadiant build system quick help\r
+\r
+You need scons v0.97.0d20070918.r2446 or newer\r
+\r
+Default build (release), just run scons at the toplevel\r
+\r
+debug build:\r
+$ scons config=debug\r
+======================================================================\r
+""" )\r
+       Return()\r
+\r
+active_configs = []\r
+\r
+# load up configurations from the save file\r
+if ( os.path.exists( conf_filename ) ):\r
+       f = open( conf_filename )\r
+       print 'reading saved configuration from site.conf'\r
+       try:\r
+               while ( True ):\r
+                       c = cPickle.load( f )\r
+                       active_configs.append( c )\r
+       except:\r
+               pass\r
+\r
+# read the command line and build configs\r
+config_statements = sys.argv[1:]\r
+active_configs = config.ConfigParser().parseStatements( active_configs, config_statements )\r
+assert( len( active_configs ) >= 1 )\r
+\r
+# save the config\r
+print 'saving updated configuration'\r
+f = open( conf_filename, 'wb' )\r
+for c in active_configs:\r
+       cPickle.dump( c, f, -1 )\r
+\r
+print 'emit build rules'\r
+for c in active_configs:\r
+       print 'emit configuration: %s' % repr( c )\r
+       c.emit()\r